blob: a9c62c6683c8c9499c7b566679fbc1646fe60b10 [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"
Alex Light163652e2020-01-08 15:18:25 -0800108#include "mirror/field.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000109#include "mirror/method.h"
110#include "mirror/method_handle_impl-inl.h"
Alex Lighta01de592016-11-15 10:43:06 -0800111#include "mirror/object.h"
Andreas Gampe52ecb652018-10-24 15:18:21 -0700112#include "mirror/object_array-alloc-inl.h"
113#include "mirror/object_array-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000114#include "mirror/object_array.h"
115#include "mirror/string.h"
Alex Lightc18eba32019-09-24 14:36:27 -0700116#include "mirror/var_handle.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -0700117#include "nativehelper/scoped_local_ref.h"
Alex Lighte77b48b2017-02-22 11:08:06 -0800118#include "non_debuggable_classes.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000119#include "obj_ptr.h"
Alex Lighta01de592016-11-15 10:43:06 -0800120#include "object_lock.h"
Alex Light24627892019-11-06 10:28:21 -0800121#include "reflective_value_visitor.h"
Alex Lighta01de592016-11-15 10:43:06 -0800122#include "runtime.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000123#include "runtime_globals.h"
Alex Light986914b2019-11-19 01:12:25 +0000124#include "scoped_thread_state_change.h"
Vladimir Marko5924a4a2018-05-29 17:40:41 +0100125#include "stack.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000126#include "thread.h"
Vladimir Marko5924a4a2018-05-29 17:40:41 +0100127#include "thread_list.h"
Alex Lighta26e3492017-06-27 17:55:37 -0700128#include "ti_breakpoint.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000129#include "ti_class_definition.h"
Alex Lighteb98b082017-01-25 13:02:32 -0800130#include "ti_class_loader.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000131#include "ti_heap.h"
132#include "ti_logging.h"
133#include "ti_thread.h"
Alex Light0e692732017-01-10 15:00:05 -0800134#include "transform.h"
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700135#include "verifier/class_verifier.h"
Andreas Gampe6d7abbd2017-04-24 13:19:09 -0700136#include "verifier/verifier_enums.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000137#include "well_known_classes.h"
138#include "write_barrier.h"
Alex Lighta01de592016-11-15 10:43:06 -0800139
140namespace openjdkjvmti {
141
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000142// Debug check to force us to directly check we saw all methods and fields exactly once directly.
143// Normally we don't need to do this since if any are missing the count will be different
144constexpr bool kCheckAllMethodsSeenOnce = art::kIsDebugBuild;
145
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800146using android::base::StringPrintf;
147
Alex Lighteee0bd42017-02-14 15:31:45 +0000148// A helper that fills in a classes obsolete_methods_ and obsolete_dex_caches_ classExt fields as
149// they are created. This ensures that we can always call any method of an obsolete ArtMethod object
150// almost as soon as they are created since the GetObsoleteDexCache method will succeed.
151class ObsoleteMap {
152 public:
Alex Lighte7a33542019-04-10 14:22:49 -0700153 art::ArtMethod* FindObsoleteVersion(art::ArtMethod* original) const
Alex Lighteee0bd42017-02-14 15:31:45 +0000154 REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
155 auto method_pair = id_map_.find(original);
156 if (method_pair != id_map_.end()) {
157 art::ArtMethod* res = obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(
158 method_pair->second, art::kRuntimePointerSize);
159 DCHECK(res != nullptr);
Alex Lighteee0bd42017-02-14 15:31:45 +0000160 return res;
161 } else {
162 return nullptr;
163 }
164 }
165
166 void RecordObsolete(art::ArtMethod* original, art::ArtMethod* obsolete)
167 REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
168 DCHECK(original != nullptr);
169 DCHECK(obsolete != nullptr);
170 int32_t slot = next_free_slot_++;
171 DCHECK_LT(slot, obsolete_methods_->GetLength());
172 DCHECK(nullptr ==
173 obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(slot, art::kRuntimePointerSize));
174 DCHECK(nullptr == obsolete_dex_caches_->Get(slot));
175 obsolete_methods_->SetElementPtrSize(slot, obsolete, art::kRuntimePointerSize);
176 obsolete_dex_caches_->Set(slot, original_dex_cache_);
177 id_map_.insert({original, slot});
178 }
179
180 ObsoleteMap(art::ObjPtr<art::mirror::PointerArray> obsolete_methods,
181 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> obsolete_dex_caches,
182 art::ObjPtr<art::mirror::DexCache> original_dex_cache)
183 : next_free_slot_(0),
184 obsolete_methods_(obsolete_methods),
185 obsolete_dex_caches_(obsolete_dex_caches),
186 original_dex_cache_(original_dex_cache) {
187 // Figure out where the first unused slot in the obsolete_methods_ array is.
188 while (obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(
189 next_free_slot_, art::kRuntimePointerSize) != nullptr) {
190 DCHECK(obsolete_dex_caches_->Get(next_free_slot_) != nullptr);
191 next_free_slot_++;
192 }
193 // Sanity check that the same slot in obsolete_dex_caches_ is free.
194 DCHECK(obsolete_dex_caches_->Get(next_free_slot_) == nullptr);
195 }
196
Alex Lighte7a33542019-04-10 14:22:49 -0700197 struct ObsoleteMethodPair {
198 art::ArtMethod* old_method;
199 art::ArtMethod* obsolete_method;
200 };
201
Vladimir Markoeab02482019-05-09 10:28:17 +0100202 class ObsoleteMapIter {
Alex Lighte7a33542019-04-10 14:22:49 -0700203 public:
Vladimir Markoeab02482019-05-09 10:28:17 +0100204 using iterator_category = std::forward_iterator_tag;
205 using value_type = ObsoleteMethodPair;
206 using difference_type = ptrdiff_t;
207 using pointer = void; // Unsupported.
208 using reference = void; // Unsupported.
209
Alex Lighte7a33542019-04-10 14:22:49 -0700210 ObsoleteMethodPair operator*() const
211 REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
Vladimir Markoeab02482019-05-09 10:28:17 +0100212 art::ArtMethod* obsolete = map_->obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(
213 iter_->second, art::kRuntimePointerSize);
Alex Lighte7a33542019-04-10 14:22:49 -0700214 DCHECK(obsolete != nullptr);
215 return { iter_->first, obsolete };
216 }
217
218 bool operator==(ObsoleteMapIter other) const {
219 return map_ == other.map_ && iter_ == other.iter_;
220 }
221
222 bool operator!=(ObsoleteMapIter other) const {
223 return !(*this == other);
224 }
225
Vladimir Markoeab02482019-05-09 10:28:17 +0100226 ObsoleteMapIter operator++(int) {
Alex Lighte7a33542019-04-10 14:22:49 -0700227 ObsoleteMapIter retval = *this;
228 ++(*this);
229 return retval;
230 }
231
Vladimir Markoeab02482019-05-09 10:28:17 +0100232 ObsoleteMapIter operator++() {
Alex Lighte7a33542019-04-10 14:22:49 -0700233 ++iter_;
234 return *this;
235 }
236
237 private:
238 ObsoleteMapIter(const ObsoleteMap* map,
239 std::unordered_map<art::ArtMethod*, int32_t>::const_iterator iter)
240 : map_(map), iter_(iter) {}
241
242 const ObsoleteMap* map_;
Vladimir Markoeab02482019-05-09 10:28:17 +0100243 std::unordered_map<art::ArtMethod*, int32_t>::const_iterator iter_;
Alex Lighte7a33542019-04-10 14:22:49 -0700244
245 friend class ObsoleteMap;
246 };
247
248 ObsoleteMapIter end() const {
249 return ObsoleteMapIter(this, id_map_.cend());
250 }
251
252 ObsoleteMapIter begin() const {
253 return ObsoleteMapIter(this, id_map_.cbegin());
254 }
255
Alex Lighteee0bd42017-02-14 15:31:45 +0000256 private:
257 int32_t next_free_slot_;
258 std::unordered_map<art::ArtMethod*, int32_t> id_map_;
259 // Pointers to the fields in mirror::ClassExt. These can be held as ObjPtr since this is only used
260 // when we have an exclusive mutator_lock_ (i.e. all threads are suspended).
261 art::ObjPtr<art::mirror::PointerArray> obsolete_methods_;
262 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> obsolete_dex_caches_;
263 art::ObjPtr<art::mirror::DexCache> original_dex_cache_;
264};
265
Alex Lightdba61482016-12-21 08:20:29 -0800266// This visitor walks thread stacks and allocates and sets up the obsolete methods. It also does
267// some basic sanity checks that the obsolete method is sane.
268class ObsoleteMethodStackVisitor : public art::StackVisitor {
269 protected:
270 ObsoleteMethodStackVisitor(
271 art::Thread* thread,
272 art::LinearAlloc* allocator,
273 const std::unordered_set<art::ArtMethod*>& obsoleted_methods,
Alex Lighteee0bd42017-02-14 15:31:45 +0000274 ObsoleteMap* obsolete_maps)
Alex Lightdba61482016-12-21 08:20:29 -0800275 : StackVisitor(thread,
Andreas Gampe6e897762018-10-16 13:09:32 -0700276 /*context=*/nullptr,
Alex Lightdba61482016-12-21 08:20:29 -0800277 StackVisitor::StackWalkKind::kIncludeInlinedFrames),
278 allocator_(allocator),
279 obsoleted_methods_(obsoleted_methods),
Alex Light4ba388a2017-01-27 10:26:49 -0800280 obsolete_maps_(obsolete_maps) { }
Alex Lightdba61482016-12-21 08:20:29 -0800281
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100282 ~ObsoleteMethodStackVisitor() override {}
Alex Lightdba61482016-12-21 08:20:29 -0800283
284 public:
285 // Returns true if we successfully installed obsolete methods on this thread, filling
286 // obsolete_maps_ with the translations if needed. Returns false and fills error_msg if we fail.
287 // The stack is cleaned up when we fail.
Alex Light007ada22017-01-10 13:33:56 -0800288 static void UpdateObsoleteFrames(
Alex Lightdba61482016-12-21 08:20:29 -0800289 art::Thread* thread,
290 art::LinearAlloc* allocator,
291 const std::unordered_set<art::ArtMethod*>& obsoleted_methods,
Alex Lighteee0bd42017-02-14 15:31:45 +0000292 ObsoleteMap* obsolete_maps)
Alex Light007ada22017-01-10 13:33:56 -0800293 REQUIRES(art::Locks::mutator_lock_) {
Alex Lightdba61482016-12-21 08:20:29 -0800294 ObsoleteMethodStackVisitor visitor(thread,
295 allocator,
296 obsoleted_methods,
Alex Light007ada22017-01-10 13:33:56 -0800297 obsolete_maps);
Alex Lightdba61482016-12-21 08:20:29 -0800298 visitor.WalkStack();
Alex Lightdba61482016-12-21 08:20:29 -0800299 }
300
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100301 bool VisitFrame() override REQUIRES(art::Locks::mutator_lock_) {
Alex Lighteee0bd42017-02-14 15:31:45 +0000302 art::ScopedAssertNoThreadSuspension snts("Fixing up the stack for obsolete methods.");
Alex Lightdba61482016-12-21 08:20:29 -0800303 art::ArtMethod* old_method = GetMethod();
Alex Lightdba61482016-12-21 08:20:29 -0800304 if (obsoleted_methods_.find(old_method) != obsoleted_methods_.end()) {
Alex Lightdba61482016-12-21 08:20:29 -0800305 // We cannot ensure that the right dex file is used in inlined frames so we don't support
306 // redefining them.
Nicolas Geoffray226805d2018-12-14 10:59:02 +0000307 DCHECK(!IsInInlinedFrame()) << "Inlined frames are not supported when using redefinition: "
308 << old_method->PrettyMethod() << " is inlined into "
309 << GetOuterMethod()->PrettyMethod();
Alex Lighteee0bd42017-02-14 15:31:45 +0000310 art::ArtMethod* new_obsolete_method = obsolete_maps_->FindObsoleteVersion(old_method);
311 if (new_obsolete_method == nullptr) {
Alex Lightdba61482016-12-21 08:20:29 -0800312 // Create a new Obsolete Method and put it in the list.
313 art::Runtime* runtime = art::Runtime::Current();
314 art::ClassLinker* cl = runtime->GetClassLinker();
315 auto ptr_size = cl->GetImagePointerSize();
316 const size_t method_size = art::ArtMethod::Size(ptr_size);
Alex Light5c11a792017-03-10 14:29:22 -0800317 auto* method_storage = allocator_->Alloc(art::Thread::Current(), method_size);
Alex Light007ada22017-01-10 13:33:56 -0800318 CHECK(method_storage != nullptr) << "Unable to allocate storage for obsolete version of '"
319 << old_method->PrettyMethod() << "'";
Alex Lightdba61482016-12-21 08:20:29 -0800320 new_obsolete_method = new (method_storage) art::ArtMethod();
321 new_obsolete_method->CopyFrom(old_method, ptr_size);
322 DCHECK_EQ(new_obsolete_method->GetDeclaringClass(), old_method->GetDeclaringClass());
323 new_obsolete_method->SetIsObsolete();
Alex Lightfcbafb32017-02-02 15:09:54 -0800324 new_obsolete_method->SetDontCompile();
Alex Lightdb01a092017-04-03 15:39:55 -0700325 cl->SetEntryPointsForObsoleteMethod(new_obsolete_method);
Alex Lighteee0bd42017-02-14 15:31:45 +0000326 obsolete_maps_->RecordObsolete(old_method, new_obsolete_method);
Alex Lightdba61482016-12-21 08:20:29 -0800327 }
328 DCHECK(new_obsolete_method != nullptr);
329 SetMethod(new_obsolete_method);
330 }
331 return true;
332 }
333
334 private:
335 // The linear allocator we should use to make new methods.
336 art::LinearAlloc* allocator_;
337 // The set of all methods which could be obsoleted.
338 const std::unordered_set<art::ArtMethod*>& obsoleted_methods_;
339 // A map from the original to the newly allocated obsolete method for frames on this thread. The
Alex Lighteee0bd42017-02-14 15:31:45 +0000340 // values in this map are added to the obsolete_methods_ (and obsolete_dex_caches_) fields of
341 // the redefined classes ClassExt as it is filled.
342 ObsoleteMap* obsolete_maps_;
Alex Lightdba61482016-12-21 08:20:29 -0800343};
344
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000345template <RedefinitionType kType>
346jvmtiError
347Redefiner::IsModifiableClassGeneric(jvmtiEnv* env, jclass klass, jboolean* is_redefinable) {
348 if (env == nullptr) {
349 return ERR(INVALID_ENVIRONMENT);
350 }
Alex Lighte4a88632017-01-10 07:41:24 -0800351 art::Thread* self = art::Thread::Current();
352 art::ScopedObjectAccess soa(self);
353 art::StackHandleScope<1> hs(self);
354 art::ObjPtr<art::mirror::Object> obj(self->DecodeJObject(klass));
Alex Light413a8ad2019-02-14 10:19:44 -0800355 if (obj.IsNull() || !obj->IsClass()) {
Alex Lighte4a88632017-01-10 07:41:24 -0800356 return ERR(INVALID_CLASS);
357 }
358 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(obj->AsClass()));
359 std::string err_unused;
360 *is_redefinable =
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000361 Redefiner::GetClassRedefinitionError<kType>(h_klass, &err_unused) != ERR(UNMODIFIABLE_CLASS)
362 ? JNI_TRUE
363 : JNI_FALSE;
Alex Lighte4a88632017-01-10 07:41:24 -0800364 return OK;
365}
366
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000367jvmtiError
368Redefiner::IsStructurallyModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_redefinable) {
369 return Redefiner::IsModifiableClassGeneric<RedefinitionType::kStructural>(
370 env, klass, is_redefinable);
371}
372
373jvmtiError Redefiner::IsModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_redefinable) {
374 return Redefiner::IsModifiableClassGeneric<RedefinitionType::kNormal>(env, klass, is_redefinable);
375}
376
377template <RedefinitionType kType>
378jvmtiError Redefiner::GetClassRedefinitionError(jclass klass, /*out*/ std::string* error_msg) {
Alex Light9e7859c2018-04-05 13:49:43 -0700379 art::Thread* self = art::Thread::Current();
380 art::ScopedObjectAccess soa(self);
381 art::StackHandleScope<1> hs(self);
382 art::ObjPtr<art::mirror::Object> obj(self->DecodeJObject(klass));
Alex Light413a8ad2019-02-14 10:19:44 -0800383 if (obj.IsNull() || !obj->IsClass()) {
Alex Light9e7859c2018-04-05 13:49:43 -0700384 return ERR(INVALID_CLASS);
385 }
386 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(obj->AsClass()));
Alex Lightd55b8442019-10-15 15:46:07 -0700387 return Redefiner::GetClassRedefinitionError<kType>(h_klass, error_msg);
Alex Light9e7859c2018-04-05 13:49:43 -0700388}
389
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000390template <RedefinitionType kType>
Alex Lighte4a88632017-01-10 07:41:24 -0800391jvmtiError Redefiner::GetClassRedefinitionError(art::Handle<art::mirror::Class> klass,
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000392 /*out*/ std::string* error_msg) {
393 art::Thread* self = art::Thread::Current();
Alex Light9e7859c2018-04-05 13:49:43 -0700394 if (!klass->IsResolved()) {
395 // It's only a problem to try to retransform/redefine a unprepared class if it's happening on
396 // the same thread as the class-linking process. If it's on another thread we will be able to
397 // wait for the preparation to finish and continue from there.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000398 if (klass->GetLockOwnerThreadId() == self->GetThreadId()) {
Alex Light9e7859c2018-04-05 13:49:43 -0700399 *error_msg = "Modification of class " + klass->PrettyClass() +
400 " from within the classes ClassLoad callback is not supported to prevent deadlocks." +
401 " Please use ClassFileLoadHook directly instead.";
402 return ERR(INTERNAL);
403 } else {
404 LOG(WARNING) << klass->PrettyClass() << " is not yet resolved. Attempting to transform "
405 << "it could cause arbitrary length waits as the class is being resolved.";
406 }
407 }
Alex Lighte4a88632017-01-10 07:41:24 -0800408 if (klass->IsPrimitive()) {
409 *error_msg = "Modification of primitive classes is not supported";
410 return ERR(UNMODIFIABLE_CLASS);
411 } else if (klass->IsInterface()) {
412 *error_msg = "Modification of Interface classes is currently not supported";
413 return ERR(UNMODIFIABLE_CLASS);
Alex Light09f274f2017-02-21 15:00:48 -0800414 } else if (klass->IsStringClass()) {
415 *error_msg = "Modification of String class is not supported";
416 return ERR(UNMODIFIABLE_CLASS);
Alex Lighte4a88632017-01-10 07:41:24 -0800417 } else if (klass->IsArrayClass()) {
418 *error_msg = "Modification of Array classes is not supported";
419 return ERR(UNMODIFIABLE_CLASS);
420 } else if (klass->IsProxyClass()) {
421 *error_msg = "Modification of proxy classes is not supported";
422 return ERR(UNMODIFIABLE_CLASS);
423 }
424
Alex Lighte77b48b2017-02-22 11:08:06 -0800425 for (jclass c : art::NonDebuggableClasses::GetNonDebuggableClasses()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000426 if (klass.Get() == self->DecodeJObject(c)->AsClass()) {
Alex Lighte77b48b2017-02-22 11:08:06 -0800427 *error_msg = "Class might have stack frames that cannot be made obsolete";
428 return ERR(UNMODIFIABLE_CLASS);
429 }
430 }
431
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000432 if (kType == RedefinitionType::kStructural) {
Alex Lightfb119572019-09-18 15:04:53 -0700433 // Class initialization interacts really badly with structural redefinition since we need to
434 // make the old class obsolete. We currently just blanket don't allow it.
435 // TODO It might be nice to allow this at some point.
436 if (klass->IsInitializing() &&
437 !klass->IsInitialized() &&
438 klass->GetClinitThreadId() == self->GetTid()) {
439 // We are in the class-init running on this thread.
440 *error_msg = "Modification of class " + klass->PrettyClass() + " during class" +
441 " initialization is not allowed.";
442 return ERR(INTERNAL);
443 }
444 if (!art::Runtime::Current()->GetClassLinker()->EnsureInitialized(
445 self, klass, /*can_init_fields=*/true, /*can_init_parents=*/true)) {
446 self->AssertPendingException();
447 *error_msg = "Class " + klass->PrettyClass() + " failed initialization. Structural" +
448 " redefinition of erroneous classes is not allowed. Failure was: " +
449 self->GetException()->Dump();
450 self->ClearException();
451 return ERR(INVALID_CLASS);
452 }
Alex Lightf1b18fa2019-11-11 14:22:00 -0800453 if (klass->IsMirrored()) {
454 std::string pc(klass->PrettyClass());
455 *error_msg = StringPrintf("Class %s is a mirror class and cannot be structurally redefined.",
456 pc.c_str());
457 return ERR(UNMODIFIABLE_CLASS);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000458 }
459 // Check Thread specifically since it's not a root but too many things reach into it with Unsafe
460 // too allow structural redefinition.
461 if (klass->IsAssignableFrom(
462 self->DecodeJObject(art::WellKnownClasses::java_lang_Thread)->AsClass())) {
463 *error_msg =
464 "java.lang.Thread has fields accessed using sun.misc.unsafe directly. It is not "
465 "safe to structurally redefine it.";
466 return ERR(UNMODIFIABLE_CLASS);
467 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000468 // Check for fields/methods which were returned before moving to index jni id type.
469 // TODO We might want to rework how this is done. Once full redefinition is implemented we will
470 // need to check any subtypes too.
471 art::ObjPtr<art::mirror::ClassExt> ext(klass->GetExtData());
472 if (!ext.IsNull()) {
Alex Lightbc19b752019-12-02 18:54:13 +0000473 if (ext->HasInstanceFieldPointerIdMarker() ||
474 ext->HasMethodPointerIdMarker() ||
475 ext->HasStaticFieldPointerIdMarker()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000476 return ERR(UNMODIFIABLE_CLASS);
477 }
478 }
479 }
Alex Lighte4a88632017-01-10 07:41:24 -0800480 return OK;
481}
482
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000483template jvmtiError Redefiner::GetClassRedefinitionError<RedefinitionType::kNormal>(
484 art::Handle<art::mirror::Class> klass, /*out*/ std::string* error_msg);
485template jvmtiError Redefiner::GetClassRedefinitionError<RedefinitionType::kStructural>(
486 art::Handle<art::mirror::Class> klass, /*out*/ std::string* error_msg);
487
Alex Lighta01de592016-11-15 10:43:06 -0800488// Moves dex data to an anonymous, read-only mmap'd region.
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100489art::MemMap Redefiner::MoveDataToMemMap(const std::string& original_location,
490 art::ArrayRef<const unsigned char> data,
491 std::string* error_msg) {
492 art::MemMap map = art::MemMap::MapAnonymous(
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800493 StringPrintf("%s-transformed", original_location.c_str()).c_str(),
Alex Lightb7354d52017-03-30 15:17:01 -0700494 data.size(),
Alex Lighta01de592016-11-15 10:43:06 -0800495 PROT_READ|PROT_WRITE,
Andreas Gampe6e897762018-10-16 13:09:32 -0700496 /*low_4gb=*/ false,
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100497 error_msg);
498 if (LIKELY(map.IsValid())) {
499 memcpy(map.Begin(), data.data(), data.size());
500 // Make the dex files mmap read only. This matches how other DexFiles are mmaped and prevents
501 // programs from corrupting it.
502 map.Protect(PROT_READ);
Alex Lighta01de592016-11-15 10:43:06 -0800503 }
Alex Lighta01de592016-11-15 10:43:06 -0800504 return map;
505}
506
Alex Lighta7e38d82017-01-19 14:57:28 -0800507Redefiner::ClassRedefinition::ClassRedefinition(
508 Redefiner* driver,
509 jclass klass,
510 const art::DexFile* redefined_dex_file,
511 const char* class_sig,
Vladimir Markoe1993c72017-06-14 17:01:38 +0100512 art::ArrayRef<const unsigned char> orig_dex_file) :
Alex Lighta7e38d82017-01-19 14:57:28 -0800513 driver_(driver),
514 klass_(klass),
515 dex_file_(redefined_dex_file),
516 class_sig_(class_sig),
517 original_dex_file_(orig_dex_file) {
Alex Light0e692732017-01-10 15:00:05 -0800518 GetMirrorClass()->MonitorEnter(driver_->self_);
519}
520
521Redefiner::ClassRedefinition::~ClassRedefinition() {
522 if (driver_ != nullptr) {
523 GetMirrorClass()->MonitorExit(driver_->self_);
524 }
525}
526
Alex Lightd55b8442019-10-15 15:46:07 -0700527template<RedefinitionType kType>
528jvmtiError Redefiner::RedefineClassesGeneric(jvmtiEnv* jenv,
529 jint class_count,
530 const jvmtiClassDefinition* definitions) {
Alex Light3732beb2019-10-04 13:35:34 -0700531 art::Runtime* runtime = art::Runtime::Current();
532 art::Thread* self = art::Thread::Current();
533 ArtJvmTiEnv* env = ArtJvmTiEnv::AsArtJvmTiEnv(jenv);
Alex Light0e692732017-01-10 15:00:05 -0800534 if (env == nullptr) {
Alex Light3732beb2019-10-04 13:35:34 -0700535 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE env was null!";
Alex Light0e692732017-01-10 15:00:05 -0800536 return ERR(INVALID_ENVIRONMENT);
537 } else if (class_count < 0) {
Alex Light3732beb2019-10-04 13:35:34 -0700538 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE class_count was less then 0";
Alex Light0e692732017-01-10 15:00:05 -0800539 return ERR(ILLEGAL_ARGUMENT);
540 } else if (class_count == 0) {
541 // We don't actually need to do anything. Just return OK.
542 return OK;
543 } else if (definitions == nullptr) {
Alex Light3732beb2019-10-04 13:35:34 -0700544 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE null definitions!";
Alex Light0e692732017-01-10 15:00:05 -0800545 return ERR(NULL_POINTER);
546 }
Alex Light3732beb2019-10-04 13:35:34 -0700547 std::string error_msg;
Alex Light6ac57502017-01-19 15:05:06 -0800548 std::vector<ArtClassDefinition> def_vector;
549 def_vector.reserve(class_count);
550 for (jint i = 0; i < class_count; i++) {
Alex Lightd55b8442019-10-15 15:46:07 -0700551 jvmtiError res = Redefiner::GetClassRedefinitionError<RedefinitionType::kNormal>(
552 definitions[i].klass, &error_msg);
Alex Lightce6ee702017-03-06 15:46:43 -0800553 if (res != OK) {
Alex Light3732beb2019-10-04 13:35:34 -0700554 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE " << error_msg;
Alex Lightce6ee702017-03-06 15:46:43 -0800555 return res;
Alex Lightce6ee702017-03-06 15:46:43 -0800556 }
Alex Light6ac57502017-01-19 15:05:06 -0800557 ArtClassDefinition def;
Alex Light64e4c142018-01-30 13:46:37 -0800558 res = def.Init(self, definitions[i]);
Alex Light6ac57502017-01-19 15:05:06 -0800559 if (res != OK) {
Alex Light3732beb2019-10-04 13:35:34 -0700560 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE bad definition " << i;
Alex Light6ac57502017-01-19 15:05:06 -0800561 return res;
562 }
563 def_vector.push_back(std::move(def));
564 }
565 // Call all the transformation events.
Alex Lightd55b8442019-10-15 15:46:07 -0700566 Transformer::RetransformClassesDirect<kType>(self, &def_vector);
567 if (kType == RedefinitionType::kStructural) {
568 Transformer::RetransformClassesDirect<RedefinitionType::kNormal>(self, &def_vector);
569 }
570 jvmtiError res = RedefineClassesDirect(env, runtime, self, def_vector, kType, &error_msg);
Alex Light3732beb2019-10-04 13:35:34 -0700571 if (res != OK) {
572 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE " << error_msg;
573 }
574 return res;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000575}
576
Alex Lightd55b8442019-10-15 15:46:07 -0700577jvmtiError Redefiner::StructurallyRedefineClasses(jvmtiEnv* jenv,
578 jint class_count,
579 const jvmtiClassDefinition* definitions) {
580 ArtJvmTiEnv* art_env = ArtJvmTiEnv::AsArtJvmTiEnv(jenv);
581 if (art_env == nullptr) {
582 return ERR(INVALID_ENVIRONMENT);
583 } else if (art_env->capabilities.can_redefine_classes != 1) {
584 return ERR(MUST_POSSESS_CAPABILITY);
585 }
586 return RedefineClassesGeneric<RedefinitionType::kStructural>(jenv, class_count, definitions);
587}
588
589jvmtiError Redefiner::RedefineClasses(jvmtiEnv* jenv,
590 jint class_count,
591 const jvmtiClassDefinition* definitions) {
592 return RedefineClassesGeneric<RedefinitionType::kNormal>(jenv, class_count, definitions);
593}
594
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000595jvmtiError Redefiner::StructurallyRedefineClassDirect(jvmtiEnv* env,
596 jclass klass,
597 const unsigned char* data,
598 jint data_size) {
599 if (env == nullptr) {
600 return ERR(INVALID_ENVIRONMENT);
601 } else if (ArtJvmTiEnv::AsArtJvmTiEnv(env)->capabilities.can_redefine_classes != 1) {
602 JVMTI_LOG(INFO, env) << "Does not have can_redefine_classes cap!";
603 return ERR(MUST_POSSESS_CAPABILITY);
604 }
605 std::vector<ArtClassDefinition> acds;
606 ArtClassDefinition acd;
607 jvmtiError err = acd.Init(
608 art::Thread::Current(),
609 jvmtiClassDefinition{ .klass = klass, .class_byte_count = data_size, .class_bytes = data });
610 if (err != OK) {
611 return err;
612 }
613 acds.push_back(std::move(acd));
614 std::string err_msg;
615 err = RedefineClassesDirect(ArtJvmTiEnv::AsArtJvmTiEnv(env),
616 art::Runtime::Current(),
617 art::Thread::Current(),
618 acds,
619 RedefinitionType::kStructural,
620 &err_msg);
621 if (err != OK) {
622 JVMTI_LOG(WARNING, env) << "Failed structural redefinition: " << err_msg;
623 }
624 return err;
Alex Light6ac57502017-01-19 15:05:06 -0800625}
626
627jvmtiError Redefiner::RedefineClassesDirect(ArtJvmTiEnv* env,
628 art::Runtime* runtime,
629 art::Thread* self,
630 const std::vector<ArtClassDefinition>& definitions,
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000631 RedefinitionType type,
Alex Light6ac57502017-01-19 15:05:06 -0800632 std::string* error_msg) {
633 DCHECK(env != nullptr);
634 if (definitions.size() == 0) {
635 // We don't actually need to do anything. Just return OK.
636 return OK;
637 }
Alex Lightc2d0c962019-10-23 14:14:25 -0700638 // We need to fiddle with the verification class flags. To do this we need to make sure there are
639 // no concurrent redefinitions of the same class at the same time. For simplicity and because
640 // this is not expected to be a common occurrence we will just wrap the whole thing in a TOP-level
641 // lock.
642
Alex Light0e692732017-01-10 15:00:05 -0800643 // Stop JIT for the duration of this redefine since the JIT might concurrently compile a method we
644 // are going to redefine.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000645 // TODO We should prevent user-code suspensions to make sure this isn't held for too long.
Alex Light0e692732017-01-10 15:00:05 -0800646 art::jit::ScopedJitSuspend suspend_jit;
647 // Get shared mutator lock so we can lock all the classes.
648 art::ScopedObjectAccess soa(self);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000649 Redefiner r(env, runtime, self, type, error_msg);
Alex Light6ac57502017-01-19 15:05:06 -0800650 for (const ArtClassDefinition& def : definitions) {
651 // Only try to transform classes that have been modified.
Alex Light40528472017-03-28 09:07:36 -0700652 if (def.IsModified()) {
Alex Light6ac57502017-01-19 15:05:06 -0800653 jvmtiError res = r.AddRedefinition(env, def);
654 if (res != OK) {
655 return res;
656 }
Alex Light0e692732017-01-10 15:00:05 -0800657 }
658 }
659 return r.Run();
660}
661
Alex Light6ac57502017-01-19 15:05:06 -0800662jvmtiError Redefiner::AddRedefinition(ArtJvmTiEnv* env, const ArtClassDefinition& def) {
Alex Light0e692732017-01-10 15:00:05 -0800663 std::string original_dex_location;
664 jvmtiError ret = OK;
Alex Lightb7354d52017-03-30 15:17:01 -0700665 if ((ret = GetClassLocation(env, def.GetClass(), &original_dex_location))) {
Alex Light0e692732017-01-10 15:00:05 -0800666 *error_msg_ = "Unable to get original dex file location!";
667 return ret;
668 }
Alex Light52a2db52017-01-19 23:00:21 +0000669 char* generic_ptr_unused = nullptr;
670 char* signature_ptr = nullptr;
Alex Lightb7354d52017-03-30 15:17:01 -0700671 if ((ret = env->GetClassSignature(def.GetClass(), &signature_ptr, &generic_ptr_unused)) != OK) {
Alex Light6ac57502017-01-19 15:05:06 -0800672 *error_msg_ = "Unable to get class signature!";
673 return ret;
Alex Light52a2db52017-01-19 23:00:21 +0000674 }
Andreas Gampe54711412017-02-21 12:41:43 -0800675 JvmtiUniquePtr<char> generic_unique_ptr(MakeJvmtiUniquePtr(env, generic_ptr_unused));
676 JvmtiUniquePtr<char> signature_unique_ptr(MakeJvmtiUniquePtr(env, signature_ptr));
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100677 art::MemMap map = MoveDataToMemMap(original_dex_location, def.GetDexData(), error_msg_);
Alex Light6ac57502017-01-19 15:05:06 -0800678 std::ostringstream os;
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100679 if (!map.IsValid()) {
Alex Lightb7354d52017-03-30 15:17:01 -0700680 os << "Failed to create anonymous mmap for modified dex file of class " << def.GetName()
Alex Light0e692732017-01-10 15:00:05 -0800681 << "in dex file " << original_dex_location << " because: " << *error_msg_;
682 *error_msg_ = os.str();
Alex Lighta01de592016-11-15 10:43:06 -0800683 return ERR(OUT_OF_MEMORY);
684 }
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100685 if (map.Size() < sizeof(art::DexFile::Header)) {
Alex Light0e692732017-01-10 15:00:05 -0800686 *error_msg_ = "Could not read dex file header because dex_data was too short";
Alex Lighta01de592016-11-15 10:43:06 -0800687 return ERR(INVALID_CLASS_FORMAT);
688 }
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100689 std::string name = map.GetName();
690 uint32_t checksum = reinterpret_cast<const art::DexFile::Header*>(map.Begin())->checksum_;
David Sehr013fd802018-01-11 22:55:24 -0800691 const art::ArtDexFileLoader dex_file_loader;
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100692 std::unique_ptr<const art::DexFile> dex_file(dex_file_loader.Open(name,
David Sehr013fd802018-01-11 22:55:24 -0800693 checksum,
694 std::move(map),
Andreas Gampe6e897762018-10-16 13:09:32 -0700695 /*verify=*/true,
696 /*verify_checksum=*/true,
David Sehr013fd802018-01-11 22:55:24 -0800697 error_msg_));
Alex Lighta01de592016-11-15 10:43:06 -0800698 if (dex_file.get() == nullptr) {
Alex Lightb7354d52017-03-30 15:17:01 -0700699 os << "Unable to load modified dex file for " << def.GetName() << ": " << *error_msg_;
Alex Light0e692732017-01-10 15:00:05 -0800700 *error_msg_ = os.str();
Alex Lighta01de592016-11-15 10:43:06 -0800701 return ERR(INVALID_CLASS_FORMAT);
702 }
Alex Light0e692732017-01-10 15:00:05 -0800703 redefinitions_.push_back(
Alex Lighta7e38d82017-01-19 14:57:28 -0800704 Redefiner::ClassRedefinition(this,
Alex Lightb7354d52017-03-30 15:17:01 -0700705 def.GetClass(),
Alex Lighta7e38d82017-01-19 14:57:28 -0800706 dex_file.release(),
707 signature_ptr,
Alex Light40528472017-03-28 09:07:36 -0700708 def.GetNewOriginalDexFile()));
Alex Light0e692732017-01-10 15:00:05 -0800709 return OK;
Alex Lighta01de592016-11-15 10:43:06 -0800710}
711
Vladimir Marko4617d582019-03-28 13:48:31 +0000712art::ObjPtr<art::mirror::Class> Redefiner::ClassRedefinition::GetMirrorClass() {
Alex Light0e692732017-01-10 15:00:05 -0800713 return driver_->self_->DecodeJObject(klass_)->AsClass();
Alex Lighta01de592016-11-15 10:43:06 -0800714}
715
Vladimir Markoc524e9e2019-03-26 10:54:50 +0000716art::ObjPtr<art::mirror::ClassLoader> Redefiner::ClassRedefinition::GetClassLoader() {
Alex Lighta01de592016-11-15 10:43:06 -0800717 return GetMirrorClass()->GetClassLoader();
718}
719
Alex Light0e692732017-01-10 15:00:05 -0800720art::mirror::DexCache* Redefiner::ClassRedefinition::CreateNewDexCache(
721 art::Handle<art::mirror::ClassLoader> loader) {
Alex Light07f06212017-06-01 14:01:43 -0700722 art::StackHandleScope<2> hs(driver_->self_);
723 art::ClassLinker* cl = driver_->runtime_->GetClassLinker();
724 art::Handle<art::mirror::DexCache> cache(hs.NewHandle(
725 art::ObjPtr<art::mirror::DexCache>::DownCast(
Vladimir Markob4eb1b12018-05-24 11:09:38 +0100726 art::GetClassRoot<art::mirror::DexCache>(cl)->AllocObject(driver_->self_))));
Alex Light07f06212017-06-01 14:01:43 -0700727 if (cache.IsNull()) {
728 driver_->self_->AssertPendingOOMException();
729 return nullptr;
730 }
731 art::Handle<art::mirror::String> location(hs.NewHandle(
732 cl->GetInternTable()->InternStrong(dex_file_->GetLocation().c_str())));
733 if (location.IsNull()) {
734 driver_->self_->AssertPendingOOMException();
735 return nullptr;
736 }
737 art::WriterMutexLock mu(driver_->self_, *art::Locks::dex_lock_);
738 art::mirror::DexCache::InitializeDexCache(driver_->self_,
739 cache.Get(),
740 location.Get(),
741 dex_file_.get(),
742 loader.IsNull() ? driver_->runtime_->GetLinearAlloc()
743 : loader->GetAllocator(),
744 art::kRuntimePointerSize);
745 return cache.Get();
Alex Lighta01de592016-11-15 10:43:06 -0800746}
747
Alex Light0e692732017-01-10 15:00:05 -0800748void Redefiner::RecordFailure(jvmtiError result,
749 const std::string& class_sig,
750 const std::string& error_msg) {
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800751 *error_msg_ = StringPrintf("Unable to perform redefinition of '%s': %s",
Alex Light0e692732017-01-10 15:00:05 -0800752 class_sig.c_str(),
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800753 error_msg.c_str());
Alex Lighta01de592016-11-15 10:43:06 -0800754 result_ = result;
755}
756
Alex Light2f814aa2017-03-24 15:21:34 +0000757art::mirror::Object* Redefiner::ClassRedefinition::AllocateOrGetOriginalDexFile() {
Alex Lighta7e38d82017-01-19 14:57:28 -0800758 // If we have been specifically given a new set of bytes use that
759 if (original_dex_file_.size() != 0) {
Alex Light440b5d92017-01-24 15:32:25 -0800760 return art::mirror::ByteArray::AllocateAndFill(
761 driver_->self_,
Vladimir Markoe1993c72017-06-14 17:01:38 +0100762 reinterpret_cast<const signed char*>(original_dex_file_.data()),
Vladimir Markobcf17522018-06-01 13:14:32 +0100763 original_dex_file_.size()).Ptr();
Alex Lighta01de592016-11-15 10:43:06 -0800764 }
Alex Lighta7e38d82017-01-19 14:57:28 -0800765
766 // See if we already have one set.
767 art::ObjPtr<art::mirror::ClassExt> ext(GetMirrorClass()->GetExtData());
768 if (!ext.IsNull()) {
Alex Light2f814aa2017-03-24 15:21:34 +0000769 art::ObjPtr<art::mirror::Object> old_original_dex_file(ext->GetOriginalDexFile());
770 if (!old_original_dex_file.IsNull()) {
Alex Lighta7e38d82017-01-19 14:57:28 -0800771 // We do. Use it.
Alex Light2f814aa2017-03-24 15:21:34 +0000772 return old_original_dex_file.Ptr();
Alex Lighta7e38d82017-01-19 14:57:28 -0800773 }
Alex Lighta01de592016-11-15 10:43:06 -0800774 }
Alex Lighta7e38d82017-01-19 14:57:28 -0800775
Alex Light2f814aa2017-03-24 15:21:34 +0000776 // return the current dex_cache which has the dex file in it.
777 art::ObjPtr<art::mirror::DexCache> current_dex_cache(GetMirrorClass()->GetDexCache());
Alex Lighta7e38d82017-01-19 14:57:28 -0800778 // TODO Handle this or make it so it cannot happen.
Alex Light2f814aa2017-03-24 15:21:34 +0000779 if (current_dex_cache->GetDexFile()->NumClassDefs() != 1) {
Alex Lighta7e38d82017-01-19 14:57:28 -0800780 LOG(WARNING) << "Current dex file has more than one class in it. Calling RetransformClasses "
781 << "on this class might fail if no transformations are applied to it!";
Alex Lighta01de592016-11-15 10:43:06 -0800782 }
Alex Light2f814aa2017-03-24 15:21:34 +0000783 return current_dex_cache.Ptr();
Alex Lighta01de592016-11-15 10:43:06 -0800784}
785
Alex Lightdba61482016-12-21 08:20:29 -0800786struct CallbackCtx {
Alex Lighteee0bd42017-02-14 15:31:45 +0000787 ObsoleteMap* obsolete_map;
Alex Lightdba61482016-12-21 08:20:29 -0800788 art::LinearAlloc* allocator;
Alex Lightdba61482016-12-21 08:20:29 -0800789 std::unordered_set<art::ArtMethod*> obsolete_methods;
Alex Lightdba61482016-12-21 08:20:29 -0800790
Alex Lighteee0bd42017-02-14 15:31:45 +0000791 explicit CallbackCtx(ObsoleteMap* map, art::LinearAlloc* alloc)
792 : obsolete_map(map), allocator(alloc) {}
Alex Lightdba61482016-12-21 08:20:29 -0800793};
794
Alex Lightdba61482016-12-21 08:20:29 -0800795void DoAllocateObsoleteMethodsCallback(art::Thread* t, void* vdata) NO_THREAD_SAFETY_ANALYSIS {
796 CallbackCtx* data = reinterpret_cast<CallbackCtx*>(vdata);
Alex Light007ada22017-01-10 13:33:56 -0800797 ObsoleteMethodStackVisitor::UpdateObsoleteFrames(t,
798 data->allocator,
799 data->obsolete_methods,
Alex Lighteee0bd42017-02-14 15:31:45 +0000800 data->obsolete_map);
Alex Lightdba61482016-12-21 08:20:29 -0800801}
802
803// This creates any ArtMethod* structures needed for obsolete methods and ensures that the stack is
804// updated so they will be run.
Alex Light0e692732017-01-10 15:00:05 -0800805// TODO Rewrite so we can do this only once regardless of how many redefinitions there are.
Vladimir Markod93e3742018-07-18 10:58:13 +0100806void Redefiner::ClassRedefinition::FindAndAllocateObsoleteMethods(
807 art::ObjPtr<art::mirror::Class> art_klass) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000808 DCHECK(!IsStructuralRedefinition());
Alex Lightdba61482016-12-21 08:20:29 -0800809 art::ScopedAssertNoThreadSuspension ns("No thread suspension during thread stack walking");
Vladimir Markod93e3742018-07-18 10:58:13 +0100810 art::ObjPtr<art::mirror::ClassExt> ext = art_klass->GetExtData();
Alex Lightdba61482016-12-21 08:20:29 -0800811 CHECK(ext->GetObsoleteMethods() != nullptr);
Alex Light7916f202017-01-27 09:00:15 -0800812 art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
Alex Lighteee0bd42017-02-14 15:31:45 +0000813 // This holds pointers to the obsolete methods map fields which are updated as needed.
814 ObsoleteMap map(ext->GetObsoleteMethods(), ext->GetObsoleteDexCaches(), art_klass->GetDexCache());
815 CallbackCtx ctx(&map, linker->GetAllocatorForClassLoader(art_klass->GetClassLoader()));
Alex Lightdba61482016-12-21 08:20:29 -0800816 // Add all the declared methods to the map
817 for (auto& m : art_klass->GetDeclaredMethods(art::kRuntimePointerSize)) {
Alex Light7532d582017-02-13 16:36:06 -0800818 if (m.IsIntrinsic()) {
819 LOG(WARNING) << "Redefining intrinsic method " << m.PrettyMethod() << ". This may cause the "
820 << "unexpected use of the original definition of " << m.PrettyMethod() << "in "
821 << "methods that have already been compiled.";
822 }
Alex Lighteee0bd42017-02-14 15:31:45 +0000823 // It is possible to simply filter out some methods where they cannot really become obsolete,
824 // such as native methods and keep their original (possibly optimized) implementations. We don't
825 // do this, however, since we would need to mark these functions (still in the classes
826 // declared_methods array) as obsolete so we will find the correct dex file to get meta-data
827 // from (for example about stack-frame size). Furthermore we would be unable to get some useful
828 // error checking from the interpreter which ensure we don't try to start executing obsolete
829 // methods.
Nicolas Geoffray7558d272017-02-10 10:01:47 +0000830 ctx.obsolete_methods.insert(&m);
Alex Lightdba61482016-12-21 08:20:29 -0800831 }
832 {
Alex Light0e692732017-01-10 15:00:05 -0800833 art::MutexLock mu(driver_->self_, *art::Locks::thread_list_lock_);
Alex Lightdba61482016-12-21 08:20:29 -0800834 art::ThreadList* list = art::Runtime::Current()->GetThreadList();
835 list->ForEach(DoAllocateObsoleteMethodsCallback, static_cast<void*>(&ctx));
Vladimir Markoeab02482019-05-09 10:28:17 +0100836 // After we've done walking all threads' stacks and updating method pointers on them,
837 // update JIT data structures (used by the stack walk above) to point to the new methods.
Alex Lighte7a33542019-04-10 14:22:49 -0700838 art::jit::Jit* jit = art::Runtime::Current()->GetJit();
839 if (jit != nullptr) {
840 for (const ObsoleteMap::ObsoleteMethodPair& it : *ctx.obsolete_map) {
841 // Notify the JIT we are making this obsolete method. It will update the jit's internal
842 // structures to keep track of the new obsolete method.
843 jit->GetCodeCache()->MoveObsoleteMethod(it.old_method, it.obsolete_method);
844 }
845 }
Alex Lightdba61482016-12-21 08:20:29 -0800846 }
Alex Lightdba61482016-12-21 08:20:29 -0800847}
848
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000849namespace {
850template <typename T> struct SignatureType {};
851template <> struct SignatureType<art::ArtField> { using type = std::string_view; };
852template <> struct SignatureType<art::ArtMethod> { using type = art::Signature; };
853
854template <typename T> struct NameAndSignature {
855 public:
856 using SigType = typename SignatureType<T>::type;
857
858 NameAndSignature(const art::DexFile* dex_file, uint32_t id);
859
860 NameAndSignature(const std::string_view& name, const SigType& sig) : name_(name), sig_(sig) {}
861
862 bool operator==(const NameAndSignature<T>& o) {
863 return name_ == o.name_ && sig_ == o.sig_;
Alex Light6161f132017-01-25 10:30:20 -0800864 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000865
866 std::ostream& dump(std::ostream& os) const {
867 return os << "'" << name_ << "' (sig: " << sig_ << ")";
868 }
869
870 std::string ToString() const {
871 std::ostringstream os;
872 os << *this;
873 return os.str();
874 }
875
876 std::string_view name_;
877 SigType sig_;
878};
879
880template <typename T>
881std::ostream& operator<<(std::ostream& os, const NameAndSignature<T>& nas) {
882 return nas.dump(os);
Alex Light6161f132017-01-25 10:30:20 -0800883}
884
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000885using FieldNameAndSignature = NameAndSignature<art::ArtField>;
886template <>
887FieldNameAndSignature::NameAndSignature(const art::DexFile* dex_file, uint32_t id)
888 : FieldNameAndSignature(dex_file->GetFieldName(dex_file->GetFieldId(id)),
889 dex_file->GetFieldTypeDescriptor(dex_file->GetFieldId(id))) {}
890
891using MethodNameAndSignature = NameAndSignature<art::ArtMethod>;
892template <>
893MethodNameAndSignature::NameAndSignature(const art::DexFile* dex_file, uint32_t id)
894 : MethodNameAndSignature(dex_file->GetMethodName(dex_file->GetMethodId(id)),
895 dex_file->GetMethodSignature(dex_file->GetMethodId(id))) {}
896
897} // namespace
898
899void Redefiner::ClassRedefinition::RecordNewMethodAdded() {
900 DCHECK(driver_->IsStructuralRedefinition());
901 added_methods_ = true;
902}
903void Redefiner::ClassRedefinition::RecordNewFieldAdded() {
904 DCHECK(driver_->IsStructuralRedefinition());
905 added_fields_ = true;
906}
907
908bool Redefiner::ClassRedefinition::CheckMethods() {
Alex Light6161f132017-01-25 10:30:20 -0800909 art::StackHandleScope<1> hs(driver_->self_);
910 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
911 DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
912
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000913 // 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 -0700914 art::ClassAccessor accessor(*dex_file_, dex_file_->GetClassDef(0));
915 uint32_t num_new_method = accessor.NumMethods();
Alex Light6161f132017-01-25 10:30:20 -0800916 uint32_t num_old_method = h_klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize).size();
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000917 const bool is_structural = driver_->IsStructuralRedefinition();
918 if (!is_structural && num_new_method != num_old_method) {
Alex Light6161f132017-01-25 10:30:20 -0800919 bool bigger = num_new_method > num_old_method;
920 RecordFailure(bigger ? ERR(UNSUPPORTED_REDEFINITION_METHOD_ADDED)
921 : ERR(UNSUPPORTED_REDEFINITION_METHOD_DELETED),
922 StringPrintf("Total number of declared methods changed from %d to %d",
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000923 num_old_method,
924 num_new_method));
Alex Light6161f132017-01-25 10:30:20 -0800925 return false;
926 }
927
928 // Skip all of the fields. We should have already checked this.
Alex Light6161f132017-01-25 10:30:20 -0800929 // Check each of the methods. NB we don't need to specifically check for removals since the 2 dex
930 // files have the same number of methods, which means there must be an equal amount of additions
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -0700931 // and removals. We should have already checked the fields.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000932 const art::DexFile& old_dex_file = h_klass->GetDexFile();
933 art::ClassAccessor old_accessor(old_dex_file, *h_klass->GetClassDef());
934 // We need this to check for methods going missing in structural cases.
935 std::vector<bool> seen_old_methods(
936 (kCheckAllMethodsSeenOnce || is_structural) ? old_accessor.NumMethods() : 0, false);
937 const auto old_methods = old_accessor.GetMethods();
938 for (const art::ClassAccessor::Method& new_method : accessor.GetMethods()) {
Alex Light6161f132017-01-25 10:30:20 -0800939 // Get the data on the method we are searching for
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000940 MethodNameAndSignature new_method_id(dex_file_.get(), new_method.GetIndex());
941 const auto old_iter =
942 std::find_if(old_methods.cbegin(), old_methods.cend(), [&](const auto& current_old_method) {
943 MethodNameAndSignature old_method_id(&old_dex_file, current_old_method.GetIndex());
944 return old_method_id == new_method_id;
945 });
946
Alex Light986914b2019-11-19 01:12:25 +0000947 if (!new_method.IsStaticOrDirect()) {
948 RecordHasVirtualMembers();
949 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000950 if (old_iter == old_methods.cend()) {
Alex Light270db1c2019-12-03 12:20:01 +0000951 if (is_structural) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000952 RecordNewMethodAdded();
953 } else {
954 RecordFailure(
955 ERR(UNSUPPORTED_REDEFINITION_METHOD_ADDED),
956 StringPrintf("Unknown virtual method %s was added!", new_method_id.ToString().c_str()));
957 return false;
958 }
959 } else if (new_method.GetAccessFlags() != old_iter->GetAccessFlags()) {
960 RecordFailure(
961 ERR(UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED),
962 StringPrintf("method %s had different access flags", new_method_id.ToString().c_str()));
Alex Light6161f132017-01-25 10:30:20 -0800963 return false;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000964 } else if (kCheckAllMethodsSeenOnce || is_structural) {
965 // We only need this if we are structural.
966 size_t off = std::distance(old_methods.cbegin(), old_iter);
967 DCHECK(!seen_old_methods[off])
968 << "field at " << off << "("
969 << MethodNameAndSignature(&old_dex_file, old_iter->GetIndex()) << ") already seen?";
970 seen_old_methods[off] = true;
Alex Light6161f132017-01-25 10:30:20 -0800971 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000972 }
973 if ((kCheckAllMethodsSeenOnce || is_structural) &&
974 !std::all_of(seen_old_methods.cbegin(), seen_old_methods.cend(), [](auto x) { return x; })) {
975 DCHECK(is_structural) << "We should have hit an earlier failure before getting here!";
976 auto first_fail =
977 std::find_if(seen_old_methods.cbegin(), seen_old_methods.cend(), [](auto x) { return !x; });
978 auto off = std::distance(seen_old_methods.cbegin(), first_fail);
979 auto fail = old_methods.cbegin();
980 std::advance(fail, off);
981 RecordFailure(
982 ERR(UNSUPPORTED_REDEFINITION_METHOD_DELETED),
983 StringPrintf("Method %s missing!",
Alex Lightdaad67f2019-12-16 13:01:46 -0800984 MethodNameAndSignature(&old_dex_file, fail->GetIndex()).ToString().c_str()));
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000985 return false;
Alex Light6161f132017-01-25 10:30:20 -0800986 }
987 return true;
988}
989
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000990bool Redefiner::ClassRedefinition::CheckFields() {
Alex Light6161f132017-01-25 10:30:20 -0800991 art::StackHandleScope<1> hs(driver_->self_);
992 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
993 DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -0700994 art::ClassAccessor new_accessor(*dex_file_, dex_file_->GetClassDef(0));
995
Alex Light6161f132017-01-25 10:30:20 -0800996 const art::DexFile& old_dex_file = h_klass->GetDexFile();
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -0700997 art::ClassAccessor old_accessor(old_dex_file, *h_klass->GetClassDef());
Alex Light6161f132017-01-25 10:30:20 -0800998 // Instance and static fields can be differentiated by their flags so no need to check them
999 // separately.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001000 std::vector<bool> seen_old_fields(old_accessor.NumFields(), false);
1001 const auto old_fields = old_accessor.GetFields();
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -07001002 for (const art::ClassAccessor::Field& new_field : new_accessor.GetFields()) {
Alex Light6161f132017-01-25 10:30:20 -08001003 // Get the data on the method we are searching for
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001004 FieldNameAndSignature new_field_id(dex_file_.get(), new_field.GetIndex());
1005 const auto old_iter =
1006 std::find_if(old_fields.cbegin(), old_fields.cend(), [&](const auto& old_iter) {
1007 FieldNameAndSignature old_field_id(&old_dex_file, old_iter.GetIndex());
1008 return old_field_id == new_field_id;
1009 });
Alex Light986914b2019-11-19 01:12:25 +00001010 if (!new_field.IsStatic()) {
1011 RecordHasVirtualMembers();
1012 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001013 if (old_iter == old_fields.cend()) {
Alex Light270db1c2019-12-03 12:20:01 +00001014 if (driver_->IsStructuralRedefinition()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001015 RecordNewFieldAdded();
1016 } else {
1017 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
1018 StringPrintf("Unknown field %s added!", new_field_id.ToString().c_str()));
1019 return false;
1020 }
1021 } else if (new_field.GetAccessFlags() != old_iter->GetAccessFlags()) {
1022 RecordFailure(
1023 ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
1024 StringPrintf("Field %s had different access flags", new_field_id.ToString().c_str()));
Alex Light6161f132017-01-25 10:30:20 -08001025 return false;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001026 } else {
1027 size_t off = std::distance(old_fields.cbegin(), old_iter);
1028 DCHECK(!seen_old_fields[off])
1029 << "field at " << off << "(" << FieldNameAndSignature(&old_dex_file, old_iter->GetIndex())
1030 << ") already seen?";
1031 seen_old_fields[off] = true;
Alex Light6161f132017-01-25 10:30:20 -08001032 }
Alex Light6161f132017-01-25 10:30:20 -08001033 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001034 if (!std::all_of(seen_old_fields.cbegin(), seen_old_fields.cend(), [](auto x) { return x; })) {
1035 auto first_fail =
1036 std::find_if(seen_old_fields.cbegin(), seen_old_fields.cend(), [](auto x) { return !x; });
1037 auto off = std::distance(seen_old_fields.cbegin(), first_fail);
1038 auto fail = old_fields.cbegin();
1039 std::advance(fail, off);
1040 RecordFailure(
1041 ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
1042 StringPrintf("Field %s is missing!",
1043 FieldNameAndSignature(&old_dex_file, fail->GetIndex()).ToString().c_str()));
Alex Light6161f132017-01-25 10:30:20 -08001044 return false;
1045 }
1046 return true;
1047}
1048
Alex Light0e692732017-01-10 15:00:05 -08001049bool Redefiner::ClassRedefinition::CheckClass() {
Alex Light0e692732017-01-10 15:00:05 -08001050 art::StackHandleScope<1> hs(driver_->self_);
Alex Light460d1b42017-01-10 15:37:17 +00001051 // Easy check that only 1 class def is present.
1052 if (dex_file_->NumClassDefs() != 1) {
1053 RecordFailure(ERR(ILLEGAL_ARGUMENT),
1054 StringPrintf("Expected 1 class def in dex file but found %d",
1055 dex_file_->NumClassDefs()));
1056 return false;
1057 }
1058 // Get the ClassDef from the new DexFile.
1059 // Since the dex file has only a single class def the index is always 0.
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001060 const art::dex::ClassDef& def = dex_file_->GetClassDef(0);
Alex Light460d1b42017-01-10 15:37:17 +00001061 // Get the class as it is now.
1062 art::Handle<art::mirror::Class> current_class(hs.NewHandle(GetMirrorClass()));
1063
1064 // Check the access flags didn't change.
1065 if (def.GetJavaAccessFlags() != (current_class->GetAccessFlags() & art::kAccValidClassFlags)) {
1066 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED),
1067 "Cannot change modifiers of class by redefinition");
1068 return false;
1069 }
1070
1071 // Check class name.
1072 // These should have been checked by the dexfile verifier on load.
1073 DCHECK_NE(def.class_idx_, art::dex::TypeIndex::Invalid()) << "Invalid type index";
1074 const char* descriptor = dex_file_->StringByTypeIdx(def.class_idx_);
1075 DCHECK(descriptor != nullptr) << "Invalid dex file structure!";
1076 if (!current_class->DescriptorEquals(descriptor)) {
1077 std::string storage;
1078 RecordFailure(ERR(NAMES_DONT_MATCH),
1079 StringPrintf("expected file to contain class called '%s' but found '%s'!",
1080 current_class->GetDescriptor(&storage),
1081 descriptor));
1082 return false;
1083 }
1084 if (current_class->IsObjectClass()) {
1085 if (def.superclass_idx_ != art::dex::TypeIndex::Invalid()) {
1086 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Superclass added!");
1087 return false;
1088 }
1089 } else {
1090 const char* super_descriptor = dex_file_->StringByTypeIdx(def.superclass_idx_);
1091 DCHECK(descriptor != nullptr) << "Invalid dex file structure!";
1092 if (!current_class->GetSuperClass()->DescriptorEquals(super_descriptor)) {
1093 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Superclass changed");
1094 return false;
1095 }
1096 }
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001097 const art::dex::TypeList* interfaces = dex_file_->GetInterfacesList(def);
Alex Light460d1b42017-01-10 15:37:17 +00001098 if (interfaces == nullptr) {
1099 if (current_class->NumDirectInterfaces() != 0) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001100 // TODO Support this for kStructural.
Alex Light460d1b42017-01-10 15:37:17 +00001101 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Interfaces added");
1102 return false;
1103 }
1104 } else {
1105 DCHECK(!current_class->IsProxyClass());
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001106 const art::dex::TypeList* current_interfaces = current_class->GetInterfaceTypeList();
Alex Light460d1b42017-01-10 15:37:17 +00001107 if (current_interfaces == nullptr || current_interfaces->Size() != interfaces->Size()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001108 // TODO Support this for kStructural.
Alex Light460d1b42017-01-10 15:37:17 +00001109 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Interfaces added or removed");
1110 return false;
1111 }
1112 // The order of interfaces is (barely) meaningful so we error if it changes.
1113 const art::DexFile& orig_dex_file = current_class->GetDexFile();
1114 for (uint32_t i = 0; i < interfaces->Size(); i++) {
1115 if (strcmp(
1116 dex_file_->StringByTypeIdx(interfaces->GetTypeItem(i).type_idx_),
1117 orig_dex_file.StringByTypeIdx(current_interfaces->GetTypeItem(i).type_idx_)) != 0) {
1118 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED),
1119 "Interfaces changed or re-ordered");
1120 return false;
1121 }
1122 }
1123 }
Alex Light460d1b42017-01-10 15:37:17 +00001124 return true;
1125}
1126
Alex Light0e692732017-01-10 15:00:05 -08001127bool Redefiner::ClassRedefinition::CheckRedefinable() {
Alex Lighte4a88632017-01-10 07:41:24 -08001128 std::string err;
Alex Light0e692732017-01-10 15:00:05 -08001129 art::StackHandleScope<1> hs(driver_->self_);
Alex Light460d1b42017-01-10 15:37:17 +00001130
Alex Lighte4a88632017-01-10 07:41:24 -08001131 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001132 jvmtiError res;
Alex Lightd55b8442019-10-15 15:46:07 -07001133 if (driver_->type_ == RedefinitionType::kStructural && this->IsStructuralRedefinition()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001134 res = Redefiner::GetClassRedefinitionError<RedefinitionType::kStructural>(h_klass, &err);
Alex Lightd55b8442019-10-15 15:46:07 -07001135 } else {
1136 res = Redefiner::GetClassRedefinitionError<RedefinitionType::kNormal>(h_klass, &err);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001137 }
Alex Lighte4a88632017-01-10 07:41:24 -08001138 if (res != OK) {
1139 RecordFailure(res, err);
1140 return false;
1141 } else {
1142 return true;
1143 }
Alex Light460d1b42017-01-10 15:37:17 +00001144}
1145
Alex Light0e692732017-01-10 15:00:05 -08001146bool Redefiner::ClassRedefinition::CheckRedefinitionIsValid() {
Alex Lightd55b8442019-10-15 15:46:07 -07001147 return CheckClass() && CheckFields() && CheckMethods() && CheckRedefinable();
Alex Light460d1b42017-01-10 15:37:17 +00001148}
1149
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001150class RedefinitionDataIter;
1151
Alex Light0e692732017-01-10 15:00:05 -08001152// A wrapper that lets us hold onto the arbitrary sized data needed for redefinitions in a
1153// reasonably sane way. This adds no fields to the normal ObjectArray. By doing this we can avoid
1154// having to deal with the fact that we need to hold an arbitrary number of references live.
1155class RedefinitionDataHolder {
1156 public:
1157 enum DataSlot : int32_t {
1158 kSlotSourceClassLoader = 0,
1159 kSlotJavaDexFile = 1,
1160 kSlotNewDexFileCookie = 2,
1161 kSlotNewDexCache = 3,
1162 kSlotMirrorClass = 4,
Alex Lighta7e38d82017-01-19 14:57:28 -08001163 kSlotOrigDexFile = 5,
Alex Light1e3926a2017-04-07 10:38:06 -07001164 kSlotOldObsoleteMethods = 6,
1165 kSlotOldDexCaches = 7,
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001166 kSlotNewClassObject = 8,
Alex Light986914b2019-11-19 01:12:25 +00001167 kSlotOldInstanceObjects = 9,
1168 kSlotNewInstanceObjects = 10,
Alex Light270db1c2019-12-03 12:20:01 +00001169 kSlotOldClasses = 11,
1170 kSlotNewClasses = 12,
Alex Light0e692732017-01-10 15:00:05 -08001171
1172 // Must be last one.
Alex Light270db1c2019-12-03 12:20:01 +00001173 kNumSlots = 13,
Alex Light0e692732017-01-10 15:00:05 -08001174 };
1175
1176 // This needs to have a HandleScope passed in that is capable of creating a new Handle without
1177 // overflowing. Only one handle will be created. This object has a lifetime identical to that of
1178 // the passed in handle-scope.
1179 RedefinitionDataHolder(art::StackHandleScope<1>* hs,
1180 art::Runtime* runtime,
1181 art::Thread* self,
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001182 std::vector<Redefiner::ClassRedefinition>* redefinitions)
1183 REQUIRES_SHARED(art::Locks::mutator_lock_) :
Vladimir Markob4eb1b12018-05-24 11:09:38 +01001184 arr_(hs->NewHandle(art::mirror::ObjectArray<art::mirror::Object>::Alloc(
1185 self,
1186 art::GetClassRoot<art::mirror::ObjectArray<art::mirror::Object>>(runtime->GetClassLinker()),
1187 redefinitions->size() * kNumSlots))),
Alex Lightfb537082019-12-10 14:38:34 -08001188 redefinitions_(redefinitions),
1189 initialized_(redefinitions_->size(), false),
1190 actually_structural_(redefinitions_->size(), false),
1191 initial_structural_(redefinitions_->size(), false) {}
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 Lightfb537082019-12-10 14:38:34 -08001263 bool IsInitialized(jint klass_index) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1264 return initialized_[klass_index];
1265 }
1266 bool IsActuallyStructural(jint klass_index) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1267 return actually_structural_[klass_index];
1268 }
1269
1270 bool IsInitialStructural(jint klass_index) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1271 return initial_structural_[klass_index];
1272 }
Alex Light986914b2019-11-19 01:12:25 +00001273
Vladimir Markod93e3742018-07-18 10:58:13 +01001274 void SetSourceClassLoader(jint klass_index, art::ObjPtr<art::mirror::ClassLoader> loader)
Alex Light0e692732017-01-10 15:00:05 -08001275 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1276 SetSlot(klass_index, kSlotSourceClassLoader, loader);
1277 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001278 void SetJavaDexFile(jint klass_index, art::ObjPtr<art::mirror::Object> dexfile)
Alex Light0e692732017-01-10 15:00:05 -08001279 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1280 SetSlot(klass_index, kSlotJavaDexFile, dexfile);
1281 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001282 void SetNewDexFileCookie(jint klass_index, art::ObjPtr<art::mirror::LongArray> cookie)
Alex Light0e692732017-01-10 15:00:05 -08001283 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1284 SetSlot(klass_index, kSlotNewDexFileCookie, cookie);
1285 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001286 void SetNewDexCache(jint klass_index, art::ObjPtr<art::mirror::DexCache> cache)
Alex Light0e692732017-01-10 15:00:05 -08001287 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1288 SetSlot(klass_index, kSlotNewDexCache, cache);
1289 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001290 void SetMirrorClass(jint klass_index, art::ObjPtr<art::mirror::Class> klass)
Alex Light0e692732017-01-10 15:00:05 -08001291 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1292 SetSlot(klass_index, kSlotMirrorClass, klass);
1293 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001294 void SetOriginalDexFile(jint klass_index, art::ObjPtr<art::mirror::Object> bytes)
Alex Lighta7e38d82017-01-19 14:57:28 -08001295 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1296 SetSlot(klass_index, kSlotOrigDexFile, bytes);
1297 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001298 void SetOldObsoleteMethods(jint klass_index, art::ObjPtr<art::mirror::PointerArray> methods)
Alex Light1e3926a2017-04-07 10:38:06 -07001299 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1300 SetSlot(klass_index, kSlotOldObsoleteMethods, methods);
1301 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001302 void SetOldDexCaches(jint klass_index,
1303 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> caches)
Alex Light1e3926a2017-04-07 10:38:06 -07001304 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1305 SetSlot(klass_index, kSlotOldDexCaches, caches);
1306 }
Alex Light0e692732017-01-10 15:00:05 -08001307
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001308 void SetNewClassObject(jint klass_index, art::ObjPtr<art::mirror::Class> klass)
1309 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1310 SetSlot(klass_index, kSlotNewClassObject, klass);
1311 }
1312
Alex Light986914b2019-11-19 01:12:25 +00001313 void SetOldInstanceObjects(jint klass_index,
1314 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)
1315 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1316 SetSlot(klass_index, kSlotOldInstanceObjects, objs);
1317 }
1318 void SetNewInstanceObjects(jint klass_index,
1319 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)
1320 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1321 SetSlot(klass_index, kSlotNewInstanceObjects, objs);
1322 }
Alex Light270db1c2019-12-03 12:20:01 +00001323 void SetOldClasses(jint klass_index,
1324 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)
1325 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1326 SetSlot(klass_index, kSlotOldClasses, klasses);
1327 }
1328 void SetNewClasses(jint klass_index,
1329 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)
1330 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1331 SetSlot(klass_index, kSlotNewClasses, klasses);
1332 }
Alex Lightfb537082019-12-10 14:38:34 -08001333 void SetInitialized(jint klass_index) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1334 initialized_[klass_index] = true;
1335 }
1336 void SetActuallyStructural(jint klass_index) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1337 actually_structural_[klass_index] = true;
1338 }
1339 void SetInitialStructural(jint klass_index) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1340 initial_structural_[klass_index] = true;
1341 }
Alex Light8c889d22017-02-06 13:58:27 -08001342 int32_t Length() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light0e692732017-01-10 15:00:05 -08001343 return arr_->GetLength() / kNumSlots;
1344 }
1345
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001346 std::vector<Redefiner::ClassRedefinition>* GetRedefinitions()
1347 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1348 return redefinitions_;
1349 }
1350
1351 bool operator==(const RedefinitionDataHolder& other) const
1352 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1353 return arr_.Get() == other.arr_.Get();
1354 }
1355
1356 bool operator!=(const RedefinitionDataHolder& other) const
1357 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1358 return !(*this == other);
1359 }
1360
1361 RedefinitionDataIter begin() REQUIRES_SHARED(art::Locks::mutator_lock_);
1362 RedefinitionDataIter end() REQUIRES_SHARED(art::Locks::mutator_lock_);
1363
Alex Light0e692732017-01-10 15:00:05 -08001364 private:
Alex Light8c889d22017-02-06 13:58:27 -08001365 mutable art::Handle<art::mirror::ObjectArray<art::mirror::Object>> arr_;
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001366 std::vector<Redefiner::ClassRedefinition>* redefinitions_;
Alex Lightfb537082019-12-10 14:38:34 -08001367 // Used to mark a particular redefinition as fully initialized.
1368 std::vector<bool> initialized_;
1369 // Used to mark a redefinition as 'actually' structural. That is either the redefinition is
1370 // structural or a superclass is.
1371 std::vector<bool> actually_structural_;
1372 // Used to mark a redefinition as the initial structural redefinition. This redefinition will take
1373 // care of updating all of its subtypes.
1374 std::vector<bool> initial_structural_;
Alex Light0e692732017-01-10 15:00:05 -08001375
Vladimir Markod93e3742018-07-18 10:58:13 +01001376 art::ObjPtr<art::mirror::Object> GetSlot(jint klass_index, DataSlot slot) const
1377 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light0e692732017-01-10 15:00:05 -08001378 DCHECK_LT(klass_index, Length());
1379 return arr_->Get((kNumSlots * klass_index) + slot);
1380 }
1381
1382 void SetSlot(jint klass_index,
1383 DataSlot slot,
1384 art::ObjPtr<art::mirror::Object> obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1385 DCHECK(!art::Runtime::Current()->IsActiveTransaction());
1386 DCHECK_LT(klass_index, Length());
1387 arr_->Set<false>((kNumSlots * klass_index) + slot, obj);
1388 }
1389
1390 DISALLOW_COPY_AND_ASSIGN(RedefinitionDataHolder);
1391};
1392
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001393class RedefinitionDataIter {
1394 public:
1395 RedefinitionDataIter(int32_t idx, RedefinitionDataHolder& holder) : idx_(idx), holder_(holder) {}
1396
1397 RedefinitionDataIter(const RedefinitionDataIter&) = default;
1398 RedefinitionDataIter(RedefinitionDataIter&&) = default;
1399 RedefinitionDataIter& operator=(const RedefinitionDataIter&) = default;
1400 RedefinitionDataIter& operator=(RedefinitionDataIter&&) = default;
1401
1402 bool operator==(const RedefinitionDataIter& other) const
1403 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1404 return idx_ == other.idx_ && holder_ == other.holder_;
1405 }
1406
1407 bool operator!=(const RedefinitionDataIter& other) const
1408 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1409 return !(*this == other);
1410 }
1411
1412 RedefinitionDataIter operator++() { // Value after modification.
1413 idx_++;
1414 return *this;
1415 }
1416
1417 RedefinitionDataIter operator++(int) {
1418 RedefinitionDataIter temp = *this;
1419 idx_++;
1420 return temp;
1421 }
1422
1423 RedefinitionDataIter operator+(ssize_t delta) const {
1424 RedefinitionDataIter temp = *this;
1425 temp += delta;
1426 return temp;
1427 }
1428
1429 RedefinitionDataIter& operator+=(ssize_t delta) {
1430 idx_ += delta;
1431 return *this;
1432 }
1433
Alex Light986914b2019-11-19 01:12:25 +00001434 // Compat for STL iterators.
1435 RedefinitionDataIter& operator*() {
1436 return *this;
1437 }
1438
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001439 Redefiner::ClassRedefinition& GetRedefinition() REQUIRES_SHARED(art::Locks::mutator_lock_) {
1440 return (*holder_.GetRedefinitions())[idx_];
1441 }
1442
1443 RedefinitionDataHolder& GetHolder() {
1444 return holder_;
1445 }
1446
Vladimir Markod93e3742018-07-18 10:58:13 +01001447 art::ObjPtr<art::mirror::ClassLoader> GetSourceClassLoader() const
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001448 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1449 return holder_.GetSourceClassLoader(idx_);
1450 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001451 art::ObjPtr<art::mirror::Object> GetJavaDexFile() const
1452 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001453 return holder_.GetJavaDexFile(idx_);
1454 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001455 art::ObjPtr<art::mirror::LongArray> GetNewDexFileCookie() const
1456 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001457 return holder_.GetNewDexFileCookie(idx_);
1458 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001459 art::ObjPtr<art::mirror::DexCache> GetNewDexCache() const
1460 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001461 return holder_.GetNewDexCache(idx_);
1462 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001463 art::ObjPtr<art::mirror::Class> GetMirrorClass() const
1464 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001465 return holder_.GetMirrorClass(idx_);
1466 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001467 art::ObjPtr<art::mirror::Object> GetOriginalDexFile() const
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001468 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light2f814aa2017-03-24 15:21:34 +00001469 return holder_.GetOriginalDexFile(idx_);
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001470 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001471 art::ObjPtr<art::mirror::PointerArray> GetOldObsoleteMethods() const
Alex Light1e3926a2017-04-07 10:38:06 -07001472 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1473 return holder_.GetOldObsoleteMethods(idx_);
1474 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001475 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> GetOldDexCaches() const
Alex Light1e3926a2017-04-07 10:38:06 -07001476 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1477 return holder_.GetOldDexCaches(idx_);
1478 }
1479
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001480 art::ObjPtr<art::mirror::Class> GetNewClassObject() const
1481 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1482 return holder_.GetNewClassObject(idx_);
1483 }
1484
Alex Light986914b2019-11-19 01:12:25 +00001485 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> GetOldInstanceObjects() const
1486 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1487 return holder_.GetOldInstanceObjects(idx_);
1488 }
1489 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> GetNewInstanceObjects() const
1490 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1491 return holder_.GetNewInstanceObjects(idx_);
1492 }
Alex Light270db1c2019-12-03 12:20:01 +00001493 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> GetOldClasses() const
1494 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1495 return holder_.GetOldClasses(idx_);
1496 }
1497 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> GetNewClasses() const
1498 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1499 return holder_.GetNewClasses(idx_);
1500 }
Alex Lightfb537082019-12-10 14:38:34 -08001501 bool IsInitialized() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1502 return holder_.IsInitialized(idx_);
1503 }
1504 bool IsActuallyStructural() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1505 return holder_.IsActuallyStructural(idx_);
1506 }
1507 bool IsInitialStructural() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1508 return holder_.IsInitialStructural(idx_);
1509 }
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001510 int32_t GetIndex() const {
1511 return idx_;
1512 }
1513
1514 void SetSourceClassLoader(art::mirror::ClassLoader* loader)
1515 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1516 holder_.SetSourceClassLoader(idx_, loader);
1517 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001518 void SetJavaDexFile(art::ObjPtr<art::mirror::Object> dexfile)
1519 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001520 holder_.SetJavaDexFile(idx_, dexfile);
1521 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001522 void SetNewDexFileCookie(art::ObjPtr<art::mirror::LongArray> cookie)
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001523 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1524 holder_.SetNewDexFileCookie(idx_, cookie);
1525 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001526 void SetNewDexCache(art::ObjPtr<art::mirror::DexCache> cache)
1527 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001528 holder_.SetNewDexCache(idx_, cache);
1529 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001530 void SetMirrorClass(art::ObjPtr<art::mirror::Class> klass)
1531 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001532 holder_.SetMirrorClass(idx_, klass);
1533 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001534 void SetOriginalDexFile(art::ObjPtr<art::mirror::Object> bytes)
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001535 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light2f814aa2017-03-24 15:21:34 +00001536 holder_.SetOriginalDexFile(idx_, bytes);
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001537 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001538 void SetOldObsoleteMethods(art::ObjPtr<art::mirror::PointerArray> methods)
Alex Light1e3926a2017-04-07 10:38:06 -07001539 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1540 holder_.SetOldObsoleteMethods(idx_, methods);
1541 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001542 void SetOldDexCaches(art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> caches)
Alex Light1e3926a2017-04-07 10:38:06 -07001543 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1544 holder_.SetOldDexCaches(idx_, caches);
1545 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001546 void SetNewClassObject(art::ObjPtr<art::mirror::Class> klass)
1547 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1548 holder_.SetNewClassObject(idx_, klass);
1549 }
Alex Light986914b2019-11-19 01:12:25 +00001550 void SetOldInstanceObjects(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)
1551 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1552 holder_.SetOldInstanceObjects(idx_, objs);
1553 }
1554 void SetNewInstanceObjects(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> objs)
1555 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1556 holder_.SetNewInstanceObjects(idx_, objs);
1557 }
Alex Light270db1c2019-12-03 12:20:01 +00001558 void SetOldClasses(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)
1559 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1560 holder_.SetOldClasses(idx_, klasses);
1561 }
1562 void SetNewClasses(art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> klasses)
1563 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1564 holder_.SetNewClasses(idx_, klasses);
1565 }
Alex Lightfb537082019-12-10 14:38:34 -08001566 void SetInitialized() REQUIRES_SHARED(art::Locks::mutator_lock_) {
1567 holder_.SetInitialized(idx_);
1568 }
1569 void SetActuallyStructural() REQUIRES_SHARED(art::Locks::mutator_lock_) {
1570 holder_.SetActuallyStructural(idx_);
1571 }
1572 void SetInitialStructural() REQUIRES_SHARED(art::Locks::mutator_lock_) {
1573 holder_.SetInitialStructural(idx_);
1574 }
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001575
1576 private:
1577 int32_t idx_;
1578 RedefinitionDataHolder& holder_;
1579};
1580
1581RedefinitionDataIter RedefinitionDataHolder::begin() {
1582 return RedefinitionDataIter(0, *this);
1583}
1584
1585RedefinitionDataIter RedefinitionDataHolder::end() {
1586 return RedefinitionDataIter(Length(), *this);
1587}
1588
1589bool Redefiner::ClassRedefinition::CheckVerification(const RedefinitionDataIter& iter) {
Alex Light8c889d22017-02-06 13:58:27 -08001590 DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
1591 art::StackHandleScope<2> hs(driver_->self_);
1592 std::string error;
1593 // TODO Make verification log level lower
Andreas Gampe6d7abbd2017-04-24 13:19:09 -07001594 art::verifier::FailureKind failure =
Andreas Gampea43ba3d2019-03-13 15:49:20 -07001595 art::verifier::ClassVerifier::VerifyClass(driver_->self_,
1596 dex_file_.get(),
1597 hs.NewHandle(iter.GetNewDexCache()),
1598 hs.NewHandle(GetClassLoader()),
1599 /*class_def=*/ dex_file_->GetClassDef(0),
1600 /*callbacks=*/ nullptr,
1601 /*allow_soft_failures=*/ true,
1602 /*log_level=*/
1603 art::verifier::HardFailLogMode::kLogWarning,
1604 art::Runtime::Current()->GetTargetSdkVersion(),
1605 &error);
Alex Light53330612017-10-04 15:29:53 -07001606 switch (failure) {
1607 case art::verifier::FailureKind::kNoFailure:
Alex Lightb1eebde2019-10-22 16:30:47 +00001608 // TODO It is possible that by doing redefinition previous NO_COMPILE verification failures
1609 // were fixed. It would be nice to reflect this in the new implementations.
1610 return true;
Alex Light53330612017-10-04 15:29:53 -07001611 case art::verifier::FailureKind::kSoftFailure:
Alex Lightb1eebde2019-10-22 16:30:47 +00001612 // Soft failures might require interpreter on some methods. It won't prevent redefinition but
1613 // it does mean we need to run the verifier again and potentially update method flags after
1614 // performing the swap.
1615 needs_reverify_ = true;
Alex Light53330612017-10-04 15:29:53 -07001616 return true;
1617 case art::verifier::FailureKind::kHardFailure: {
1618 RecordFailure(ERR(FAILS_VERIFICATION), "Failed to verify class. Error was: " + error);
1619 return false;
1620 }
Alex Light8c889d22017-02-06 13:58:27 -08001621 }
Alex Light8c889d22017-02-06 13:58:27 -08001622}
1623
Alex Light1babae02017-02-01 15:35:34 -08001624// Looks through the previously allocated cookies to see if we need to update them with another new
1625// dexfile. This is so that even if multiple classes with the same classloader are redefined at
1626// once they are all added to the classloader.
1627bool Redefiner::ClassRedefinition::AllocateAndRememberNewDexFileCookie(
Alex Light1babae02017-02-01 15:35:34 -08001628 art::Handle<art::mirror::ClassLoader> source_class_loader,
1629 art::Handle<art::mirror::Object> dex_file_obj,
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001630 /*out*/RedefinitionDataIter* cur_data) {
Alex Light1babae02017-02-01 15:35:34 -08001631 art::StackHandleScope<2> hs(driver_->self_);
1632 art::MutableHandle<art::mirror::LongArray> old_cookie(
1633 hs.NewHandle<art::mirror::LongArray>(nullptr));
1634 bool has_older_cookie = false;
1635 // See if we already have a cookie that a previous redefinition got from the same classloader.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001636 for (auto old_data = cur_data->GetHolder().begin(); old_data != *cur_data; ++old_data) {
1637 if (old_data.GetSourceClassLoader() == source_class_loader.Get()) {
Alex Light1babae02017-02-01 15:35:34 -08001638 // Since every instance of this classloader should have the same cookie associated with it we
1639 // can stop looking here.
1640 has_older_cookie = true;
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001641 old_cookie.Assign(old_data.GetNewDexFileCookie());
Alex Light1babae02017-02-01 15:35:34 -08001642 break;
1643 }
1644 }
1645 if (old_cookie.IsNull()) {
1646 // No older cookie. Get it directly from the dex_file_obj
1647 // We should not have seen this classloader elsewhere.
1648 CHECK(!has_older_cookie);
1649 old_cookie.Assign(ClassLoaderHelper::GetDexFileCookie(dex_file_obj));
1650 }
1651 // Use the old cookie to generate the new one with the new DexFile* added in.
1652 art::Handle<art::mirror::LongArray>
1653 new_cookie(hs.NewHandle(ClassLoaderHelper::AllocateNewDexFileCookie(driver_->self_,
1654 old_cookie,
1655 dex_file_.get())));
1656 // Make sure the allocation worked.
1657 if (new_cookie.IsNull()) {
1658 return false;
1659 }
1660
1661 // Save the cookie.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001662 cur_data->SetNewDexFileCookie(new_cookie.Get());
Alex Light1babae02017-02-01 15:35:34 -08001663 // If there are other copies of this same classloader we need to make sure that we all have the
1664 // same cookie.
1665 if (has_older_cookie) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001666 for (auto old_data = cur_data->GetHolder().begin(); old_data != *cur_data; ++old_data) {
Alex Light1babae02017-02-01 15:35:34 -08001667 // We will let the GC take care of the cookie we allocated for this one.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001668 if (old_data.GetSourceClassLoader() == source_class_loader.Get()) {
1669 old_data.SetNewDexFileCookie(new_cookie.Get());
Alex Light1babae02017-02-01 15:35:34 -08001670 }
1671 }
1672 }
1673
1674 return true;
1675}
1676
Alex Lightfb537082019-12-10 14:38:34 -08001677bool CompareClasses(art::ObjPtr<art::mirror::Class> l, art::ObjPtr<art::mirror::Class> r)
1678 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1679 auto parents = [](art::ObjPtr<art::mirror::Class> c) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1680 uint32_t res = 0;
1681 while (!c->IsObjectClass()) {
1682 res++;
1683 c = c->GetSuperClass();
1684 }
1685 return res;
1686 };
1687 return parents(l.Ptr()) < parents(r.Ptr());
1688}
1689
Alex Light986914b2019-11-19 01:12:25 +00001690bool Redefiner::ClassRedefinition::CollectAndCreateNewInstances(
1691 /*out*/ RedefinitionDataIter* cur_data) {
Alex Lightfb537082019-12-10 14:38:34 -08001692 if (!cur_data->IsInitialStructural()) {
1693 // An earlier structural redefinition already remade all the instances.
Alex Light986914b2019-11-19 01:12:25 +00001694 return true;
1695 }
Alex Lightfb537082019-12-10 14:38:34 -08001696 art::gc::Heap* heap = driver_->runtime_->GetHeap();
Alex Light986914b2019-11-19 01:12:25 +00001697 art::VariableSizedHandleScope hs(driver_->self_);
1698 art::Handle<art::mirror::Class> old_klass(hs.NewHandle(cur_data->GetMirrorClass()));
1699 std::vector<art::Handle<art::mirror::Object>> old_instances;
Alex Light986914b2019-11-19 01:12:25 +00001700 auto is_instance = [&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light270db1c2019-12-03 12:20:01 +00001701 return obj->InstanceOf(old_klass.Get());
Alex Light986914b2019-11-19 01:12:25 +00001702 };
1703 heap->VisitObjects([&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1704 if (is_instance(obj)) {
Alex Light986914b2019-11-19 01:12:25 +00001705 old_instances.push_back(hs.NewHandle(obj));
1706 }
1707 });
1708 VLOG(plugin) << "Collected " << old_instances.size() << " instances to recreate!";
Alex Light270db1c2019-12-03 12:20:01 +00001709 art::Handle<art::mirror::ObjectArray<art::mirror::Class>> old_classes_arr(
Alex Lightfb537082019-12-10 14:38:34 -08001710 hs.NewHandle(cur_data->GetOldClasses()));
Alex Light270db1c2019-12-03 12:20:01 +00001711 art::Handle<art::mirror::ObjectArray<art::mirror::Class>> new_classes_arr(
Alex Lightfb537082019-12-10 14:38:34 -08001712 hs.NewHandle(cur_data->GetNewClasses()));
Alex Light3f4041b2020-01-09 12:59:22 -08001713 DCHECK_EQ(old_classes_arr->GetLength(), new_classes_arr->GetLength());
Alex Lightbaf938f2020-01-10 10:40:46 -08001714 DCHECK_GT(old_classes_arr->GetLength(), 0);
Alex Light986914b2019-11-19 01:12:25 +00001715 art::Handle<art::mirror::Class> obj_array_class(
1716 hs.NewHandle(art::GetClassRoot<art::mirror::ObjectArray<art::mirror::Object>>(
1717 driver_->runtime_->GetClassLinker())));
1718 art::Handle<art::mirror::ObjectArray<art::mirror::Object>> old_instances_arr(
1719 hs.NewHandle(art::mirror::ObjectArray<art::mirror::Object>::Alloc(
1720 driver_->self_, obj_array_class.Get(), old_instances.size())));
1721 if (old_instances_arr.IsNull()) {
1722 driver_->self_->AssertPendingOOMException();
1723 driver_->self_->ClearException();
1724 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate old_instance arrays!");
1725 return false;
1726 }
1727 for (uint32_t i = 0; i < old_instances.size(); ++i) {
1728 old_instances_arr->Set(i, old_instances[i].Get());
1729 }
1730 cur_data->SetOldInstanceObjects(old_instances_arr.Get());
1731
1732 art::Handle<art::mirror::ObjectArray<art::mirror::Object>> new_instances_arr(
1733 hs.NewHandle(art::mirror::ObjectArray<art::mirror::Object>::Alloc(
1734 driver_->self_, obj_array_class.Get(), old_instances.size())));
1735 if (new_instances_arr.IsNull()) {
1736 driver_->self_->AssertPendingOOMException();
1737 driver_->self_->ClearException();
1738 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate new_instance arrays!");
1739 return false;
1740 }
Alex Light270db1c2019-12-03 12:20:01 +00001741 for (auto pair : art::ZipCount(art::IterationRange(old_instances.begin(), old_instances.end()))) {
1742 art::Handle<art::mirror::Object> hinstance(pair.first);
1743 int32_t i = pair.second;
1744 auto iterator = art::ZipLeft(old_classes_arr.Iterate<art::mirror::Class>(),
1745 new_classes_arr.Iterate<art::mirror::Class>());
Alex Lightbaf938f2020-01-10 10:40:46 -08001746 auto it = std::find_if(iterator.begin(),
1747 iterator.end(),
1748 [&](auto class_pair) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1749 return class_pair.first == hinstance->GetClass();
1750 });
1751 DCHECK(it != iterator.end()) << "Unable to find class pair for "
1752 << hinstance->GetClass()->PrettyClass() << " (instance " << i
1753 << ")";
1754 auto [_, new_type] = *it;
Alex Light2f494282020-01-07 22:53:09 +00001755 // Make sure when allocating the new instance we don't add it's finalizer since we will directly
1756 // replace the old object in the finalizer reference. If we added it here to we would call
1757 // finalize twice.
1758 // NB If a type is changed from being non-finalizable to finalizable the finalizers on any
1759 // objects created before the redefine will never be called. This is (sort of) allowable by
1760 // the spec and greatly simplifies implementation.
1761 // TODO Make it so we will always call all finalizers, even if the object when it was created
1762 // wasn't finalizable. To do this we need to be careful of handling failure correctly and making
1763 // sure that objects aren't finalized multiple times and that instances of failed redefinitions
1764 // aren't finalized.
1765 art::ObjPtr<art::mirror::Object> new_instance(
1766 new_type->Alloc</*kIsInstrumented=*/true,
1767 art::mirror::Class::AddFinalizer::kNoAddFinalizer,
1768 /*kCheckAddFinalizer=*/false>(
1769 driver_->self_, driver_->runtime_->GetHeap()->GetCurrentAllocator()));
Alex Light986914b2019-11-19 01:12:25 +00001770 if (new_instance.IsNull()) {
1771 driver_->self_->AssertPendingOOMException();
1772 driver_->self_->ClearException();
1773 std::string msg(
1774 StringPrintf("Could not allocate instance %d of %zu", i, old_instances.size()));
1775 RecordFailure(ERR(OUT_OF_MEMORY), msg);
1776 return false;
1777 }
1778 new_instances_arr->Set(i, new_instance);
1779 }
1780 cur_data->SetNewInstanceObjects(new_instances_arr.Get());
1781 return true;
1782}
1783
Alex Lightfb537082019-12-10 14:38:34 -08001784bool Redefiner::ClassRedefinition::FinishRemainingCommonAllocations(
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001785 /*out*/RedefinitionDataIter* cur_data) {
Alex Light7916f202017-01-27 09:00:15 -08001786 art::ScopedObjectAccessUnchecked soa(driver_->self_);
Alex Lightfb537082019-12-10 14:38:34 -08001787 art::StackHandleScope<2> hs(driver_->self_);
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001788 cur_data->SetMirrorClass(GetMirrorClass());
Alex Lighta7e38d82017-01-19 14:57:28 -08001789 // This shouldn't allocate
1790 art::Handle<art::mirror::ClassLoader> loader(hs.NewHandle(GetClassLoader()));
Alex Light7916f202017-01-27 09:00:15 -08001791 // The bootclasspath is handled specially so it doesn't have a j.l.DexFile.
1792 if (!art::ClassLinker::IsBootClassLoader(soa, loader.Get())) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001793 cur_data->SetSourceClassLoader(loader.Get());
Alex Light7916f202017-01-27 09:00:15 -08001794 art::Handle<art::mirror::Object> dex_file_obj(hs.NewHandle(
1795 ClassLoaderHelper::FindSourceDexFileObject(driver_->self_, loader)));
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001796 cur_data->SetJavaDexFile(dex_file_obj.Get());
Andreas Gampefa4333d2017-02-14 11:10:34 -08001797 if (dex_file_obj == nullptr) {
Alex Light7916f202017-01-27 09:00:15 -08001798 RecordFailure(ERR(INTERNAL), "Unable to find dex file!");
1799 return false;
1800 }
Alex Light1babae02017-02-01 15:35:34 -08001801 // Allocate the new dex file cookie.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001802 if (!AllocateAndRememberNewDexFileCookie(loader, dex_file_obj, cur_data)) {
Alex Light7916f202017-01-27 09:00:15 -08001803 driver_->self_->AssertPendingOOMException();
1804 driver_->self_->ClearException();
1805 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate dex file array for class loader");
1806 return false;
1807 }
Alex Lighta7e38d82017-01-19 14:57:28 -08001808 }
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001809 cur_data->SetNewDexCache(CreateNewDexCache(loader));
1810 if (cur_data->GetNewDexCache() == nullptr) {
Vladimir Markocd556b02017-02-03 11:47:34 +00001811 driver_->self_->AssertPendingException();
Alex Lighta7e38d82017-01-19 14:57:28 -08001812 driver_->self_->ClearException();
1813 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate DexCache");
1814 return false;
1815 }
1816
1817 // We won't always need to set this field.
Alex Light2f814aa2017-03-24 15:21:34 +00001818 cur_data->SetOriginalDexFile(AllocateOrGetOriginalDexFile());
1819 if (cur_data->GetOriginalDexFile() == nullptr) {
Alex Lighta7e38d82017-01-19 14:57:28 -08001820 driver_->self_->AssertPendingOOMException();
1821 driver_->self_->ClearException();
1822 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate array for original dex file");
1823 return false;
1824 }
Alex Lightfb537082019-12-10 14:38:34 -08001825 return true;
1826}
1827
1828bool Redefiner::ClassRedefinition::FinishNewClassAllocations(RedefinitionDataHolder &holder,
1829 RedefinitionDataIter *cur_data) {
1830 if (cur_data->IsInitialized() || !cur_data->IsActuallyStructural()) {
1831 cur_data->SetInitialized();
1832 return true;
1833 }
1834
1835 art::VariableSizedHandleScope hs(driver_->self_);
1836 // If we weren't the lowest structural redef the superclass would have already initialized us.
1837 CHECK(IsStructuralRedefinition());
1838 CHECK(cur_data->IsInitialStructural()) << "Should have already been initialized by supertype";
1839 auto setup_single_redefinition =
1840 [this](RedefinitionDataIter* data, art::Handle<art::mirror::Class> super_class)
1841 REQUIRES_SHARED(art::Locks::mutator_lock_) -> art::ObjPtr<art::mirror::Class> {
1842 art::StackHandleScope<3> chs(driver_->self_);
1843 art::Handle<art::mirror::Class> nc(
1844 chs.NewHandle(AllocateNewClassObject(chs.NewHandle(data->GetMirrorClass()),
1845 super_class,
1846 chs.NewHandle(data->GetNewDexCache()),
1847 /*dex_class_def_index*/ 0)));
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001848 if (nc.IsNull()) {
Alex Lightfb537082019-12-10 14:38:34 -08001849 return nullptr;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001850 }
1851
Alex Lightfb537082019-12-10 14:38:34 -08001852 data->SetNewClassObject(nc.Get());
Alex Light24627892019-11-06 10:28:21 -08001853 // We really want to be able to resolve to the new class-object using this dex-cache for
1854 // verification work. Since we haven't put it in the class-table yet we wll just manually add it
1855 // to the dex-cache.
1856 // TODO: We should maybe do this in a better spot.
Alex Lightfb537082019-12-10 14:38:34 -08001857 data->GetNewDexCache()->SetResolvedType(nc->GetDexTypeIndex(), nc.Get());
1858 data->SetInitialized();
1859 return nc.Get();
1860 };
1861
1862 std::vector<art::Handle<art::mirror::Class>> old_types;
1863 {
1864 art::gc::Heap* heap = driver_->runtime_->GetHeap();
1865 art::Handle<art::mirror::Class>
1866 old_klass(hs.NewHandle(cur_data->GetMirrorClass()));
1867 if (setup_single_redefinition(cur_data, hs.NewHandle(old_klass->GetSuperClass())).IsNull()) {
1868 return false;
1869 }
1870 auto is_subtype = [&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1871 // We've already waited for class defines to be finished and paused them. All classes should be
1872 // either resolved or error. We don't need to do anything with error classes, since they cannot
1873 // be accessed in any observable way.
1874 return obj->IsClass() && obj->AsClass()->IsResolved() &&
1875 old_klass->IsAssignableFrom(obj->AsClass());
1876 };
1877 heap->VisitObjects([&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1878 if (is_subtype(obj)) {
1879 old_types.push_back(hs.NewHandle(obj->AsClass()));
1880 }
1881 });
Alex Lightbaf938f2020-01-10 10:40:46 -08001882 DCHECK_GT(old_types.size(), 0u) << "Expected to find at least old_klass!";
Alex Lightfb537082019-12-10 14:38:34 -08001883 VLOG(plugin) << "Found " << old_types.size() << " types that are/are subtypes of "
1884 << old_klass->PrettyClass();
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001885 }
Alex Lightfb537082019-12-10 14:38:34 -08001886
1887 art::Handle<art::mirror::Class> cls_array_class(
1888 hs.NewHandle(art::GetClassRoot<art::mirror::ObjectArray<art::mirror::Class>>(
1889 driver_->runtime_->GetClassLinker())));
1890 art::Handle<art::mirror::ObjectArray<art::mirror::Class>> old_classes_arr(
1891 hs.NewHandle(art::mirror::ObjectArray<art::mirror::Class>::Alloc(
1892 driver_->self_, cls_array_class.Get(), old_types.size())));
1893 if (old_classes_arr.IsNull()) {
1894 driver_->self_->AssertPendingOOMException();
1895 driver_->self_->ClearException();
1896 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate old_classes arrays!");
1897 return false;
1898 }
1899 // Sort the old_types topologically.
1900 {
1901 art::ScopedAssertNoThreadSuspension sants("Sort classes");
1902 // Sort them by the distance to the base-class. This ensures that any class occurs before any of
1903 // its subtypes.
1904 std::sort(old_types.begin(),
1905 old_types.end(),
1906 [](auto& l, auto& r) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1907 return CompareClasses(l.Get(), r.Get());
1908 });
1909 }
1910 for (uint32_t i = 0; i < old_types.size(); ++i) {
Alex Lightbaf938f2020-01-10 10:40:46 -08001911 DCHECK(!old_types[i].IsNull()) << i;
Alex Lightfb537082019-12-10 14:38:34 -08001912 old_classes_arr->Set(i, old_types[i].Get());
1913 }
1914 cur_data->SetOldClasses(old_classes_arr.Get());
Alex Lightbaf938f2020-01-10 10:40:46 -08001915 DCHECK_GT(old_classes_arr->GetLength(), 0);
Alex Lightfb537082019-12-10 14:38:34 -08001916
1917 art::Handle<art::mirror::ObjectArray<art::mirror::Class>> new_classes_arr(
1918 hs.NewHandle(art::mirror::ObjectArray<art::mirror::Class>::Alloc(
1919 driver_->self_, cls_array_class.Get(), old_types.size())));
1920 if (new_classes_arr.IsNull()) {
1921 driver_->self_->AssertPendingOOMException();
1922 driver_->self_->ClearException();
1923 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate new_classes arrays!");
1924 return false;
1925 }
1926
1927 art::MutableHandle<art::mirror::DexCache> dch(hs.NewHandle<art::mirror::DexCache>(nullptr));
1928 art::MutableHandle<art::mirror::Class> superclass(hs.NewHandle<art::mirror::Class>(nullptr));
1929 for (size_t i = 0; i < old_types.size(); i++) {
1930 art::Handle<art::mirror::Class>& old_type = old_types[i];
1931 if (old_type.Get() == cur_data->GetMirrorClass()) {
1932 CHECK_EQ(i, 0u) << "original class not at index 0. Bad sort!";
1933 new_classes_arr->Set(i, cur_data->GetNewClassObject());
1934 continue;
1935 } else {
1936 auto old_super = std::find_if(old_types.begin(),
1937 old_types.begin() + i,
1938 [&](art::Handle<art::mirror::Class>& v)
1939 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1940 return v.Get() == old_type->GetSuperClass();
1941 });
1942 // Only the GetMirrorClass should not be in this list.
1943 CHECK(old_super != old_types.begin() + i)
1944 << "from first " << i << " could not find super of " << old_type->PrettyClass()
1945 << " expected to find " << old_type->GetSuperClass()->PrettyClass();
1946 superclass.Assign(new_classes_arr->Get(std::distance(old_types.begin(), old_super)));
1947 auto new_redef = std::find_if(
1948 *cur_data + 1, holder.end(), [&](auto it) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1949 return it.GetMirrorClass() == old_type.Get();
1950 });
1951 art::ObjPtr<art::mirror::Class> new_type;
1952 if (new_redef == holder.end()) {
1953 // We aren't also redefining this subclass. Just allocate a new class and continue.
1954 dch.Assign(old_type->GetDexCache());
1955 new_type =
1956 AllocateNewClassObject(old_type, superclass, dch, old_type->GetDexClassDefIndex());
1957 } else {
1958 // This subclass is also being redefined. We need to use its new dex-file to load the new
1959 // class.
1960 CHECK(new_redef.IsActuallyStructural());
1961 CHECK(!new_redef.IsInitialStructural());
1962 new_type = setup_single_redefinition(&new_redef, superclass);
1963 }
1964 if (new_type == nullptr) {
1965 VLOG(plugin) << "Failed to load new version of class " << old_type->PrettyClass()
1966 << " for structural redefinition!";
1967 return false;
1968 }
1969 new_classes_arr->Set(i, new_type);
1970 }
1971 }
1972 cur_data->SetNewClasses(new_classes_arr.Get());
Alex Lighta7e38d82017-01-19 14:57:28 -08001973 return true;
1974}
1975
Alex Light270db1c2019-12-03 12:20:01 +00001976uint32_t Redefiner::ClassRedefinition::GetNewClassSize(art::ClassAccessor& accessor) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001977 uint32_t num_8bit_static_fields = 0;
1978 uint32_t num_16bit_static_fields = 0;
1979 uint32_t num_32bit_static_fields = 0;
1980 uint32_t num_64bit_static_fields = 0;
1981 uint32_t num_ref_static_fields = 0;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001982 for (const art::ClassAccessor::Field& f : accessor.GetStaticFields()) {
Alex Light270db1c2019-12-03 12:20:01 +00001983 std::string_view desc(accessor.GetDexFile().GetFieldTypeDescriptor(
1984 accessor.GetDexFile().GetFieldId(f.GetIndex())));
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001985 if (desc[0] == 'L' || desc[0] == '[') {
1986 num_ref_static_fields++;
1987 } else if (desc == "Z" || desc == "B") {
1988 num_8bit_static_fields++;
1989 } else if (desc == "C" || desc == "S") {
1990 num_16bit_static_fields++;
1991 } else if (desc == "I" || desc == "F") {
1992 num_32bit_static_fields++;
1993 } else if (desc == "J" || desc == "D") {
1994 num_64bit_static_fields++;
1995 } else {
1996 LOG(FATAL) << "Unknown type descriptor! " << desc;
1997 }
1998 }
1999
Alex Light270db1c2019-12-03 12:20:01 +00002000 return art::mirror::Class::ComputeClassSize(/*has_embedded_vtable=*/ false,
2001 /*num_vtable_entries=*/ 0,
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002002 num_8bit_static_fields,
2003 num_16bit_static_fields,
2004 num_32bit_static_fields,
2005 num_64bit_static_fields,
2006 num_ref_static_fields,
2007 art::kRuntimePointerSize);
2008}
2009
2010art::ObjPtr<art::mirror::Class>
2011Redefiner::ClassRedefinition::AllocateNewClassObject(art::Handle<art::mirror::DexCache> cache) {
Alex Light270db1c2019-12-03 12:20:01 +00002012 art::StackHandleScope<2> hs(driver_->self_);
2013 art::Handle<art::mirror::Class> old_class(hs.NewHandle(GetMirrorClass()));
2014 art::Handle<art::mirror::Class> super_class(hs.NewHandle(old_class->GetSuperClass()));
2015 return AllocateNewClassObject(old_class, super_class, cache, /*dex_class_def_index*/0);
2016}
2017
2018art::ObjPtr<art::mirror::Class> Redefiner::ClassRedefinition::AllocateNewClassObject(
2019 art::Handle<art::mirror::Class> old_class,
2020 art::Handle<art::mirror::Class> super_class,
2021 art::Handle<art::mirror::DexCache> cache,
2022 uint16_t dex_class_def_index) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002023 // This is a stripped down DefineClass. We don't want to use DefineClass directly because it needs
2024 // to perform a lot of extra steps to tell the ClassTable and the jit and everything about a new
2025 // class. For now we will need to rely on our tests catching any issues caused by changes in how
2026 // class_linker sets up classes.
2027 // TODO Unify/move this into ClassLinker maybe.
Alex Light270db1c2019-12-03 12:20:01 +00002028 art::StackHandleScope<3> hs(driver_->self_);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002029 art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
Alex Light270db1c2019-12-03 12:20:01 +00002030 const art::DexFile* dex_file = cache->GetDexFile();
2031 art::ClassAccessor accessor(*dex_file, dex_class_def_index);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002032 art::Handle<art::mirror::Class> new_class(hs.NewHandle(linker->AllocClass(
Alex Light270db1c2019-12-03 12:20:01 +00002033 driver_->self_, GetNewClassSize(accessor))));
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002034 if (new_class.IsNull()) {
2035 driver_->self_->AssertPendingOOMException();
Alex Light270db1c2019-12-03 12:20:01 +00002036 RecordFailure(
2037 ERR(OUT_OF_MEMORY),
2038 "Unable to allocate class object for redefinition of " + old_class->PrettyClass());
2039 driver_->self_->ClearException();
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002040 return nullptr;
2041 }
2042 new_class->SetDexCache(cache.Get());
Alex Light270db1c2019-12-03 12:20:01 +00002043 linker->SetupClass(*dex_file,
2044 dex_file->GetClassDef(dex_class_def_index),
2045 new_class,
2046 old_class->GetClassLoader());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002047
2048 // Make sure we are ready for linking. The lock isn't really needed since this isn't visible to
2049 // other threads but the linker expects it.
2050 art::ObjectLock<art::mirror::Class> lock(driver_->self_, new_class);
2051 new_class->SetClinitThreadId(driver_->self_->GetTid());
2052 // Make sure we have a valid empty iftable even if there are errors.
2053 new_class->SetIfTable(art::GetClassRoot<art::mirror::Object>(linker)->GetIfTable());
Alex Light270db1c2019-12-03 12:20:01 +00002054 linker->LoadClass(
2055 driver_->self_, *dex_file, dex_file->GetClassDef(dex_class_def_index), new_class);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002056 // NB. We know the interfaces and supers didn't change! :)
2057 art::MutableHandle<art::mirror::Class> linked_class(hs.NewHandle<art::mirror::Class>(nullptr));
2058 art::Handle<art::mirror::ObjectArray<art::mirror::Class>> proxy_ifaces(
2059 hs.NewHandle<art::mirror::ObjectArray<art::mirror::Class>>(nullptr));
2060 // No changing hierarchy so everything is loaded.
Alex Light270db1c2019-12-03 12:20:01 +00002061 new_class->SetSuperClass(super_class.Get());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002062 art::mirror::Class::SetStatus(new_class, art::ClassStatus::kLoaded, nullptr);
2063 if (!linker->LinkClass(driver_->self_, nullptr, new_class, proxy_ifaces, &linked_class)) {
Alex Light270db1c2019-12-03 12:20:01 +00002064 std::ostringstream oss;
2065 oss << "failed to link class due to "
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002066 << (driver_->self_->IsExceptionPending() ? driver_->self_->GetException()->Dump()
2067 : " unknown");
Alex Light270db1c2019-12-03 12:20:01 +00002068 RecordFailure(ERR(INTERNAL), oss.str());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002069 driver_->self_->ClearException();
2070 return nullptr;
2071 }
Alex Light270db1c2019-12-03 12:20:01 +00002072 // Everything is already resolved.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002073 art::ObjectLock<art::mirror::Class> objlock(driver_->self_, linked_class);
Alex Lightfb119572019-09-18 15:04:53 -07002074 // Mark the class as initialized.
Alex Light270db1c2019-12-03 12:20:01 +00002075 CHECK(old_class->IsResolved())
2076 << "Attempting to redefine an unresolved class " << old_class->PrettyClass()
Alex Lightfb119572019-09-18 15:04:53 -07002077 << " status=" << old_class->GetStatus();
Alex Light270db1c2019-12-03 12:20:01 +00002078 CHECK(linked_class->IsResolved());
2079 if (old_class->WasVerificationAttempted()) {
2080 // Match verification-attempted flag
2081 linked_class->SetVerificationAttempted();
2082 }
2083 if (old_class->ShouldSkipHiddenApiChecks()) {
2084 // Match skip hiddenapi flag
2085 linked_class->SetSkipHiddenApiChecks();
2086 }
2087 if (old_class->IsInitialized()) {
2088 // We already verified the class earlier. No need to do it again.
2089 linker->ForceClassInitialized(driver_->self_, linked_class);
2090 } else if (old_class->GetStatus() > linked_class->GetStatus()) {
2091 // We want to match the old status.
2092 art::mirror::Class::SetStatus(linked_class, old_class->GetStatus(), driver_->self_);
2093 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002094 // Make sure we have ext-data space for method & field ids. We won't know if we need them until
2095 // it's too late to create them.
2096 // TODO We might want to remove these arrays if they're not needed.
Alex Lightbc19b752019-12-02 18:54:13 +00002097 if (!art::mirror::Class::EnsureInstanceFieldIds(linked_class) ||
2098 !art::mirror::Class::EnsureStaticFieldIds(linked_class) ||
2099 !art::mirror::Class::EnsureMethodIds(linked_class)) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002100 driver_->self_->AssertPendingOOMException();
2101 driver_->self_->ClearException();
Alex Light270db1c2019-12-03 12:20:01 +00002102 RecordFailure(
2103 ERR(OUT_OF_MEMORY),
2104 "Unable to allocate jni-id arrays for redefinition of " + old_class->PrettyClass());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002105 return nullptr;
2106 }
2107 // Finish setting up methods.
2108 linked_class->VisitMethods([&](art::ArtMethod* m) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2109 linker->SetEntryPointsToInterpreter(m);
2110 m->SetNotIntrinsic();
2111 DCHECK(m->IsCopied() || m->GetDeclaringClass() == linked_class.Get())
2112 << m->PrettyMethod()
2113 << " m->GetDeclaringClass(): " << m->GetDeclaringClass()->PrettyClass()
2114 << " != linked_class.Get(): " << linked_class->PrettyClass();
2115 }, art::kRuntimePointerSize);
2116 if (art::kIsDebugBuild) {
2117 linked_class->VisitFields([&](art::ArtField* f) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2118 DCHECK_EQ(f->GetDeclaringClass(), linked_class.Get());
2119 });
2120 }
Alex Light270db1c2019-12-03 12:20:01 +00002121 // Reset ClinitThreadId back to the thread that loaded the old class. This is needed if we are in
2122 // the middle of initializing a class.
2123 linked_class->SetClinitThreadId(old_class->GetClinitThreadId());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002124 return linked_class.Get();
2125}
2126
Alex Lighta26e3492017-06-27 17:55:37 -07002127void Redefiner::ClassRedefinition::UnregisterJvmtiBreakpoints() {
Vladimir Marko4617d582019-03-28 13:48:31 +00002128 BreakpointUtil::RemoveBreakpointsInClass(driver_->env_, GetMirrorClass().Ptr());
Alex Lighta26e3492017-06-27 17:55:37 -07002129}
2130
Alex Light5643caf2017-02-08 11:39:07 -08002131void Redefiner::ClassRedefinition::UnregisterBreakpoints() {
Alex Lighte34fe442018-02-21 17:35:55 -08002132 if (LIKELY(!art::Dbg::IsDebuggerActive())) {
2133 return;
2134 }
Alex Light5643caf2017-02-08 11:39:07 -08002135 art::JDWP::JdwpState* state = art::Dbg::GetJdwpState();
2136 if (state != nullptr) {
2137 state->UnregisterLocationEventsOnClass(GetMirrorClass());
2138 }
2139}
2140
2141void Redefiner::UnregisterAllBreakpoints() {
Alex Light5643caf2017-02-08 11:39:07 -08002142 for (Redefiner::ClassRedefinition& redef : redefinitions_) {
2143 redef.UnregisterBreakpoints();
Alex Lighte34fe442018-02-21 17:35:55 -08002144 redef.UnregisterJvmtiBreakpoints();
Alex Light5643caf2017-02-08 11:39:07 -08002145 }
2146}
2147
Alex Light0e692732017-01-10 15:00:05 -08002148bool Redefiner::CheckAllRedefinitionAreValid() {
2149 for (Redefiner::ClassRedefinition& redef : redefinitions_) {
2150 if (!redef.CheckRedefinitionIsValid()) {
2151 return false;
2152 }
2153 }
2154 return true;
2155}
2156
Alex Light1e3926a2017-04-07 10:38:06 -07002157void Redefiner::RestoreObsoleteMethodMapsIfUnneeded(RedefinitionDataHolder& holder) {
2158 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2159 data.GetRedefinition().RestoreObsoleteMethodMapsIfUnneeded(&data);
2160 }
2161}
2162
Alex Lightfb537082019-12-10 14:38:34 -08002163void Redefiner::MarkStructuralChanges(RedefinitionDataHolder& holder) {
2164 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2165 if (data.IsActuallyStructural()) {
2166 // A superclass was structural and it marked all subclasses already. No need to do anything.
2167 CHECK(!data.IsInitialStructural());
2168 } else if (data.GetRedefinition().IsStructuralRedefinition()) {
2169 data.SetActuallyStructural();
2170 data.SetInitialStructural();
2171 // Go over all potential subtypes and mark any that are actually subclasses as structural.
2172 for (RedefinitionDataIter sub_data = data + 1; sub_data != holder.end(); ++sub_data) {
2173 if (sub_data.GetRedefinition().GetMirrorClass()->IsSubClass(
2174 data.GetRedefinition().GetMirrorClass())) {
2175 sub_data.SetActuallyStructural();
2176 }
2177 }
2178 }
2179 }
2180}
2181
Alex Light1e3926a2017-04-07 10:38:06 -07002182bool Redefiner::EnsureAllClassAllocationsFinished(RedefinitionDataHolder& holder) {
2183 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2184 if (!data.GetRedefinition().EnsureClassAllocationsFinished(&data)) {
Alex Light0e692732017-01-10 15:00:05 -08002185 return false;
2186 }
2187 }
2188 return true;
2189}
2190
Alex Light986914b2019-11-19 01:12:25 +00002191bool Redefiner::CollectAndCreateNewInstances(RedefinitionDataHolder& holder) {
2192 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2193 // Allocate the data this redefinition requires.
2194 if (!data.GetRedefinition().CollectAndCreateNewInstances(&data)) {
2195 return false;
2196 }
2197 }
2198 return true;
2199}
2200
Alex Lightfb537082019-12-10 14:38:34 -08002201bool Redefiner::FinishAllNewClassAllocations(RedefinitionDataHolder& holder) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002202 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
Alex Light0e692732017-01-10 15:00:05 -08002203 // Allocate the data this redefinition requires.
Alex Lightfb537082019-12-10 14:38:34 -08002204 if (!data.GetRedefinition().FinishNewClassAllocations(holder, &data)) {
2205 return false;
2206 }
2207 }
2208 return true;
2209}
2210
2211bool Redefiner::FinishAllRemainingCommonAllocations(RedefinitionDataHolder& holder) {
2212 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2213 // Allocate the data this redefinition requires.
2214 if (!data.GetRedefinition().FinishRemainingCommonAllocations(&data)) {
Alex Light0e692732017-01-10 15:00:05 -08002215 return false;
2216 }
Alex Light0e692732017-01-10 15:00:05 -08002217 }
2218 return true;
2219}
2220
2221void Redefiner::ClassRedefinition::ReleaseDexFile() {
Andreas Gampeafaf7f82018-10-16 11:32:38 -07002222 dex_file_.release(); // NOLINT b/117926937
Alex Light0e692732017-01-10 15:00:05 -08002223}
2224
2225void Redefiner::ReleaseAllDexFiles() {
2226 for (Redefiner::ClassRedefinition& redef : redefinitions_) {
2227 redef.ReleaseDexFile();
2228 }
2229}
2230
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002231bool Redefiner::CheckAllClassesAreVerified(RedefinitionDataHolder& holder) {
2232 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2233 if (!data.GetRedefinition().CheckVerification(data)) {
Alex Light8c889d22017-02-06 13:58:27 -08002234 return false;
2235 }
Alex Light8c889d22017-02-06 13:58:27 -08002236 }
2237 return true;
2238}
2239
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002240class ScopedDisableConcurrentAndMovingGc {
2241 public:
2242 ScopedDisableConcurrentAndMovingGc(art::gc::Heap* heap, art::Thread* self)
2243 : heap_(heap), self_(self) {
2244 if (heap_->IsGcConcurrentAndMoving()) {
2245 heap_->IncrementDisableMovingGC(self_);
2246 }
2247 }
2248
2249 ~ScopedDisableConcurrentAndMovingGc() {
2250 if (heap_->IsGcConcurrentAndMoving()) {
2251 heap_->DecrementDisableMovingGC(self_);
2252 }
2253 }
2254 private:
2255 art::gc::Heap* heap_;
2256 art::Thread* self_;
2257};
2258
Alex Light270db1c2019-12-03 12:20:01 +00002259class ClassDefinitionPauser : public art::ClassLoadCallback {
2260 public:
2261 explicit ClassDefinitionPauser(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_)
2262 : self_(self),
2263 is_running_(false),
2264 barrier_(0),
2265 release_mu_("SuspendClassDefinition lock", art::kGenericBottomLock),
2266 release_barrier_(0),
2267 release_cond_("SuspendClassDefinition condvar", release_mu_),
2268 count_(0),
2269 release_(false) {
2270 art::Locks::mutator_lock_->AssertSharedHeld(self_);
2271 }
2272 ~ClassDefinitionPauser() REQUIRES_SHARED(art::Locks::mutator_lock_) {
2273 art::Locks::mutator_lock_->AssertSharedHeld(self_);
Alex Lightf6c69e52020-01-17 15:30:40 -08002274 CHECK(release_) << "Must call Release()";
2275 }
2276 void Release() REQUIRES(art::Locks::mutator_lock_) {
Alex Light270db1c2019-12-03 12:20:01 +00002277 if (is_running_) {
Alex Lightf6c69e52020-01-17 15:30:40 -08002278 art::Locks::mutator_lock_->AssertExclusiveHeld(self_);
Alex Light270db1c2019-12-03 12:20:01 +00002279 uint32_t count;
2280 // Wake up everything.
2281 {
2282 art::MutexLock mu(self_, release_mu_);
2283 release_ = true;
Alex Lightf6c69e52020-01-17 15:30:40 -08002284 // We have an exclusive mutator so all threads must be suspended and therefore they've
2285 // either already incremented this count_ or they are stuck somewhere before it.
Alex Light270db1c2019-12-03 12:20:01 +00002286 count = count_;
2287 release_cond_.Broadcast(self_);
2288 }
2289 // Wait for all threads to leave this structs code.
Alex Light270db1c2019-12-03 12:20:01 +00002290 VLOG(plugin) << "Resuming " << count << " threads paused before class-allocation!";
Alex Lightf6c69e52020-01-17 15:30:40 -08002291 release_barrier_.Increment</*locks=*/art::Barrier::kAllowHoldingLocks>(self_, count);
2292 } else {
2293 release_ = true;
Alex Light270db1c2019-12-03 12:20:01 +00002294 }
2295 }
2296 void BeginDefineClass() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
2297 art::Thread* this_thread = art::Thread::Current();
2298 if (this_thread == self_) {
2299 // Allow the redefining thread to do whatever.
2300 return;
2301 }
2302 if (this_thread->GetDefineClassCount() != 0) {
2303 // We are in the middle of a recursive define-class. Don't suspend now allow it to finish.
2304 VLOG(plugin) << "Recursive DefineClass in " << *this_thread
2305 << " allowed to proceed despite class-def pause initiated by " << *self_;
2306 return;
2307 }
Alex Lightf6c69e52020-01-17 15:30:40 -08002308 // If we are suspended (no mutator-lock) then the pausing thread could do everything before the
2309 // count_++ including destroying this object, causing UAF/deadlock.
2310 art::Locks::mutator_lock_->AssertSharedHeld(this_thread);
2311 ++count_;
Alex Light270db1c2019-12-03 12:20:01 +00002312 art::ScopedThreadSuspension sts(this_thread, art::ThreadState::kSuspended);
2313 {
2314 art::MutexLock mu(this_thread, release_mu_);
Alex Light270db1c2019-12-03 12:20:01 +00002315 VLOG(plugin) << "Suspending " << *this_thread << " due to class definition. class-def pause "
2316 << "initiated by " << *self_;
Alex Light270db1c2019-12-03 12:20:01 +00002317 while (!release_) {
2318 release_cond_.Wait(this_thread);
2319 }
2320 }
2321 release_barrier_.Pass(this_thread);
2322 }
Alex Lightf6c69e52020-01-17 15:30:40 -08002323
Alex Light270db1c2019-12-03 12:20:01 +00002324 void EndDefineClass() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
2325 art::Thread* this_thread = art::Thread::Current();
2326 if (this_thread == self_) {
2327 // Allow the redefining thread to do whatever.
2328 return;
2329 }
2330 if (this_thread->GetDefineClassCount() == 0) {
2331 // We are done with defining classes.
2332 barrier_.Pass(this_thread);
2333 }
2334 }
2335
2336 void ClassLoad(art::Handle<art::mirror::Class> klass ATTRIBUTE_UNUSED) override {}
2337 void ClassPrepare(art::Handle<art::mirror::Class> klass1 ATTRIBUTE_UNUSED,
2338 art::Handle<art::mirror::Class> klass2 ATTRIBUTE_UNUSED) override {}
2339
2340 void SetRunning() {
2341 is_running_ = true;
2342 }
2343 void WaitFor(uint32_t t) REQUIRES(!art::Locks::mutator_lock_) {
2344 barrier_.Increment(self_, t);
2345 }
2346
2347 private:
2348 art::Thread* self_;
2349 bool is_running_;
2350 art::Barrier barrier_;
2351 art::Mutex release_mu_;
2352 art::Barrier release_barrier_;
2353 art::ConditionVariable release_cond_;
Alex Lightf6c69e52020-01-17 15:30:40 -08002354 std::atomic<uint32_t> count_;
Alex Light270db1c2019-12-03 12:20:01 +00002355 bool release_;
2356};
2357
2358class ScopedSuspendClassLoading {
2359 public:
2360 ScopedSuspendClassLoading(art::Thread* self, art::Runtime* runtime, RedefinitionDataHolder& h)
2361 REQUIRES_SHARED(art::Locks::mutator_lock_)
Alex Lightf6c69e52020-01-17 15:30:40 -08002362 : self_(self), runtime_(runtime), pauser_() {
Alex Light270db1c2019-12-03 12:20:01 +00002363 if (std::any_of(h.begin(), h.end(), [](auto r) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2364 return r.GetRedefinition().IsStructuralRedefinition();
2365 })) {
2366 VLOG(plugin) << "Pausing Class loading for structural redefinition.";
Alex Lightf6c69e52020-01-17 15:30:40 -08002367 pauser_.emplace(self);
Alex Light270db1c2019-12-03 12:20:01 +00002368 {
2369 art::ScopedThreadSuspension sts(self_, art::ThreadState::kNative);
2370 uint32_t in_progress_defines = 0;
2371 {
2372 art::ScopedSuspendAll ssa(__FUNCTION__);
Alex Lightf6c69e52020-01-17 15:30:40 -08002373 pauser_->SetRunning();
2374 runtime_->GetRuntimeCallbacks()->AddClassLoadCallback(&pauser_.value());
Alex Light270db1c2019-12-03 12:20:01 +00002375 art::MutexLock mu(self_, *art::Locks::thread_list_lock_);
2376 runtime_->GetThreadList()->ForEach([&](art::Thread* t) {
2377 if (t != self_ && t->GetDefineClassCount() != 0) {
2378 in_progress_defines++;
2379 }
2380 });
Alex Lightf6c69e52020-01-17 15:30:40 -08002381 VLOG(plugin) << "Waiting for " << in_progress_defines
2382 << " in progress class-loads to finish";
Alex Light270db1c2019-12-03 12:20:01 +00002383 }
Alex Lightf6c69e52020-01-17 15:30:40 -08002384 pauser_->WaitFor(in_progress_defines);
Alex Light270db1c2019-12-03 12:20:01 +00002385 }
2386 }
2387 }
2388 ~ScopedSuspendClassLoading() {
Alex Lightf6c69e52020-01-17 15:30:40 -08002389 if (pauser_.has_value()) {
Alex Light270db1c2019-12-03 12:20:01 +00002390 art::ScopedThreadSuspension sts(self_, art::ThreadState::kNative);
2391 art::ScopedSuspendAll ssa(__FUNCTION__);
Alex Lightf6c69e52020-01-17 15:30:40 -08002392 pauser_->Release();
2393 runtime_->GetRuntimeCallbacks()->RemoveClassLoadCallback(&pauser_.value());
Alex Light270db1c2019-12-03 12:20:01 +00002394 }
2395 }
2396
2397 private:
2398 art::Thread* self_;
2399 art::Runtime* runtime_;
Alex Lightf6c69e52020-01-17 15:30:40 -08002400 std::optional<ClassDefinitionPauser> pauser_;
Alex Light270db1c2019-12-03 12:20:01 +00002401};
2402
Alex Light986914b2019-11-19 01:12:25 +00002403class ScopedSuspendAllocations {
2404 public:
2405 ScopedSuspendAllocations(art::Runtime* runtime, RedefinitionDataHolder& h)
2406 REQUIRES_SHARED(art::Locks::mutator_lock_)
2407 : paused_(false) {
2408 if (std::any_of(h.begin(),
2409 h.end(),
2410 [](auto r) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2411 return r.GetRedefinition().IsStructuralRedefinition();
2412 })) {
2413 VLOG(plugin) << "Pausing allocations for structural redefinition.";
2414 paused_ = true;
2415 AllocationManager::Get()->PauseAllocations(art::Thread::Current());
2416 // Collect garbage so we don't need to recreate as much.
2417 runtime->GetHeap()->CollectGarbage(/*clear_soft_references=*/false);
2418 }
2419 }
2420
2421 ~ScopedSuspendAllocations() REQUIRES_SHARED(art::Locks::mutator_lock_) {
2422 if (paused_) {
2423 AllocationManager::Get()->ResumeAllocations(art::Thread::Current());
2424 }
2425 }
2426
2427 private:
2428 bool paused_;
2429
2430 DISALLOW_COPY_AND_ASSIGN(ScopedSuspendAllocations);
2431};
2432
Alex Lighta01de592016-11-15 10:43:06 -08002433jvmtiError Redefiner::Run() {
Alex Light0e692732017-01-10 15:00:05 -08002434 art::StackHandleScope<1> hs(self_);
Alex Lightfb537082019-12-10 14:38:34 -08002435 // Sort the redefinitions_ array topologically by class. This makes later steps easier since we
2436 // know that every class precedes all of its supertypes.
2437 std::sort(redefinitions_.begin(),
2438 redefinitions_.end(),
2439 [&](auto& l, auto& r) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2440 return CompareClasses(l.GetMirrorClass(), r.GetMirrorClass());
2441 });
2442 // Allocate an array to hold onto all java temporary objects associated with this
2443 // redefinition. We will let this be collected after the end of this function.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002444 RedefinitionDataHolder holder(&hs, runtime_, self_, &redefinitions_);
Alex Light0e692732017-01-10 15:00:05 -08002445 if (holder.IsNull()) {
2446 self_->AssertPendingOOMException();
2447 self_->ClearException();
2448 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate storage for temporaries");
2449 return result_;
2450 }
2451
Alex Lighta01de592016-11-15 10:43:06 -08002452 // First we just allocate the ClassExt and its fields that we need. These can be updated
Alex Lightfb537082019-12-10 14:38:34 -08002453 // atomically without any issues (since we allocate the map arrays as empty).
2454 if (!CheckAllRedefinitionAreValid()) {
2455 return result_;
2456 }
2457 // Mark structural changes.
2458 MarkStructuralChanges(holder);
2459 // Now we pause class loading. If we are doing a structural redefinition we will need to get an
2460 // accurate picture of the classes loaded and having loads in the middle would make that
2461 // impossible. This only pauses class-loading if we actually have at least one structural
2462 // redefinition.
2463 ScopedSuspendClassLoading suspend_class_load(self_, runtime_, holder);
2464 if (!EnsureAllClassAllocationsFinished(holder) ||
2465 !FinishAllRemainingCommonAllocations(holder) ||
2466 !FinishAllNewClassAllocations(holder) ||
Alex Light8c889d22017-02-06 13:58:27 -08002467 !CheckAllClassesAreVerified(holder)) {
Alex Lighta01de592016-11-15 10:43:06 -08002468 return result_;
2469 }
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002470
Alex Light986914b2019-11-19 01:12:25 +00002471 ScopedSuspendAllocations suspend_alloc(runtime_, holder);
2472 if (!CollectAndCreateNewInstances(holder)) {
2473 return result_;
2474 }
2475
Alex Light5643caf2017-02-08 11:39:07 -08002476 // At this point we can no longer fail without corrupting the runtime state.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002477 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
Alex Light07f06212017-06-01 14:01:43 -07002478 art::ClassLinker* cl = runtime_->GetClassLinker();
2479 cl->RegisterExistingDexCache(data.GetNewDexCache(), data.GetSourceClassLoader());
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002480 if (data.GetSourceClassLoader() == nullptr) {
Mathieu Chartier0a19e212019-11-27 14:35:24 -08002481 cl->AppendToBootClassPath(self_, &data.GetRedefinition().GetDexFile());
Alex Light7916f202017-01-27 09:00:15 -08002482 }
Alex Light7916f202017-01-27 09:00:15 -08002483 }
Alex Light5643caf2017-02-08 11:39:07 -08002484 UnregisterAllBreakpoints();
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002485
Alex Lightc2d0c962019-10-23 14:14:25 -07002486 {
2487 // Disable GC and wait for it to be done if we are a moving GC. This is fine since we are done
2488 // allocating so no deadlocks.
2489 ScopedDisableConcurrentAndMovingGc sdcamgc(runtime_->GetHeap(), self_);
Alex Lightc5f5a6e2017-03-01 16:57:08 -08002490
Alex Lightc2d0c962019-10-23 14:14:25 -07002491 // Do transition to final suspension
2492 // TODO We might want to give this its own suspended state!
2493 // TODO This isn't right. We need to change state without any chance of suspend ideally!
2494 art::ScopedThreadSuspension sts(self_, art::ThreadState::kNative);
2495 art::ScopedSuspendAll ssa("Final installation of redefined Classes!", /*long_suspend=*/true);
2496 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2497 art::ScopedAssertNoThreadSuspension nts("Updating runtime objects for redefinition");
2498 ClassRedefinition& redef = data.GetRedefinition();
2499 if (data.GetSourceClassLoader() != nullptr) {
2500 ClassLoaderHelper::UpdateJavaDexFile(data.GetJavaDexFile(), data.GetNewDexFileCookie());
2501 }
2502 redef.UpdateClass(data);
Alex Light7916f202017-01-27 09:00:15 -08002503 }
Alex Lightc2d0c962019-10-23 14:14:25 -07002504 RestoreObsoleteMethodMapsIfUnneeded(holder);
2505 // TODO We should check for if any of the redefined methods are intrinsic methods here and, if
2506 // any are, force a full-world deoptimization before finishing redefinition. If we don't do this
2507 // then methods that have been jitted prior to the current redefinition being applied might
2508 // continue to use the old versions of the intrinsics!
2509 // TODO Do the dex_file release at a more reasonable place. This works but it muddles who really
2510 // owns the DexFile and when ownership is transferred.
2511 ReleaseAllDexFiles();
Alex Light0e692732017-01-10 15:00:05 -08002512 }
Alex Lightb1eebde2019-10-22 16:30:47 +00002513 // By now the class-linker knows about all the classes so we can safetly retry verification and
2514 // update method flags.
2515 ReverifyClasses(holder);
Alex Lighta01de592016-11-15 10:43:06 -08002516 return OK;
2517}
2518
Alex Lightb1eebde2019-10-22 16:30:47 +00002519void Redefiner::ReverifyClasses(RedefinitionDataHolder& holder) {
Alex Lightb1eebde2019-10-22 16:30:47 +00002520 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
2521 data.GetRedefinition().ReverifyClass(data);
2522 }
2523}
2524
2525void Redefiner::ClassRedefinition::ReverifyClass(const RedefinitionDataIter &cur_data) {
2526 if (!needs_reverify_) {
2527 return;
2528 }
2529 VLOG(plugin) << "Reverifying " << class_sig_ << " due to soft failures";
2530 std::string error;
2531 // TODO Make verification log level lower
2532 art::verifier::FailureKind failure =
2533 art::verifier::ClassVerifier::ReverifyClass(driver_->self_,
2534 cur_data.GetMirrorClass(),
2535 /*log_level=*/
2536 art::verifier::HardFailLogMode::kLogWarning,
2537 /*api_level=*/
2538 art::Runtime::Current()->GetTargetSdkVersion(),
2539 &error);
2540 CHECK_NE(failure, art::verifier::FailureKind::kHardFailure);
2541}
2542
Alex Light0e692732017-01-10 15:00:05 -08002543void Redefiner::ClassRedefinition::UpdateMethods(art::ObjPtr<art::mirror::Class> mclass,
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002544 const art::dex::ClassDef& class_def) {
Alex Light0e692732017-01-10 15:00:05 -08002545 art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
Alex Lighta01de592016-11-15 10:43:06 -08002546 art::PointerSize image_pointer_size = linker->GetImagePointerSize();
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002547 const art::dex::TypeId& declaring_class_id = dex_file_->GetTypeId(class_def.class_idx_);
Alex Lighta01de592016-11-15 10:43:06 -08002548 const art::DexFile& old_dex_file = mclass->GetDexFile();
Alex Light200b9d72016-12-15 11:34:13 -08002549 // Update methods.
Alex Light00e475c2017-07-19 16:36:23 -07002550 for (art::ArtMethod& method : mclass->GetDeclaredMethods(image_pointer_size)) {
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002551 const art::dex::StringId* new_name_id = dex_file_->FindStringId(method.GetName());
Alex Lighta01de592016-11-15 10:43:06 -08002552 art::dex::TypeIndex method_return_idx =
2553 dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(method.GetReturnTypeDescriptor()));
2554 const auto* old_type_list = method.GetParameterTypeList();
2555 std::vector<art::dex::TypeIndex> new_type_list;
2556 for (uint32_t i = 0; old_type_list != nullptr && i < old_type_list->Size(); i++) {
2557 new_type_list.push_back(
2558 dex_file_->GetIndexForTypeId(
2559 *dex_file_->FindTypeId(
2560 old_dex_file.GetTypeDescriptor(
2561 old_dex_file.GetTypeId(
2562 old_type_list->GetTypeItem(i).type_idx_)))));
2563 }
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002564 const art::dex::ProtoId* proto_id = dex_file_->FindProtoId(method_return_idx, new_type_list);
Alex Lightdba61482016-12-21 08:20:29 -08002565 CHECK(proto_id != nullptr || old_type_list == nullptr);
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002566 const art::dex::MethodId* method_id = dex_file_->FindMethodId(declaring_class_id,
2567 *new_name_id,
2568 *proto_id);
Alex Lightdba61482016-12-21 08:20:29 -08002569 CHECK(method_id != nullptr);
Alex Lighta01de592016-11-15 10:43:06 -08002570 uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id);
2571 method.SetDexMethodIndex(dex_method_idx);
2572 linker->SetEntryPointsToInterpreter(&method);
Alex Light200b9d72016-12-15 11:34:13 -08002573 method.SetCodeItemOffset(dex_file_->FindCodeItemOffset(class_def, dex_method_idx));
Alex Light7532d582017-02-13 16:36:06 -08002574 // Clear all the intrinsics related flags.
Orion Hodsoncfcc9cf2017-09-29 15:07:27 +01002575 method.SetNotIntrinsic();
Alex Lighta01de592016-11-15 10:43:06 -08002576 }
Alex Light200b9d72016-12-15 11:34:13 -08002577}
2578
Alex Light0e692732017-01-10 15:00:05 -08002579void Redefiner::ClassRedefinition::UpdateFields(art::ObjPtr<art::mirror::Class> mclass) {
Alex Light163652e2020-01-08 15:18:25 -08002580 std::unordered_map<uint32_t, uint32_t> dex_field_index_map;
Alex Light200b9d72016-12-15 11:34:13 -08002581 // TODO The IFields & SFields pointers should be combined like the methods_ arrays were.
2582 for (auto fields_iter : {mclass->GetIFields(), mclass->GetSFields()}) {
2583 for (art::ArtField& field : fields_iter) {
2584 std::string declaring_class_name;
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002585 const art::dex::TypeId* new_declaring_id =
Alex Light200b9d72016-12-15 11:34:13 -08002586 dex_file_->FindTypeId(field.GetDeclaringClass()->GetDescriptor(&declaring_class_name));
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002587 const art::dex::StringId* new_name_id = dex_file_->FindStringId(field.GetName());
2588 const art::dex::TypeId* new_type_id = dex_file_->FindTypeId(field.GetTypeDescriptor());
Alex Light200b9d72016-12-15 11:34:13 -08002589 CHECK(new_name_id != nullptr && new_type_id != nullptr && new_declaring_id != nullptr);
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002590 const art::dex::FieldId* new_field_id =
Alex Light200b9d72016-12-15 11:34:13 -08002591 dex_file_->FindFieldId(*new_declaring_id, *new_name_id, *new_type_id);
2592 CHECK(new_field_id != nullptr);
Alex Light163652e2020-01-08 15:18:25 -08002593 uint32_t new_field_index = dex_file_->GetIndexForFieldId(*new_field_id);
2594 // We need to keep track of the changes to the index so we can update any
2595 // java.lang.reflect.Field objects that happen to be on the heap.
2596 dex_field_index_map[field.GetDexFieldIndex()] = new_field_index;
Alex Light200b9d72016-12-15 11:34:13 -08002597 // We only need to update the index since the other data in the ArtField cannot be updated.
Alex Light163652e2020-01-08 15:18:25 -08002598 field.SetDexFieldIndex(new_field_index);
Alex Light200b9d72016-12-15 11:34:13 -08002599 }
2600 }
Alex Light163652e2020-01-08 15:18:25 -08002601 // walk the heap to update any java/lang/reflect/Field objects that refer to any of these fields.
2602 // TODO We could combine this and do one heap-walk for all redefined classes.
2603 art::ObjPtr<art::mirror::Class> reflect_field(art::GetClassRoot<art::mirror::Field>());
2604 auto vis = [&](art::ObjPtr<art::mirror::Object> obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2605 // j.l.r.Field is a final class.
2606 if (obj->GetClass() != reflect_field) {
2607 return;
2608 }
2609 art::ObjPtr<art::mirror::Field> fld(art::down_cast<art::mirror::Field*>(obj.Ptr()));
2610 // Only this class is getting new indexs.
2611 if (fld->GetDeclaringClass() != mclass) {
2612 return;
2613 }
2614 auto it = dex_field_index_map.find(fld->GetDexFieldIndex());
2615 if (it != dex_field_index_map.end()) {
2616 fld->SetDexFieldIndex</*kTransactionActive=*/false>(it->second);
2617 }
2618 };
2619 driver_->runtime_->GetHeap()->VisitObjectsPaused(vis);
Alex Light200b9d72016-12-15 11:34:13 -08002620}
2621
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002622void Redefiner::ClassRedefinition::CollectNewFieldAndMethodMappings(
2623 const RedefinitionDataIter& data,
2624 std::map<art::ArtMethod*, art::ArtMethod*>* method_map,
2625 std::map<art::ArtField*, art::ArtField*>* field_map) {
Alex Light270db1c2019-12-03 12:20:01 +00002626 for (auto [new_cls, old_cls] :
2627 art::ZipLeft(data.GetNewClasses()->Iterate(), data.GetOldClasses()->Iterate())) {
2628 for (art::ArtField& f : old_cls->GetSFields()) {
2629 (*field_map)[&f] = new_cls->FindDeclaredStaticField(f.GetName(), f.GetTypeDescriptor());
2630 }
2631 for (art::ArtField& f : old_cls->GetIFields()) {
2632 (*field_map)[&f] = new_cls->FindDeclaredInstanceField(f.GetName(), f.GetTypeDescriptor());
2633 }
2634 auto new_methods = new_cls->GetMethods(art::kRuntimePointerSize);
2635 for (art::ArtMethod& m : old_cls->GetMethods(art::kRuntimePointerSize)) {
2636 // No support for finding methods in this way since it's generally not needed. Just do it the
2637 // easy way.
2638 auto nm_iter = std::find_if(
2639 new_methods.begin(),
2640 new_methods.end(),
2641 [&](art::ArtMethod& cand) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2642 return cand.GetNameView() == m.GetNameView() && cand.GetSignature() == m.GetSignature();
2643 });
2644 CHECK(nm_iter != new_methods.end())
2645 << "Could not find redefined version of " << m.PrettyMethod();
2646 (*method_map)[&m] = &(*nm_iter);
2647 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002648 }
2649}
2650
Alex Light986914b2019-11-19 01:12:25 +00002651static void CopyField(art::ObjPtr<art::mirror::Object> target,
2652 art::ArtField* new_field,
2653 art::ObjPtr<art::mirror::Object> source,
2654 art::ArtField& old_field) REQUIRES(art::Locks::mutator_lock_) {
2655 art::Primitive::Type ftype = old_field.GetTypeAsPrimitiveType();
2656 CHECK_EQ(ftype, new_field->GetTypeAsPrimitiveType())
2657 << old_field.PrettyField() << " vs " << new_field->PrettyField();
2658 if (ftype == art::Primitive::kPrimNot) {
2659 new_field->SetObject<false>(target, old_field.GetObject(source));
2660 } else {
2661 switch (ftype) {
2662#define UPDATE_FIELD(TYPE) \
2663 case art::Primitive::kPrim##TYPE: \
2664 new_field->Set##TYPE<false>(target, old_field.Get##TYPE(source)); \
2665 break
2666 UPDATE_FIELD(Int);
2667 UPDATE_FIELD(Float);
2668 UPDATE_FIELD(Long);
2669 UPDATE_FIELD(Double);
2670 UPDATE_FIELD(Short);
2671 UPDATE_FIELD(Char);
2672 UPDATE_FIELD(Byte);
2673 UPDATE_FIELD(Boolean);
2674 case art::Primitive::kPrimNot:
2675 case art::Primitive::kPrimVoid:
2676 LOG(FATAL) << "Unexpected field with type " << ftype << " found!";
2677 UNREACHABLE();
2678#undef UPDATE_FIELD
2679 }
2680 }
2681}
2682
2683static void CopyFields(bool is_static,
2684 art::ObjPtr<art::mirror::Object> target,
2685 art::ObjPtr<art::mirror::Class> target_class,
2686 art::ObjPtr<art::mirror::Object> source,
2687 art::ObjPtr<art::mirror::Class> source_class)
2688 REQUIRES(art::Locks::mutator_lock_) {
2689 DCHECK(!source_class->IsObjectClass() && !target_class->IsObjectClass())
2690 << "Should not be overriding object class fields. Target: " << target_class->PrettyClass()
2691 << " Source: " << source_class->PrettyClass();
2692 for (art::ArtField& f : (is_static ? source_class->GetSFields() : source_class->GetIFields())) {
2693 art::ArtField* new_field =
2694 (is_static ? target_class->FindDeclaredStaticField(f.GetName(), f.GetTypeDescriptor())
2695 : target_class->FindDeclaredInstanceField(f.GetName(), f.GetTypeDescriptor()));
2696 CHECK(new_field != nullptr) << "could not find new version of " << f.PrettyField();
2697 CopyField(target, new_field, source, f);
2698 }
2699 if (!is_static && !target_class->GetSuperClass()->IsObjectClass()) {
2700 CopyFields(
2701 is_static, target, target_class->GetSuperClass(), source, source_class->GetSuperClass());
2702 }
2703}
2704
2705static void ClearField(art::ObjPtr<art::mirror::Object> target, art::ArtField& field)
2706 REQUIRES(art::Locks::mutator_lock_) {
2707 art::Primitive::Type ftype = field.GetTypeAsPrimitiveType();
2708 if (ftype == art::Primitive::kPrimNot) {
2709 field.SetObject<false>(target, nullptr);
2710 } else {
2711 switch (ftype) {
2712#define UPDATE_FIELD(TYPE) \
2713 case art::Primitive::kPrim##TYPE: \
2714 field.Set##TYPE<false>(target, 0); \
2715 break
2716 UPDATE_FIELD(Int);
2717 UPDATE_FIELD(Float);
2718 UPDATE_FIELD(Long);
2719 UPDATE_FIELD(Double);
2720 UPDATE_FIELD(Short);
2721 UPDATE_FIELD(Char);
2722 UPDATE_FIELD(Byte);
2723 UPDATE_FIELD(Boolean);
2724 case art::Primitive::kPrimNot:
2725 case art::Primitive::kPrimVoid:
2726 LOG(FATAL) << "Unexpected field with type " << ftype << " found!";
2727 UNREACHABLE();
2728#undef UPDATE_FIELD
2729 }
2730 }
2731}
2732
2733static void ClearFields(bool is_static,
2734 art::ObjPtr<art::mirror::Object> target,
2735 art::ObjPtr<art::mirror::Class> target_class)
2736 REQUIRES(art::Locks::mutator_lock_) {
2737 DCHECK(!target_class->IsObjectClass());
2738 for (art::ArtField& f : (is_static ? target_class->GetSFields() : target_class->GetIFields())) {
2739 ClearField(target, f);
2740 }
2741 if (!is_static && !target_class->GetSuperClass()->IsObjectClass()) {
2742 ClearFields(is_static, target, target_class->GetSuperClass());
2743 }
2744}
2745
2746static void CopyAndClearFields(bool is_static,
2747 art::ObjPtr<art::mirror::Object> target,
2748 art::ObjPtr<art::mirror::Class> target_class,
2749 art::ObjPtr<art::mirror::Object> source,
2750 art::ObjPtr<art::mirror::Class> source_class)
2751 REQUIRES(art::Locks::mutator_lock_) {
2752 // Copy all non-j.l.Object fields
2753 CopyFields(is_static, target, target_class, source, source_class);
2754 // Copy the lock-word.
2755 target->SetLockWord(source->GetLockWord(false), false);
2756 // Clear (reset) the old one.
2757 source->SetLockWord(art::LockWord::Default(), false);
2758 art::WriteBarrier::ForEveryFieldWrite(target);
2759
2760 // Clear the fields from the old class. We don't need it anymore.
2761 ClearFields(is_static, source, source_class);
2762 art::WriteBarrier::ForEveryFieldWrite(source);
2763}
2764
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002765void Redefiner::ClassRedefinition::UpdateClassStructurally(const RedefinitionDataIter& holder) {
Alex Lightfb537082019-12-10 14:38:34 -08002766 DCHECK(holder.IsActuallyStructural());
2767 DCHECK(holder.IsInitialStructural());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002768 // LETS GO. We've got all new class structures so no need to do all the updating of the stacks.
2769 // Instead we need to update everything else.
2770 // Just replace the class and be done with it.
2771 art::Locks::mutator_lock_->AssertExclusiveHeld(driver_->self_);
2772 art::ScopedAssertNoThreadSuspension sants(__FUNCTION__);
2773 art::ObjPtr<art::mirror::Class> orig(holder.GetMirrorClass());
2774 art::ObjPtr<art::mirror::Class> replacement(holder.GetNewClassObject());
Alex Light270db1c2019-12-03 12:20:01 +00002775 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> new_classes(holder.GetNewClasses());
2776 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Class>> old_classes(holder.GetOldClasses());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002777 // Collect mappings from old to new fields/methods
2778 std::map<art::ArtMethod*, art::ArtMethod*> method_map;
2779 std::map<art::ArtField*, art::ArtField*> field_map;
2780 CollectNewFieldAndMethodMappings(holder, &method_map, &field_map);
Alex Light986914b2019-11-19 01:12:25 +00002781 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> new_instances(
2782 holder.GetNewInstanceObjects());
2783 art::ObjPtr<art::mirror::ObjectArray<art::mirror::Object>> old_instances(
2784 holder.GetOldInstanceObjects());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002785 CHECK(!orig.IsNull());
2786 CHECK(!replacement.IsNull());
Alex Light270db1c2019-12-03 12:20:01 +00002787 // Once we do the ReplaceReferences old_classes will have the new_classes in it. We want to keep
2788 // ahold of the old classes so copy them now.
2789 std::vector<art::ObjPtr<art::mirror::Class>> old_classes_vec(old_classes->Iterate().begin(),
2790 old_classes->Iterate().end());
Alex Light986914b2019-11-19 01:12:25 +00002791 // Copy over the static fields of the class and all the instance fields.
Alex Light270db1c2019-12-03 12:20:01 +00002792 for (auto [new_class, old_class] : art::ZipLeft(new_classes->Iterate(), old_classes->Iterate())) {
2793 CHECK(!new_class.IsNull());
2794 CHECK(!old_class.IsNull());
2795 CHECK(!old_class->IsErroneous());
2796 if (old_class->GetStatus() > new_class->GetStatus()) {
2797 // Some verification/initialization step happened during interval between
2798 // creating the new class and now. Just copy the new status.
2799 new_class->SetStatusLocked(old_class->GetStatus());
2800 }
2801 CopyAndClearFields(true, new_class, new_class, old_class, old_class);
2802 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002803
Alex Light986914b2019-11-19 01:12:25 +00002804 // Copy and clear the fields of the old-instances.
Alex Light270db1c2019-12-03 12:20:01 +00002805 for (auto [new_instance, old_instance] :
2806 art::ZipLeft(new_instances->Iterate(), old_instances->Iterate())) {
Alex Light986914b2019-11-19 01:12:25 +00002807 CopyAndClearFields(/*is_static=*/false,
2808 new_instance,
2809 new_instance->GetClass(),
2810 old_instance,
2811 old_instance->GetClass());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002812 }
2813 // Mark old class obsolete.
Alex Light270db1c2019-12-03 12:20:01 +00002814 for (auto old_class : old_classes->Iterate()) {
2815 old_class->SetObsoleteObject();
2816 // Mark methods obsolete. We need to wait until later to actually clear the jit data.
2817 for (art::ArtMethod& m : old_class->GetMethods(art::kRuntimePointerSize)) {
2818 m.SetIsObsolete();
2819 if (m.IsInvokable()) {
2820 m.SetDontCompile();
2821 }
2822 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002823 }
Alex Lightc18eba32019-09-24 14:36:27 -07002824 // Update live pointers in ART code.
Alex Light24627892019-11-06 10:28:21 -08002825 auto could_change_resolution_of = [&](auto* field_or_method,
2826 const auto& info) REQUIRES(art::Locks::mutator_lock_) {
2827 constexpr bool is_method = std::is_same_v<art::ArtMethod*, decltype(field_or_method)>;
2828 static_assert(is_method || std::is_same_v<art::ArtField*, decltype(field_or_method)>,
2829 "Input is not field or method!");
2830 // Only dex-cache is used for resolution
2831 if (LIKELY(info.GetType() != art::ReflectionSourceType::kSourceDexCacheResolvedField &&
2832 info.GetType() != art::ReflectionSourceType::kSourceDexCacheResolvedMethod)) {
2833 return false;
2834 }
2835 if constexpr (is_method) {
2836 // Only direct methods are used without further indirection through a vtable/IFTable.
2837 // Constructors cannot be shadowed.
2838 if (LIKELY(!field_or_method->IsDirect() || field_or_method->IsConstructor())) {
2839 return false;
2840 }
2841 } else {
2842 // Only non-private fields can be shadowed in a manner that's visible.
2843 if (LIKELY(field_or_method->IsPrivate())) {
2844 return false;
2845 }
2846 }
2847 // We can only shadow things from our superclasses
2848 if (LIKELY(!field_or_method->GetDeclaringClass()->IsAssignableFrom(orig))) {
2849 return false;
2850 }
2851 if constexpr (is_method) {
2852 auto direct_methods = replacement->GetDirectMethods(art::kRuntimePointerSize);
2853 return std::find_if(direct_methods.begin(),
2854 direct_methods.end(),
2855 [&](art::ArtMethod& m) REQUIRES(art::Locks::mutator_lock_) {
2856 return UNLIKELY(m.HasSameNameAndSignature(field_or_method));
2857 }) != direct_methods.end();
2858 } else {
2859 auto pred = [&](art::ArtField& f) REQUIRES(art::Locks::mutator_lock_) {
2860 return std::string_view(f.GetName()) == std::string_view(field_or_method->GetName()) &&
2861 std::string_view(f.GetTypeDescriptor()) ==
2862 std::string_view(field_or_method->GetTypeDescriptor());
2863 };
2864 if (field_or_method->IsStatic()) {
2865 auto sfields = replacement->GetSFields();
2866 return std::find_if(sfields.begin(), sfields.end(), pred) != sfields.end();
2867 } else {
2868 auto ifields = replacement->GetIFields();
2869 return std::find_if(ifields.begin(), ifields.end(), pred) != ifields.end();
2870 }
2871 }
2872 };
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002873 // TODO Performing 2 stack-walks back to back isn't the greatest. We might want to try to combine
2874 // it with the one ReplaceReferences does. Doing so would be rather complicated though.
Alex Lightc18eba32019-09-24 14:36:27 -07002875 driver_->runtime_->VisitReflectiveTargets(
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002876 [&](art::ArtField* f, const auto& info) REQUIRES(art::Locks::mutator_lock_) {
Alex Light28b6efe2019-11-06 12:49:41 -08002877 DCHECK(f != nullptr) << info;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002878 auto it = field_map.find(f);
Alex Light24627892019-11-06 10:28:21 -08002879 if (it != field_map.end()) {
2880 VLOG(plugin) << "Updating " << info << " object for (field) "
2881 << it->second->PrettyField();
2882 return it->second;
2883 } else if (UNLIKELY(could_change_resolution_of(f, info))) {
2884 // Resolution might change. Just clear the resolved value.
2885 VLOG(plugin) << "Clearing resolution " << info << " for (field) " << f->PrettyField();
2886 return static_cast<art::ArtField*>(nullptr);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002887 }
Alex Light24627892019-11-06 10:28:21 -08002888 return f;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002889 },
2890 [&](art::ArtMethod* m, const auto& info) REQUIRES(art::Locks::mutator_lock_) {
Alex Light28b6efe2019-11-06 12:49:41 -08002891 DCHECK(m != nullptr) << info;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002892 auto it = method_map.find(m);
Alex Light24627892019-11-06 10:28:21 -08002893 if (it != method_map.end()) {
2894 VLOG(plugin) << "Updating " << info << " object for (method) "
2895 << it->second->PrettyMethod();
2896 return it->second;
2897 } else if (UNLIKELY(could_change_resolution_of(m, info))) {
2898 // Resolution might change. Just clear the resolved value.
2899 VLOG(plugin) << "Clearing resolution " << info << " for (method) " << m->PrettyMethod();
2900 return static_cast<art::ArtMethod*>(nullptr);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002901 }
Alex Light24627892019-11-06 10:28:21 -08002902 return m;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002903 });
2904
2905 // Force every frame of every thread to deoptimize (any frame might have eg offsets compiled in).
2906 driver_->runtime_->GetInstrumentation()->DeoptimizeAllThreadFrames();
2907
Alex Light986914b2019-11-19 01:12:25 +00002908 std::unordered_map<art::ObjPtr<art::mirror::Object>,
2909 art::ObjPtr<art::mirror::Object>,
2910 art::HashObjPtr> map;
Alex Light270db1c2019-12-03 12:20:01 +00002911 for (auto [new_class, old_class] : art::ZipLeft(new_classes->Iterate(), old_classes->Iterate())) {
2912 map.emplace(old_class, new_class);
2913 }
2914 for (auto [new_instance, old_instance] :
2915 art::ZipLeft(new_instances->Iterate(), old_instances->Iterate())) {
2916 map.emplace(old_instance, new_instance);
2917 // Bare-bones check that the mapping is correct.
2918 CHECK(new_instance->GetClass() == map[old_instance->GetClass()]->AsClass())
2919 << new_instance->GetClass()->PrettyClass() << " vs "
2920 << map[old_instance->GetClass()]->AsClass()->PrettyClass();
Alex Light986914b2019-11-19 01:12:25 +00002921 }
2922
2923 // Actually perform the general replacement. This doesn't affect ArtMethod/ArtFields. It does
2924 // affect the declaring_class field of all the obsolete objects, which is unfortunate and needs to
2925 // be undone. This replaces the mirror::Class in 'holder' as well. It's magic!
2926 HeapExtensions::ReplaceReferences(driver_->self_, map);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002927
2928 // Save the old class so that the JIT gc doesn't get confused by it being collected before the
2929 // jit code. This is also needed to keep the dex-caches of any obsolete methods live.
Alex Light270db1c2019-12-03 12:20:01 +00002930 for (auto [new_class, old_class] :
2931 art::ZipLeft(new_classes->Iterate(), art::MakeIterationRange(old_classes_vec))) {
2932 new_class->GetExtData()->SetObsoleteClass(old_class);
2933 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002934
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002935 art::jit::Jit* jit = driver_->runtime_->GetJit();
2936 if (jit != nullptr) {
2937 // Clear jit.
2938 // TODO We might want to have some way to tell the JIT not to wait the kJitSamplesBatchSize
2939 // invokes to start compiling things again.
2940 jit->GetCodeCache()->InvalidateAllCompiledCode();
2941 }
2942
2943 // Clear thread caches
2944 {
2945 // TODO We might be able to avoid doing this but given the rather unstructured nature of the
2946 // interpreter cache it's probably not worth the effort.
2947 art::MutexLock mu(driver_->self_, *art::Locks::thread_list_lock_);
2948 driver_->runtime_->GetThreadList()->ForEach(
2949 [](art::Thread* t) { t->GetInterpreterCache()->Clear(t); });
2950 }
2951
2952 if (art::kIsDebugBuild) {
2953 // Just make sure we didn't screw up any of the now obsolete methods or fields. We need their
2954 // declaring-class to still be the obolete class
2955 orig->VisitMethods([&](art::ArtMethod* method) REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light270db1c2019-12-03 12:20:01 +00002956 if (method->IsCopied()) {
2957 // Copied methods have interfaces as their declaring class.
2958 return;
2959 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002960 DCHECK_EQ(method->GetDeclaringClass(), orig) << method->GetDeclaringClass()->PrettyClass()
2961 << " vs " << orig->PrettyClass();
2962 }, art::kRuntimePointerSize);
2963 orig->VisitFields([&](art::ArtField* field) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2964 DCHECK_EQ(field->GetDeclaringClass(), orig) << field->GetDeclaringClass()->PrettyClass()
2965 << " vs " << orig->PrettyClass();
2966 });
2967 }
2968}
2969
2970// Redefines the class in place
2971void Redefiner::ClassRedefinition::UpdateClassInPlace(const RedefinitionDataIter& holder) {
2972 art::ObjPtr<art::mirror::Class> mclass(holder.GetMirrorClass());
2973 // TODO Rewrite so we don't do a stack walk for each and every class.
2974 FindAndAllocateObsoleteMethods(mclass);
2975 art::ObjPtr<art::mirror::DexCache> new_dex_cache(holder.GetNewDexCache());
2976 art::ObjPtr<art::mirror::Object> original_dex_file(holder.GetOriginalDexFile());
Alex Light6ac57502017-01-19 15:05:06 -08002977 DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002978 const art::dex::ClassDef& class_def = dex_file_->GetClassDef(0);
Vladimir Marko5122e6b2017-08-17 16:10:09 +01002979 UpdateMethods(mclass, class_def);
Alex Light007ada22017-01-10 13:33:56 -08002980 UpdateFields(mclass);
Alex Light200b9d72016-12-15 11:34:13 -08002981
David Brazdil1a658632018-12-01 17:54:26 +00002982 art::ObjPtr<art::mirror::ClassExt> ext(mclass->GetExtData());
2983 CHECK(!ext.IsNull());
2984 ext->SetOriginalDexFile(original_dex_file);
2985
2986 // If this is the first time the class is being redefined, store
2987 // the native DexFile pointer and initial ClassDef index in ClassExt.
2988 // This preserves the pointer for hiddenapi access checks which need
2989 // to read access flags from the initial DexFile.
2990 if (ext->GetPreRedefineDexFile() == nullptr) {
2991 ext->SetPreRedefineDexFile(&mclass->GetDexFile());
2992 ext->SetPreRedefineClassDefIndex(mclass->GetDexClassDefIndex());
2993 }
2994
Alex Lighta01de592016-11-15 10:43:06 -08002995 // Update the class fields.
2996 // Need to update class last since the ArtMethod gets its DexFile from the class (which is needed
2997 // to call GetReturnTypeDescriptor and GetParameterTypeList above).
2998 mclass->SetDexCache(new_dex_cache.Ptr());
Alex Light6ac57502017-01-19 15:05:06 -08002999 mclass->SetDexClassDefIndex(dex_file_->GetIndexForClassDef(class_def));
Alex Light0e692732017-01-10 15:00:05 -08003000 mclass->SetDexTypeIndex(dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(class_sig_.c_str())));
Alex Light035105f2018-03-05 17:48:48 -08003001
3002 // Notify the jit that all the methods in this class were redefined. Need to do this last since
3003 // the jit relies on the dex_file_ being correct (for native methods at least) to find the method
3004 // meta-data.
3005 art::jit::Jit* jit = driver_->runtime_->GetJit();
3006 if (jit != nullptr) {
3007 art::PointerSize image_pointer_size =
3008 driver_->runtime_->GetClassLinker()->GetImagePointerSize();
3009 auto code_cache = jit->GetCodeCache();
3010 // Non-invokable methods don't have any JIT data associated with them so we don't need to tell
3011 // the jit about them.
3012 for (art::ArtMethod& method : mclass->GetDeclaredMethods(image_pointer_size)) {
3013 if (method.IsInvokable()) {
3014 code_cache->NotifyMethodRedefined(&method);
3015 }
3016 }
3017 }
Alex Lighta01de592016-11-15 10:43:06 -08003018}
3019
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00003020// Performs final updates to class for redefinition.
3021void Redefiner::ClassRedefinition::UpdateClass(const RedefinitionDataIter& holder) {
Alex Lightfb537082019-12-10 14:38:34 -08003022 CHECK(holder.IsInitialized());
3023 if (holder.IsInitialStructural()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00003024 UpdateClassStructurally(holder);
Alex Lightfb537082019-12-10 14:38:34 -08003025 } else if (!holder.IsActuallyStructural()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00003026 UpdateClassInPlace(holder);
3027 }
Alex Lightc2d0c962019-10-23 14:14:25 -07003028 UpdateClassCommon(holder);
3029}
3030
3031void Redefiner::ClassRedefinition::UpdateClassCommon(const RedefinitionDataIter &cur_data) {
3032 // NB This is after we've already replaced all old-refs with new-refs in the structural case.
3033 art::ObjPtr<art::mirror::Class> klass(cur_data.GetMirrorClass());
3034 DCHECK(!IsStructuralRedefinition() || klass == cur_data.GetNewClassObject());
3035 if (!needs_reverify_) {
3036 return;
3037 }
3038 // Force the most restrictive interpreter environment. We don't know what the final verification
3039 // will allow. We will clear these after retrying verification once we drop the mutator-lock.
3040 klass->VisitMethods([](art::ArtMethod* m) REQUIRES_SHARED(art::Locks::mutator_lock_) {
3041 if (!m->IsNative() && m->IsInvokable() && !m->IsObsolete()) {
3042 m->ClearSkipAccessChecks();
3043 m->SetDontCompile();
3044 m->SetMustCountLocks();
3045 }
3046 }, art::kRuntimePointerSize);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00003047}
3048
Alex Light1e3926a2017-04-07 10:38:06 -07003049// Restores the old obsolete methods maps if it turns out they weren't needed (ie there were no new
3050// obsolete methods).
3051void Redefiner::ClassRedefinition::RestoreObsoleteMethodMapsIfUnneeded(
3052 const RedefinitionDataIter* cur_data) {
Alex Lightfb537082019-12-10 14:38:34 -08003053 if (cur_data->IsActuallyStructural()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00003054 // We didn't touch these in this case.
3055 return;
3056 }
Vladimir Markod93e3742018-07-18 10:58:13 +01003057 art::ObjPtr<art::mirror::Class> klass = GetMirrorClass();
3058 art::ObjPtr<art::mirror::ClassExt> ext = klass->GetExtData();
3059 art::ObjPtr<art::mirror::PointerArray> methods = ext->GetObsoleteMethods();
3060 art::ObjPtr<art::mirror::PointerArray> old_methods = cur_data->GetOldObsoleteMethods();
Alex Light70713df2017-04-18 13:03:31 -07003061 int32_t old_length = old_methods == nullptr ? 0 : old_methods->GetLength();
Alex Light1e3926a2017-04-07 10:38:06 -07003062 int32_t expected_length =
3063 old_length + klass->NumDirectMethods() + klass->NumDeclaredVirtualMethods();
3064 // Check to make sure we are only undoing this one.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00003065 if (methods.IsNull()) {
3066 // No new obsolete methods! We can get rid of the maps.
3067 ext->SetObsoleteArrays(cur_data->GetOldObsoleteMethods(), cur_data->GetOldDexCaches());
3068 } else if (expected_length == methods->GetLength()) {
Alex Light70713df2017-04-18 13:03:31 -07003069 for (int32_t i = 0; i < expected_length; i++) {
3070 art::ArtMethod* expected = nullptr;
3071 if (i < old_length) {
3072 expected = old_methods->GetElementPtrSize<art::ArtMethod*>(i, art::kRuntimePointerSize);
3073 }
3074 if (methods->GetElementPtrSize<art::ArtMethod*>(i, art::kRuntimePointerSize) != expected) {
Alex Light1e3926a2017-04-07 10:38:06 -07003075 // We actually have some new obsolete methods. Just abort since we cannot safely shrink the
3076 // obsolete methods array.
3077 return;
3078 }
3079 }
3080 // No new obsolete methods! We can get rid of the maps.
3081 ext->SetObsoleteArrays(cur_data->GetOldObsoleteMethods(), cur_data->GetOldDexCaches());
3082 }
3083}
3084
Alex Lighta01de592016-11-15 10:43:06 -08003085// This function does all (java) allocations we need to do for the Class being redefined.
3086// TODO Change this name maybe?
Alex Light1e3926a2017-04-07 10:38:06 -07003087bool Redefiner::ClassRedefinition::EnsureClassAllocationsFinished(
3088 /*out*/RedefinitionDataIter* cur_data) {
Alex Light0e692732017-01-10 15:00:05 -08003089 art::StackHandleScope<2> hs(driver_->self_);
3090 art::Handle<art::mirror::Class> klass(hs.NewHandle(
3091 driver_->self_->DecodeJObject(klass_)->AsClass()));
Andreas Gampefa4333d2017-02-14 11:10:34 -08003092 if (klass == nullptr) {
Alex Lighta01de592016-11-15 10:43:06 -08003093 RecordFailure(ERR(INVALID_CLASS), "Unable to decode class argument!");
3094 return false;
3095 }
3096 // Allocate the classExt
Vladimir Marko3068d582019-05-28 16:39:29 +01003097 art::Handle<art::mirror::ClassExt> ext =
3098 hs.NewHandle(art::mirror::Class::EnsureExtDataPresent(klass, driver_->self_));
Andreas Gampefa4333d2017-02-14 11:10:34 -08003099 if (ext == nullptr) {
Alex Lighta01de592016-11-15 10:43:06 -08003100 // No memory. Clear exception (it's not useful) and return error.
Alex Light0e692732017-01-10 15:00:05 -08003101 driver_->self_->AssertPendingOOMException();
3102 driver_->self_->ClearException();
Alex Lighta01de592016-11-15 10:43:06 -08003103 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate ClassExt");
3104 return false;
3105 }
Alex Lightfb537082019-12-10 14:38:34 -08003106 if (!cur_data->IsActuallyStructural()) {
3107 CHECK(!IsStructuralRedefinition());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00003108 // First save the old values of the 2 arrays that make up the obsolete methods maps. Then
3109 // allocate the 2 arrays that make up the obsolete methods map. Since the contents of the arrays
3110 // are only modified when all threads (other than the modifying one) are suspended we don't need
3111 // to worry about missing the unsyncronized writes to the array. We do synchronize when setting
3112 // it however, since that can happen at any time.
3113 cur_data->SetOldObsoleteMethods(ext->GetObsoleteMethods());
3114 cur_data->SetOldDexCaches(ext->GetObsoleteDexCaches());
3115 if (!art::mirror::ClassExt::ExtendObsoleteArrays(
3116 ext, driver_->self_, klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize).size())) {
3117 // OOM. Clear exception and return error.
3118 driver_->self_->AssertPendingOOMException();
3119 driver_->self_->ClearException();
3120 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate/extend obsolete methods map");
3121 return false;
3122 }
Alex Lighta01de592016-11-15 10:43:06 -08003123 }
3124 return true;
3125}
3126
3127} // namespace openjdkjvmti