blob: 05d7de7f10ea58673666ee8c34491151f250810a [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
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000045#include "android-base/thread_annotations.h"
Andreas Gampea1d2f952017-04-20 22:53:58 -070046#include "art_field-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000047#include "art_field.h"
Alex Lighta01de592016-11-15 10:43:06 -080048#include "art_jvmti.h"
Steven Morelande431e272017-07-18 16:53:49 -070049#include "art_method-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000050#include "art_method.h"
Vladimir Markoe1993c72017-06-14 17:01:38 +010051#include "base/array_ref.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000052#include "base/casts.h"
53#include "base/enums.h"
54#include "base/globals.h"
55#include "base/length_prefixed_array.h"
56#include "base/utils.h"
Andreas Gampec6ea7d02017-02-01 16:46:28 -080057#include "class_linker-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000058#include "class_linker.h"
Vladimir Markob4eb1b12018-05-24 11:09:38 +010059#include "class_root.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000060#include "class_status.h"
Alex Light5643caf2017-02-08 11:39:07 -080061#include "debugger.h"
David Sehr013fd802018-01-11 22:55:24 -080062#include "dex/art_dex_file_loader.h"
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -070063#include "dex/class_accessor-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000064#include "dex/class_accessor.h"
David Sehr9e734c72018-01-04 17:56:19 -080065#include "dex/dex_file.h"
66#include "dex/dex_file_loader.h"
67#include "dex/dex_file_types.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000068#include "dex/primitive.h"
Andreas Gampead1aa632019-01-02 10:30:54 -080069#include "dex/signature-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000070#include "dex/signature.h"
Alex Lighta01de592016-11-15 10:43:06 -080071#include "events-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000072#include "events.h"
Alex Lighta01de592016-11-15 10:43:06 -080073#include "gc/allocation_listener.h"
Alex Light6abd5392017-01-05 17:53:00 -080074#include "gc/heap.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000075#include "gc/heap-inl.h"
76#include "gc/heap-visit-objects-inl.h"
77#include "handle.h"
78#include "handle_scope.h"
Alex Lighta01de592016-11-15 10:43:06 -080079#include "instrumentation.h"
Alex Light07f06212017-06-01 14:01:43 -070080#include "intern_table.h"
Alex Light5643caf2017-02-08 11:39:07 -080081#include "jdwp/jdwp.h"
82#include "jdwp/jdwp_constants.h"
83#include "jdwp/jdwp_event.h"
84#include "jdwp/object_registry.h"
Alex Lightdba61482016-12-21 08:20:29 -080085#include "jit/jit.h"
86#include "jit/jit_code_cache.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010087#include "jni/jni_env_ext-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000088#include "jni/jni_id_manager.h"
89#include "jvmti.h"
Alex Lighta01de592016-11-15 10:43:06 -080090#include "jvmti_allocator.h"
Vladimir Marko5924a4a2018-05-29 17:40:41 +010091#include "linear_alloc.h"
Andreas Gampe8e0f0432018-10-24 13:38:03 -070092#include "mirror/array-alloc-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000093#include "mirror/array.h"
Andreas Gampe70f5fd02018-10-24 19:58:37 -070094#include "mirror/class-alloc-inl.h"
Alex Light6161f132017-01-25 10:30:20 -080095#include "mirror/class-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000096#include "mirror/class-refvisitor-inl.h"
97#include "mirror/class.h"
Vladimir Markobb206de2019-03-28 10:30:32 +000098#include "mirror/class_ext-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +000099#include "mirror/dex_cache-inl.h"
100#include "mirror/dex_cache.h"
101#include "mirror/executable-inl.h"
102#include "mirror/field-inl.h"
103#include "mirror/method.h"
104#include "mirror/method_handle_impl-inl.h"
Alex Lighta01de592016-11-15 10:43:06 -0800105#include "mirror/object.h"
Andreas Gampe52ecb652018-10-24 15:18:21 -0700106#include "mirror/object_array-alloc-inl.h"
107#include "mirror/object_array-inl.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000108#include "mirror/object_array.h"
109#include "mirror/string.h"
Alex Lightc18eba32019-09-24 14:36:27 -0700110#include "mirror/var_handle.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -0700111#include "nativehelper/scoped_local_ref.h"
Alex Lighte77b48b2017-02-22 11:08:06 -0800112#include "non_debuggable_classes.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000113#include "obj_ptr.h"
Alex Lighta01de592016-11-15 10:43:06 -0800114#include "object_lock.h"
115#include "runtime.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000116#include "runtime_globals.h"
Vladimir Marko5924a4a2018-05-29 17:40:41 +0100117#include "stack.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000118#include "thread.h"
Vladimir Marko5924a4a2018-05-29 17:40:41 +0100119#include "thread_list.h"
Alex Lighta26e3492017-06-27 17:55:37 -0700120#include "ti_breakpoint.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000121#include "ti_class_definition.h"
Alex Lighteb98b082017-01-25 13:02:32 -0800122#include "ti_class_loader.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000123#include "ti_heap.h"
124#include "ti_logging.h"
125#include "ti_thread.h"
Alex Light0e692732017-01-10 15:00:05 -0800126#include "transform.h"
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700127#include "verifier/class_verifier.h"
Andreas Gampe6d7abbd2017-04-24 13:19:09 -0700128#include "verifier/verifier_enums.h"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000129#include "well_known_classes.h"
130#include "write_barrier.h"
Alex Lighta01de592016-11-15 10:43:06 -0800131
132namespace openjdkjvmti {
133
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000134// Debug check to force us to directly check we saw all methods and fields exactly once directly.
135// Normally we don't need to do this since if any are missing the count will be different
136constexpr bool kCheckAllMethodsSeenOnce = art::kIsDebugBuild;
137
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800138using android::base::StringPrintf;
139
Alex Lighteee0bd42017-02-14 15:31:45 +0000140// A helper that fills in a classes obsolete_methods_ and obsolete_dex_caches_ classExt fields as
141// they are created. This ensures that we can always call any method of an obsolete ArtMethod object
142// almost as soon as they are created since the GetObsoleteDexCache method will succeed.
143class ObsoleteMap {
144 public:
Alex Lighte7a33542019-04-10 14:22:49 -0700145 art::ArtMethod* FindObsoleteVersion(art::ArtMethod* original) const
Alex Lighteee0bd42017-02-14 15:31:45 +0000146 REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
147 auto method_pair = id_map_.find(original);
148 if (method_pair != id_map_.end()) {
149 art::ArtMethod* res = obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(
150 method_pair->second, art::kRuntimePointerSize);
151 DCHECK(res != nullptr);
Alex Lighteee0bd42017-02-14 15:31:45 +0000152 return res;
153 } else {
154 return nullptr;
155 }
156 }
157
158 void RecordObsolete(art::ArtMethod* original, art::ArtMethod* obsolete)
159 REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
160 DCHECK(original != nullptr);
161 DCHECK(obsolete != nullptr);
162 int32_t slot = next_free_slot_++;
163 DCHECK_LT(slot, obsolete_methods_->GetLength());
164 DCHECK(nullptr ==
165 obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(slot, art::kRuntimePointerSize));
166 DCHECK(nullptr == obsolete_dex_caches_->Get(slot));
167 obsolete_methods_->SetElementPtrSize(slot, obsolete, art::kRuntimePointerSize);
168 obsolete_dex_caches_->Set(slot, original_dex_cache_);
169 id_map_.insert({original, slot});
170 }
171
172 ObsoleteMap(art::ObjPtr<art::mirror::PointerArray> obsolete_methods,
173 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> obsolete_dex_caches,
174 art::ObjPtr<art::mirror::DexCache> original_dex_cache)
175 : next_free_slot_(0),
176 obsolete_methods_(obsolete_methods),
177 obsolete_dex_caches_(obsolete_dex_caches),
178 original_dex_cache_(original_dex_cache) {
179 // Figure out where the first unused slot in the obsolete_methods_ array is.
180 while (obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(
181 next_free_slot_, art::kRuntimePointerSize) != nullptr) {
182 DCHECK(obsolete_dex_caches_->Get(next_free_slot_) != nullptr);
183 next_free_slot_++;
184 }
185 // Sanity check that the same slot in obsolete_dex_caches_ is free.
186 DCHECK(obsolete_dex_caches_->Get(next_free_slot_) == nullptr);
187 }
188
Alex Lighte7a33542019-04-10 14:22:49 -0700189 struct ObsoleteMethodPair {
190 art::ArtMethod* old_method;
191 art::ArtMethod* obsolete_method;
192 };
193
Vladimir Markoeab02482019-05-09 10:28:17 +0100194 class ObsoleteMapIter {
Alex Lighte7a33542019-04-10 14:22:49 -0700195 public:
Vladimir Markoeab02482019-05-09 10:28:17 +0100196 using iterator_category = std::forward_iterator_tag;
197 using value_type = ObsoleteMethodPair;
198 using difference_type = ptrdiff_t;
199 using pointer = void; // Unsupported.
200 using reference = void; // Unsupported.
201
Alex Lighte7a33542019-04-10 14:22:49 -0700202 ObsoleteMethodPair operator*() const
203 REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
Vladimir Markoeab02482019-05-09 10:28:17 +0100204 art::ArtMethod* obsolete = map_->obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(
205 iter_->second, art::kRuntimePointerSize);
Alex Lighte7a33542019-04-10 14:22:49 -0700206 DCHECK(obsolete != nullptr);
207 return { iter_->first, obsolete };
208 }
209
210 bool operator==(ObsoleteMapIter other) const {
211 return map_ == other.map_ && iter_ == other.iter_;
212 }
213
214 bool operator!=(ObsoleteMapIter other) const {
215 return !(*this == other);
216 }
217
Vladimir Markoeab02482019-05-09 10:28:17 +0100218 ObsoleteMapIter operator++(int) {
Alex Lighte7a33542019-04-10 14:22:49 -0700219 ObsoleteMapIter retval = *this;
220 ++(*this);
221 return retval;
222 }
223
Vladimir Markoeab02482019-05-09 10:28:17 +0100224 ObsoleteMapIter operator++() {
Alex Lighte7a33542019-04-10 14:22:49 -0700225 ++iter_;
226 return *this;
227 }
228
229 private:
230 ObsoleteMapIter(const ObsoleteMap* map,
231 std::unordered_map<art::ArtMethod*, int32_t>::const_iterator iter)
232 : map_(map), iter_(iter) {}
233
234 const ObsoleteMap* map_;
Vladimir Markoeab02482019-05-09 10:28:17 +0100235 std::unordered_map<art::ArtMethod*, int32_t>::const_iterator iter_;
Alex Lighte7a33542019-04-10 14:22:49 -0700236
237 friend class ObsoleteMap;
238 };
239
240 ObsoleteMapIter end() const {
241 return ObsoleteMapIter(this, id_map_.cend());
242 }
243
244 ObsoleteMapIter begin() const {
245 return ObsoleteMapIter(this, id_map_.cbegin());
246 }
247
Alex Lighteee0bd42017-02-14 15:31:45 +0000248 private:
249 int32_t next_free_slot_;
250 std::unordered_map<art::ArtMethod*, int32_t> id_map_;
251 // Pointers to the fields in mirror::ClassExt. These can be held as ObjPtr since this is only used
252 // when we have an exclusive mutator_lock_ (i.e. all threads are suspended).
253 art::ObjPtr<art::mirror::PointerArray> obsolete_methods_;
254 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> obsolete_dex_caches_;
255 art::ObjPtr<art::mirror::DexCache> original_dex_cache_;
256};
257
Alex Lightdba61482016-12-21 08:20:29 -0800258// This visitor walks thread stacks and allocates and sets up the obsolete methods. It also does
259// some basic sanity checks that the obsolete method is sane.
260class ObsoleteMethodStackVisitor : public art::StackVisitor {
261 protected:
262 ObsoleteMethodStackVisitor(
263 art::Thread* thread,
264 art::LinearAlloc* allocator,
265 const std::unordered_set<art::ArtMethod*>& obsoleted_methods,
Alex Lighteee0bd42017-02-14 15:31:45 +0000266 ObsoleteMap* obsolete_maps)
Alex Lightdba61482016-12-21 08:20:29 -0800267 : StackVisitor(thread,
Andreas Gampe6e897762018-10-16 13:09:32 -0700268 /*context=*/nullptr,
Alex Lightdba61482016-12-21 08:20:29 -0800269 StackVisitor::StackWalkKind::kIncludeInlinedFrames),
270 allocator_(allocator),
271 obsoleted_methods_(obsoleted_methods),
Alex Light4ba388a2017-01-27 10:26:49 -0800272 obsolete_maps_(obsolete_maps) { }
Alex Lightdba61482016-12-21 08:20:29 -0800273
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100274 ~ObsoleteMethodStackVisitor() override {}
Alex Lightdba61482016-12-21 08:20:29 -0800275
276 public:
277 // Returns true if we successfully installed obsolete methods on this thread, filling
278 // obsolete_maps_ with the translations if needed. Returns false and fills error_msg if we fail.
279 // The stack is cleaned up when we fail.
Alex Light007ada22017-01-10 13:33:56 -0800280 static void UpdateObsoleteFrames(
Alex Lightdba61482016-12-21 08:20:29 -0800281 art::Thread* thread,
282 art::LinearAlloc* allocator,
283 const std::unordered_set<art::ArtMethod*>& obsoleted_methods,
Alex Lighteee0bd42017-02-14 15:31:45 +0000284 ObsoleteMap* obsolete_maps)
Alex Light007ada22017-01-10 13:33:56 -0800285 REQUIRES(art::Locks::mutator_lock_) {
Alex Lightdba61482016-12-21 08:20:29 -0800286 ObsoleteMethodStackVisitor visitor(thread,
287 allocator,
288 obsoleted_methods,
Alex Light007ada22017-01-10 13:33:56 -0800289 obsolete_maps);
Alex Lightdba61482016-12-21 08:20:29 -0800290 visitor.WalkStack();
Alex Lightdba61482016-12-21 08:20:29 -0800291 }
292
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100293 bool VisitFrame() override REQUIRES(art::Locks::mutator_lock_) {
Alex Lighteee0bd42017-02-14 15:31:45 +0000294 art::ScopedAssertNoThreadSuspension snts("Fixing up the stack for obsolete methods.");
Alex Lightdba61482016-12-21 08:20:29 -0800295 art::ArtMethod* old_method = GetMethod();
Alex Lightdba61482016-12-21 08:20:29 -0800296 if (obsoleted_methods_.find(old_method) != obsoleted_methods_.end()) {
Alex Lightdba61482016-12-21 08:20:29 -0800297 // We cannot ensure that the right dex file is used in inlined frames so we don't support
298 // redefining them.
Nicolas Geoffray226805d2018-12-14 10:59:02 +0000299 DCHECK(!IsInInlinedFrame()) << "Inlined frames are not supported when using redefinition: "
300 << old_method->PrettyMethod() << " is inlined into "
301 << GetOuterMethod()->PrettyMethod();
Alex Lighteee0bd42017-02-14 15:31:45 +0000302 art::ArtMethod* new_obsolete_method = obsolete_maps_->FindObsoleteVersion(old_method);
303 if (new_obsolete_method == nullptr) {
Alex Lightdba61482016-12-21 08:20:29 -0800304 // Create a new Obsolete Method and put it in the list.
305 art::Runtime* runtime = art::Runtime::Current();
306 art::ClassLinker* cl = runtime->GetClassLinker();
307 auto ptr_size = cl->GetImagePointerSize();
308 const size_t method_size = art::ArtMethod::Size(ptr_size);
Alex Light5c11a792017-03-10 14:29:22 -0800309 auto* method_storage = allocator_->Alloc(art::Thread::Current(), method_size);
Alex Light007ada22017-01-10 13:33:56 -0800310 CHECK(method_storage != nullptr) << "Unable to allocate storage for obsolete version of '"
311 << old_method->PrettyMethod() << "'";
Alex Lightdba61482016-12-21 08:20:29 -0800312 new_obsolete_method = new (method_storage) art::ArtMethod();
313 new_obsolete_method->CopyFrom(old_method, ptr_size);
314 DCHECK_EQ(new_obsolete_method->GetDeclaringClass(), old_method->GetDeclaringClass());
315 new_obsolete_method->SetIsObsolete();
Alex Lightfcbafb32017-02-02 15:09:54 -0800316 new_obsolete_method->SetDontCompile();
Alex Lightdb01a092017-04-03 15:39:55 -0700317 cl->SetEntryPointsForObsoleteMethod(new_obsolete_method);
Alex Lighteee0bd42017-02-14 15:31:45 +0000318 obsolete_maps_->RecordObsolete(old_method, new_obsolete_method);
Alex Lightdba61482016-12-21 08:20:29 -0800319 }
320 DCHECK(new_obsolete_method != nullptr);
321 SetMethod(new_obsolete_method);
322 }
323 return true;
324 }
325
326 private:
327 // The linear allocator we should use to make new methods.
328 art::LinearAlloc* allocator_;
329 // The set of all methods which could be obsoleted.
330 const std::unordered_set<art::ArtMethod*>& obsoleted_methods_;
331 // A map from the original to the newly allocated obsolete method for frames on this thread. The
Alex Lighteee0bd42017-02-14 15:31:45 +0000332 // values in this map are added to the obsolete_methods_ (and obsolete_dex_caches_) fields of
333 // the redefined classes ClassExt as it is filled.
334 ObsoleteMap* obsolete_maps_;
Alex Lightdba61482016-12-21 08:20:29 -0800335};
336
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000337template <RedefinitionType kType>
338jvmtiError
339Redefiner::IsModifiableClassGeneric(jvmtiEnv* env, jclass klass, jboolean* is_redefinable) {
340 if (env == nullptr) {
341 return ERR(INVALID_ENVIRONMENT);
342 }
Alex Lighte4a88632017-01-10 07:41:24 -0800343 art::Thread* self = art::Thread::Current();
344 art::ScopedObjectAccess soa(self);
345 art::StackHandleScope<1> hs(self);
346 art::ObjPtr<art::mirror::Object> obj(self->DecodeJObject(klass));
Alex Light413a8ad2019-02-14 10:19:44 -0800347 if (obj.IsNull() || !obj->IsClass()) {
Alex Lighte4a88632017-01-10 07:41:24 -0800348 return ERR(INVALID_CLASS);
349 }
350 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(obj->AsClass()));
351 std::string err_unused;
352 *is_redefinable =
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000353 Redefiner::GetClassRedefinitionError<kType>(h_klass, &err_unused) != ERR(UNMODIFIABLE_CLASS)
354 ? JNI_TRUE
355 : JNI_FALSE;
Alex Lighte4a88632017-01-10 07:41:24 -0800356 return OK;
357}
358
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000359jvmtiError
360Redefiner::IsStructurallyModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_redefinable) {
361 return Redefiner::IsModifiableClassGeneric<RedefinitionType::kStructural>(
362 env, klass, is_redefinable);
363}
364
365jvmtiError Redefiner::IsModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_redefinable) {
366 return Redefiner::IsModifiableClassGeneric<RedefinitionType::kNormal>(env, klass, is_redefinable);
367}
368
369template <RedefinitionType kType>
370jvmtiError Redefiner::GetClassRedefinitionError(jclass klass, /*out*/ std::string* error_msg) {
Alex Light9e7859c2018-04-05 13:49:43 -0700371 art::Thread* self = art::Thread::Current();
372 art::ScopedObjectAccess soa(self);
373 art::StackHandleScope<1> hs(self);
374 art::ObjPtr<art::mirror::Object> obj(self->DecodeJObject(klass));
Alex Light413a8ad2019-02-14 10:19:44 -0800375 if (obj.IsNull() || !obj->IsClass()) {
Alex Light9e7859c2018-04-05 13:49:43 -0700376 return ERR(INVALID_CLASS);
377 }
378 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(obj->AsClass()));
379 return Redefiner::GetClassRedefinitionError(h_klass, error_msg);
380}
381
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000382template <RedefinitionType kType>
Alex Lighte4a88632017-01-10 07:41:24 -0800383jvmtiError Redefiner::GetClassRedefinitionError(art::Handle<art::mirror::Class> klass,
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000384 /*out*/ std::string* error_msg) {
385 art::Thread* self = art::Thread::Current();
Alex Light9e7859c2018-04-05 13:49:43 -0700386 if (!klass->IsResolved()) {
387 // It's only a problem to try to retransform/redefine a unprepared class if it's happening on
388 // the same thread as the class-linking process. If it's on another thread we will be able to
389 // wait for the preparation to finish and continue from there.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000390 if (klass->GetLockOwnerThreadId() == self->GetThreadId()) {
Alex Light9e7859c2018-04-05 13:49:43 -0700391 *error_msg = "Modification of class " + klass->PrettyClass() +
392 " from within the classes ClassLoad callback is not supported to prevent deadlocks." +
393 " Please use ClassFileLoadHook directly instead.";
394 return ERR(INTERNAL);
395 } else {
396 LOG(WARNING) << klass->PrettyClass() << " is not yet resolved. Attempting to transform "
397 << "it could cause arbitrary length waits as the class is being resolved.";
398 }
399 }
Alex Lighte4a88632017-01-10 07:41:24 -0800400 if (klass->IsPrimitive()) {
401 *error_msg = "Modification of primitive classes is not supported";
402 return ERR(UNMODIFIABLE_CLASS);
403 } else if (klass->IsInterface()) {
404 *error_msg = "Modification of Interface classes is currently not supported";
405 return ERR(UNMODIFIABLE_CLASS);
Alex Light09f274f2017-02-21 15:00:48 -0800406 } else if (klass->IsStringClass()) {
407 *error_msg = "Modification of String class is not supported";
408 return ERR(UNMODIFIABLE_CLASS);
Alex Lighte4a88632017-01-10 07:41:24 -0800409 } else if (klass->IsArrayClass()) {
410 *error_msg = "Modification of Array classes is not supported";
411 return ERR(UNMODIFIABLE_CLASS);
412 } else if (klass->IsProxyClass()) {
413 *error_msg = "Modification of proxy classes is not supported";
414 return ERR(UNMODIFIABLE_CLASS);
415 }
416
Alex Lighte77b48b2017-02-22 11:08:06 -0800417 for (jclass c : art::NonDebuggableClasses::GetNonDebuggableClasses()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000418 if (klass.Get() == self->DecodeJObject(c)->AsClass()) {
Alex Lighte77b48b2017-02-22 11:08:06 -0800419 *error_msg = "Class might have stack frames that cannot be made obsolete";
420 return ERR(UNMODIFIABLE_CLASS);
421 }
422 }
423
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000424 if (kType == RedefinitionType::kStructural) {
Alex Lightfb119572019-09-18 15:04:53 -0700425 // Class initialization interacts really badly with structural redefinition since we need to
426 // make the old class obsolete. We currently just blanket don't allow it.
427 // TODO It might be nice to allow this at some point.
428 if (klass->IsInitializing() &&
429 !klass->IsInitialized() &&
430 klass->GetClinitThreadId() == self->GetTid()) {
431 // We are in the class-init running on this thread.
432 *error_msg = "Modification of class " + klass->PrettyClass() + " during class" +
433 " initialization is not allowed.";
434 return ERR(INTERNAL);
435 }
436 if (!art::Runtime::Current()->GetClassLinker()->EnsureInitialized(
437 self, klass, /*can_init_fields=*/true, /*can_init_parents=*/true)) {
438 self->AssertPendingException();
439 *error_msg = "Class " + klass->PrettyClass() + " failed initialization. Structural" +
440 " redefinition of erroneous classes is not allowed. Failure was: " +
441 self->GetException()->Dump();
442 self->ClearException();
443 return ERR(INVALID_CLASS);
444 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000445 art::StackHandleScope<2> hs(self);
446 art::Handle<art::mirror::ObjectArray<art::mirror::Class>> roots(
447 hs.NewHandle(art::Runtime::Current()->GetClassLinker()->GetClassRoots()));
448 art::MutableHandle<art::mirror::Class> obj(hs.NewHandle<art::mirror::Class>(nullptr));
449 for (int32_t i = 0; i < roots->GetLength(); i++) {
450 obj.Assign(roots->Get(i));
451 // check if the redefined class is a superclass of any root (i.e. mirror plus a few other
452 // important types).
453 if (klass->IsAssignableFrom(obj.Get())) {
454 std::string pc(klass->PrettyClass());
455 *error_msg = StringPrintf("Class %s is an important runtime class and cannot be "
456 "structurally redefined.",
457 pc.c_str());
458 return ERR(UNMODIFIABLE_CLASS);
459 }
460 }
461 // Check Thread specifically since it's not a root but too many things reach into it with Unsafe
462 // too allow structural redefinition.
463 if (klass->IsAssignableFrom(
464 self->DecodeJObject(art::WellKnownClasses::java_lang_Thread)->AsClass())) {
465 *error_msg =
466 "java.lang.Thread has fields accessed using sun.misc.unsafe directly. It is not "
467 "safe to structurally redefine it.";
468 return ERR(UNMODIFIABLE_CLASS);
469 }
470 // Check for already existing non-static fields/methods.
471 // TODO Remove this once we support generic method/field addition.
472 bool non_static_method = false;
473 klass->VisitMethods([&](art::ArtMethod* m) REQUIRES_SHARED(art::Locks::mutator_lock_) {
474 // Since direct-methods (ie privates + <init> are not in any vtable/iftable we can update
475 // them).
476 if (!m->IsDirect()) {
477 non_static_method = true;
478 *error_msg = StringPrintf("%s has a non-direct function %s",
479 klass->PrettyClass().c_str(),
480 m->PrettyMethod().c_str());
481 }
482 }, art::kRuntimePointerSize);
483 if (non_static_method) {
484 return ERR(UNMODIFIABLE_CLASS);
485 }
486 bool non_static_field = false;
487 klass->VisitFields([&](art::ArtField* f) REQUIRES_SHARED(art::Locks::mutator_lock_) {
488 if (!f->IsStatic()) {
489 non_static_field = true;
490 *error_msg = StringPrintf(
491 "%s has a non-static field %s", klass->PrettyClass().c_str(), f->PrettyField().c_str());
492 }
493 });
494 if (non_static_field) {
495 return ERR(UNMODIFIABLE_CLASS);
496 }
497 // Check for fields/methods which were returned before moving to index jni id type.
498 // TODO We might want to rework how this is done. Once full redefinition is implemented we will
499 // need to check any subtypes too.
500 art::ObjPtr<art::mirror::ClassExt> ext(klass->GetExtData());
501 if (!ext.IsNull()) {
502 bool non_index_id = false;
503 ext->VisitJFieldIDs([&](jfieldID id, uint32_t idx, bool is_static)
504 REQUIRES_SHARED(art::Locks::mutator_lock_) {
505 if (!art::jni::JniIdManager::IsIndexId(id)) {
506 non_index_id = true;
507 *error_msg =
508 StringPrintf("%s Field %d (%s) has non-index jni-ids.",
509 (is_static ? "static" : "non-static"),
510 idx,
511 (is_static ? klass->GetStaticField(idx)
512 : klass->GetInstanceField(idx))->PrettyField().c_str());
513 }
514 });
515 ext->VisitJMethodIDs([&](jmethodID id, uint32_t idx)
516 REQUIRES_SHARED(art::Locks::mutator_lock_) {
517 if (!art::jni::JniIdManager::IsIndexId(id)) {
518 non_index_id = true;
519 *error_msg = StringPrintf(
520 "method %d (%s) has non-index jni-ids.",
521 idx,
522 klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize)[idx].PrettyMethod().c_str());
523 }
524 });
525 if (non_index_id) {
526 return ERR(UNMODIFIABLE_CLASS);
527 }
528 }
529 }
Alex Lighte4a88632017-01-10 07:41:24 -0800530 return OK;
531}
532
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000533template jvmtiError Redefiner::GetClassRedefinitionError<RedefinitionType::kNormal>(
534 art::Handle<art::mirror::Class> klass, /*out*/ std::string* error_msg);
535template jvmtiError Redefiner::GetClassRedefinitionError<RedefinitionType::kStructural>(
536 art::Handle<art::mirror::Class> klass, /*out*/ std::string* error_msg);
537
Alex Lighta01de592016-11-15 10:43:06 -0800538// Moves dex data to an anonymous, read-only mmap'd region.
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100539art::MemMap Redefiner::MoveDataToMemMap(const std::string& original_location,
540 art::ArrayRef<const unsigned char> data,
541 std::string* error_msg) {
542 art::MemMap map = art::MemMap::MapAnonymous(
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800543 StringPrintf("%s-transformed", original_location.c_str()).c_str(),
Alex Lightb7354d52017-03-30 15:17:01 -0700544 data.size(),
Alex Lighta01de592016-11-15 10:43:06 -0800545 PROT_READ|PROT_WRITE,
Andreas Gampe6e897762018-10-16 13:09:32 -0700546 /*low_4gb=*/ false,
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100547 error_msg);
548 if (LIKELY(map.IsValid())) {
549 memcpy(map.Begin(), data.data(), data.size());
550 // Make the dex files mmap read only. This matches how other DexFiles are mmaped and prevents
551 // programs from corrupting it.
552 map.Protect(PROT_READ);
Alex Lighta01de592016-11-15 10:43:06 -0800553 }
Alex Lighta01de592016-11-15 10:43:06 -0800554 return map;
555}
556
Alex Lighta7e38d82017-01-19 14:57:28 -0800557Redefiner::ClassRedefinition::ClassRedefinition(
558 Redefiner* driver,
559 jclass klass,
560 const art::DexFile* redefined_dex_file,
561 const char* class_sig,
Vladimir Markoe1993c72017-06-14 17:01:38 +0100562 art::ArrayRef<const unsigned char> orig_dex_file) :
Alex Lighta7e38d82017-01-19 14:57:28 -0800563 driver_(driver),
564 klass_(klass),
565 dex_file_(redefined_dex_file),
566 class_sig_(class_sig),
567 original_dex_file_(orig_dex_file) {
Alex Light0e692732017-01-10 15:00:05 -0800568 GetMirrorClass()->MonitorEnter(driver_->self_);
569}
570
571Redefiner::ClassRedefinition::~ClassRedefinition() {
572 if (driver_ != nullptr) {
573 GetMirrorClass()->MonitorExit(driver_->self_);
574 }
575}
576
Alex Light3732beb2019-10-04 13:35:34 -0700577jvmtiError Redefiner::RedefineClasses(jvmtiEnv* jenv,
Alex Light0e692732017-01-10 15:00:05 -0800578 jint class_count,
Alex Light3732beb2019-10-04 13:35:34 -0700579 const jvmtiClassDefinition* definitions) {
580 art::Runtime* runtime = art::Runtime::Current();
581 art::Thread* self = art::Thread::Current();
582 ArtJvmTiEnv* env = ArtJvmTiEnv::AsArtJvmTiEnv(jenv);
Alex Light0e692732017-01-10 15:00:05 -0800583 if (env == nullptr) {
Alex Light3732beb2019-10-04 13:35:34 -0700584 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE env was null!";
Alex Light0e692732017-01-10 15:00:05 -0800585 return ERR(INVALID_ENVIRONMENT);
586 } else if (class_count < 0) {
Alex Light3732beb2019-10-04 13:35:34 -0700587 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE class_count was less then 0";
Alex Light0e692732017-01-10 15:00:05 -0800588 return ERR(ILLEGAL_ARGUMENT);
589 } else if (class_count == 0) {
590 // We don't actually need to do anything. Just return OK.
591 return OK;
592 } else if (definitions == nullptr) {
Alex Light3732beb2019-10-04 13:35:34 -0700593 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE null definitions!";
Alex Light0e692732017-01-10 15:00:05 -0800594 return ERR(NULL_POINTER);
595 }
Alex Light3732beb2019-10-04 13:35:34 -0700596 std::string error_msg;
Alex Light6ac57502017-01-19 15:05:06 -0800597 std::vector<ArtClassDefinition> def_vector;
598 def_vector.reserve(class_count);
599 for (jint i = 0; i < class_count; i++) {
Alex Light3732beb2019-10-04 13:35:34 -0700600 jvmtiError res = Redefiner::GetClassRedefinitionError(definitions[i].klass, &error_msg);
Alex Lightce6ee702017-03-06 15:46:43 -0800601 if (res != OK) {
Alex Light3732beb2019-10-04 13:35:34 -0700602 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE " << error_msg;
Alex Lightce6ee702017-03-06 15:46:43 -0800603 return res;
Alex Lightce6ee702017-03-06 15:46:43 -0800604 }
Alex Light6ac57502017-01-19 15:05:06 -0800605 ArtClassDefinition def;
Alex Light64e4c142018-01-30 13:46:37 -0800606 res = def.Init(self, definitions[i]);
Alex Light6ac57502017-01-19 15:05:06 -0800607 if (res != OK) {
Alex Light3732beb2019-10-04 13:35:34 -0700608 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE bad definition " << i;
Alex Light6ac57502017-01-19 15:05:06 -0800609 return res;
610 }
611 def_vector.push_back(std::move(def));
612 }
613 // Call all the transformation events.
Alex Light15ffafd2019-10-17 13:58:01 -0700614 Transformer::RetransformClassesDirect(self, &def_vector);
615 jvmtiError res = RedefineClassesDirect(
Alex Light3732beb2019-10-04 13:35:34 -0700616 env, runtime, self, def_vector, RedefinitionType::kNormal, &error_msg);
617 if (res != OK) {
618 JVMTI_LOG(WARNING, env) << "FAILURE TO REDEFINE " << error_msg;
619 }
620 return res;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000621}
622
623jvmtiError Redefiner::StructurallyRedefineClassDirect(jvmtiEnv* env,
624 jclass klass,
625 const unsigned char* data,
626 jint data_size) {
627 if (env == nullptr) {
628 return ERR(INVALID_ENVIRONMENT);
629 } else if (ArtJvmTiEnv::AsArtJvmTiEnv(env)->capabilities.can_redefine_classes != 1) {
630 JVMTI_LOG(INFO, env) << "Does not have can_redefine_classes cap!";
631 return ERR(MUST_POSSESS_CAPABILITY);
632 }
633 std::vector<ArtClassDefinition> acds;
634 ArtClassDefinition acd;
635 jvmtiError err = acd.Init(
636 art::Thread::Current(),
637 jvmtiClassDefinition{ .klass = klass, .class_byte_count = data_size, .class_bytes = data });
638 if (err != OK) {
639 return err;
640 }
641 acds.push_back(std::move(acd));
642 std::string err_msg;
643 err = RedefineClassesDirect(ArtJvmTiEnv::AsArtJvmTiEnv(env),
644 art::Runtime::Current(),
645 art::Thread::Current(),
646 acds,
647 RedefinitionType::kStructural,
648 &err_msg);
649 if (err != OK) {
650 JVMTI_LOG(WARNING, env) << "Failed structural redefinition: " << err_msg;
651 }
652 return err;
Alex Light6ac57502017-01-19 15:05:06 -0800653}
654
655jvmtiError Redefiner::RedefineClassesDirect(ArtJvmTiEnv* env,
656 art::Runtime* runtime,
657 art::Thread* self,
658 const std::vector<ArtClassDefinition>& definitions,
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000659 RedefinitionType type,
Alex Light6ac57502017-01-19 15:05:06 -0800660 std::string* error_msg) {
661 DCHECK(env != nullptr);
662 if (definitions.size() == 0) {
663 // We don't actually need to do anything. Just return OK.
664 return OK;
665 }
Alex Lightc2d0c962019-10-23 14:14:25 -0700666 // We need to fiddle with the verification class flags. To do this we need to make sure there are
667 // no concurrent redefinitions of the same class at the same time. For simplicity and because
668 // this is not expected to be a common occurrence we will just wrap the whole thing in a TOP-level
669 // lock.
670
Alex Light0e692732017-01-10 15:00:05 -0800671 // Stop JIT for the duration of this redefine since the JIT might concurrently compile a method we
672 // are going to redefine.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000673 // TODO We should prevent user-code suspensions to make sure this isn't held for too long.
Alex Light0e692732017-01-10 15:00:05 -0800674 art::jit::ScopedJitSuspend suspend_jit;
675 // Get shared mutator lock so we can lock all the classes.
676 art::ScopedObjectAccess soa(self);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000677 Redefiner r(env, runtime, self, type, error_msg);
Alex Light6ac57502017-01-19 15:05:06 -0800678 for (const ArtClassDefinition& def : definitions) {
679 // Only try to transform classes that have been modified.
Alex Light40528472017-03-28 09:07:36 -0700680 if (def.IsModified()) {
Alex Light6ac57502017-01-19 15:05:06 -0800681 jvmtiError res = r.AddRedefinition(env, def);
682 if (res != OK) {
683 return res;
684 }
Alex Light0e692732017-01-10 15:00:05 -0800685 }
686 }
687 return r.Run();
688}
689
Alex Light6ac57502017-01-19 15:05:06 -0800690jvmtiError Redefiner::AddRedefinition(ArtJvmTiEnv* env, const ArtClassDefinition& def) {
Alex Light0e692732017-01-10 15:00:05 -0800691 std::string original_dex_location;
692 jvmtiError ret = OK;
Alex Lightb7354d52017-03-30 15:17:01 -0700693 if ((ret = GetClassLocation(env, def.GetClass(), &original_dex_location))) {
Alex Light0e692732017-01-10 15:00:05 -0800694 *error_msg_ = "Unable to get original dex file location!";
695 return ret;
696 }
Alex Light52a2db52017-01-19 23:00:21 +0000697 char* generic_ptr_unused = nullptr;
698 char* signature_ptr = nullptr;
Alex Lightb7354d52017-03-30 15:17:01 -0700699 if ((ret = env->GetClassSignature(def.GetClass(), &signature_ptr, &generic_ptr_unused)) != OK) {
Alex Light6ac57502017-01-19 15:05:06 -0800700 *error_msg_ = "Unable to get class signature!";
701 return ret;
Alex Light52a2db52017-01-19 23:00:21 +0000702 }
Andreas Gampe54711412017-02-21 12:41:43 -0800703 JvmtiUniquePtr<char> generic_unique_ptr(MakeJvmtiUniquePtr(env, generic_ptr_unused));
704 JvmtiUniquePtr<char> signature_unique_ptr(MakeJvmtiUniquePtr(env, signature_ptr));
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100705 art::MemMap map = MoveDataToMemMap(original_dex_location, def.GetDexData(), error_msg_);
Alex Light6ac57502017-01-19 15:05:06 -0800706 std::ostringstream os;
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100707 if (!map.IsValid()) {
Alex Lightb7354d52017-03-30 15:17:01 -0700708 os << "Failed to create anonymous mmap for modified dex file of class " << def.GetName()
Alex Light0e692732017-01-10 15:00:05 -0800709 << "in dex file " << original_dex_location << " because: " << *error_msg_;
710 *error_msg_ = os.str();
Alex Lighta01de592016-11-15 10:43:06 -0800711 return ERR(OUT_OF_MEMORY);
712 }
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100713 if (map.Size() < sizeof(art::DexFile::Header)) {
Alex Light0e692732017-01-10 15:00:05 -0800714 *error_msg_ = "Could not read dex file header because dex_data was too short";
Alex Lighta01de592016-11-15 10:43:06 -0800715 return ERR(INVALID_CLASS_FORMAT);
716 }
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100717 std::string name = map.GetName();
718 uint32_t checksum = reinterpret_cast<const art::DexFile::Header*>(map.Begin())->checksum_;
David Sehr013fd802018-01-11 22:55:24 -0800719 const art::ArtDexFileLoader dex_file_loader;
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100720 std::unique_ptr<const art::DexFile> dex_file(dex_file_loader.Open(name,
David Sehr013fd802018-01-11 22:55:24 -0800721 checksum,
722 std::move(map),
Andreas Gampe6e897762018-10-16 13:09:32 -0700723 /*verify=*/true,
724 /*verify_checksum=*/true,
David Sehr013fd802018-01-11 22:55:24 -0800725 error_msg_));
Alex Lighta01de592016-11-15 10:43:06 -0800726 if (dex_file.get() == nullptr) {
Alex Lightb7354d52017-03-30 15:17:01 -0700727 os << "Unable to load modified dex file for " << def.GetName() << ": " << *error_msg_;
Alex Light0e692732017-01-10 15:00:05 -0800728 *error_msg_ = os.str();
Alex Lighta01de592016-11-15 10:43:06 -0800729 return ERR(INVALID_CLASS_FORMAT);
730 }
Alex Light0e692732017-01-10 15:00:05 -0800731 redefinitions_.push_back(
Alex Lighta7e38d82017-01-19 14:57:28 -0800732 Redefiner::ClassRedefinition(this,
Alex Lightb7354d52017-03-30 15:17:01 -0700733 def.GetClass(),
Alex Lighta7e38d82017-01-19 14:57:28 -0800734 dex_file.release(),
735 signature_ptr,
Alex Light40528472017-03-28 09:07:36 -0700736 def.GetNewOriginalDexFile()));
Alex Light0e692732017-01-10 15:00:05 -0800737 return OK;
Alex Lighta01de592016-11-15 10:43:06 -0800738}
739
Vladimir Marko4617d582019-03-28 13:48:31 +0000740art::ObjPtr<art::mirror::Class> Redefiner::ClassRedefinition::GetMirrorClass() {
Alex Light0e692732017-01-10 15:00:05 -0800741 return driver_->self_->DecodeJObject(klass_)->AsClass();
Alex Lighta01de592016-11-15 10:43:06 -0800742}
743
Vladimir Markoc524e9e2019-03-26 10:54:50 +0000744art::ObjPtr<art::mirror::ClassLoader> Redefiner::ClassRedefinition::GetClassLoader() {
Alex Lighta01de592016-11-15 10:43:06 -0800745 return GetMirrorClass()->GetClassLoader();
746}
747
Alex Light0e692732017-01-10 15:00:05 -0800748art::mirror::DexCache* Redefiner::ClassRedefinition::CreateNewDexCache(
749 art::Handle<art::mirror::ClassLoader> loader) {
Alex Light07f06212017-06-01 14:01:43 -0700750 art::StackHandleScope<2> hs(driver_->self_);
751 art::ClassLinker* cl = driver_->runtime_->GetClassLinker();
752 art::Handle<art::mirror::DexCache> cache(hs.NewHandle(
753 art::ObjPtr<art::mirror::DexCache>::DownCast(
Vladimir Markob4eb1b12018-05-24 11:09:38 +0100754 art::GetClassRoot<art::mirror::DexCache>(cl)->AllocObject(driver_->self_))));
Alex Light07f06212017-06-01 14:01:43 -0700755 if (cache.IsNull()) {
756 driver_->self_->AssertPendingOOMException();
757 return nullptr;
758 }
759 art::Handle<art::mirror::String> location(hs.NewHandle(
760 cl->GetInternTable()->InternStrong(dex_file_->GetLocation().c_str())));
761 if (location.IsNull()) {
762 driver_->self_->AssertPendingOOMException();
763 return nullptr;
764 }
765 art::WriterMutexLock mu(driver_->self_, *art::Locks::dex_lock_);
766 art::mirror::DexCache::InitializeDexCache(driver_->self_,
767 cache.Get(),
768 location.Get(),
769 dex_file_.get(),
770 loader.IsNull() ? driver_->runtime_->GetLinearAlloc()
771 : loader->GetAllocator(),
772 art::kRuntimePointerSize);
773 return cache.Get();
Alex Lighta01de592016-11-15 10:43:06 -0800774}
775
Alex Light0e692732017-01-10 15:00:05 -0800776void Redefiner::RecordFailure(jvmtiError result,
777 const std::string& class_sig,
778 const std::string& error_msg) {
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800779 *error_msg_ = StringPrintf("Unable to perform redefinition of '%s': %s",
Alex Light0e692732017-01-10 15:00:05 -0800780 class_sig.c_str(),
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800781 error_msg.c_str());
Alex Lighta01de592016-11-15 10:43:06 -0800782 result_ = result;
783}
784
Alex Light2f814aa2017-03-24 15:21:34 +0000785art::mirror::Object* Redefiner::ClassRedefinition::AllocateOrGetOriginalDexFile() {
Alex Lighta7e38d82017-01-19 14:57:28 -0800786 // If we have been specifically given a new set of bytes use that
787 if (original_dex_file_.size() != 0) {
Alex Light440b5d92017-01-24 15:32:25 -0800788 return art::mirror::ByteArray::AllocateAndFill(
789 driver_->self_,
Vladimir Markoe1993c72017-06-14 17:01:38 +0100790 reinterpret_cast<const signed char*>(original_dex_file_.data()),
Vladimir Markobcf17522018-06-01 13:14:32 +0100791 original_dex_file_.size()).Ptr();
Alex Lighta01de592016-11-15 10:43:06 -0800792 }
Alex Lighta7e38d82017-01-19 14:57:28 -0800793
794 // See if we already have one set.
795 art::ObjPtr<art::mirror::ClassExt> ext(GetMirrorClass()->GetExtData());
796 if (!ext.IsNull()) {
Alex Light2f814aa2017-03-24 15:21:34 +0000797 art::ObjPtr<art::mirror::Object> old_original_dex_file(ext->GetOriginalDexFile());
798 if (!old_original_dex_file.IsNull()) {
Alex Lighta7e38d82017-01-19 14:57:28 -0800799 // We do. Use it.
Alex Light2f814aa2017-03-24 15:21:34 +0000800 return old_original_dex_file.Ptr();
Alex Lighta7e38d82017-01-19 14:57:28 -0800801 }
Alex Lighta01de592016-11-15 10:43:06 -0800802 }
Alex Lighta7e38d82017-01-19 14:57:28 -0800803
Alex Light2f814aa2017-03-24 15:21:34 +0000804 // return the current dex_cache which has the dex file in it.
805 art::ObjPtr<art::mirror::DexCache> current_dex_cache(GetMirrorClass()->GetDexCache());
Alex Lighta7e38d82017-01-19 14:57:28 -0800806 // TODO Handle this or make it so it cannot happen.
Alex Light2f814aa2017-03-24 15:21:34 +0000807 if (current_dex_cache->GetDexFile()->NumClassDefs() != 1) {
Alex Lighta7e38d82017-01-19 14:57:28 -0800808 LOG(WARNING) << "Current dex file has more than one class in it. Calling RetransformClasses "
809 << "on this class might fail if no transformations are applied to it!";
Alex Lighta01de592016-11-15 10:43:06 -0800810 }
Alex Light2f814aa2017-03-24 15:21:34 +0000811 return current_dex_cache.Ptr();
Alex Lighta01de592016-11-15 10:43:06 -0800812}
813
Alex Lightdba61482016-12-21 08:20:29 -0800814struct CallbackCtx {
Alex Lighteee0bd42017-02-14 15:31:45 +0000815 ObsoleteMap* obsolete_map;
Alex Lightdba61482016-12-21 08:20:29 -0800816 art::LinearAlloc* allocator;
Alex Lightdba61482016-12-21 08:20:29 -0800817 std::unordered_set<art::ArtMethod*> obsolete_methods;
Alex Lightdba61482016-12-21 08:20:29 -0800818
Alex Lighteee0bd42017-02-14 15:31:45 +0000819 explicit CallbackCtx(ObsoleteMap* map, art::LinearAlloc* alloc)
820 : obsolete_map(map), allocator(alloc) {}
Alex Lightdba61482016-12-21 08:20:29 -0800821};
822
Alex Lightdba61482016-12-21 08:20:29 -0800823void DoAllocateObsoleteMethodsCallback(art::Thread* t, void* vdata) NO_THREAD_SAFETY_ANALYSIS {
824 CallbackCtx* data = reinterpret_cast<CallbackCtx*>(vdata);
Alex Light007ada22017-01-10 13:33:56 -0800825 ObsoleteMethodStackVisitor::UpdateObsoleteFrames(t,
826 data->allocator,
827 data->obsolete_methods,
Alex Lighteee0bd42017-02-14 15:31:45 +0000828 data->obsolete_map);
Alex Lightdba61482016-12-21 08:20:29 -0800829}
830
831// This creates any ArtMethod* structures needed for obsolete methods and ensures that the stack is
832// updated so they will be run.
Alex Light0e692732017-01-10 15:00:05 -0800833// TODO Rewrite so we can do this only once regardless of how many redefinitions there are.
Vladimir Markod93e3742018-07-18 10:58:13 +0100834void Redefiner::ClassRedefinition::FindAndAllocateObsoleteMethods(
835 art::ObjPtr<art::mirror::Class> art_klass) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000836 DCHECK(!IsStructuralRedefinition());
Alex Lightdba61482016-12-21 08:20:29 -0800837 art::ScopedAssertNoThreadSuspension ns("No thread suspension during thread stack walking");
Vladimir Markod93e3742018-07-18 10:58:13 +0100838 art::ObjPtr<art::mirror::ClassExt> ext = art_klass->GetExtData();
Alex Lightdba61482016-12-21 08:20:29 -0800839 CHECK(ext->GetObsoleteMethods() != nullptr);
Alex Light7916f202017-01-27 09:00:15 -0800840 art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
Alex Lighteee0bd42017-02-14 15:31:45 +0000841 // This holds pointers to the obsolete methods map fields which are updated as needed.
842 ObsoleteMap map(ext->GetObsoleteMethods(), ext->GetObsoleteDexCaches(), art_klass->GetDexCache());
843 CallbackCtx ctx(&map, linker->GetAllocatorForClassLoader(art_klass->GetClassLoader()));
Alex Lightdba61482016-12-21 08:20:29 -0800844 // Add all the declared methods to the map
845 for (auto& m : art_klass->GetDeclaredMethods(art::kRuntimePointerSize)) {
Alex Light7532d582017-02-13 16:36:06 -0800846 if (m.IsIntrinsic()) {
847 LOG(WARNING) << "Redefining intrinsic method " << m.PrettyMethod() << ". This may cause the "
848 << "unexpected use of the original definition of " << m.PrettyMethod() << "in "
849 << "methods that have already been compiled.";
850 }
Alex Lighteee0bd42017-02-14 15:31:45 +0000851 // It is possible to simply filter out some methods where they cannot really become obsolete,
852 // such as native methods and keep their original (possibly optimized) implementations. We don't
853 // do this, however, since we would need to mark these functions (still in the classes
854 // declared_methods array) as obsolete so we will find the correct dex file to get meta-data
855 // from (for example about stack-frame size). Furthermore we would be unable to get some useful
856 // error checking from the interpreter which ensure we don't try to start executing obsolete
857 // methods.
Nicolas Geoffray7558d272017-02-10 10:01:47 +0000858 ctx.obsolete_methods.insert(&m);
Alex Lightdba61482016-12-21 08:20:29 -0800859 }
860 {
Alex Light0e692732017-01-10 15:00:05 -0800861 art::MutexLock mu(driver_->self_, *art::Locks::thread_list_lock_);
Alex Lightdba61482016-12-21 08:20:29 -0800862 art::ThreadList* list = art::Runtime::Current()->GetThreadList();
863 list->ForEach(DoAllocateObsoleteMethodsCallback, static_cast<void*>(&ctx));
Vladimir Markoeab02482019-05-09 10:28:17 +0100864 // After we've done walking all threads' stacks and updating method pointers on them,
865 // update JIT data structures (used by the stack walk above) to point to the new methods.
Alex Lighte7a33542019-04-10 14:22:49 -0700866 art::jit::Jit* jit = art::Runtime::Current()->GetJit();
867 if (jit != nullptr) {
868 for (const ObsoleteMap::ObsoleteMethodPair& it : *ctx.obsolete_map) {
869 // Notify the JIT we are making this obsolete method. It will update the jit's internal
870 // structures to keep track of the new obsolete method.
871 jit->GetCodeCache()->MoveObsoleteMethod(it.old_method, it.obsolete_method);
872 }
873 }
Alex Lightdba61482016-12-21 08:20:29 -0800874 }
Alex Lightdba61482016-12-21 08:20:29 -0800875}
876
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000877namespace {
878template <typename T> struct SignatureType {};
879template <> struct SignatureType<art::ArtField> { using type = std::string_view; };
880template <> struct SignatureType<art::ArtMethod> { using type = art::Signature; };
881
882template <typename T> struct NameAndSignature {
883 public:
884 using SigType = typename SignatureType<T>::type;
885
886 NameAndSignature(const art::DexFile* dex_file, uint32_t id);
887
888 NameAndSignature(const std::string_view& name, const SigType& sig) : name_(name), sig_(sig) {}
889
890 bool operator==(const NameAndSignature<T>& o) {
891 return name_ == o.name_ && sig_ == o.sig_;
Alex Light6161f132017-01-25 10:30:20 -0800892 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000893
894 std::ostream& dump(std::ostream& os) const {
895 return os << "'" << name_ << "' (sig: " << sig_ << ")";
896 }
897
898 std::string ToString() const {
899 std::ostringstream os;
900 os << *this;
901 return os.str();
902 }
903
904 std::string_view name_;
905 SigType sig_;
906};
907
908template <typename T>
909std::ostream& operator<<(std::ostream& os, const NameAndSignature<T>& nas) {
910 return nas.dump(os);
Alex Light6161f132017-01-25 10:30:20 -0800911}
912
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000913using FieldNameAndSignature = NameAndSignature<art::ArtField>;
914template <>
915FieldNameAndSignature::NameAndSignature(const art::DexFile* dex_file, uint32_t id)
916 : FieldNameAndSignature(dex_file->GetFieldName(dex_file->GetFieldId(id)),
917 dex_file->GetFieldTypeDescriptor(dex_file->GetFieldId(id))) {}
918
919using MethodNameAndSignature = NameAndSignature<art::ArtMethod>;
920template <>
921MethodNameAndSignature::NameAndSignature(const art::DexFile* dex_file, uint32_t id)
922 : MethodNameAndSignature(dex_file->GetMethodName(dex_file->GetMethodId(id)),
923 dex_file->GetMethodSignature(dex_file->GetMethodId(id))) {}
924
925} // namespace
926
927void Redefiner::ClassRedefinition::RecordNewMethodAdded() {
928 DCHECK(driver_->IsStructuralRedefinition());
929 added_methods_ = true;
930}
931void Redefiner::ClassRedefinition::RecordNewFieldAdded() {
932 DCHECK(driver_->IsStructuralRedefinition());
933 added_fields_ = true;
934}
935
936bool Redefiner::ClassRedefinition::CheckMethods() {
Alex Light6161f132017-01-25 10:30:20 -0800937 art::StackHandleScope<1> hs(driver_->self_);
938 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
939 DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
940
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000941 // 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 -0700942 art::ClassAccessor accessor(*dex_file_, dex_file_->GetClassDef(0));
943 uint32_t num_new_method = accessor.NumMethods();
Alex Light6161f132017-01-25 10:30:20 -0800944 uint32_t num_old_method = h_klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize).size();
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000945 const bool is_structural = driver_->IsStructuralRedefinition();
946 if (!is_structural && num_new_method != num_old_method) {
Alex Light6161f132017-01-25 10:30:20 -0800947 bool bigger = num_new_method > num_old_method;
948 RecordFailure(bigger ? ERR(UNSUPPORTED_REDEFINITION_METHOD_ADDED)
949 : ERR(UNSUPPORTED_REDEFINITION_METHOD_DELETED),
950 StringPrintf("Total number of declared methods changed from %d to %d",
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000951 num_old_method,
952 num_new_method));
Alex Light6161f132017-01-25 10:30:20 -0800953 return false;
954 }
955
956 // Skip all of the fields. We should have already checked this.
Alex Light6161f132017-01-25 10:30:20 -0800957 // Check each of the methods. NB we don't need to specifically check for removals since the 2 dex
958 // files have the same number of methods, which means there must be an equal amount of additions
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -0700959 // and removals. We should have already checked the fields.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000960 const art::DexFile& old_dex_file = h_klass->GetDexFile();
961 art::ClassAccessor old_accessor(old_dex_file, *h_klass->GetClassDef());
962 // We need this to check for methods going missing in structural cases.
963 std::vector<bool> seen_old_methods(
964 (kCheckAllMethodsSeenOnce || is_structural) ? old_accessor.NumMethods() : 0, false);
965 const auto old_methods = old_accessor.GetMethods();
966 for (const art::ClassAccessor::Method& new_method : accessor.GetMethods()) {
Alex Light6161f132017-01-25 10:30:20 -0800967 // Get the data on the method we are searching for
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000968 MethodNameAndSignature new_method_id(dex_file_.get(), new_method.GetIndex());
969 const auto old_iter =
970 std::find_if(old_methods.cbegin(), old_methods.cend(), [&](const auto& current_old_method) {
971 MethodNameAndSignature old_method_id(&old_dex_file, current_old_method.GetIndex());
972 return old_method_id == new_method_id;
973 });
974
975 if (old_iter == old_methods.cend()) {
976 // TODO Support adding non-static methods.
977 if (is_structural && new_method.IsStaticOrDirect()) {
978 RecordNewMethodAdded();
979 } else {
980 RecordFailure(
981 ERR(UNSUPPORTED_REDEFINITION_METHOD_ADDED),
982 StringPrintf("Unknown virtual method %s was added!", new_method_id.ToString().c_str()));
983 return false;
984 }
985 } else if (new_method.GetAccessFlags() != old_iter->GetAccessFlags()) {
986 RecordFailure(
987 ERR(UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED),
988 StringPrintf("method %s had different access flags", new_method_id.ToString().c_str()));
Alex Light6161f132017-01-25 10:30:20 -0800989 return false;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000990 } else if (kCheckAllMethodsSeenOnce || is_structural) {
991 // We only need this if we are structural.
992 size_t off = std::distance(old_methods.cbegin(), old_iter);
993 DCHECK(!seen_old_methods[off])
994 << "field at " << off << "("
995 << MethodNameAndSignature(&old_dex_file, old_iter->GetIndex()) << ") already seen?";
996 seen_old_methods[off] = true;
Alex Light6161f132017-01-25 10:30:20 -0800997 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000998 }
999 if ((kCheckAllMethodsSeenOnce || is_structural) &&
1000 !std::all_of(seen_old_methods.cbegin(), seen_old_methods.cend(), [](auto x) { return x; })) {
1001 DCHECK(is_structural) << "We should have hit an earlier failure before getting here!";
1002 auto first_fail =
1003 std::find_if(seen_old_methods.cbegin(), seen_old_methods.cend(), [](auto x) { return !x; });
1004 auto off = std::distance(seen_old_methods.cbegin(), first_fail);
1005 auto fail = old_methods.cbegin();
1006 std::advance(fail, off);
1007 RecordFailure(
1008 ERR(UNSUPPORTED_REDEFINITION_METHOD_DELETED),
1009 StringPrintf("Method %s missing!",
1010 FieldNameAndSignature(&old_dex_file, fail->GetIndex()).ToString().c_str()));
1011 return false;
Alex Light6161f132017-01-25 10:30:20 -08001012 }
1013 return true;
1014}
1015
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001016bool Redefiner::ClassRedefinition::CheckFields() {
Alex Light6161f132017-01-25 10:30:20 -08001017 art::StackHandleScope<1> hs(driver_->self_);
1018 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
1019 DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -07001020 art::ClassAccessor new_accessor(*dex_file_, dex_file_->GetClassDef(0));
1021
Alex Light6161f132017-01-25 10:30:20 -08001022 const art::DexFile& old_dex_file = h_klass->GetDexFile();
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -07001023 art::ClassAccessor old_accessor(old_dex_file, *h_klass->GetClassDef());
Alex Light6161f132017-01-25 10:30:20 -08001024 // Instance and static fields can be differentiated by their flags so no need to check them
1025 // separately.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001026 std::vector<bool> seen_old_fields(old_accessor.NumFields(), false);
1027 const auto old_fields = old_accessor.GetFields();
Mathieu Chartier4ac9ade2018-07-24 10:27:21 -07001028 for (const art::ClassAccessor::Field& new_field : new_accessor.GetFields()) {
Alex Light6161f132017-01-25 10:30:20 -08001029 // Get the data on the method we are searching for
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001030 FieldNameAndSignature new_field_id(dex_file_.get(), new_field.GetIndex());
1031 const auto old_iter =
1032 std::find_if(old_fields.cbegin(), old_fields.cend(), [&](const auto& old_iter) {
1033 FieldNameAndSignature old_field_id(&old_dex_file, old_iter.GetIndex());
1034 return old_field_id == new_field_id;
1035 });
1036 if (old_iter == old_fields.cend()) {
1037 // TODO Support adding non-static fields.
1038 if (driver_->IsStructuralRedefinition() && new_field.IsStatic()) {
1039 RecordNewFieldAdded();
1040 } else {
1041 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
1042 StringPrintf("Unknown field %s added!", new_field_id.ToString().c_str()));
1043 return false;
1044 }
1045 } else if (new_field.GetAccessFlags() != old_iter->GetAccessFlags()) {
1046 RecordFailure(
1047 ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
1048 StringPrintf("Field %s had different access flags", new_field_id.ToString().c_str()));
Alex Light6161f132017-01-25 10:30:20 -08001049 return false;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001050 } else {
1051 size_t off = std::distance(old_fields.cbegin(), old_iter);
1052 DCHECK(!seen_old_fields[off])
1053 << "field at " << off << "(" << FieldNameAndSignature(&old_dex_file, old_iter->GetIndex())
1054 << ") already seen?";
1055 seen_old_fields[off] = true;
Alex Light6161f132017-01-25 10:30:20 -08001056 }
Alex Light6161f132017-01-25 10:30:20 -08001057 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001058 if (!std::all_of(seen_old_fields.cbegin(), seen_old_fields.cend(), [](auto x) { return x; })) {
1059 auto first_fail =
1060 std::find_if(seen_old_fields.cbegin(), seen_old_fields.cend(), [](auto x) { return !x; });
1061 auto off = std::distance(seen_old_fields.cbegin(), first_fail);
1062 auto fail = old_fields.cbegin();
1063 std::advance(fail, off);
1064 RecordFailure(
1065 ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
1066 StringPrintf("Field %s is missing!",
1067 FieldNameAndSignature(&old_dex_file, fail->GetIndex()).ToString().c_str()));
Alex Light6161f132017-01-25 10:30:20 -08001068 return false;
1069 }
1070 return true;
1071}
1072
Alex Light0e692732017-01-10 15:00:05 -08001073bool Redefiner::ClassRedefinition::CheckClass() {
Alex Light0e692732017-01-10 15:00:05 -08001074 art::StackHandleScope<1> hs(driver_->self_);
Alex Light460d1b42017-01-10 15:37:17 +00001075 // Easy check that only 1 class def is present.
1076 if (dex_file_->NumClassDefs() != 1) {
1077 RecordFailure(ERR(ILLEGAL_ARGUMENT),
1078 StringPrintf("Expected 1 class def in dex file but found %d",
1079 dex_file_->NumClassDefs()));
1080 return false;
1081 }
1082 // Get the ClassDef from the new DexFile.
1083 // Since the dex file has only a single class def the index is always 0.
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001084 const art::dex::ClassDef& def = dex_file_->GetClassDef(0);
Alex Light460d1b42017-01-10 15:37:17 +00001085 // Get the class as it is now.
1086 art::Handle<art::mirror::Class> current_class(hs.NewHandle(GetMirrorClass()));
1087
1088 // Check the access flags didn't change.
1089 if (def.GetJavaAccessFlags() != (current_class->GetAccessFlags() & art::kAccValidClassFlags)) {
1090 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED),
1091 "Cannot change modifiers of class by redefinition");
1092 return false;
1093 }
1094
1095 // Check class name.
1096 // These should have been checked by the dexfile verifier on load.
1097 DCHECK_NE(def.class_idx_, art::dex::TypeIndex::Invalid()) << "Invalid type index";
1098 const char* descriptor = dex_file_->StringByTypeIdx(def.class_idx_);
1099 DCHECK(descriptor != nullptr) << "Invalid dex file structure!";
1100 if (!current_class->DescriptorEquals(descriptor)) {
1101 std::string storage;
1102 RecordFailure(ERR(NAMES_DONT_MATCH),
1103 StringPrintf("expected file to contain class called '%s' but found '%s'!",
1104 current_class->GetDescriptor(&storage),
1105 descriptor));
1106 return false;
1107 }
1108 if (current_class->IsObjectClass()) {
1109 if (def.superclass_idx_ != art::dex::TypeIndex::Invalid()) {
1110 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Superclass added!");
1111 return false;
1112 }
1113 } else {
1114 const char* super_descriptor = dex_file_->StringByTypeIdx(def.superclass_idx_);
1115 DCHECK(descriptor != nullptr) << "Invalid dex file structure!";
1116 if (!current_class->GetSuperClass()->DescriptorEquals(super_descriptor)) {
1117 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Superclass changed");
1118 return false;
1119 }
1120 }
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001121 const art::dex::TypeList* interfaces = dex_file_->GetInterfacesList(def);
Alex Light460d1b42017-01-10 15:37:17 +00001122 if (interfaces == nullptr) {
1123 if (current_class->NumDirectInterfaces() != 0) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001124 // TODO Support this for kStructural.
Alex Light460d1b42017-01-10 15:37:17 +00001125 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Interfaces added");
1126 return false;
1127 }
1128 } else {
1129 DCHECK(!current_class->IsProxyClass());
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001130 const art::dex::TypeList* current_interfaces = current_class->GetInterfaceTypeList();
Alex Light460d1b42017-01-10 15:37:17 +00001131 if (current_interfaces == nullptr || current_interfaces->Size() != interfaces->Size()) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001132 // TODO Support this for kStructural.
Alex Light460d1b42017-01-10 15:37:17 +00001133 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Interfaces added or removed");
1134 return false;
1135 }
1136 // The order of interfaces is (barely) meaningful so we error if it changes.
1137 const art::DexFile& orig_dex_file = current_class->GetDexFile();
1138 for (uint32_t i = 0; i < interfaces->Size(); i++) {
1139 if (strcmp(
1140 dex_file_->StringByTypeIdx(interfaces->GetTypeItem(i).type_idx_),
1141 orig_dex_file.StringByTypeIdx(current_interfaces->GetTypeItem(i).type_idx_)) != 0) {
1142 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED),
1143 "Interfaces changed or re-ordered");
1144 return false;
1145 }
1146 }
1147 }
Alex Light460d1b42017-01-10 15:37:17 +00001148 return true;
1149}
1150
Alex Light0e692732017-01-10 15:00:05 -08001151bool Redefiner::ClassRedefinition::CheckRedefinable() {
Alex Lighte4a88632017-01-10 07:41:24 -08001152 std::string err;
Alex Light0e692732017-01-10 15:00:05 -08001153 art::StackHandleScope<1> hs(driver_->self_);
Alex Light460d1b42017-01-10 15:37:17 +00001154
Alex Lighte4a88632017-01-10 07:41:24 -08001155 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001156 jvmtiError res;
1157 switch (driver_->type_) {
1158 case RedefinitionType::kNormal:
1159 res = Redefiner::GetClassRedefinitionError<RedefinitionType::kNormal>(h_klass, &err);
1160 break;
1161 case RedefinitionType::kStructural:
1162 res = Redefiner::GetClassRedefinitionError<RedefinitionType::kStructural>(h_klass, &err);
1163 break;
1164 }
Alex Lighte4a88632017-01-10 07:41:24 -08001165 if (res != OK) {
1166 RecordFailure(res, err);
1167 return false;
1168 } else {
1169 return true;
1170 }
Alex Light460d1b42017-01-10 15:37:17 +00001171}
1172
Alex Light0e692732017-01-10 15:00:05 -08001173bool Redefiner::ClassRedefinition::CheckRedefinitionIsValid() {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001174 return CheckRedefinable() && CheckClass() && CheckFields() && CheckMethods();
Alex Light460d1b42017-01-10 15:37:17 +00001175}
1176
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001177class RedefinitionDataIter;
1178
Alex Light0e692732017-01-10 15:00:05 -08001179// A wrapper that lets us hold onto the arbitrary sized data needed for redefinitions in a
1180// reasonably sane way. This adds no fields to the normal ObjectArray. By doing this we can avoid
1181// having to deal with the fact that we need to hold an arbitrary number of references live.
1182class RedefinitionDataHolder {
1183 public:
1184 enum DataSlot : int32_t {
1185 kSlotSourceClassLoader = 0,
1186 kSlotJavaDexFile = 1,
1187 kSlotNewDexFileCookie = 2,
1188 kSlotNewDexCache = 3,
1189 kSlotMirrorClass = 4,
Alex Lighta7e38d82017-01-19 14:57:28 -08001190 kSlotOrigDexFile = 5,
Alex Light1e3926a2017-04-07 10:38:06 -07001191 kSlotOldObsoleteMethods = 6,
1192 kSlotOldDexCaches = 7,
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001193 kSlotNewClassObject = 8,
Alex Light0e692732017-01-10 15:00:05 -08001194
1195 // Must be last one.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001196 kNumSlots = 9,
Alex Light0e692732017-01-10 15:00:05 -08001197 };
1198
1199 // This needs to have a HandleScope passed in that is capable of creating a new Handle without
1200 // overflowing. Only one handle will be created. This object has a lifetime identical to that of
1201 // the passed in handle-scope.
1202 RedefinitionDataHolder(art::StackHandleScope<1>* hs,
1203 art::Runtime* runtime,
1204 art::Thread* self,
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001205 std::vector<Redefiner::ClassRedefinition>* redefinitions)
1206 REQUIRES_SHARED(art::Locks::mutator_lock_) :
Vladimir Markob4eb1b12018-05-24 11:09:38 +01001207 arr_(hs->NewHandle(art::mirror::ObjectArray<art::mirror::Object>::Alloc(
1208 self,
1209 art::GetClassRoot<art::mirror::ObjectArray<art::mirror::Object>>(runtime->GetClassLinker()),
1210 redefinitions->size() * kNumSlots))),
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001211 redefinitions_(redefinitions) {}
Alex Light0e692732017-01-10 15:00:05 -08001212
1213 bool IsNull() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1214 return arr_.IsNull();
1215 }
1216
Vladimir Markod93e3742018-07-18 10:58:13 +01001217 art::ObjPtr<art::mirror::ClassLoader> GetSourceClassLoader(jint klass_index) const
Alex Light0e692732017-01-10 15:00:05 -08001218 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Vladimir Markod93e3742018-07-18 10:58:13 +01001219 return art::ObjPtr<art::mirror::ClassLoader>::DownCast(
1220 GetSlot(klass_index, kSlotSourceClassLoader));
Alex Light0e692732017-01-10 15:00:05 -08001221 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001222 art::ObjPtr<art::mirror::Object> GetJavaDexFile(jint klass_index) const
Alex Light8c889d22017-02-06 13:58:27 -08001223 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light0e692732017-01-10 15:00:05 -08001224 return GetSlot(klass_index, kSlotJavaDexFile);
1225 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001226 art::ObjPtr<art::mirror::LongArray> GetNewDexFileCookie(jint klass_index) const
Alex Light0e692732017-01-10 15:00:05 -08001227 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Vladimir Markod93e3742018-07-18 10:58:13 +01001228 return art::ObjPtr<art::mirror::LongArray>::DownCast(
1229 GetSlot(klass_index, kSlotNewDexFileCookie));
Alex Light0e692732017-01-10 15:00:05 -08001230 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001231 art::ObjPtr<art::mirror::DexCache> GetNewDexCache(jint klass_index) const
Alex Light0e692732017-01-10 15:00:05 -08001232 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Vladimir Markod93e3742018-07-18 10:58:13 +01001233 return art::ObjPtr<art::mirror::DexCache>::DownCast(GetSlot(klass_index, kSlotNewDexCache));
Alex Light0e692732017-01-10 15:00:05 -08001234 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001235 art::ObjPtr<art::mirror::Class> GetMirrorClass(jint klass_index) const
Alex Light8c889d22017-02-06 13:58:27 -08001236 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Vladimir Markod93e3742018-07-18 10:58:13 +01001237 return art::ObjPtr<art::mirror::Class>::DownCast(GetSlot(klass_index, kSlotMirrorClass));
Alex Light0e692732017-01-10 15:00:05 -08001238 }
1239
Vladimir Markod93e3742018-07-18 10:58:13 +01001240 art::ObjPtr<art::mirror::Object> GetOriginalDexFile(jint klass_index) const
Alex Lighta7e38d82017-01-19 14:57:28 -08001241 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Vladimir Markod93e3742018-07-18 10:58:13 +01001242 return art::ObjPtr<art::mirror::Object>::DownCast(GetSlot(klass_index, kSlotOrigDexFile));
Alex Lighta7e38d82017-01-19 14:57:28 -08001243 }
1244
Vladimir Markod93e3742018-07-18 10:58:13 +01001245 art::ObjPtr<art::mirror::PointerArray> GetOldObsoleteMethods(jint klass_index) const
Alex Light1e3926a2017-04-07 10:38:06 -07001246 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Vladimir Markod93e3742018-07-18 10:58:13 +01001247 return art::ObjPtr<art::mirror::PointerArray>::DownCast(
Alex Light1e3926a2017-04-07 10:38:06 -07001248 GetSlot(klass_index, kSlotOldObsoleteMethods));
1249 }
1250
Vladimir Markod93e3742018-07-18 10:58:13 +01001251 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> GetOldDexCaches(
1252 jint klass_index) const REQUIRES_SHARED(art::Locks::mutator_lock_) {
1253 return art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>>::DownCast(
Alex Light1e3926a2017-04-07 10:38:06 -07001254 GetSlot(klass_index, kSlotOldDexCaches));
1255 }
1256
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001257 art::ObjPtr<art::mirror::Class> GetNewClassObject(jint klass_index) const
1258 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1259 return art::ObjPtr<art::mirror::Class>::DownCast(GetSlot(klass_index, kSlotNewClassObject));
1260 }
1261
Vladimir Markod93e3742018-07-18 10:58:13 +01001262 void SetSourceClassLoader(jint klass_index, art::ObjPtr<art::mirror::ClassLoader> loader)
Alex Light0e692732017-01-10 15:00:05 -08001263 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1264 SetSlot(klass_index, kSlotSourceClassLoader, loader);
1265 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001266 void SetJavaDexFile(jint klass_index, art::ObjPtr<art::mirror::Object> dexfile)
Alex Light0e692732017-01-10 15:00:05 -08001267 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1268 SetSlot(klass_index, kSlotJavaDexFile, dexfile);
1269 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001270 void SetNewDexFileCookie(jint klass_index, art::ObjPtr<art::mirror::LongArray> cookie)
Alex Light0e692732017-01-10 15:00:05 -08001271 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1272 SetSlot(klass_index, kSlotNewDexFileCookie, cookie);
1273 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001274 void SetNewDexCache(jint klass_index, art::ObjPtr<art::mirror::DexCache> cache)
Alex Light0e692732017-01-10 15:00:05 -08001275 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1276 SetSlot(klass_index, kSlotNewDexCache, cache);
1277 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001278 void SetMirrorClass(jint klass_index, art::ObjPtr<art::mirror::Class> klass)
Alex Light0e692732017-01-10 15:00:05 -08001279 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1280 SetSlot(klass_index, kSlotMirrorClass, klass);
1281 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001282 void SetOriginalDexFile(jint klass_index, art::ObjPtr<art::mirror::Object> bytes)
Alex Lighta7e38d82017-01-19 14:57:28 -08001283 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1284 SetSlot(klass_index, kSlotOrigDexFile, bytes);
1285 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001286 void SetOldObsoleteMethods(jint klass_index, art::ObjPtr<art::mirror::PointerArray> methods)
Alex Light1e3926a2017-04-07 10:38:06 -07001287 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1288 SetSlot(klass_index, kSlotOldObsoleteMethods, methods);
1289 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001290 void SetOldDexCaches(jint klass_index,
1291 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> caches)
Alex Light1e3926a2017-04-07 10:38:06 -07001292 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1293 SetSlot(klass_index, kSlotOldDexCaches, caches);
1294 }
Alex Light0e692732017-01-10 15:00:05 -08001295
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001296 void SetNewClassObject(jint klass_index, art::ObjPtr<art::mirror::Class> klass)
1297 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1298 SetSlot(klass_index, kSlotNewClassObject, klass);
1299 }
1300
Alex Light8c889d22017-02-06 13:58:27 -08001301 int32_t Length() const REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light0e692732017-01-10 15:00:05 -08001302 return arr_->GetLength() / kNumSlots;
1303 }
1304
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001305 std::vector<Redefiner::ClassRedefinition>* GetRedefinitions()
1306 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1307 return redefinitions_;
1308 }
1309
1310 bool operator==(const RedefinitionDataHolder& other) const
1311 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1312 return arr_.Get() == other.arr_.Get();
1313 }
1314
1315 bool operator!=(const RedefinitionDataHolder& other) const
1316 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1317 return !(*this == other);
1318 }
1319
1320 RedefinitionDataIter begin() REQUIRES_SHARED(art::Locks::mutator_lock_);
1321 RedefinitionDataIter end() REQUIRES_SHARED(art::Locks::mutator_lock_);
1322
Alex Light0e692732017-01-10 15:00:05 -08001323 private:
Alex Light8c889d22017-02-06 13:58:27 -08001324 mutable art::Handle<art::mirror::ObjectArray<art::mirror::Object>> arr_;
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001325 std::vector<Redefiner::ClassRedefinition>* redefinitions_;
Alex Light0e692732017-01-10 15:00:05 -08001326
Vladimir Markod93e3742018-07-18 10:58:13 +01001327 art::ObjPtr<art::mirror::Object> GetSlot(jint klass_index, DataSlot slot) const
1328 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light0e692732017-01-10 15:00:05 -08001329 DCHECK_LT(klass_index, Length());
1330 return arr_->Get((kNumSlots * klass_index) + slot);
1331 }
1332
1333 void SetSlot(jint klass_index,
1334 DataSlot slot,
1335 art::ObjPtr<art::mirror::Object> obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1336 DCHECK(!art::Runtime::Current()->IsActiveTransaction());
1337 DCHECK_LT(klass_index, Length());
1338 arr_->Set<false>((kNumSlots * klass_index) + slot, obj);
1339 }
1340
1341 DISALLOW_COPY_AND_ASSIGN(RedefinitionDataHolder);
1342};
1343
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001344class RedefinitionDataIter {
1345 public:
1346 RedefinitionDataIter(int32_t idx, RedefinitionDataHolder& holder) : idx_(idx), holder_(holder) {}
1347
1348 RedefinitionDataIter(const RedefinitionDataIter&) = default;
1349 RedefinitionDataIter(RedefinitionDataIter&&) = default;
1350 RedefinitionDataIter& operator=(const RedefinitionDataIter&) = default;
1351 RedefinitionDataIter& operator=(RedefinitionDataIter&&) = default;
1352
1353 bool operator==(const RedefinitionDataIter& other) const
1354 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1355 return idx_ == other.idx_ && holder_ == other.holder_;
1356 }
1357
1358 bool operator!=(const RedefinitionDataIter& other) const
1359 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1360 return !(*this == other);
1361 }
1362
1363 RedefinitionDataIter operator++() { // Value after modification.
1364 idx_++;
1365 return *this;
1366 }
1367
1368 RedefinitionDataIter operator++(int) {
1369 RedefinitionDataIter temp = *this;
1370 idx_++;
1371 return temp;
1372 }
1373
1374 RedefinitionDataIter operator+(ssize_t delta) const {
1375 RedefinitionDataIter temp = *this;
1376 temp += delta;
1377 return temp;
1378 }
1379
1380 RedefinitionDataIter& operator+=(ssize_t delta) {
1381 idx_ += delta;
1382 return *this;
1383 }
1384
1385 Redefiner::ClassRedefinition& GetRedefinition() REQUIRES_SHARED(art::Locks::mutator_lock_) {
1386 return (*holder_.GetRedefinitions())[idx_];
1387 }
1388
1389 RedefinitionDataHolder& GetHolder() {
1390 return holder_;
1391 }
1392
Vladimir Markod93e3742018-07-18 10:58:13 +01001393 art::ObjPtr<art::mirror::ClassLoader> GetSourceClassLoader() const
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001394 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1395 return holder_.GetSourceClassLoader(idx_);
1396 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001397 art::ObjPtr<art::mirror::Object> GetJavaDexFile() const
1398 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001399 return holder_.GetJavaDexFile(idx_);
1400 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001401 art::ObjPtr<art::mirror::LongArray> GetNewDexFileCookie() const
1402 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001403 return holder_.GetNewDexFileCookie(idx_);
1404 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001405 art::ObjPtr<art::mirror::DexCache> GetNewDexCache() const
1406 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001407 return holder_.GetNewDexCache(idx_);
1408 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001409 art::ObjPtr<art::mirror::Class> GetMirrorClass() const
1410 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001411 return holder_.GetMirrorClass(idx_);
1412 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001413 art::ObjPtr<art::mirror::Object> GetOriginalDexFile() const
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001414 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light2f814aa2017-03-24 15:21:34 +00001415 return holder_.GetOriginalDexFile(idx_);
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001416 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001417 art::ObjPtr<art::mirror::PointerArray> GetOldObsoleteMethods() const
Alex Light1e3926a2017-04-07 10:38:06 -07001418 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1419 return holder_.GetOldObsoleteMethods(idx_);
1420 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001421 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> GetOldDexCaches() const
Alex Light1e3926a2017-04-07 10:38:06 -07001422 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1423 return holder_.GetOldDexCaches(idx_);
1424 }
1425
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001426 art::ObjPtr<art::mirror::Class> GetNewClassObject() const
1427 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1428 return holder_.GetNewClassObject(idx_);
1429 }
1430
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001431 int32_t GetIndex() const {
1432 return idx_;
1433 }
1434
1435 void SetSourceClassLoader(art::mirror::ClassLoader* loader)
1436 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1437 holder_.SetSourceClassLoader(idx_, loader);
1438 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001439 void SetJavaDexFile(art::ObjPtr<art::mirror::Object> dexfile)
1440 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001441 holder_.SetJavaDexFile(idx_, dexfile);
1442 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001443 void SetNewDexFileCookie(art::ObjPtr<art::mirror::LongArray> cookie)
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001444 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1445 holder_.SetNewDexFileCookie(idx_, cookie);
1446 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001447 void SetNewDexCache(art::ObjPtr<art::mirror::DexCache> cache)
1448 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001449 holder_.SetNewDexCache(idx_, cache);
1450 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001451 void SetMirrorClass(art::ObjPtr<art::mirror::Class> klass)
1452 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001453 holder_.SetMirrorClass(idx_, klass);
1454 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001455 void SetOriginalDexFile(art::ObjPtr<art::mirror::Object> bytes)
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001456 REQUIRES_SHARED(art::Locks::mutator_lock_) {
Alex Light2f814aa2017-03-24 15:21:34 +00001457 holder_.SetOriginalDexFile(idx_, bytes);
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001458 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001459 void SetOldObsoleteMethods(art::ObjPtr<art::mirror::PointerArray> methods)
Alex Light1e3926a2017-04-07 10:38:06 -07001460 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1461 holder_.SetOldObsoleteMethods(idx_, methods);
1462 }
Vladimir Markod93e3742018-07-18 10:58:13 +01001463 void SetOldDexCaches(art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> caches)
Alex Light1e3926a2017-04-07 10:38:06 -07001464 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1465 holder_.SetOldDexCaches(idx_, caches);
1466 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001467 void SetNewClassObject(art::ObjPtr<art::mirror::Class> klass)
1468 REQUIRES_SHARED(art::Locks::mutator_lock_) {
1469 holder_.SetNewClassObject(idx_, klass);
1470 }
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001471
1472 private:
1473 int32_t idx_;
1474 RedefinitionDataHolder& holder_;
1475};
1476
1477RedefinitionDataIter RedefinitionDataHolder::begin() {
1478 return RedefinitionDataIter(0, *this);
1479}
1480
1481RedefinitionDataIter RedefinitionDataHolder::end() {
1482 return RedefinitionDataIter(Length(), *this);
1483}
1484
1485bool Redefiner::ClassRedefinition::CheckVerification(const RedefinitionDataIter& iter) {
Alex Light8c889d22017-02-06 13:58:27 -08001486 DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
1487 art::StackHandleScope<2> hs(driver_->self_);
1488 std::string error;
1489 // TODO Make verification log level lower
Andreas Gampe6d7abbd2017-04-24 13:19:09 -07001490 art::verifier::FailureKind failure =
Andreas Gampea43ba3d2019-03-13 15:49:20 -07001491 art::verifier::ClassVerifier::VerifyClass(driver_->self_,
1492 dex_file_.get(),
1493 hs.NewHandle(iter.GetNewDexCache()),
1494 hs.NewHandle(GetClassLoader()),
1495 /*class_def=*/ dex_file_->GetClassDef(0),
1496 /*callbacks=*/ nullptr,
1497 /*allow_soft_failures=*/ true,
1498 /*log_level=*/
1499 art::verifier::HardFailLogMode::kLogWarning,
1500 art::Runtime::Current()->GetTargetSdkVersion(),
1501 &error);
Alex Light53330612017-10-04 15:29:53 -07001502 switch (failure) {
1503 case art::verifier::FailureKind::kNoFailure:
Alex Lightb1eebde2019-10-22 16:30:47 +00001504 // TODO It is possible that by doing redefinition previous NO_COMPILE verification failures
1505 // were fixed. It would be nice to reflect this in the new implementations.
1506 return true;
Alex Light53330612017-10-04 15:29:53 -07001507 case art::verifier::FailureKind::kSoftFailure:
Alex Lightb1eebde2019-10-22 16:30:47 +00001508 // Soft failures might require interpreter on some methods. It won't prevent redefinition but
1509 // it does mean we need to run the verifier again and potentially update method flags after
1510 // performing the swap.
1511 needs_reverify_ = true;
Alex Light53330612017-10-04 15:29:53 -07001512 return true;
1513 case art::verifier::FailureKind::kHardFailure: {
1514 RecordFailure(ERR(FAILS_VERIFICATION), "Failed to verify class. Error was: " + error);
1515 return false;
1516 }
Alex Light8c889d22017-02-06 13:58:27 -08001517 }
Alex Light8c889d22017-02-06 13:58:27 -08001518}
1519
Alex Light1babae02017-02-01 15:35:34 -08001520// Looks through the previously allocated cookies to see if we need to update them with another new
1521// dexfile. This is so that even if multiple classes with the same classloader are redefined at
1522// once they are all added to the classloader.
1523bool Redefiner::ClassRedefinition::AllocateAndRememberNewDexFileCookie(
Alex Light1babae02017-02-01 15:35:34 -08001524 art::Handle<art::mirror::ClassLoader> source_class_loader,
1525 art::Handle<art::mirror::Object> dex_file_obj,
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001526 /*out*/RedefinitionDataIter* cur_data) {
Alex Light1babae02017-02-01 15:35:34 -08001527 art::StackHandleScope<2> hs(driver_->self_);
1528 art::MutableHandle<art::mirror::LongArray> old_cookie(
1529 hs.NewHandle<art::mirror::LongArray>(nullptr));
1530 bool has_older_cookie = false;
1531 // See if we already have a cookie that a previous redefinition got from the same classloader.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001532 for (auto old_data = cur_data->GetHolder().begin(); old_data != *cur_data; ++old_data) {
1533 if (old_data.GetSourceClassLoader() == source_class_loader.Get()) {
Alex Light1babae02017-02-01 15:35:34 -08001534 // Since every instance of this classloader should have the same cookie associated with it we
1535 // can stop looking here.
1536 has_older_cookie = true;
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001537 old_cookie.Assign(old_data.GetNewDexFileCookie());
Alex Light1babae02017-02-01 15:35:34 -08001538 break;
1539 }
1540 }
1541 if (old_cookie.IsNull()) {
1542 // No older cookie. Get it directly from the dex_file_obj
1543 // We should not have seen this classloader elsewhere.
1544 CHECK(!has_older_cookie);
1545 old_cookie.Assign(ClassLoaderHelper::GetDexFileCookie(dex_file_obj));
1546 }
1547 // Use the old cookie to generate the new one with the new DexFile* added in.
1548 art::Handle<art::mirror::LongArray>
1549 new_cookie(hs.NewHandle(ClassLoaderHelper::AllocateNewDexFileCookie(driver_->self_,
1550 old_cookie,
1551 dex_file_.get())));
1552 // Make sure the allocation worked.
1553 if (new_cookie.IsNull()) {
1554 return false;
1555 }
1556
1557 // Save the cookie.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001558 cur_data->SetNewDexFileCookie(new_cookie.Get());
Alex Light1babae02017-02-01 15:35:34 -08001559 // If there are other copies of this same classloader we need to make sure that we all have the
1560 // same cookie.
1561 if (has_older_cookie) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001562 for (auto old_data = cur_data->GetHolder().begin(); old_data != *cur_data; ++old_data) {
Alex Light1babae02017-02-01 15:35:34 -08001563 // We will let the GC take care of the cookie we allocated for this one.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001564 if (old_data.GetSourceClassLoader() == source_class_loader.Get()) {
1565 old_data.SetNewDexFileCookie(new_cookie.Get());
Alex Light1babae02017-02-01 15:35:34 -08001566 }
1567 }
1568 }
1569
1570 return true;
1571}
1572
Alex Lighta7e38d82017-01-19 14:57:28 -08001573bool Redefiner::ClassRedefinition::FinishRemainingAllocations(
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001574 /*out*/RedefinitionDataIter* cur_data) {
Alex Light7916f202017-01-27 09:00:15 -08001575 art::ScopedObjectAccessUnchecked soa(driver_->self_);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001576 art::StackHandleScope<4> hs(driver_->self_);
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001577 cur_data->SetMirrorClass(GetMirrorClass());
Alex Lighta7e38d82017-01-19 14:57:28 -08001578 // This shouldn't allocate
1579 art::Handle<art::mirror::ClassLoader> loader(hs.NewHandle(GetClassLoader()));
Alex Light7916f202017-01-27 09:00:15 -08001580 // The bootclasspath is handled specially so it doesn't have a j.l.DexFile.
1581 if (!art::ClassLinker::IsBootClassLoader(soa, loader.Get())) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001582 cur_data->SetSourceClassLoader(loader.Get());
Alex Light7916f202017-01-27 09:00:15 -08001583 art::Handle<art::mirror::Object> dex_file_obj(hs.NewHandle(
1584 ClassLoaderHelper::FindSourceDexFileObject(driver_->self_, loader)));
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001585 cur_data->SetJavaDexFile(dex_file_obj.Get());
Andreas Gampefa4333d2017-02-14 11:10:34 -08001586 if (dex_file_obj == nullptr) {
Alex Light7916f202017-01-27 09:00:15 -08001587 RecordFailure(ERR(INTERNAL), "Unable to find dex file!");
1588 return false;
1589 }
Alex Light1babae02017-02-01 15:35:34 -08001590 // Allocate the new dex file cookie.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001591 if (!AllocateAndRememberNewDexFileCookie(loader, dex_file_obj, cur_data)) {
Alex Light7916f202017-01-27 09:00:15 -08001592 driver_->self_->AssertPendingOOMException();
1593 driver_->self_->ClearException();
1594 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate dex file array for class loader");
1595 return false;
1596 }
Alex Lighta7e38d82017-01-19 14:57:28 -08001597 }
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001598 cur_data->SetNewDexCache(CreateNewDexCache(loader));
1599 if (cur_data->GetNewDexCache() == nullptr) {
Vladimir Markocd556b02017-02-03 11:47:34 +00001600 driver_->self_->AssertPendingException();
Alex Lighta7e38d82017-01-19 14:57:28 -08001601 driver_->self_->ClearException();
1602 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate DexCache");
1603 return false;
1604 }
1605
1606 // We won't always need to set this field.
Alex Light2f814aa2017-03-24 15:21:34 +00001607 cur_data->SetOriginalDexFile(AllocateOrGetOriginalDexFile());
1608 if (cur_data->GetOriginalDexFile() == nullptr) {
Alex Lighta7e38d82017-01-19 14:57:28 -08001609 driver_->self_->AssertPendingOOMException();
1610 driver_->self_->ClearException();
1611 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate array for original dex file");
1612 return false;
1613 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001614 if (added_fields_ || added_methods_) {
1615 art::Handle<art::mirror::Class> nc(hs.NewHandle(
1616 AllocateNewClassObject(hs.NewHandle(cur_data->GetNewDexCache()))));
1617 if (nc.IsNull()) {
1618 driver_->self_->ClearException();
1619 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate new class object");
1620 return false;
1621 }
1622
1623 cur_data->SetNewClassObject(nc.Get());
1624 }
Alex Lighta7e38d82017-01-19 14:57:28 -08001625 return true;
1626}
1627
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001628uint32_t Redefiner::ClassRedefinition::GetNewClassSize(bool with_embedded_tables,
1629 art::Handle<art::mirror::Class> old_klass) {
1630 // TODO Once we can add methods this won't work any more.
1631 uint32_t num_vtable_entries = old_klass->GetVTableLength();
1632 uint32_t num_8bit_static_fields = 0;
1633 uint32_t num_16bit_static_fields = 0;
1634 uint32_t num_32bit_static_fields = 0;
1635 uint32_t num_64bit_static_fields = 0;
1636 uint32_t num_ref_static_fields = 0;
1637 art::ClassAccessor accessor(*dex_file_, dex_file_->GetClassDef(0));
1638 for (const art::ClassAccessor::Field& f : accessor.GetStaticFields()) {
1639 std::string_view desc(dex_file_->GetFieldTypeDescriptor(dex_file_->GetFieldId(f.GetIndex())));
1640 if (desc[0] == 'L' || desc[0] == '[') {
1641 num_ref_static_fields++;
1642 } else if (desc == "Z" || desc == "B") {
1643 num_8bit_static_fields++;
1644 } else if (desc == "C" || desc == "S") {
1645 num_16bit_static_fields++;
1646 } else if (desc == "I" || desc == "F") {
1647 num_32bit_static_fields++;
1648 } else if (desc == "J" || desc == "D") {
1649 num_64bit_static_fields++;
1650 } else {
1651 LOG(FATAL) << "Unknown type descriptor! " << desc;
1652 }
1653 }
1654
1655 return art::mirror::Class::ComputeClassSize(with_embedded_tables,
1656 with_embedded_tables ? num_vtable_entries : 0,
1657 num_8bit_static_fields,
1658 num_16bit_static_fields,
1659 num_32bit_static_fields,
1660 num_64bit_static_fields,
1661 num_ref_static_fields,
1662 art::kRuntimePointerSize);
1663}
1664
1665art::ObjPtr<art::mirror::Class>
1666Redefiner::ClassRedefinition::AllocateNewClassObject(art::Handle<art::mirror::DexCache> cache) {
1667 // This is a stripped down DefineClass. We don't want to use DefineClass directly because it needs
1668 // to perform a lot of extra steps to tell the ClassTable and the jit and everything about a new
1669 // class. For now we will need to rely on our tests catching any issues caused by changes in how
1670 // class_linker sets up classes.
1671 // TODO Unify/move this into ClassLinker maybe.
1672 art::StackHandleScope<5> hs(driver_->self_);
1673 art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
1674 art::Handle<art::mirror::Class> old_class(hs.NewHandle(GetMirrorClass()));
1675 art::Handle<art::mirror::Class> new_class(hs.NewHandle(linker->AllocClass(
1676 driver_->self_, GetNewClassSize(/*with_embedded_tables=*/false, old_class))));
1677 if (new_class.IsNull()) {
1678 driver_->self_->AssertPendingOOMException();
1679 JVMTI_LOG(ERROR, driver_->env_) << "Unable to allocate new class object!";
1680 return nullptr;
1681 }
1682 new_class->SetDexCache(cache.Get());
1683 linker->SetupClass(*dex_file_, dex_file_->GetClassDef(0), new_class, old_class->GetClassLoader());
1684
1685 // Make sure we are ready for linking. The lock isn't really needed since this isn't visible to
1686 // other threads but the linker expects it.
1687 art::ObjectLock<art::mirror::Class> lock(driver_->self_, new_class);
1688 new_class->SetClinitThreadId(driver_->self_->GetTid());
1689 // Make sure we have a valid empty iftable even if there are errors.
1690 new_class->SetIfTable(art::GetClassRoot<art::mirror::Object>(linker)->GetIfTable());
1691 linker->LoadClass(driver_->self_, *dex_file_, dex_file_->GetClassDef(0), new_class);
1692 // NB. We know the interfaces and supers didn't change! :)
1693 art::MutableHandle<art::mirror::Class> linked_class(hs.NewHandle<art::mirror::Class>(nullptr));
1694 art::Handle<art::mirror::ObjectArray<art::mirror::Class>> proxy_ifaces(
1695 hs.NewHandle<art::mirror::ObjectArray<art::mirror::Class>>(nullptr));
1696 // No changing hierarchy so everything is loaded.
1697 new_class->SetSuperClass(old_class->GetSuperClass());
1698 art::mirror::Class::SetStatus(new_class, art::ClassStatus::kLoaded, nullptr);
1699 if (!linker->LinkClass(driver_->self_, nullptr, new_class, proxy_ifaces, &linked_class)) {
1700 JVMTI_LOG(ERROR, driver_->env_)
1701 << "failed to link class due to "
1702 << (driver_->self_->IsExceptionPending() ? driver_->self_->GetException()->Dump()
1703 : " unknown");
1704 driver_->self_->ClearException();
1705 return nullptr;
1706 }
1707 // We will initialize it manually.
1708 art::ObjectLock<art::mirror::Class> objlock(driver_->self_, linked_class);
1709 // We already verified the class earlier. No need to do it again.
1710 linked_class->SetVerificationAttempted();
Alex Lightfb119572019-09-18 15:04:53 -07001711 // Mark the class as initialized.
1712 CHECK(old_class->IsInitialized())
1713 << "Attempting to redefine an uninitalized class " << old_class->PrettyClass()
1714 << " status=" << old_class->GetStatus();
1715 linker->ForceClassInitialized(driver_->self_, linked_class);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001716 // Make sure we have ext-data space for method & field ids. We won't know if we need them until
1717 // it's too late to create them.
1718 // TODO We might want to remove these arrays if they're not needed.
1719 if (art::mirror::Class::GetOrCreateInstanceFieldIds(linked_class).IsNull() ||
1720 art::mirror::Class::GetOrCreateStaticFieldIds(linked_class).IsNull() ||
1721 art::mirror::Class::GetOrCreateMethodIds(linked_class).IsNull()) {
1722 driver_->self_->AssertPendingOOMException();
1723 driver_->self_->ClearException();
1724 JVMTI_LOG(ERROR, driver_->env_) << "Unable to allocate jni-id arrays!";
1725 return nullptr;
1726 }
1727 // Finish setting up methods.
1728 linked_class->VisitMethods([&](art::ArtMethod* m) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1729 linker->SetEntryPointsToInterpreter(m);
1730 m->SetNotIntrinsic();
1731 DCHECK(m->IsCopied() || m->GetDeclaringClass() == linked_class.Get())
1732 << m->PrettyMethod()
1733 << " m->GetDeclaringClass(): " << m->GetDeclaringClass()->PrettyClass()
1734 << " != linked_class.Get(): " << linked_class->PrettyClass();
1735 }, art::kRuntimePointerSize);
1736 if (art::kIsDebugBuild) {
1737 linked_class->VisitFields([&](art::ArtField* f) REQUIRES_SHARED(art::Locks::mutator_lock_) {
1738 DCHECK_EQ(f->GetDeclaringClass(), linked_class.Get());
1739 });
1740 }
1741 return linked_class.Get();
1742}
1743
Alex Lighta26e3492017-06-27 17:55:37 -07001744void Redefiner::ClassRedefinition::UnregisterJvmtiBreakpoints() {
Vladimir Marko4617d582019-03-28 13:48:31 +00001745 BreakpointUtil::RemoveBreakpointsInClass(driver_->env_, GetMirrorClass().Ptr());
Alex Lighta26e3492017-06-27 17:55:37 -07001746}
1747
Alex Light5643caf2017-02-08 11:39:07 -08001748void Redefiner::ClassRedefinition::UnregisterBreakpoints() {
Alex Lighte34fe442018-02-21 17:35:55 -08001749 if (LIKELY(!art::Dbg::IsDebuggerActive())) {
1750 return;
1751 }
Alex Light5643caf2017-02-08 11:39:07 -08001752 art::JDWP::JdwpState* state = art::Dbg::GetJdwpState();
1753 if (state != nullptr) {
1754 state->UnregisterLocationEventsOnClass(GetMirrorClass());
1755 }
1756}
1757
1758void Redefiner::UnregisterAllBreakpoints() {
Alex Light5643caf2017-02-08 11:39:07 -08001759 for (Redefiner::ClassRedefinition& redef : redefinitions_) {
1760 redef.UnregisterBreakpoints();
Alex Lighte34fe442018-02-21 17:35:55 -08001761 redef.UnregisterJvmtiBreakpoints();
Alex Light5643caf2017-02-08 11:39:07 -08001762 }
1763}
1764
Alex Light0e692732017-01-10 15:00:05 -08001765bool Redefiner::CheckAllRedefinitionAreValid() {
1766 for (Redefiner::ClassRedefinition& redef : redefinitions_) {
1767 if (!redef.CheckRedefinitionIsValid()) {
1768 return false;
1769 }
1770 }
1771 return true;
1772}
1773
Alex Light1e3926a2017-04-07 10:38:06 -07001774void Redefiner::RestoreObsoleteMethodMapsIfUnneeded(RedefinitionDataHolder& holder) {
1775 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
1776 data.GetRedefinition().RestoreObsoleteMethodMapsIfUnneeded(&data);
1777 }
1778}
1779
1780bool Redefiner::EnsureAllClassAllocationsFinished(RedefinitionDataHolder& holder) {
1781 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
1782 if (!data.GetRedefinition().EnsureClassAllocationsFinished(&data)) {
Alex Light0e692732017-01-10 15:00:05 -08001783 return false;
1784 }
1785 }
1786 return true;
1787}
1788
1789bool Redefiner::FinishAllRemainingAllocations(RedefinitionDataHolder& holder) {
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001790 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
Alex Light0e692732017-01-10 15:00:05 -08001791 // Allocate the data this redefinition requires.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001792 if (!data.GetRedefinition().FinishRemainingAllocations(&data)) {
Alex Light0e692732017-01-10 15:00:05 -08001793 return false;
1794 }
Alex Light0e692732017-01-10 15:00:05 -08001795 }
1796 return true;
1797}
1798
1799void Redefiner::ClassRedefinition::ReleaseDexFile() {
Andreas Gampeafaf7f82018-10-16 11:32:38 -07001800 dex_file_.release(); // NOLINT b/117926937
Alex Light0e692732017-01-10 15:00:05 -08001801}
1802
1803void Redefiner::ReleaseAllDexFiles() {
1804 for (Redefiner::ClassRedefinition& redef : redefinitions_) {
1805 redef.ReleaseDexFile();
1806 }
1807}
1808
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001809bool Redefiner::CheckAllClassesAreVerified(RedefinitionDataHolder& holder) {
1810 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
1811 if (!data.GetRedefinition().CheckVerification(data)) {
Alex Light8c889d22017-02-06 13:58:27 -08001812 return false;
1813 }
Alex Light8c889d22017-02-06 13:58:27 -08001814 }
1815 return true;
1816}
1817
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001818class ScopedDisableConcurrentAndMovingGc {
1819 public:
1820 ScopedDisableConcurrentAndMovingGc(art::gc::Heap* heap, art::Thread* self)
1821 : heap_(heap), self_(self) {
1822 if (heap_->IsGcConcurrentAndMoving()) {
1823 heap_->IncrementDisableMovingGC(self_);
1824 }
1825 }
1826
1827 ~ScopedDisableConcurrentAndMovingGc() {
1828 if (heap_->IsGcConcurrentAndMoving()) {
1829 heap_->DecrementDisableMovingGC(self_);
1830 }
1831 }
1832 private:
1833 art::gc::Heap* heap_;
1834 art::Thread* self_;
1835};
1836
Alex Lighta01de592016-11-15 10:43:06 -08001837jvmtiError Redefiner::Run() {
Alex Light0e692732017-01-10 15:00:05 -08001838 art::StackHandleScope<1> hs(self_);
1839 // Allocate an array to hold onto all java temporary objects associated with this redefinition.
1840 // We will let this be collected after the end of this function.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001841 RedefinitionDataHolder holder(&hs, runtime_, self_, &redefinitions_);
Alex Light0e692732017-01-10 15:00:05 -08001842 if (holder.IsNull()) {
1843 self_->AssertPendingOOMException();
1844 self_->ClearException();
1845 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate storage for temporaries");
1846 return result_;
1847 }
1848
Alex Lighta01de592016-11-15 10:43:06 -08001849 // First we just allocate the ClassExt and its fields that we need. These can be updated
1850 // atomically without any issues (since we allocate the map arrays as empty) so we don't bother
1851 // doing a try loop. The other allocations we need to ensure that nothing has changed in the time
1852 // between allocating them and pausing all threads before we can update them so we need to do a
1853 // try loop.
Alex Light0e692732017-01-10 15:00:05 -08001854 if (!CheckAllRedefinitionAreValid() ||
Alex Light1e3926a2017-04-07 10:38:06 -07001855 !EnsureAllClassAllocationsFinished(holder) ||
Alex Light8c889d22017-02-06 13:58:27 -08001856 !FinishAllRemainingAllocations(holder) ||
1857 !CheckAllClassesAreVerified(holder)) {
Alex Lighta01de592016-11-15 10:43:06 -08001858 return result_;
1859 }
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001860
Alex Light5643caf2017-02-08 11:39:07 -08001861 // At this point we can no longer fail without corrupting the runtime state.
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001862 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
Alex Light07f06212017-06-01 14:01:43 -07001863 art::ClassLinker* cl = runtime_->GetClassLinker();
1864 cl->RegisterExistingDexCache(data.GetNewDexCache(), data.GetSourceClassLoader());
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001865 if (data.GetSourceClassLoader() == nullptr) {
Alex Light07f06212017-06-01 14:01:43 -07001866 cl->AppendToBootClassPath(self_, data.GetRedefinition().GetDexFile());
Alex Light7916f202017-01-27 09:00:15 -08001867 }
Alex Light7916f202017-01-27 09:00:15 -08001868 }
Alex Light5643caf2017-02-08 11:39:07 -08001869 UnregisterAllBreakpoints();
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001870
Alex Lightc2d0c962019-10-23 14:14:25 -07001871 {
1872 // Disable GC and wait for it to be done if we are a moving GC. This is fine since we are done
1873 // allocating so no deadlocks.
1874 ScopedDisableConcurrentAndMovingGc sdcamgc(runtime_->GetHeap(), self_);
Alex Lightc5f5a6e2017-03-01 16:57:08 -08001875
Alex Lightc2d0c962019-10-23 14:14:25 -07001876 // Do transition to final suspension
1877 // TODO We might want to give this its own suspended state!
1878 // TODO This isn't right. We need to change state without any chance of suspend ideally!
1879 art::ScopedThreadSuspension sts(self_, art::ThreadState::kNative);
1880 art::ScopedSuspendAll ssa("Final installation of redefined Classes!", /*long_suspend=*/true);
1881 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
1882 art::ScopedAssertNoThreadSuspension nts("Updating runtime objects for redefinition");
1883 ClassRedefinition& redef = data.GetRedefinition();
1884 if (data.GetSourceClassLoader() != nullptr) {
1885 ClassLoaderHelper::UpdateJavaDexFile(data.GetJavaDexFile(), data.GetNewDexFileCookie());
1886 }
1887 redef.UpdateClass(data);
Alex Light7916f202017-01-27 09:00:15 -08001888 }
Alex Lightc2d0c962019-10-23 14:14:25 -07001889 RestoreObsoleteMethodMapsIfUnneeded(holder);
1890 // TODO We should check for if any of the redefined methods are intrinsic methods here and, if
1891 // any are, force a full-world deoptimization before finishing redefinition. If we don't do this
1892 // then methods that have been jitted prior to the current redefinition being applied might
1893 // continue to use the old versions of the intrinsics!
1894 // TODO Do the dex_file release at a more reasonable place. This works but it muddles who really
1895 // owns the DexFile and when ownership is transferred.
1896 ReleaseAllDexFiles();
Alex Light0e692732017-01-10 15:00:05 -08001897 }
Alex Lightb1eebde2019-10-22 16:30:47 +00001898 // By now the class-linker knows about all the classes so we can safetly retry verification and
1899 // update method flags.
1900 ReverifyClasses(holder);
Alex Lighta01de592016-11-15 10:43:06 -08001901 return OK;
1902}
1903
Alex Lightb1eebde2019-10-22 16:30:47 +00001904void Redefiner::ReverifyClasses(RedefinitionDataHolder& holder) {
Alex Lightb1eebde2019-10-22 16:30:47 +00001905 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) {
1906 data.GetRedefinition().ReverifyClass(data);
1907 }
1908}
1909
1910void Redefiner::ClassRedefinition::ReverifyClass(const RedefinitionDataIter &cur_data) {
1911 if (!needs_reverify_) {
1912 return;
1913 }
1914 VLOG(plugin) << "Reverifying " << class_sig_ << " due to soft failures";
1915 std::string error;
1916 // TODO Make verification log level lower
1917 art::verifier::FailureKind failure =
1918 art::verifier::ClassVerifier::ReverifyClass(driver_->self_,
1919 cur_data.GetMirrorClass(),
1920 /*log_level=*/
1921 art::verifier::HardFailLogMode::kLogWarning,
1922 /*api_level=*/
1923 art::Runtime::Current()->GetTargetSdkVersion(),
1924 &error);
1925 CHECK_NE(failure, art::verifier::FailureKind::kHardFailure);
1926}
1927
Alex Light0e692732017-01-10 15:00:05 -08001928void Redefiner::ClassRedefinition::UpdateMethods(art::ObjPtr<art::mirror::Class> mclass,
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001929 const art::dex::ClassDef& class_def) {
Alex Light0e692732017-01-10 15:00:05 -08001930 art::ClassLinker* linker = driver_->runtime_->GetClassLinker();
Alex Lighta01de592016-11-15 10:43:06 -08001931 art::PointerSize image_pointer_size = linker->GetImagePointerSize();
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001932 const art::dex::TypeId& declaring_class_id = dex_file_->GetTypeId(class_def.class_idx_);
Alex Lighta01de592016-11-15 10:43:06 -08001933 const art::DexFile& old_dex_file = mclass->GetDexFile();
Alex Light200b9d72016-12-15 11:34:13 -08001934 // Update methods.
Alex Light00e475c2017-07-19 16:36:23 -07001935 for (art::ArtMethod& method : mclass->GetDeclaredMethods(image_pointer_size)) {
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001936 const art::dex::StringId* new_name_id = dex_file_->FindStringId(method.GetName());
Alex Lighta01de592016-11-15 10:43:06 -08001937 art::dex::TypeIndex method_return_idx =
1938 dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(method.GetReturnTypeDescriptor()));
1939 const auto* old_type_list = method.GetParameterTypeList();
1940 std::vector<art::dex::TypeIndex> new_type_list;
1941 for (uint32_t i = 0; old_type_list != nullptr && i < old_type_list->Size(); i++) {
1942 new_type_list.push_back(
1943 dex_file_->GetIndexForTypeId(
1944 *dex_file_->FindTypeId(
1945 old_dex_file.GetTypeDescriptor(
1946 old_dex_file.GetTypeId(
1947 old_type_list->GetTypeItem(i).type_idx_)))));
1948 }
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001949 const art::dex::ProtoId* proto_id = dex_file_->FindProtoId(method_return_idx, new_type_list);
Alex Lightdba61482016-12-21 08:20:29 -08001950 CHECK(proto_id != nullptr || old_type_list == nullptr);
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001951 const art::dex::MethodId* method_id = dex_file_->FindMethodId(declaring_class_id,
1952 *new_name_id,
1953 *proto_id);
Alex Lightdba61482016-12-21 08:20:29 -08001954 CHECK(method_id != nullptr);
Alex Lighta01de592016-11-15 10:43:06 -08001955 uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id);
1956 method.SetDexMethodIndex(dex_method_idx);
1957 linker->SetEntryPointsToInterpreter(&method);
Alex Light200b9d72016-12-15 11:34:13 -08001958 method.SetCodeItemOffset(dex_file_->FindCodeItemOffset(class_def, dex_method_idx));
Alex Light7532d582017-02-13 16:36:06 -08001959 // Clear all the intrinsics related flags.
Orion Hodsoncfcc9cf2017-09-29 15:07:27 +01001960 method.SetNotIntrinsic();
Alex Lighta01de592016-11-15 10:43:06 -08001961 }
Alex Light200b9d72016-12-15 11:34:13 -08001962}
1963
Alex Light0e692732017-01-10 15:00:05 -08001964void Redefiner::ClassRedefinition::UpdateFields(art::ObjPtr<art::mirror::Class> mclass) {
Alex Light200b9d72016-12-15 11:34:13 -08001965 // TODO The IFields & SFields pointers should be combined like the methods_ arrays were.
1966 for (auto fields_iter : {mclass->GetIFields(), mclass->GetSFields()}) {
1967 for (art::ArtField& field : fields_iter) {
1968 std::string declaring_class_name;
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001969 const art::dex::TypeId* new_declaring_id =
Alex Light200b9d72016-12-15 11:34:13 -08001970 dex_file_->FindTypeId(field.GetDeclaringClass()->GetDescriptor(&declaring_class_name));
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001971 const art::dex::StringId* new_name_id = dex_file_->FindStringId(field.GetName());
1972 const art::dex::TypeId* new_type_id = dex_file_->FindTypeId(field.GetTypeDescriptor());
Alex Light200b9d72016-12-15 11:34:13 -08001973 CHECK(new_name_id != nullptr && new_type_id != nullptr && new_declaring_id != nullptr);
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08001974 const art::dex::FieldId* new_field_id =
Alex Light200b9d72016-12-15 11:34:13 -08001975 dex_file_->FindFieldId(*new_declaring_id, *new_name_id, *new_type_id);
1976 CHECK(new_field_id != nullptr);
1977 // We only need to update the index since the other data in the ArtField cannot be updated.
1978 field.SetDexFieldIndex(dex_file_->GetIndexForFieldId(*new_field_id));
1979 }
1980 }
Alex Light200b9d72016-12-15 11:34:13 -08001981}
1982
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001983void Redefiner::ClassRedefinition::CollectNewFieldAndMethodMappings(
1984 const RedefinitionDataIter& data,
1985 std::map<art::ArtMethod*, art::ArtMethod*>* method_map,
1986 std::map<art::ArtField*, art::ArtField*>* field_map) {
1987 art::ObjPtr<art::mirror::Class> old_cls(data.GetMirrorClass());
1988 art::ObjPtr<art::mirror::Class> new_cls(data.GetNewClassObject());
1989 for (art::ArtField& f : old_cls->GetSFields()) {
1990 (*field_map)[&f] = new_cls->FindDeclaredStaticField(f.GetName(), f.GetTypeDescriptor());
1991 }
1992 for (art::ArtField& f : old_cls->GetIFields()) {
1993 (*field_map)[&f] = new_cls->FindDeclaredInstanceField(f.GetName(), f.GetTypeDescriptor());
1994 }
1995 auto new_methods = new_cls->GetMethods(art::kRuntimePointerSize);
1996 for (art::ArtMethod& m : old_cls->GetMethods(art::kRuntimePointerSize)) {
1997 // No support for finding methods in this way since it's generally not needed. Just do it the
1998 // easy way.
1999 auto nm_iter = std::find_if(
2000 new_methods.begin(),
2001 new_methods.end(),
2002 [&](art::ArtMethod& cand) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2003 return cand.GetNameView() == m.GetNameView() && cand.GetSignature() == m.GetSignature();
2004 });
2005 CHECK(nm_iter != new_methods.end())
2006 << "Could not find redefined version of " << m.PrettyMethod();
2007 (*method_map)[&m] = &(*nm_iter);
2008 }
2009}
2010
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002011void Redefiner::ClassRedefinition::UpdateClassStructurally(const RedefinitionDataIter& holder) {
2012 DCHECK(IsStructuralRedefinition());
2013 // LETS GO. We've got all new class structures so no need to do all the updating of the stacks.
2014 // Instead we need to update everything else.
2015 // Just replace the class and be done with it.
2016 art::Locks::mutator_lock_->AssertExclusiveHeld(driver_->self_);
2017 art::ScopedAssertNoThreadSuspension sants(__FUNCTION__);
2018 art::ObjPtr<art::mirror::Class> orig(holder.GetMirrorClass());
2019 art::ObjPtr<art::mirror::Class> replacement(holder.GetNewClassObject());
2020 // Collect mappings from old to new fields/methods
2021 std::map<art::ArtMethod*, art::ArtMethod*> method_map;
2022 std::map<art::ArtField*, art::ArtField*> field_map;
2023 CollectNewFieldAndMethodMappings(holder, &method_map, &field_map);
2024 // Copy over the fields of the object.
2025 CHECK(!orig.IsNull());
2026 CHECK(!replacement.IsNull());
2027 for (art::ArtField& f : orig->GetSFields()) {
2028 art::ArtField* new_field =
2029 replacement->FindDeclaredStaticField(f.GetName(), f.GetTypeDescriptor());
2030 CHECK(new_field != nullptr) << "could not find new version of " << f.PrettyField();
2031 art::Primitive::Type ftype = f.GetTypeAsPrimitiveType();
2032 CHECK_EQ(ftype, new_field->GetTypeAsPrimitiveType())
2033 << f.PrettyField() << " vs " << new_field->PrettyField();
2034 if (ftype == art::Primitive::kPrimNot) {
2035 new_field->SetObject<false>(replacement, f.GetObject(orig));
2036 } else {
2037 switch (ftype) {
2038#define UPDATE_FIELD(TYPE) \
2039 case art::Primitive::kPrim##TYPE: \
2040 new_field->Set##TYPE<false>(replacement, f.Get##TYPE(orig)); \
2041 break
2042
2043 UPDATE_FIELD(Int);
2044 UPDATE_FIELD(Float);
2045 UPDATE_FIELD(Long);
2046 UPDATE_FIELD(Double);
2047 UPDATE_FIELD(Short);
2048 UPDATE_FIELD(Char);
2049 UPDATE_FIELD(Byte);
2050 UPDATE_FIELD(Boolean);
2051 case art::Primitive::kPrimNot:
2052 case art::Primitive::kPrimVoid:
2053 LOG(FATAL) << "Unexpected field with type " << ftype << " found!";
2054 UNREACHABLE();
2055#undef UPDATE_FIELD
2056 }
2057 }
2058 }
2059 // Mark old class obsolete.
2060 orig->SetObsoleteObject();
2061 // Mark methods obsolete. We need to wait until later to actually clear the jit data.
2062 for (art::ArtMethod& m : orig->GetMethods(art::kRuntimePointerSize)) {
2063 m.SetIsObsolete();
2064 m.SetDontCompile();
2065 DCHECK_EQ(orig, m.GetDeclaringClass());
2066 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002067 // Copy the lock-word
2068 replacement->SetLockWord(orig->GetLockWord(false), false);
2069 orig->SetLockWord(art::LockWord::Default(), false);
Alex Lightc18eba32019-09-24 14:36:27 -07002070 // Update live pointers in ART code.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002071 // TODO Performing 2 stack-walks back to back isn't the greatest. We might want to try to combine
2072 // it with the one ReplaceReferences does. Doing so would be rather complicated though.
Alex Lightc18eba32019-09-24 14:36:27 -07002073 driver_->runtime_->VisitReflectiveTargets(
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002074 [&](art::ArtField* f, const auto& info) REQUIRES(art::Locks::mutator_lock_) {
2075 auto it = field_map.find(f);
2076 if (it == field_map.end()) {
2077 return f;
2078 }
2079 VLOG(plugin) << "Updating " << info << " object for (field) " << it->second->PrettyField();
2080 return it->second;
2081 },
2082 [&](art::ArtMethod* m, const auto& info) REQUIRES(art::Locks::mutator_lock_) {
2083 auto it = method_map.find(m);
2084 if (it == method_map.end()) {
2085 return m;
2086 }
Alex Lightc18eba32019-09-24 14:36:27 -07002087 VLOG(plugin) << "Updating " << info << " object for (method) "
2088 << it->second->PrettyMethod();
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002089 return it->second;
2090 });
2091
2092 // Force every frame of every thread to deoptimize (any frame might have eg offsets compiled in).
2093 driver_->runtime_->GetInstrumentation()->DeoptimizeAllThreadFrames();
2094
2095 // Actually perform the general replacement. This doesn't affect ArtMethod/ArtFields.
2096 // This replaces the mirror::Class in 'holder' as well. It's magic!
2097 HeapExtensions::ReplaceReference(driver_->self_, orig, replacement);
2098
2099 // Save the old class so that the JIT gc doesn't get confused by it being collected before the
2100 // jit code. This is also needed to keep the dex-caches of any obsolete methods live.
2101 replacement->GetExtData()->SetObsoleteClass(orig);
2102
2103 // Clear the static fields of the old-class.
2104 for (art::ArtField& f : orig->GetSFields()) {
2105 switch (f.GetTypeAsPrimitiveType()) {
2106 #define UPDATE_FIELD(TYPE) \
2107 case art::Primitive::kPrim ## TYPE: \
2108 f.Set ## TYPE <false>(orig, 0); \
2109 break
2110
2111 UPDATE_FIELD(Int);
2112 UPDATE_FIELD(Float);
2113 UPDATE_FIELD(Long);
2114 UPDATE_FIELD(Double);
2115 UPDATE_FIELD(Short);
2116 UPDATE_FIELD(Char);
2117 UPDATE_FIELD(Byte);
2118 UPDATE_FIELD(Boolean);
2119 case art::Primitive::kPrimNot:
2120 f.SetObject<false>(orig, nullptr);
2121 break;
2122 case art::Primitive::kPrimVoid:
2123 LOG(FATAL) << "Unexpected field with type void found!";
2124 UNREACHABLE();
2125 #undef UPDATE_FIELD
2126 }
2127 }
2128
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002129 art::jit::Jit* jit = driver_->runtime_->GetJit();
2130 if (jit != nullptr) {
2131 // Clear jit.
2132 // TODO We might want to have some way to tell the JIT not to wait the kJitSamplesBatchSize
2133 // invokes to start compiling things again.
2134 jit->GetCodeCache()->InvalidateAllCompiledCode();
2135 }
2136
2137 // Clear thread caches
2138 {
2139 // TODO We might be able to avoid doing this but given the rather unstructured nature of the
2140 // interpreter cache it's probably not worth the effort.
2141 art::MutexLock mu(driver_->self_, *art::Locks::thread_list_lock_);
2142 driver_->runtime_->GetThreadList()->ForEach(
2143 [](art::Thread* t) { t->GetInterpreterCache()->Clear(t); });
2144 }
2145
2146 if (art::kIsDebugBuild) {
2147 // Just make sure we didn't screw up any of the now obsolete methods or fields. We need their
2148 // declaring-class to still be the obolete class
2149 orig->VisitMethods([&](art::ArtMethod* method) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2150 DCHECK_EQ(method->GetDeclaringClass(), orig) << method->GetDeclaringClass()->PrettyClass()
2151 << " vs " << orig->PrettyClass();
2152 }, art::kRuntimePointerSize);
2153 orig->VisitFields([&](art::ArtField* field) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2154 DCHECK_EQ(field->GetDeclaringClass(), orig) << field->GetDeclaringClass()->PrettyClass()
2155 << " vs " << orig->PrettyClass();
2156 });
2157 }
2158}
2159
2160// Redefines the class in place
2161void Redefiner::ClassRedefinition::UpdateClassInPlace(const RedefinitionDataIter& holder) {
2162 art::ObjPtr<art::mirror::Class> mclass(holder.GetMirrorClass());
2163 // TODO Rewrite so we don't do a stack walk for each and every class.
2164 FindAndAllocateObsoleteMethods(mclass);
2165 art::ObjPtr<art::mirror::DexCache> new_dex_cache(holder.GetNewDexCache());
2166 art::ObjPtr<art::mirror::Object> original_dex_file(holder.GetOriginalDexFile());
Alex Light6ac57502017-01-19 15:05:06 -08002167 DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
Andreas Gampe3f1dcd32018-12-28 09:39:56 -08002168 const art::dex::ClassDef& class_def = dex_file_->GetClassDef(0);
Vladimir Marko5122e6b2017-08-17 16:10:09 +01002169 UpdateMethods(mclass, class_def);
Alex Light007ada22017-01-10 13:33:56 -08002170 UpdateFields(mclass);
Alex Light200b9d72016-12-15 11:34:13 -08002171
David Brazdil1a658632018-12-01 17:54:26 +00002172 art::ObjPtr<art::mirror::ClassExt> ext(mclass->GetExtData());
2173 CHECK(!ext.IsNull());
2174 ext->SetOriginalDexFile(original_dex_file);
2175
2176 // If this is the first time the class is being redefined, store
2177 // the native DexFile pointer and initial ClassDef index in ClassExt.
2178 // This preserves the pointer for hiddenapi access checks which need
2179 // to read access flags from the initial DexFile.
2180 if (ext->GetPreRedefineDexFile() == nullptr) {
2181 ext->SetPreRedefineDexFile(&mclass->GetDexFile());
2182 ext->SetPreRedefineClassDefIndex(mclass->GetDexClassDefIndex());
2183 }
2184
Alex Lighta01de592016-11-15 10:43:06 -08002185 // Update the class fields.
2186 // Need to update class last since the ArtMethod gets its DexFile from the class (which is needed
2187 // to call GetReturnTypeDescriptor and GetParameterTypeList above).
2188 mclass->SetDexCache(new_dex_cache.Ptr());
Alex Light6ac57502017-01-19 15:05:06 -08002189 mclass->SetDexClassDefIndex(dex_file_->GetIndexForClassDef(class_def));
Alex Light0e692732017-01-10 15:00:05 -08002190 mclass->SetDexTypeIndex(dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(class_sig_.c_str())));
Alex Light035105f2018-03-05 17:48:48 -08002191
2192 // Notify the jit that all the methods in this class were redefined. Need to do this last since
2193 // the jit relies on the dex_file_ being correct (for native methods at least) to find the method
2194 // meta-data.
2195 art::jit::Jit* jit = driver_->runtime_->GetJit();
2196 if (jit != nullptr) {
2197 art::PointerSize image_pointer_size =
2198 driver_->runtime_->GetClassLinker()->GetImagePointerSize();
2199 auto code_cache = jit->GetCodeCache();
2200 // Non-invokable methods don't have any JIT data associated with them so we don't need to tell
2201 // the jit about them.
2202 for (art::ArtMethod& method : mclass->GetDeclaredMethods(image_pointer_size)) {
2203 if (method.IsInvokable()) {
2204 code_cache->NotifyMethodRedefined(&method);
2205 }
2206 }
2207 }
Alex Lighta01de592016-11-15 10:43:06 -08002208}
2209
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002210// Performs final updates to class for redefinition.
2211void Redefiner::ClassRedefinition::UpdateClass(const RedefinitionDataIter& holder) {
2212 if (IsStructuralRedefinition()) {
2213 UpdateClassStructurally(holder);
2214 } else {
2215 UpdateClassInPlace(holder);
2216 }
Alex Lightc2d0c962019-10-23 14:14:25 -07002217 UpdateClassCommon(holder);
2218}
2219
2220void Redefiner::ClassRedefinition::UpdateClassCommon(const RedefinitionDataIter &cur_data) {
2221 // NB This is after we've already replaced all old-refs with new-refs in the structural case.
2222 art::ObjPtr<art::mirror::Class> klass(cur_data.GetMirrorClass());
2223 DCHECK(!IsStructuralRedefinition() || klass == cur_data.GetNewClassObject());
2224 if (!needs_reverify_) {
2225 return;
2226 }
2227 // Force the most restrictive interpreter environment. We don't know what the final verification
2228 // will allow. We will clear these after retrying verification once we drop the mutator-lock.
2229 klass->VisitMethods([](art::ArtMethod* m) REQUIRES_SHARED(art::Locks::mutator_lock_) {
2230 if (!m->IsNative() && m->IsInvokable() && !m->IsObsolete()) {
2231 m->ClearSkipAccessChecks();
2232 m->SetDontCompile();
2233 m->SetMustCountLocks();
2234 }
2235 }, art::kRuntimePointerSize);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002236}
2237
Alex Light1e3926a2017-04-07 10:38:06 -07002238// Restores the old obsolete methods maps if it turns out they weren't needed (ie there were no new
2239// obsolete methods).
2240void Redefiner::ClassRedefinition::RestoreObsoleteMethodMapsIfUnneeded(
2241 const RedefinitionDataIter* cur_data) {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002242 if (IsStructuralRedefinition()) {
2243 // We didn't touch these in this case.
2244 return;
2245 }
Vladimir Markod93e3742018-07-18 10:58:13 +01002246 art::ObjPtr<art::mirror::Class> klass = GetMirrorClass();
2247 art::ObjPtr<art::mirror::ClassExt> ext = klass->GetExtData();
2248 art::ObjPtr<art::mirror::PointerArray> methods = ext->GetObsoleteMethods();
2249 art::ObjPtr<art::mirror::PointerArray> old_methods = cur_data->GetOldObsoleteMethods();
Alex Light70713df2017-04-18 13:03:31 -07002250 int32_t old_length = old_methods == nullptr ? 0 : old_methods->GetLength();
Alex Light1e3926a2017-04-07 10:38:06 -07002251 int32_t expected_length =
2252 old_length + klass->NumDirectMethods() + klass->NumDeclaredVirtualMethods();
2253 // Check to make sure we are only undoing this one.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002254 if (methods.IsNull()) {
2255 // No new obsolete methods! We can get rid of the maps.
2256 ext->SetObsoleteArrays(cur_data->GetOldObsoleteMethods(), cur_data->GetOldDexCaches());
2257 } else if (expected_length == methods->GetLength()) {
Alex Light70713df2017-04-18 13:03:31 -07002258 for (int32_t i = 0; i < expected_length; i++) {
2259 art::ArtMethod* expected = nullptr;
2260 if (i < old_length) {
2261 expected = old_methods->GetElementPtrSize<art::ArtMethod*>(i, art::kRuntimePointerSize);
2262 }
2263 if (methods->GetElementPtrSize<art::ArtMethod*>(i, art::kRuntimePointerSize) != expected) {
Alex Light1e3926a2017-04-07 10:38:06 -07002264 // We actually have some new obsolete methods. Just abort since we cannot safely shrink the
2265 // obsolete methods array.
2266 return;
2267 }
2268 }
2269 // No new obsolete methods! We can get rid of the maps.
2270 ext->SetObsoleteArrays(cur_data->GetOldObsoleteMethods(), cur_data->GetOldDexCaches());
2271 }
2272}
2273
Alex Lighta01de592016-11-15 10:43:06 -08002274// This function does all (java) allocations we need to do for the Class being redefined.
2275// TODO Change this name maybe?
Alex Light1e3926a2017-04-07 10:38:06 -07002276bool Redefiner::ClassRedefinition::EnsureClassAllocationsFinished(
2277 /*out*/RedefinitionDataIter* cur_data) {
Alex Light0e692732017-01-10 15:00:05 -08002278 art::StackHandleScope<2> hs(driver_->self_);
2279 art::Handle<art::mirror::Class> klass(hs.NewHandle(
2280 driver_->self_->DecodeJObject(klass_)->AsClass()));
Andreas Gampefa4333d2017-02-14 11:10:34 -08002281 if (klass == nullptr) {
Alex Lighta01de592016-11-15 10:43:06 -08002282 RecordFailure(ERR(INVALID_CLASS), "Unable to decode class argument!");
2283 return false;
2284 }
2285 // Allocate the classExt
Vladimir Marko3068d582019-05-28 16:39:29 +01002286 art::Handle<art::mirror::ClassExt> ext =
2287 hs.NewHandle(art::mirror::Class::EnsureExtDataPresent(klass, driver_->self_));
Andreas Gampefa4333d2017-02-14 11:10:34 -08002288 if (ext == nullptr) {
Alex Lighta01de592016-11-15 10:43:06 -08002289 // No memory. Clear exception (it's not useful) and return error.
Alex Light0e692732017-01-10 15:00:05 -08002290 driver_->self_->AssertPendingOOMException();
2291 driver_->self_->ClearException();
Alex Lighta01de592016-11-15 10:43:06 -08002292 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate ClassExt");
2293 return false;
2294 }
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00002295 if (!IsStructuralRedefinition()) {
2296 // First save the old values of the 2 arrays that make up the obsolete methods maps. Then
2297 // allocate the 2 arrays that make up the obsolete methods map. Since the contents of the arrays
2298 // are only modified when all threads (other than the modifying one) are suspended we don't need
2299 // to worry about missing the unsyncronized writes to the array. We do synchronize when setting
2300 // it however, since that can happen at any time.
2301 cur_data->SetOldObsoleteMethods(ext->GetObsoleteMethods());
2302 cur_data->SetOldDexCaches(ext->GetObsoleteDexCaches());
2303 if (!art::mirror::ClassExt::ExtendObsoleteArrays(
2304 ext, driver_->self_, klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize).size())) {
2305 // OOM. Clear exception and return error.
2306 driver_->self_->AssertPendingOOMException();
2307 driver_->self_->ClearException();
2308 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate/extend obsolete methods map");
2309 return false;
2310 }
Alex Lighta01de592016-11-15 10:43:06 -08002311 }
2312 return true;
2313}
2314
2315} // namespace openjdkjvmti