1 /* Copyright (C) 2016 The Android Open Source Project 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This file implements interfaces from the file jvmti.h. This implementation 5 * is licensed under the same terms as the file jvmti.h. The 6 * copyright and license information for the file jvmti.h follows. 7 * 8 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10 * 11 * This code is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License version 2 only, as 13 * published by the Free Software Foundation. Oracle designates this 14 * particular file as subject to the "Classpath" exception as provided 15 * by Oracle in the LICENSE file that accompanied this code. 16 * 17 * This code is distributed in the hope that it will be useful, but WITHOUT 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 * version 2 for more details (a copy is included in the LICENSE file that 21 * accompanied this code). 22 * 23 * You should have received a copy of the GNU General Public License version 24 * 2 along with this work; if not, write to the Free Software Foundation, 25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26 * 27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28 * or visit www.oracle.com if you need additional information or have any 29 * questions. 30 */ 31 32 #include "ti_redefine.h" 33 34 #include <limits> 35 36 #include "android-base/stringprintf.h" 37 38 #include "art_field-inl.h" 39 #include "art_jvmti.h" 40 #include "art_method-inl.h" 41 #include "base/array_ref.h" 42 #include "base/logging.h" 43 #include "base/stringpiece.h" 44 #include "class_linker-inl.h" 45 #include "debugger.h" 46 #include "dex_file.h" 47 #include "dex_file_types.h" 48 #include "events-inl.h" 49 #include "gc/allocation_listener.h" 50 #include "gc/heap.h" 51 #include "instrumentation.h" 52 #include "intern_table.h" 53 #include "jdwp/jdwp.h" 54 #include "jdwp/jdwp_constants.h" 55 #include "jdwp/jdwp_event.h" 56 #include "jdwp/object_registry.h" 57 #include "jit/jit.h" 58 #include "jit/jit_code_cache.h" 59 #include "jni_env_ext-inl.h" 60 #include "jvmti_allocator.h" 61 #include "mirror/class-inl.h" 62 #include "mirror/class_ext.h" 63 #include "mirror/object.h" 64 #include "nativehelper/ScopedLocalRef.h" 65 #include "non_debuggable_classes.h" 66 #include "object_lock.h" 67 #include "runtime.h" 68 #include "ti_breakpoint.h" 69 #include "ti_class_loader.h" 70 #include "transform.h" 71 #include "verifier/method_verifier.h" 72 #include "verifier/verifier_enums.h" 73 74 namespace openjdkjvmti { 75 76 using android::base::StringPrintf; 77 78 // A helper that fills in a classes obsolete_methods_ and obsolete_dex_caches_ classExt fields as 79 // they are created. This ensures that we can always call any method of an obsolete ArtMethod object 80 // almost as soon as they are created since the GetObsoleteDexCache method will succeed. 81 class ObsoleteMap { 82 public: 83 art::ArtMethod* FindObsoleteVersion(art::ArtMethod* original) 84 REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) { 85 auto method_pair = id_map_.find(original); 86 if (method_pair != id_map_.end()) { 87 art::ArtMethod* res = obsolete_methods_->GetElementPtrSize<art::ArtMethod*>( 88 method_pair->second, art::kRuntimePointerSize); 89 DCHECK(res != nullptr); 90 DCHECK_EQ(original, res->GetNonObsoleteMethod()); 91 return res; 92 } else { 93 return nullptr; 94 } 95 } 96 97 void RecordObsolete(art::ArtMethod* original, art::ArtMethod* obsolete) 98 REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) { 99 DCHECK(original != nullptr); 100 DCHECK(obsolete != nullptr); 101 int32_t slot = next_free_slot_++; 102 DCHECK_LT(slot, obsolete_methods_->GetLength()); 103 DCHECK(nullptr == 104 obsolete_methods_->GetElementPtrSize<art::ArtMethod*>(slot, art::kRuntimePointerSize)); 105 DCHECK(nullptr == obsolete_dex_caches_->Get(slot)); 106 obsolete_methods_->SetElementPtrSize(slot, obsolete, art::kRuntimePointerSize); 107 obsolete_dex_caches_->Set(slot, original_dex_cache_); 108 id_map_.insert({original, slot}); 109 } 110 111 ObsoleteMap(art::ObjPtr<art::mirror::PointerArray> obsolete_methods, 112 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> obsolete_dex_caches, 113 art::ObjPtr<art::mirror::DexCache> original_dex_cache) 114 : next_free_slot_(0), 115 obsolete_methods_(obsolete_methods), 116 obsolete_dex_caches_(obsolete_dex_caches), 117 original_dex_cache_(original_dex_cache) { 118 // Figure out where the first unused slot in the obsolete_methods_ array is. 119 while (obsolete_methods_->GetElementPtrSize<art::ArtMethod*>( 120 next_free_slot_, art::kRuntimePointerSize) != nullptr) { 121 DCHECK(obsolete_dex_caches_->Get(next_free_slot_) != nullptr); 122 next_free_slot_++; 123 } 124 // Sanity check that the same slot in obsolete_dex_caches_ is free. 125 DCHECK(obsolete_dex_caches_->Get(next_free_slot_) == nullptr); 126 } 127 128 private: 129 int32_t next_free_slot_; 130 std::unordered_map<art::ArtMethod*, int32_t> id_map_; 131 // Pointers to the fields in mirror::ClassExt. These can be held as ObjPtr since this is only used 132 // when we have an exclusive mutator_lock_ (i.e. all threads are suspended). 133 art::ObjPtr<art::mirror::PointerArray> obsolete_methods_; 134 art::ObjPtr<art::mirror::ObjectArray<art::mirror::DexCache>> obsolete_dex_caches_; 135 art::ObjPtr<art::mirror::DexCache> original_dex_cache_; 136 }; 137 138 // This visitor walks thread stacks and allocates and sets up the obsolete methods. It also does 139 // some basic sanity checks that the obsolete method is sane. 140 class ObsoleteMethodStackVisitor : public art::StackVisitor { 141 protected: 142 ObsoleteMethodStackVisitor( 143 art::Thread* thread, 144 art::LinearAlloc* allocator, 145 const std::unordered_set<art::ArtMethod*>& obsoleted_methods, 146 ObsoleteMap* obsolete_maps) 147 : StackVisitor(thread, 148 /*context*/nullptr, 149 StackVisitor::StackWalkKind::kIncludeInlinedFrames), 150 allocator_(allocator), 151 obsoleted_methods_(obsoleted_methods), 152 obsolete_maps_(obsolete_maps) { } 153 154 ~ObsoleteMethodStackVisitor() OVERRIDE {} 155 156 public: 157 // Returns true if we successfully installed obsolete methods on this thread, filling 158 // obsolete_maps_ with the translations if needed. Returns false and fills error_msg if we fail. 159 // The stack is cleaned up when we fail. 160 static void UpdateObsoleteFrames( 161 art::Thread* thread, 162 art::LinearAlloc* allocator, 163 const std::unordered_set<art::ArtMethod*>& obsoleted_methods, 164 ObsoleteMap* obsolete_maps) 165 REQUIRES(art::Locks::mutator_lock_) { 166 ObsoleteMethodStackVisitor visitor(thread, 167 allocator, 168 obsoleted_methods, 169 obsolete_maps); 170 visitor.WalkStack(); 171 } 172 173 bool VisitFrame() OVERRIDE REQUIRES(art::Locks::mutator_lock_) { 174 art::ScopedAssertNoThreadSuspension snts("Fixing up the stack for obsolete methods."); 175 art::ArtMethod* old_method = GetMethod(); 176 if (obsoleted_methods_.find(old_method) != obsoleted_methods_.end()) { 177 // We cannot ensure that the right dex file is used in inlined frames so we don't support 178 // redefining them. 179 DCHECK(!IsInInlinedFrame()) << "Inlined frames are not supported when using redefinition"; 180 art::ArtMethod* new_obsolete_method = obsolete_maps_->FindObsoleteVersion(old_method); 181 if (new_obsolete_method == nullptr) { 182 // Create a new Obsolete Method and put it in the list. 183 art::Runtime* runtime = art::Runtime::Current(); 184 art::ClassLinker* cl = runtime->GetClassLinker(); 185 auto ptr_size = cl->GetImagePointerSize(); 186 const size_t method_size = art::ArtMethod::Size(ptr_size); 187 auto* method_storage = allocator_->Alloc(art::Thread::Current(), method_size); 188 CHECK(method_storage != nullptr) << "Unable to allocate storage for obsolete version of '" 189 << old_method->PrettyMethod() << "'"; 190 new_obsolete_method = new (method_storage) art::ArtMethod(); 191 new_obsolete_method->CopyFrom(old_method, ptr_size); 192 DCHECK_EQ(new_obsolete_method->GetDeclaringClass(), old_method->GetDeclaringClass()); 193 new_obsolete_method->SetIsObsolete(); 194 new_obsolete_method->SetDontCompile(); 195 cl->SetEntryPointsForObsoleteMethod(new_obsolete_method); 196 obsolete_maps_->RecordObsolete(old_method, new_obsolete_method); 197 // Update JIT Data structures to point to the new method. 198 art::jit::Jit* jit = art::Runtime::Current()->GetJit(); 199 if (jit != nullptr) { 200 // Notify the JIT we are making this obsolete method. It will update the jit's internal 201 // structures to keep track of the new obsolete method. 202 jit->GetCodeCache()->MoveObsoleteMethod(old_method, new_obsolete_method); 203 } 204 } 205 DCHECK(new_obsolete_method != nullptr); 206 SetMethod(new_obsolete_method); 207 } 208 return true; 209 } 210 211 private: 212 // The linear allocator we should use to make new methods. 213 art::LinearAlloc* allocator_; 214 // The set of all methods which could be obsoleted. 215 const std::unordered_set<art::ArtMethod*>& obsoleted_methods_; 216 // A map from the original to the newly allocated obsolete method for frames on this thread. The 217 // values in this map are added to the obsolete_methods_ (and obsolete_dex_caches_) fields of 218 // the redefined classes ClassExt as it is filled. 219 ObsoleteMap* obsolete_maps_; 220 }; 221 222 jvmtiError Redefiner::IsModifiableClass(jvmtiEnv* env ATTRIBUTE_UNUSED, 223 jclass klass, 224 jboolean* is_redefinable) { 225 art::Thread* self = art::Thread::Current(); 226 art::ScopedObjectAccess soa(self); 227 art::StackHandleScope<1> hs(self); 228 art::ObjPtr<art::mirror::Object> obj(self->DecodeJObject(klass)); 229 if (obj.IsNull()) { 230 return ERR(INVALID_CLASS); 231 } 232 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(obj->AsClass())); 233 std::string err_unused; 234 *is_redefinable = 235 Redefiner::GetClassRedefinitionError(h_klass, &err_unused) == OK ? JNI_TRUE : JNI_FALSE; 236 return OK; 237 } 238 239 jvmtiError Redefiner::GetClassRedefinitionError(art::Handle<art::mirror::Class> klass, 240 /*out*/std::string* error_msg) { 241 if (klass->IsPrimitive()) { 242 *error_msg = "Modification of primitive classes is not supported"; 243 return ERR(UNMODIFIABLE_CLASS); 244 } else if (klass->IsInterface()) { 245 *error_msg = "Modification of Interface classes is currently not supported"; 246 return ERR(UNMODIFIABLE_CLASS); 247 } else if (klass->IsStringClass()) { 248 *error_msg = "Modification of String class is not supported"; 249 return ERR(UNMODIFIABLE_CLASS); 250 } else if (klass->IsArrayClass()) { 251 *error_msg = "Modification of Array classes is not supported"; 252 return ERR(UNMODIFIABLE_CLASS); 253 } else if (klass->IsProxyClass()) { 254 *error_msg = "Modification of proxy classes is not supported"; 255 return ERR(UNMODIFIABLE_CLASS); 256 } 257 258 for (jclass c : art::NonDebuggableClasses::GetNonDebuggableClasses()) { 259 if (klass.Get() == art::Thread::Current()->DecodeJObject(c)->AsClass()) { 260 *error_msg = "Class might have stack frames that cannot be made obsolete"; 261 return ERR(UNMODIFIABLE_CLASS); 262 } 263 } 264 265 return OK; 266 } 267 268 // Moves dex data to an anonymous, read-only mmap'd region. 269 std::unique_ptr<art::MemMap> Redefiner::MoveDataToMemMap(const std::string& original_location, 270 art::ArrayRef<const unsigned char> data, 271 std::string* error_msg) { 272 std::unique_ptr<art::MemMap> map(art::MemMap::MapAnonymous( 273 StringPrintf("%s-transformed", original_location.c_str()).c_str(), 274 nullptr, 275 data.size(), 276 PROT_READ|PROT_WRITE, 277 /*low_4gb*/false, 278 /*reuse*/false, 279 error_msg)); 280 if (map == nullptr) { 281 return map; 282 } 283 memcpy(map->Begin(), data.data(), data.size()); 284 // Make the dex files mmap read only. This matches how other DexFiles are mmaped and prevents 285 // programs from corrupting it. 286 map->Protect(PROT_READ); 287 return map; 288 } 289 290 Redefiner::ClassRedefinition::ClassRedefinition( 291 Redefiner* driver, 292 jclass klass, 293 const art::DexFile* redefined_dex_file, 294 const char* class_sig, 295 art::ArrayRef<const unsigned char> orig_dex_file) : 296 driver_(driver), 297 klass_(klass), 298 dex_file_(redefined_dex_file), 299 class_sig_(class_sig), 300 original_dex_file_(orig_dex_file) { 301 GetMirrorClass()->MonitorEnter(driver_->self_); 302 } 303 304 Redefiner::ClassRedefinition::~ClassRedefinition() { 305 if (driver_ != nullptr) { 306 GetMirrorClass()->MonitorExit(driver_->self_); 307 } 308 } 309 310 jvmtiError Redefiner::RedefineClasses(ArtJvmTiEnv* env, 311 EventHandler* event_handler, 312 art::Runtime* runtime, 313 art::Thread* self, 314 jint class_count, 315 const jvmtiClassDefinition* definitions, 316 /*out*/std::string* error_msg) { 317 if (env == nullptr) { 318 *error_msg = "env was null!"; 319 return ERR(INVALID_ENVIRONMENT); 320 } else if (class_count < 0) { 321 *error_msg = "class_count was less then 0"; 322 return ERR(ILLEGAL_ARGUMENT); 323 } else if (class_count == 0) { 324 // We don't actually need to do anything. Just return OK. 325 return OK; 326 } else if (definitions == nullptr) { 327 *error_msg = "null definitions!"; 328 return ERR(NULL_POINTER); 329 } 330 std::vector<ArtClassDefinition> def_vector; 331 def_vector.reserve(class_count); 332 for (jint i = 0; i < class_count; i++) { 333 jboolean is_modifiable = JNI_FALSE; 334 jvmtiError res = env->IsModifiableClass(definitions[i].klass, &is_modifiable); 335 if (res != OK) { 336 return res; 337 } else if (!is_modifiable) { 338 return ERR(UNMODIFIABLE_CLASS); 339 } 340 // We make a copy of the class_bytes to pass into the retransformation. 341 // This makes cleanup easier (since we unambiguously own the bytes) and also is useful since we 342 // will need to keep the original bytes around unaltered for subsequent RetransformClasses calls 343 // to get the passed in bytes. 344 unsigned char* class_bytes_copy = nullptr; 345 res = env->Allocate(definitions[i].class_byte_count, &class_bytes_copy); 346 if (res != OK) { 347 return res; 348 } 349 memcpy(class_bytes_copy, definitions[i].class_bytes, definitions[i].class_byte_count); 350 351 ArtClassDefinition def; 352 res = def.Init(env, definitions[i]); 353 if (res != OK) { 354 return res; 355 } 356 def_vector.push_back(std::move(def)); 357 } 358 // Call all the transformation events. 359 jvmtiError res = Transformer::RetransformClassesDirect(env, 360 event_handler, 361 self, 362 &def_vector); 363 if (res != OK) { 364 // Something went wrong with transformation! 365 return res; 366 } 367 return RedefineClassesDirect(env, runtime, self, def_vector, error_msg); 368 } 369 370 jvmtiError Redefiner::RedefineClassesDirect(ArtJvmTiEnv* env, 371 art::Runtime* runtime, 372 art::Thread* self, 373 const std::vector<ArtClassDefinition>& definitions, 374 std::string* error_msg) { 375 DCHECK(env != nullptr); 376 if (definitions.size() == 0) { 377 // We don't actually need to do anything. Just return OK. 378 return OK; 379 } 380 // Stop JIT for the duration of this redefine since the JIT might concurrently compile a method we 381 // are going to redefine. 382 art::jit::ScopedJitSuspend suspend_jit; 383 // Get shared mutator lock so we can lock all the classes. 384 art::ScopedObjectAccess soa(self); 385 Redefiner r(env, runtime, self, error_msg); 386 for (const ArtClassDefinition& def : definitions) { 387 // Only try to transform classes that have been modified. 388 if (def.IsModified()) { 389 jvmtiError res = r.AddRedefinition(env, def); 390 if (res != OK) { 391 return res; 392 } 393 } 394 } 395 return r.Run(); 396 } 397 398 jvmtiError Redefiner::AddRedefinition(ArtJvmTiEnv* env, const ArtClassDefinition& def) { 399 std::string original_dex_location; 400 jvmtiError ret = OK; 401 if ((ret = GetClassLocation(env, def.GetClass(), &original_dex_location))) { 402 *error_msg_ = "Unable to get original dex file location!"; 403 return ret; 404 } 405 char* generic_ptr_unused = nullptr; 406 char* signature_ptr = nullptr; 407 if ((ret = env->GetClassSignature(def.GetClass(), &signature_ptr, &generic_ptr_unused)) != OK) { 408 *error_msg_ = "Unable to get class signature!"; 409 return ret; 410 } 411 JvmtiUniquePtr<char> generic_unique_ptr(MakeJvmtiUniquePtr(env, generic_ptr_unused)); 412 JvmtiUniquePtr<char> signature_unique_ptr(MakeJvmtiUniquePtr(env, signature_ptr)); 413 std::unique_ptr<art::MemMap> map(MoveDataToMemMap(original_dex_location, 414 def.GetDexData(), 415 error_msg_)); 416 std::ostringstream os; 417 if (map.get() == nullptr) { 418 os << "Failed to create anonymous mmap for modified dex file of class " << def.GetName() 419 << "in dex file " << original_dex_location << " because: " << *error_msg_; 420 *error_msg_ = os.str(); 421 return ERR(OUT_OF_MEMORY); 422 } 423 if (map->Size() < sizeof(art::DexFile::Header)) { 424 *error_msg_ = "Could not read dex file header because dex_data was too short"; 425 return ERR(INVALID_CLASS_FORMAT); 426 } 427 uint32_t checksum = reinterpret_cast<const art::DexFile::Header*>(map->Begin())->checksum_; 428 std::unique_ptr<const art::DexFile> dex_file(art::DexFile::Open(map->GetName(), 429 checksum, 430 std::move(map), 431 /*verify*/true, 432 /*verify_checksum*/true, 433 error_msg_)); 434 if (dex_file.get() == nullptr) { 435 os << "Unable to load modified dex file for " << def.GetName() << ": " << *error_msg_; 436 *error_msg_ = os.str(); 437 return ERR(INVALID_CLASS_FORMAT); 438 } 439 redefinitions_.push_back( 440 Redefiner::ClassRedefinition(this, 441 def.GetClass(), 442 dex_file.release(), 443 signature_ptr, 444 def.GetNewOriginalDexFile())); 445 return OK; 446 } 447 448 art::mirror::Class* Redefiner::ClassRedefinition::GetMirrorClass() { 449 return driver_->self_->DecodeJObject(klass_)->AsClass(); 450 } 451 452 art::mirror::ClassLoader* Redefiner::ClassRedefinition::GetClassLoader() { 453 return GetMirrorClass()->GetClassLoader(); 454 } 455 456 art::mirror::DexCache* Redefiner::ClassRedefinition::CreateNewDexCache( 457 art::Handle<art::mirror::ClassLoader> loader) { 458 art::StackHandleScope<2> hs(driver_->self_); 459 art::ClassLinker* cl = driver_->runtime_->GetClassLinker(); 460 art::Handle<art::mirror::DexCache> cache(hs.NewHandle( 461 art::ObjPtr<art::mirror::DexCache>::DownCast( 462 cl->GetClassRoot(art::ClassLinker::kJavaLangDexCache)->AllocObject(driver_->self_)))); 463 if (cache.IsNull()) { 464 driver_->self_->AssertPendingOOMException(); 465 return nullptr; 466 } 467 art::Handle<art::mirror::String> location(hs.NewHandle( 468 cl->GetInternTable()->InternStrong(dex_file_->GetLocation().c_str()))); 469 if (location.IsNull()) { 470 driver_->self_->AssertPendingOOMException(); 471 return nullptr; 472 } 473 art::WriterMutexLock mu(driver_->self_, *art::Locks::dex_lock_); 474 art::mirror::DexCache::InitializeDexCache(driver_->self_, 475 cache.Get(), 476 location.Get(), 477 dex_file_.get(), 478 loader.IsNull() ? driver_->runtime_->GetLinearAlloc() 479 : loader->GetAllocator(), 480 art::kRuntimePointerSize); 481 return cache.Get(); 482 } 483 484 void Redefiner::RecordFailure(jvmtiError result, 485 const std::string& class_sig, 486 const std::string& error_msg) { 487 *error_msg_ = StringPrintf("Unable to perform redefinition of '%s': %s", 488 class_sig.c_str(), 489 error_msg.c_str()); 490 result_ = result; 491 } 492 493 art::mirror::Object* Redefiner::ClassRedefinition::AllocateOrGetOriginalDexFile() { 494 // If we have been specifically given a new set of bytes use that 495 if (original_dex_file_.size() != 0) { 496 return art::mirror::ByteArray::AllocateAndFill( 497 driver_->self_, 498 reinterpret_cast<const signed char*>(original_dex_file_.data()), 499 original_dex_file_.size()); 500 } 501 502 // See if we already have one set. 503 art::ObjPtr<art::mirror::ClassExt> ext(GetMirrorClass()->GetExtData()); 504 if (!ext.IsNull()) { 505 art::ObjPtr<art::mirror::Object> old_original_dex_file(ext->GetOriginalDexFile()); 506 if (!old_original_dex_file.IsNull()) { 507 // We do. Use it. 508 return old_original_dex_file.Ptr(); 509 } 510 } 511 512 // return the current dex_cache which has the dex file in it. 513 art::ObjPtr<art::mirror::DexCache> current_dex_cache(GetMirrorClass()->GetDexCache()); 514 // TODO Handle this or make it so it cannot happen. 515 if (current_dex_cache->GetDexFile()->NumClassDefs() != 1) { 516 LOG(WARNING) << "Current dex file has more than one class in it. Calling RetransformClasses " 517 << "on this class might fail if no transformations are applied to it!"; 518 } 519 return current_dex_cache.Ptr(); 520 } 521 522 struct CallbackCtx { 523 ObsoleteMap* obsolete_map; 524 art::LinearAlloc* allocator; 525 std::unordered_set<art::ArtMethod*> obsolete_methods; 526 527 explicit CallbackCtx(ObsoleteMap* map, art::LinearAlloc* alloc) 528 : obsolete_map(map), allocator(alloc) {} 529 }; 530 531 void DoAllocateObsoleteMethodsCallback(art::Thread* t, void* vdata) NO_THREAD_SAFETY_ANALYSIS { 532 CallbackCtx* data = reinterpret_cast<CallbackCtx*>(vdata); 533 ObsoleteMethodStackVisitor::UpdateObsoleteFrames(t, 534 data->allocator, 535 data->obsolete_methods, 536 data->obsolete_map); 537 } 538 539 // This creates any ArtMethod* structures needed for obsolete methods and ensures that the stack is 540 // updated so they will be run. 541 // TODO Rewrite so we can do this only once regardless of how many redefinitions there are. 542 void Redefiner::ClassRedefinition::FindAndAllocateObsoleteMethods(art::mirror::Class* art_klass) { 543 art::ScopedAssertNoThreadSuspension ns("No thread suspension during thread stack walking"); 544 art::mirror::ClassExt* ext = art_klass->GetExtData(); 545 CHECK(ext->GetObsoleteMethods() != nullptr); 546 art::ClassLinker* linker = driver_->runtime_->GetClassLinker(); 547 // This holds pointers to the obsolete methods map fields which are updated as needed. 548 ObsoleteMap map(ext->GetObsoleteMethods(), ext->GetObsoleteDexCaches(), art_klass->GetDexCache()); 549 CallbackCtx ctx(&map, linker->GetAllocatorForClassLoader(art_klass->GetClassLoader())); 550 // Add all the declared methods to the map 551 for (auto& m : art_klass->GetDeclaredMethods(art::kRuntimePointerSize)) { 552 if (m.IsIntrinsic()) { 553 LOG(WARNING) << "Redefining intrinsic method " << m.PrettyMethod() << ". This may cause the " 554 << "unexpected use of the original definition of " << m.PrettyMethod() << "in " 555 << "methods that have already been compiled."; 556 } 557 // It is possible to simply filter out some methods where they cannot really become obsolete, 558 // such as native methods and keep their original (possibly optimized) implementations. We don't 559 // do this, however, since we would need to mark these functions (still in the classes 560 // declared_methods array) as obsolete so we will find the correct dex file to get meta-data 561 // from (for example about stack-frame size). Furthermore we would be unable to get some useful 562 // error checking from the interpreter which ensure we don't try to start executing obsolete 563 // methods. 564 ctx.obsolete_methods.insert(&m); 565 } 566 { 567 art::MutexLock mu(driver_->self_, *art::Locks::thread_list_lock_); 568 art::ThreadList* list = art::Runtime::Current()->GetThreadList(); 569 list->ForEach(DoAllocateObsoleteMethodsCallback, static_cast<void*>(&ctx)); 570 } 571 } 572 573 // Try and get the declared method. First try to get a virtual method then a direct method if that's 574 // not found. 575 static art::ArtMethod* FindMethod(art::Handle<art::mirror::Class> klass, 576 art::StringPiece name, 577 art::Signature sig) REQUIRES_SHARED(art::Locks::mutator_lock_) { 578 DCHECK(!klass->IsProxyClass()); 579 for (art::ArtMethod& m : klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize)) { 580 if (m.GetName() == name && m.GetSignature() == sig) { 581 return &m; 582 } 583 } 584 return nullptr; 585 } 586 587 bool Redefiner::ClassRedefinition::CheckSameMethods() { 588 art::StackHandleScope<1> hs(driver_->self_); 589 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass())); 590 DCHECK_EQ(dex_file_->NumClassDefs(), 1u); 591 592 art::ClassDataItemIterator new_iter(*dex_file_, 593 dex_file_->GetClassData(dex_file_->GetClassDef(0))); 594 595 // Make sure we have the same number of methods. 596 uint32_t num_new_method = new_iter.NumVirtualMethods() + new_iter.NumDirectMethods(); 597 uint32_t num_old_method = h_klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize).size(); 598 if (num_new_method != num_old_method) { 599 bool bigger = num_new_method > num_old_method; 600 RecordFailure(bigger ? ERR(UNSUPPORTED_REDEFINITION_METHOD_ADDED) 601 : ERR(UNSUPPORTED_REDEFINITION_METHOD_DELETED), 602 StringPrintf("Total number of declared methods changed from %d to %d", 603 num_old_method, num_new_method)); 604 return false; 605 } 606 607 // Skip all of the fields. We should have already checked this. 608 new_iter.SkipAllFields(); 609 // Check each of the methods. NB we don't need to specifically check for removals since the 2 dex 610 // files have the same number of methods, which means there must be an equal amount of additions 611 // and removals. 612 for (; new_iter.HasNextVirtualMethod() || new_iter.HasNextDirectMethod(); new_iter.Next()) { 613 // Get the data on the method we are searching for 614 const art::DexFile::MethodId& new_method_id = dex_file_->GetMethodId(new_iter.GetMemberIndex()); 615 const char* new_method_name = dex_file_->GetMethodName(new_method_id); 616 art::Signature new_method_signature = dex_file_->GetMethodSignature(new_method_id); 617 art::ArtMethod* old_method = FindMethod(h_klass, new_method_name, new_method_signature); 618 // If we got past the check for the same number of methods above that means there must be at 619 // least one added and one removed method. We will return the ADDED failure message since it is 620 // easier to get a useful error report for it. 621 if (old_method == nullptr) { 622 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_METHOD_ADDED), 623 StringPrintf("Unknown method '%s' (sig: %s) was added!", 624 new_method_name, 625 new_method_signature.ToString().c_str())); 626 return false; 627 } 628 // Since direct methods have different flags than virtual ones (specifically direct methods must 629 // have kAccPrivate or kAccStatic or kAccConstructor flags) we can tell if a method changes from 630 // virtual to direct. 631 uint32_t new_flags = new_iter.GetMethodAccessFlags() & ~art::kAccPreviouslyWarm; 632 if (new_flags != (old_method->GetAccessFlags() & (art::kAccValidMethodFlags ^ art::kAccPreviouslyWarm))) { 633 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED), 634 StringPrintf("method '%s' (sig: %s) had different access flags", 635 new_method_name, 636 new_method_signature.ToString().c_str())); 637 return false; 638 } 639 } 640 return true; 641 } 642 643 bool Redefiner::ClassRedefinition::CheckSameFields() { 644 art::StackHandleScope<1> hs(driver_->self_); 645 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass())); 646 DCHECK_EQ(dex_file_->NumClassDefs(), 1u); 647 art::ClassDataItemIterator new_iter(*dex_file_, 648 dex_file_->GetClassData(dex_file_->GetClassDef(0))); 649 const art::DexFile& old_dex_file = h_klass->GetDexFile(); 650 art::ClassDataItemIterator old_iter(old_dex_file, 651 old_dex_file.GetClassData(*h_klass->GetClassDef())); 652 // Instance and static fields can be differentiated by their flags so no need to check them 653 // separately. 654 while (new_iter.HasNextInstanceField() || new_iter.HasNextStaticField()) { 655 // Get the data on the method we are searching for 656 const art::DexFile::FieldId& new_field_id = dex_file_->GetFieldId(new_iter.GetMemberIndex()); 657 const char* new_field_name = dex_file_->GetFieldName(new_field_id); 658 const char* new_field_type = dex_file_->GetFieldTypeDescriptor(new_field_id); 659 660 if (!(old_iter.HasNextInstanceField() || old_iter.HasNextStaticField())) { 661 // We are missing the old version of this method! 662 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED), 663 StringPrintf("Unknown field '%s' (type: %s) added!", 664 new_field_name, 665 new_field_type)); 666 return false; 667 } 668 669 const art::DexFile::FieldId& old_field_id = old_dex_file.GetFieldId(old_iter.GetMemberIndex()); 670 const char* old_field_name = old_dex_file.GetFieldName(old_field_id); 671 const char* old_field_type = old_dex_file.GetFieldTypeDescriptor(old_field_id); 672 673 // Check name and type. 674 if (strcmp(old_field_name, new_field_name) != 0 || 675 strcmp(old_field_type, new_field_type) != 0) { 676 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED), 677 StringPrintf("Field changed from '%s' (sig: %s) to '%s' (sig: %s)!", 678 old_field_name, 679 old_field_type, 680 new_field_name, 681 new_field_type)); 682 return false; 683 } 684 685 // Since static fields have different flags than instance ones (specifically static fields must 686 // have the kAccStatic flag) we can tell if a field changes from static to instance. 687 if (new_iter.GetFieldAccessFlags() != old_iter.GetFieldAccessFlags()) { 688 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED), 689 StringPrintf("Field '%s' (sig: %s) had different access flags", 690 new_field_name, 691 new_field_type)); 692 return false; 693 } 694 695 new_iter.Next(); 696 old_iter.Next(); 697 } 698 if (old_iter.HasNextInstanceField() || old_iter.HasNextStaticField()) { 699 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED), 700 StringPrintf("field '%s' (sig: %s) is missing!", 701 old_dex_file.GetFieldName(old_dex_file.GetFieldId( 702 old_iter.GetMemberIndex())), 703 old_dex_file.GetFieldTypeDescriptor(old_dex_file.GetFieldId( 704 old_iter.GetMemberIndex())))); 705 return false; 706 } 707 return true; 708 } 709 710 bool Redefiner::ClassRedefinition::CheckClass() { 711 art::StackHandleScope<1> hs(driver_->self_); 712 // Easy check that only 1 class def is present. 713 if (dex_file_->NumClassDefs() != 1) { 714 RecordFailure(ERR(ILLEGAL_ARGUMENT), 715 StringPrintf("Expected 1 class def in dex file but found %d", 716 dex_file_->NumClassDefs())); 717 return false; 718 } 719 // Get the ClassDef from the new DexFile. 720 // Since the dex file has only a single class def the index is always 0. 721 const art::DexFile::ClassDef& def = dex_file_->GetClassDef(0); 722 // Get the class as it is now. 723 art::Handle<art::mirror::Class> current_class(hs.NewHandle(GetMirrorClass())); 724 725 // Check the access flags didn't change. 726 if (def.GetJavaAccessFlags() != (current_class->GetAccessFlags() & art::kAccValidClassFlags)) { 727 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED), 728 "Cannot change modifiers of class by redefinition"); 729 return false; 730 } 731 732 // Check class name. 733 // These should have been checked by the dexfile verifier on load. 734 DCHECK_NE(def.class_idx_, art::dex::TypeIndex::Invalid()) << "Invalid type index"; 735 const char* descriptor = dex_file_->StringByTypeIdx(def.class_idx_); 736 DCHECK(descriptor != nullptr) << "Invalid dex file structure!"; 737 if (!current_class->DescriptorEquals(descriptor)) { 738 std::string storage; 739 RecordFailure(ERR(NAMES_DONT_MATCH), 740 StringPrintf("expected file to contain class called '%s' but found '%s'!", 741 current_class->GetDescriptor(&storage), 742 descriptor)); 743 return false; 744 } 745 if (current_class->IsObjectClass()) { 746 if (def.superclass_idx_ != art::dex::TypeIndex::Invalid()) { 747 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Superclass added!"); 748 return false; 749 } 750 } else { 751 const char* super_descriptor = dex_file_->StringByTypeIdx(def.superclass_idx_); 752 DCHECK(descriptor != nullptr) << "Invalid dex file structure!"; 753 if (!current_class->GetSuperClass()->DescriptorEquals(super_descriptor)) { 754 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Superclass changed"); 755 return false; 756 } 757 } 758 const art::DexFile::TypeList* interfaces = dex_file_->GetInterfacesList(def); 759 if (interfaces == nullptr) { 760 if (current_class->NumDirectInterfaces() != 0) { 761 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Interfaces added"); 762 return false; 763 } 764 } else { 765 DCHECK(!current_class->IsProxyClass()); 766 const art::DexFile::TypeList* current_interfaces = current_class->GetInterfaceTypeList(); 767 if (current_interfaces == nullptr || current_interfaces->Size() != interfaces->Size()) { 768 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), "Interfaces added or removed"); 769 return false; 770 } 771 // The order of interfaces is (barely) meaningful so we error if it changes. 772 const art::DexFile& orig_dex_file = current_class->GetDexFile(); 773 for (uint32_t i = 0; i < interfaces->Size(); i++) { 774 if (strcmp( 775 dex_file_->StringByTypeIdx(interfaces->GetTypeItem(i).type_idx_), 776 orig_dex_file.StringByTypeIdx(current_interfaces->GetTypeItem(i).type_idx_)) != 0) { 777 RecordFailure(ERR(UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED), 778 "Interfaces changed or re-ordered"); 779 return false; 780 } 781 } 782 } 783 return true; 784 } 785 786 bool Redefiner::ClassRedefinition::CheckRedefinable() { 787 std::string err; 788 art::StackHandleScope<1> hs(driver_->self_); 789 790 art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass())); 791 jvmtiError res = Redefiner::GetClassRedefinitionError(h_klass, &err); 792 if (res != OK) { 793 RecordFailure(res, err); 794 return false; 795 } else { 796 return true; 797 } 798 } 799 800 bool Redefiner::ClassRedefinition::CheckRedefinitionIsValid() { 801 return CheckRedefinable() && 802 CheckClass() && 803 CheckSameFields() && 804 CheckSameMethods(); 805 } 806 807 class RedefinitionDataIter; 808 809 // A wrapper that lets us hold onto the arbitrary sized data needed for redefinitions in a 810 // reasonably sane way. This adds no fields to the normal ObjectArray. By doing this we can avoid 811 // having to deal with the fact that we need to hold an arbitrary number of references live. 812 class RedefinitionDataHolder { 813 public: 814 enum DataSlot : int32_t { 815 kSlotSourceClassLoader = 0, 816 kSlotJavaDexFile = 1, 817 kSlotNewDexFileCookie = 2, 818 kSlotNewDexCache = 3, 819 kSlotMirrorClass = 4, 820 kSlotOrigDexFile = 5, 821 kSlotOldObsoleteMethods = 6, 822 kSlotOldDexCaches = 7, 823 824 // Must be last one. 825 kNumSlots = 8, 826 }; 827 828 // This needs to have a HandleScope passed in that is capable of creating a new Handle without 829 // overflowing. Only one handle will be created. This object has a lifetime identical to that of 830 // the passed in handle-scope. 831 RedefinitionDataHolder(art::StackHandleScope<1>* hs, 832 art::Runtime* runtime, 833 art::Thread* self, 834 std::vector<Redefiner::ClassRedefinition>* redefinitions) 835 REQUIRES_SHARED(art::Locks::mutator_lock_) : 836 arr_( 837 hs->NewHandle( 838 art::mirror::ObjectArray<art::mirror::Object>::Alloc( 839 self, 840 runtime->GetClassLinker()->GetClassRoot(art::ClassLinker::kObjectArrayClass), 841 redefinitions->size() * kNumSlots))), 842 redefinitions_(redefinitions) {} 843 844 bool IsNull() const REQUIRES_SHARED(art::Locks::mutator_lock_) { 845 return arr_.IsNull(); 846 } 847 848 art::mirror::ClassLoader* GetSourceClassLoader(jint klass_index) const 849 REQUIRES_SHARED(art::Locks::mutator_lock_) { 850 return art::down_cast<art::mirror::ClassLoader*>(GetSlot(klass_index, kSlotSourceClassLoader)); 851 } 852 art::mirror::Object* GetJavaDexFile(jint klass_index) const 853 REQUIRES_SHARED(art::Locks::mutator_lock_) { 854 return GetSlot(klass_index, kSlotJavaDexFile); 855 } 856 art::mirror::LongArray* GetNewDexFileCookie(jint klass_index) const 857 REQUIRES_SHARED(art::Locks::mutator_lock_) { 858 return art::down_cast<art::mirror::LongArray*>(GetSlot(klass_index, kSlotNewDexFileCookie)); 859 } 860 art::mirror::DexCache* GetNewDexCache(jint klass_index) const 861 REQUIRES_SHARED(art::Locks::mutator_lock_) { 862 return art::down_cast<art::mirror::DexCache*>(GetSlot(klass_index, kSlotNewDexCache)); 863 } 864 art::mirror::Class* GetMirrorClass(jint klass_index) const 865 REQUIRES_SHARED(art::Locks::mutator_lock_) { 866 return art::down_cast<art::mirror::Class*>(GetSlot(klass_index, kSlotMirrorClass)); 867 } 868 869 art::mirror::Object* GetOriginalDexFile(jint klass_index) const 870 REQUIRES_SHARED(art::Locks::mutator_lock_) { 871 return art::down_cast<art::mirror::Object*>(GetSlot(klass_index, kSlotOrigDexFile)); 872 } 873 874 art::mirror::PointerArray* GetOldObsoleteMethods(jint klass_index) const 875 REQUIRES_SHARED(art::Locks::mutator_lock_) { 876 return art::down_cast<art::mirror::PointerArray*>( 877 GetSlot(klass_index, kSlotOldObsoleteMethods)); 878 } 879 880 art::mirror::ObjectArray<art::mirror::DexCache>* GetOldDexCaches(jint klass_index) const 881 REQUIRES_SHARED(art::Locks::mutator_lock_) { 882 return art::down_cast<art::mirror::ObjectArray<art::mirror::DexCache>*>( 883 GetSlot(klass_index, kSlotOldDexCaches)); 884 } 885 886 void SetSourceClassLoader(jint klass_index, art::mirror::ClassLoader* loader) 887 REQUIRES_SHARED(art::Locks::mutator_lock_) { 888 SetSlot(klass_index, kSlotSourceClassLoader, loader); 889 } 890 void SetJavaDexFile(jint klass_index, art::mirror::Object* dexfile) 891 REQUIRES_SHARED(art::Locks::mutator_lock_) { 892 SetSlot(klass_index, kSlotJavaDexFile, dexfile); 893 } 894 void SetNewDexFileCookie(jint klass_index, art::mirror::LongArray* cookie) 895 REQUIRES_SHARED(art::Locks::mutator_lock_) { 896 SetSlot(klass_index, kSlotNewDexFileCookie, cookie); 897 } 898 void SetNewDexCache(jint klass_index, art::mirror::DexCache* cache) 899 REQUIRES_SHARED(art::Locks::mutator_lock_) { 900 SetSlot(klass_index, kSlotNewDexCache, cache); 901 } 902 void SetMirrorClass(jint klass_index, art::mirror::Class* klass) 903 REQUIRES_SHARED(art::Locks::mutator_lock_) { 904 SetSlot(klass_index, kSlotMirrorClass, klass); 905 } 906 void SetOriginalDexFile(jint klass_index, art::mirror::Object* bytes) 907 REQUIRES_SHARED(art::Locks::mutator_lock_) { 908 SetSlot(klass_index, kSlotOrigDexFile, bytes); 909 } 910 void SetOldObsoleteMethods(jint klass_index, art::mirror::PointerArray* methods) 911 REQUIRES_SHARED(art::Locks::mutator_lock_) { 912 SetSlot(klass_index, kSlotOldObsoleteMethods, methods); 913 } 914 void SetOldDexCaches(jint klass_index, art::mirror::ObjectArray<art::mirror::DexCache>* caches) 915 REQUIRES_SHARED(art::Locks::mutator_lock_) { 916 SetSlot(klass_index, kSlotOldDexCaches, caches); 917 } 918 919 int32_t Length() const REQUIRES_SHARED(art::Locks::mutator_lock_) { 920 return arr_->GetLength() / kNumSlots; 921 } 922 923 std::vector<Redefiner::ClassRedefinition>* GetRedefinitions() 924 REQUIRES_SHARED(art::Locks::mutator_lock_) { 925 return redefinitions_; 926 } 927 928 bool operator==(const RedefinitionDataHolder& other) const 929 REQUIRES_SHARED(art::Locks::mutator_lock_) { 930 return arr_.Get() == other.arr_.Get(); 931 } 932 933 bool operator!=(const RedefinitionDataHolder& other) const 934 REQUIRES_SHARED(art::Locks::mutator_lock_) { 935 return !(*this == other); 936 } 937 938 RedefinitionDataIter begin() REQUIRES_SHARED(art::Locks::mutator_lock_); 939 RedefinitionDataIter end() REQUIRES_SHARED(art::Locks::mutator_lock_); 940 941 private: 942 mutable art::Handle<art::mirror::ObjectArray<art::mirror::Object>> arr_; 943 std::vector<Redefiner::ClassRedefinition>* redefinitions_; 944 945 art::mirror::Object* GetSlot(jint klass_index, 946 DataSlot slot) const REQUIRES_SHARED(art::Locks::mutator_lock_) { 947 DCHECK_LT(klass_index, Length()); 948 return arr_->Get((kNumSlots * klass_index) + slot); 949 } 950 951 void SetSlot(jint klass_index, 952 DataSlot slot, 953 art::ObjPtr<art::mirror::Object> obj) REQUIRES_SHARED(art::Locks::mutator_lock_) { 954 DCHECK(!art::Runtime::Current()->IsActiveTransaction()); 955 DCHECK_LT(klass_index, Length()); 956 arr_->Set<false>((kNumSlots * klass_index) + slot, obj); 957 } 958 959 DISALLOW_COPY_AND_ASSIGN(RedefinitionDataHolder); 960 }; 961 962 class RedefinitionDataIter { 963 public: 964 RedefinitionDataIter(int32_t idx, RedefinitionDataHolder& holder) : idx_(idx), holder_(holder) {} 965 966 RedefinitionDataIter(const RedefinitionDataIter&) = default; 967 RedefinitionDataIter(RedefinitionDataIter&&) = default; 968 RedefinitionDataIter& operator=(const RedefinitionDataIter&) = default; 969 RedefinitionDataIter& operator=(RedefinitionDataIter&&) = default; 970 971 bool operator==(const RedefinitionDataIter& other) const 972 REQUIRES_SHARED(art::Locks::mutator_lock_) { 973 return idx_ == other.idx_ && holder_ == other.holder_; 974 } 975 976 bool operator!=(const RedefinitionDataIter& other) const 977 REQUIRES_SHARED(art::Locks::mutator_lock_) { 978 return !(*this == other); 979 } 980 981 RedefinitionDataIter operator++() { // Value after modification. 982 idx_++; 983 return *this; 984 } 985 986 RedefinitionDataIter operator++(int) { 987 RedefinitionDataIter temp = *this; 988 idx_++; 989 return temp; 990 } 991 992 RedefinitionDataIter operator+(ssize_t delta) const { 993 RedefinitionDataIter temp = *this; 994 temp += delta; 995 return temp; 996 } 997 998 RedefinitionDataIter& operator+=(ssize_t delta) { 999 idx_ += delta; 1000 return *this; 1001 } 1002 1003 Redefiner::ClassRedefinition& GetRedefinition() REQUIRES_SHARED(art::Locks::mutator_lock_) { 1004 return (*holder_.GetRedefinitions())[idx_]; 1005 } 1006 1007 RedefinitionDataHolder& GetHolder() { 1008 return holder_; 1009 } 1010 1011 art::mirror::ClassLoader* GetSourceClassLoader() const 1012 REQUIRES_SHARED(art::Locks::mutator_lock_) { 1013 return holder_.GetSourceClassLoader(idx_); 1014 } 1015 art::mirror::Object* GetJavaDexFile() const REQUIRES_SHARED(art::Locks::mutator_lock_) { 1016 return holder_.GetJavaDexFile(idx_); 1017 } 1018 art::mirror::LongArray* GetNewDexFileCookie() const REQUIRES_SHARED(art::Locks::mutator_lock_) { 1019 return holder_.GetNewDexFileCookie(idx_); 1020 } 1021 art::mirror::DexCache* GetNewDexCache() const REQUIRES_SHARED(art::Locks::mutator_lock_) { 1022 return holder_.GetNewDexCache(idx_); 1023 } 1024 art::mirror::Class* GetMirrorClass() const REQUIRES_SHARED(art::Locks::mutator_lock_) { 1025 return holder_.GetMirrorClass(idx_); 1026 } 1027 art::mirror::Object* GetOriginalDexFile() const 1028 REQUIRES_SHARED(art::Locks::mutator_lock_) { 1029 return holder_.GetOriginalDexFile(idx_); 1030 } 1031 art::mirror::PointerArray* GetOldObsoleteMethods() const 1032 REQUIRES_SHARED(art::Locks::mutator_lock_) { 1033 return holder_.GetOldObsoleteMethods(idx_); 1034 } 1035 art::mirror::ObjectArray<art::mirror::DexCache>* GetOldDexCaches() const 1036 REQUIRES_SHARED(art::Locks::mutator_lock_) { 1037 return holder_.GetOldDexCaches(idx_); 1038 } 1039 1040 int32_t GetIndex() const { 1041 return idx_; 1042 } 1043 1044 void SetSourceClassLoader(art::mirror::ClassLoader* loader) 1045 REQUIRES_SHARED(art::Locks::mutator_lock_) { 1046 holder_.SetSourceClassLoader(idx_, loader); 1047 } 1048 void SetJavaDexFile(art::mirror::Object* dexfile) REQUIRES_SHARED(art::Locks::mutator_lock_) { 1049 holder_.SetJavaDexFile(idx_, dexfile); 1050 } 1051 void SetNewDexFileCookie(art::mirror::LongArray* cookie) 1052 REQUIRES_SHARED(art::Locks::mutator_lock_) { 1053 holder_.SetNewDexFileCookie(idx_, cookie); 1054 } 1055 void SetNewDexCache(art::mirror::DexCache* cache) REQUIRES_SHARED(art::Locks::mutator_lock_) { 1056 holder_.SetNewDexCache(idx_, cache); 1057 } 1058 void SetMirrorClass(art::mirror::Class* klass) REQUIRES_SHARED(art::Locks::mutator_lock_) { 1059 holder_.SetMirrorClass(idx_, klass); 1060 } 1061 void SetOriginalDexFile(art::mirror::Object* bytes) 1062 REQUIRES_SHARED(art::Locks::mutator_lock_) { 1063 holder_.SetOriginalDexFile(idx_, bytes); 1064 } 1065 void SetOldObsoleteMethods(art::mirror::PointerArray* methods) 1066 REQUIRES_SHARED(art::Locks::mutator_lock_) { 1067 holder_.SetOldObsoleteMethods(idx_, methods); 1068 } 1069 void SetOldDexCaches(art::mirror::ObjectArray<art::mirror::DexCache>* caches) 1070 REQUIRES_SHARED(art::Locks::mutator_lock_) { 1071 holder_.SetOldDexCaches(idx_, caches); 1072 } 1073 1074 private: 1075 int32_t idx_; 1076 RedefinitionDataHolder& holder_; 1077 }; 1078 1079 RedefinitionDataIter RedefinitionDataHolder::begin() { 1080 return RedefinitionDataIter(0, *this); 1081 } 1082 1083 RedefinitionDataIter RedefinitionDataHolder::end() { 1084 return RedefinitionDataIter(Length(), *this); 1085 } 1086 1087 bool Redefiner::ClassRedefinition::CheckVerification(const RedefinitionDataIter& iter) { 1088 DCHECK_EQ(dex_file_->NumClassDefs(), 1u); 1089 art::StackHandleScope<2> hs(driver_->self_); 1090 std::string error; 1091 // TODO Make verification log level lower 1092 art::verifier::FailureKind failure = 1093 art::verifier::MethodVerifier::VerifyClass(driver_->self_, 1094 dex_file_.get(), 1095 hs.NewHandle(iter.GetNewDexCache()), 1096 hs.NewHandle(GetClassLoader()), 1097 dex_file_->GetClassDef(0), /*class_def*/ 1098 nullptr, /*compiler_callbacks*/ 1099 false, /*allow_soft_failures*/ 1100 /*log_level*/ 1101 art::verifier::HardFailLogMode::kLogWarning, 1102 &error); 1103 bool passes = failure == art::verifier::FailureKind::kNoFailure; 1104 if (!passes) { 1105 RecordFailure(ERR(FAILS_VERIFICATION), "Failed to verify class. Error was: " + error); 1106 } 1107 return passes; 1108 } 1109 1110 // Looks through the previously allocated cookies to see if we need to update them with another new 1111 // dexfile. This is so that even if multiple classes with the same classloader are redefined at 1112 // once they are all added to the classloader. 1113 bool Redefiner::ClassRedefinition::AllocateAndRememberNewDexFileCookie( 1114 art::Handle<art::mirror::ClassLoader> source_class_loader, 1115 art::Handle<art::mirror::Object> dex_file_obj, 1116 /*out*/RedefinitionDataIter* cur_data) { 1117 art::StackHandleScope<2> hs(driver_->self_); 1118 art::MutableHandle<art::mirror::LongArray> old_cookie( 1119 hs.NewHandle<art::mirror::LongArray>(nullptr)); 1120 bool has_older_cookie = false; 1121 // See if we already have a cookie that a previous redefinition got from the same classloader. 1122 for (auto old_data = cur_data->GetHolder().begin(); old_data != *cur_data; ++old_data) { 1123 if (old_data.GetSourceClassLoader() == source_class_loader.Get()) { 1124 // Since every instance of this classloader should have the same cookie associated with it we 1125 // can stop looking here. 1126 has_older_cookie = true; 1127 old_cookie.Assign(old_data.GetNewDexFileCookie()); 1128 break; 1129 } 1130 } 1131 if (old_cookie.IsNull()) { 1132 // No older cookie. Get it directly from the dex_file_obj 1133 // We should not have seen this classloader elsewhere. 1134 CHECK(!has_older_cookie); 1135 old_cookie.Assign(ClassLoaderHelper::GetDexFileCookie(dex_file_obj)); 1136 } 1137 // Use the old cookie to generate the new one with the new DexFile* added in. 1138 art::Handle<art::mirror::LongArray> 1139 new_cookie(hs.NewHandle(ClassLoaderHelper::AllocateNewDexFileCookie(driver_->self_, 1140 old_cookie, 1141 dex_file_.get()))); 1142 // Make sure the allocation worked. 1143 if (new_cookie.IsNull()) { 1144 return false; 1145 } 1146 1147 // Save the cookie. 1148 cur_data->SetNewDexFileCookie(new_cookie.Get()); 1149 // If there are other copies of this same classloader we need to make sure that we all have the 1150 // same cookie. 1151 if (has_older_cookie) { 1152 for (auto old_data = cur_data->GetHolder().begin(); old_data != *cur_data; ++old_data) { 1153 // We will let the GC take care of the cookie we allocated for this one. 1154 if (old_data.GetSourceClassLoader() == source_class_loader.Get()) { 1155 old_data.SetNewDexFileCookie(new_cookie.Get()); 1156 } 1157 } 1158 } 1159 1160 return true; 1161 } 1162 1163 bool Redefiner::ClassRedefinition::FinishRemainingAllocations( 1164 /*out*/RedefinitionDataIter* cur_data) { 1165 art::ScopedObjectAccessUnchecked soa(driver_->self_); 1166 art::StackHandleScope<2> hs(driver_->self_); 1167 cur_data->SetMirrorClass(GetMirrorClass()); 1168 // This shouldn't allocate 1169 art::Handle<art::mirror::ClassLoader> loader(hs.NewHandle(GetClassLoader())); 1170 // The bootclasspath is handled specially so it doesn't have a j.l.DexFile. 1171 if (!art::ClassLinker::IsBootClassLoader(soa, loader.Get())) { 1172 cur_data->SetSourceClassLoader(loader.Get()); 1173 art::Handle<art::mirror::Object> dex_file_obj(hs.NewHandle( 1174 ClassLoaderHelper::FindSourceDexFileObject(driver_->self_, loader))); 1175 cur_data->SetJavaDexFile(dex_file_obj.Get()); 1176 if (dex_file_obj == nullptr) { 1177 RecordFailure(ERR(INTERNAL), "Unable to find dex file!"); 1178 return false; 1179 } 1180 // Allocate the new dex file cookie. 1181 if (!AllocateAndRememberNewDexFileCookie(loader, dex_file_obj, cur_data)) { 1182 driver_->self_->AssertPendingOOMException(); 1183 driver_->self_->ClearException(); 1184 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate dex file array for class loader"); 1185 return false; 1186 } 1187 } 1188 cur_data->SetNewDexCache(CreateNewDexCache(loader)); 1189 if (cur_data->GetNewDexCache() == nullptr) { 1190 driver_->self_->AssertPendingException(); 1191 driver_->self_->ClearException(); 1192 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate DexCache"); 1193 return false; 1194 } 1195 1196 // We won't always need to set this field. 1197 cur_data->SetOriginalDexFile(AllocateOrGetOriginalDexFile()); 1198 if (cur_data->GetOriginalDexFile() == nullptr) { 1199 driver_->self_->AssertPendingOOMException(); 1200 driver_->self_->ClearException(); 1201 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate array for original dex file"); 1202 return false; 1203 } 1204 return true; 1205 } 1206 1207 void Redefiner::ClassRedefinition::UnregisterJvmtiBreakpoints() { 1208 BreakpointUtil::RemoveBreakpointsInClass(driver_->env_, GetMirrorClass()); 1209 } 1210 1211 void Redefiner::ClassRedefinition::UnregisterBreakpoints() { 1212 DCHECK(art::Dbg::IsDebuggerActive()); 1213 art::JDWP::JdwpState* state = art::Dbg::GetJdwpState(); 1214 if (state != nullptr) { 1215 state->UnregisterLocationEventsOnClass(GetMirrorClass()); 1216 } 1217 } 1218 1219 void Redefiner::UnregisterAllBreakpoints() { 1220 if (LIKELY(!art::Dbg::IsDebuggerActive())) { 1221 return; 1222 } 1223 for (Redefiner::ClassRedefinition& redef : redefinitions_) { 1224 redef.UnregisterBreakpoints(); 1225 } 1226 } 1227 1228 bool Redefiner::CheckAllRedefinitionAreValid() { 1229 for (Redefiner::ClassRedefinition& redef : redefinitions_) { 1230 if (!redef.CheckRedefinitionIsValid()) { 1231 return false; 1232 } 1233 } 1234 return true; 1235 } 1236 1237 void Redefiner::RestoreObsoleteMethodMapsIfUnneeded(RedefinitionDataHolder& holder) { 1238 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) { 1239 data.GetRedefinition().RestoreObsoleteMethodMapsIfUnneeded(&data); 1240 } 1241 } 1242 1243 bool Redefiner::EnsureAllClassAllocationsFinished(RedefinitionDataHolder& holder) { 1244 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) { 1245 if (!data.GetRedefinition().EnsureClassAllocationsFinished(&data)) { 1246 return false; 1247 } 1248 } 1249 return true; 1250 } 1251 1252 bool Redefiner::FinishAllRemainingAllocations(RedefinitionDataHolder& holder) { 1253 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) { 1254 // Allocate the data this redefinition requires. 1255 if (!data.GetRedefinition().FinishRemainingAllocations(&data)) { 1256 return false; 1257 } 1258 } 1259 return true; 1260 } 1261 1262 void Redefiner::ClassRedefinition::ReleaseDexFile() { 1263 dex_file_.release(); 1264 } 1265 1266 void Redefiner::ReleaseAllDexFiles() { 1267 for (Redefiner::ClassRedefinition& redef : redefinitions_) { 1268 redef.ReleaseDexFile(); 1269 } 1270 } 1271 1272 bool Redefiner::CheckAllClassesAreVerified(RedefinitionDataHolder& holder) { 1273 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) { 1274 if (!data.GetRedefinition().CheckVerification(data)) { 1275 return false; 1276 } 1277 } 1278 return true; 1279 } 1280 1281 class ScopedDisableConcurrentAndMovingGc { 1282 public: 1283 ScopedDisableConcurrentAndMovingGc(art::gc::Heap* heap, art::Thread* self) 1284 : heap_(heap), self_(self) { 1285 if (heap_->IsGcConcurrentAndMoving()) { 1286 heap_->IncrementDisableMovingGC(self_); 1287 } 1288 } 1289 1290 ~ScopedDisableConcurrentAndMovingGc() { 1291 if (heap_->IsGcConcurrentAndMoving()) { 1292 heap_->DecrementDisableMovingGC(self_); 1293 } 1294 } 1295 private: 1296 art::gc::Heap* heap_; 1297 art::Thread* self_; 1298 }; 1299 1300 jvmtiError Redefiner::Run() { 1301 art::StackHandleScope<1> hs(self_); 1302 // Allocate an array to hold onto all java temporary objects associated with this redefinition. 1303 // We will let this be collected after the end of this function. 1304 RedefinitionDataHolder holder(&hs, runtime_, self_, &redefinitions_); 1305 if (holder.IsNull()) { 1306 self_->AssertPendingOOMException(); 1307 self_->ClearException(); 1308 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate storage for temporaries"); 1309 return result_; 1310 } 1311 1312 // First we just allocate the ClassExt and its fields that we need. These can be updated 1313 // atomically without any issues (since we allocate the map arrays as empty) so we don't bother 1314 // doing a try loop. The other allocations we need to ensure that nothing has changed in the time 1315 // between allocating them and pausing all threads before we can update them so we need to do a 1316 // try loop. 1317 if (!CheckAllRedefinitionAreValid() || 1318 !EnsureAllClassAllocationsFinished(holder) || 1319 !FinishAllRemainingAllocations(holder) || 1320 !CheckAllClassesAreVerified(holder)) { 1321 return result_; 1322 } 1323 1324 // At this point we can no longer fail without corrupting the runtime state. 1325 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) { 1326 art::ClassLinker* cl = runtime_->GetClassLinker(); 1327 cl->RegisterExistingDexCache(data.GetNewDexCache(), data.GetSourceClassLoader()); 1328 if (data.GetSourceClassLoader() == nullptr) { 1329 cl->AppendToBootClassPath(self_, data.GetRedefinition().GetDexFile()); 1330 } 1331 } 1332 UnregisterAllBreakpoints(); 1333 1334 // Disable GC and wait for it to be done if we are a moving GC. This is fine since we are done 1335 // allocating so no deadlocks. 1336 ScopedDisableConcurrentAndMovingGc sdcamgc(runtime_->GetHeap(), self_); 1337 1338 // Do transition to final suspension 1339 // TODO We might want to give this its own suspended state! 1340 // TODO This isn't right. We need to change state without any chance of suspend ideally! 1341 art::ScopedThreadSuspension sts(self_, art::ThreadState::kNative); 1342 art::ScopedSuspendAll ssa("Final installation of redefined Classes!", /*long_suspend*/true); 1343 for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) { 1344 art::ScopedAssertNoThreadSuspension nts("Updating runtime objects for redefinition"); 1345 ClassRedefinition& redef = data.GetRedefinition(); 1346 if (data.GetSourceClassLoader() != nullptr) { 1347 ClassLoaderHelper::UpdateJavaDexFile(data.GetJavaDexFile(), data.GetNewDexFileCookie()); 1348 } 1349 art::mirror::Class* klass = data.GetMirrorClass(); 1350 // TODO Rewrite so we don't do a stack walk for each and every class. 1351 redef.FindAndAllocateObsoleteMethods(klass); 1352 redef.UpdateClass(klass, data.GetNewDexCache(), data.GetOriginalDexFile()); 1353 redef.UnregisterJvmtiBreakpoints(); 1354 } 1355 RestoreObsoleteMethodMapsIfUnneeded(holder); 1356 // TODO We should check for if any of the redefined methods are intrinsic methods here and, if any 1357 // are, force a full-world deoptimization before finishing redefinition. If we don't do this then 1358 // methods that have been jitted prior to the current redefinition being applied might continue 1359 // to use the old versions of the intrinsics! 1360 // TODO Do the dex_file release at a more reasonable place. This works but it muddles who really 1361 // owns the DexFile and when ownership is transferred. 1362 ReleaseAllDexFiles(); 1363 return OK; 1364 } 1365 1366 void Redefiner::ClassRedefinition::UpdateMethods(art::ObjPtr<art::mirror::Class> mclass, 1367 art::ObjPtr<art::mirror::DexCache> new_dex_cache, 1368 const art::DexFile::ClassDef& class_def) { 1369 art::ClassLinker* linker = driver_->runtime_->GetClassLinker(); 1370 art::PointerSize image_pointer_size = linker->GetImagePointerSize(); 1371 const art::DexFile::TypeId& declaring_class_id = dex_file_->GetTypeId(class_def.class_idx_); 1372 const art::DexFile& old_dex_file = mclass->GetDexFile(); 1373 // Update methods. 1374 for (art::ArtMethod& method : mclass->GetDeclaredMethods(image_pointer_size)) { 1375 const art::DexFile::StringId* new_name_id = dex_file_->FindStringId(method.GetName()); 1376 art::dex::TypeIndex method_return_idx = 1377 dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(method.GetReturnTypeDescriptor())); 1378 const auto* old_type_list = method.GetParameterTypeList(); 1379 std::vector<art::dex::TypeIndex> new_type_list; 1380 for (uint32_t i = 0; old_type_list != nullptr && i < old_type_list->Size(); i++) { 1381 new_type_list.push_back( 1382 dex_file_->GetIndexForTypeId( 1383 *dex_file_->FindTypeId( 1384 old_dex_file.GetTypeDescriptor( 1385 old_dex_file.GetTypeId( 1386 old_type_list->GetTypeItem(i).type_idx_))))); 1387 } 1388 const art::DexFile::ProtoId* proto_id = dex_file_->FindProtoId(method_return_idx, 1389 new_type_list); 1390 CHECK(proto_id != nullptr || old_type_list == nullptr); 1391 const art::DexFile::MethodId* method_id = dex_file_->FindMethodId(declaring_class_id, 1392 *new_name_id, 1393 *proto_id); 1394 CHECK(method_id != nullptr); 1395 uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id); 1396 method.SetDexMethodIndex(dex_method_idx); 1397 linker->SetEntryPointsToInterpreter(&method); 1398 method.SetCodeItemOffset(dex_file_->FindCodeItemOffset(class_def, dex_method_idx)); 1399 method.SetDexCacheResolvedMethods(new_dex_cache->GetResolvedMethods(), image_pointer_size); 1400 // Clear all the intrinsics related flags. 1401 method.ClearAccessFlags(art::kAccIntrinsic | (~art::kAccFlagsNotUsedByIntrinsic)); 1402 // Notify the jit that this method is redefined. 1403 art::jit::Jit* jit = driver_->runtime_->GetJit(); 1404 if (jit != nullptr) { 1405 jit->GetCodeCache()->NotifyMethodRedefined(&method); 1406 } 1407 } 1408 } 1409 1410 void Redefiner::ClassRedefinition::UpdateFields(art::ObjPtr<art::mirror::Class> mclass) { 1411 // TODO The IFields & SFields pointers should be combined like the methods_ arrays were. 1412 for (auto fields_iter : {mclass->GetIFields(), mclass->GetSFields()}) { 1413 for (art::ArtField& field : fields_iter) { 1414 std::string declaring_class_name; 1415 const art::DexFile::TypeId* new_declaring_id = 1416 dex_file_->FindTypeId(field.GetDeclaringClass()->GetDescriptor(&declaring_class_name)); 1417 const art::DexFile::StringId* new_name_id = dex_file_->FindStringId(field.GetName()); 1418 const art::DexFile::TypeId* new_type_id = dex_file_->FindTypeId(field.GetTypeDescriptor()); 1419 CHECK(new_name_id != nullptr && new_type_id != nullptr && new_declaring_id != nullptr); 1420 const art::DexFile::FieldId* new_field_id = 1421 dex_file_->FindFieldId(*new_declaring_id, *new_name_id, *new_type_id); 1422 CHECK(new_field_id != nullptr); 1423 // We only need to update the index since the other data in the ArtField cannot be updated. 1424 field.SetDexFieldIndex(dex_file_->GetIndexForFieldId(*new_field_id)); 1425 } 1426 } 1427 } 1428 1429 // Performs updates to class that will allow us to verify it. 1430 void Redefiner::ClassRedefinition::UpdateClass( 1431 art::ObjPtr<art::mirror::Class> mclass, 1432 art::ObjPtr<art::mirror::DexCache> new_dex_cache, 1433 art::ObjPtr<art::mirror::Object> original_dex_file) { 1434 DCHECK_EQ(dex_file_->NumClassDefs(), 1u); 1435 const art::DexFile::ClassDef& class_def = dex_file_->GetClassDef(0); 1436 UpdateMethods(mclass, new_dex_cache, class_def); 1437 UpdateFields(mclass); 1438 1439 // Update the class fields. 1440 // Need to update class last since the ArtMethod gets its DexFile from the class (which is needed 1441 // to call GetReturnTypeDescriptor and GetParameterTypeList above). 1442 mclass->SetDexCache(new_dex_cache.Ptr()); 1443 mclass->SetDexClassDefIndex(dex_file_->GetIndexForClassDef(class_def)); 1444 mclass->SetDexTypeIndex(dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(class_sig_.c_str()))); 1445 art::ObjPtr<art::mirror::ClassExt> ext(mclass->GetExtData()); 1446 CHECK(!ext.IsNull()); 1447 ext->SetOriginalDexFile(original_dex_file); 1448 } 1449 1450 // Restores the old obsolete methods maps if it turns out they weren't needed (ie there were no new 1451 // obsolete methods). 1452 void Redefiner::ClassRedefinition::RestoreObsoleteMethodMapsIfUnneeded( 1453 const RedefinitionDataIter* cur_data) { 1454 art::mirror::Class* klass = GetMirrorClass(); 1455 art::mirror::ClassExt* ext = klass->GetExtData(); 1456 art::mirror::PointerArray* methods = ext->GetObsoleteMethods(); 1457 art::mirror::PointerArray* old_methods = cur_data->GetOldObsoleteMethods(); 1458 int32_t old_length = old_methods == nullptr ? 0 : old_methods->GetLength(); 1459 int32_t expected_length = 1460 old_length + klass->NumDirectMethods() + klass->NumDeclaredVirtualMethods(); 1461 // Check to make sure we are only undoing this one. 1462 if (expected_length == methods->GetLength()) { 1463 for (int32_t i = 0; i < expected_length; i++) { 1464 art::ArtMethod* expected = nullptr; 1465 if (i < old_length) { 1466 expected = old_methods->GetElementPtrSize<art::ArtMethod*>(i, art::kRuntimePointerSize); 1467 } 1468 if (methods->GetElementPtrSize<art::ArtMethod*>(i, art::kRuntimePointerSize) != expected) { 1469 // We actually have some new obsolete methods. Just abort since we cannot safely shrink the 1470 // obsolete methods array. 1471 return; 1472 } 1473 } 1474 // No new obsolete methods! We can get rid of the maps. 1475 ext->SetObsoleteArrays(cur_data->GetOldObsoleteMethods(), cur_data->GetOldDexCaches()); 1476 } 1477 } 1478 1479 // This function does all (java) allocations we need to do for the Class being redefined. 1480 // TODO Change this name maybe? 1481 bool Redefiner::ClassRedefinition::EnsureClassAllocationsFinished( 1482 /*out*/RedefinitionDataIter* cur_data) { 1483 art::StackHandleScope<2> hs(driver_->self_); 1484 art::Handle<art::mirror::Class> klass(hs.NewHandle( 1485 driver_->self_->DecodeJObject(klass_)->AsClass())); 1486 if (klass == nullptr) { 1487 RecordFailure(ERR(INVALID_CLASS), "Unable to decode class argument!"); 1488 return false; 1489 } 1490 // Allocate the classExt 1491 art::Handle<art::mirror::ClassExt> ext(hs.NewHandle(klass->EnsureExtDataPresent(driver_->self_))); 1492 if (ext == nullptr) { 1493 // No memory. Clear exception (it's not useful) and return error. 1494 driver_->self_->AssertPendingOOMException(); 1495 driver_->self_->ClearException(); 1496 RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate ClassExt"); 1497 return false; 1498 } 1499 // First save the old values of the 2 arrays that make up the obsolete methods maps. Then 1500 // allocate the 2 arrays that make up the obsolete methods map. Since the contents of the arrays 1501 // are only modified when all threads (other than the modifying one) are suspended we don't need 1502 // to worry about missing the unsyncronized writes to the array. We do synchronize when setting it 1503 // however, since that can happen at any time. 1504 cur_data->SetOldObsoleteMethods(ext->GetObsoleteMethods()); 1505 cur_data->SetOldDexCaches(ext->GetObsoleteDexCaches()); 1506 if (!ext->ExtendObsoleteArrays( 1507 driver_->self_, klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize).size())) { 1508 // OOM. Clear exception and return error. 1509 driver_->self_->AssertPendingOOMException(); 1510 driver_->self_->ClearException(); 1511 RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate/extend obsolete methods map"); 1512 return false; 1513 } 1514 return true; 1515 } 1516 1517 } // namespace openjdkjvmti 1518