1e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe/* Copyright (C) 2016 The Android Open Source Project
2e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe *
4e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * This file implements interfaces from the file jvmti.h. This implementation
5e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * is licensed under the same terms as the file jvmti.h.  The
6e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * copyright and license information for the file jvmti.h follows.
7e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe *
8e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
9e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe *
11e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * This code is free software; you can redistribute it and/or modify it
12e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * under the terms of the GNU General Public License version 2 only, as
13e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * published by the Free Software Foundation.  Oracle designates this
14e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * particular file as subject to the "Classpath" exception as provided
15e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * by Oracle in the LICENSE file that accompanied this code.
16e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe *
17e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * This code is distributed in the hope that it will be useful, but WITHOUT
18e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * version 2 for more details (a copy is included in the LICENSE file that
21e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * accompanied this code).
22e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe *
23e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * You should have received a copy of the GNU General Public License version
24e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * 2 along with this work; if not, write to the Free Software Foundation,
25e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe *
27e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * or visit www.oracle.com if you need additional information or have any
29e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe * questions.
30e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe */
31e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe
32e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe#include "ti_class.h"
33e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe
34440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light#include "android-base/stringprintf.h"
35440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light
36e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe#include <mutex>
37e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe#include <unordered_set>
38e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe
39e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe#include "art_jvmti.h"
40e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe#include "base/macros.h"
4170f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe#include "class_table-inl.h"
4270f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe#include "class_linker.h"
43440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light#include "common_throws.h"
440eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe#include "dex_file_annotations.h"
45e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe#include "events-inl.h"
46405284789d13dd1a1d15e2888a987591f5de6b12Alex Light#include "fixed_up_dex_file.h"
47691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe#include "gc/heap.h"
48691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe#include "gc_root.h"
49e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe#include "handle.h"
50e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe#include "jni_env_ext-inl.h"
51ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe#include "jni_internal.h"
52440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light#include "mirror/array-inl.h"
53440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light#include "mirror/class-inl.h"
54440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light#include "mirror/class_ext.h"
550eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe#include "mirror/object_array-inl.h"
56a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe#include "mirror/object_reference.h"
57a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe#include "mirror/object-inl.h"
58c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe#include "mirror/object-refvisitor-inl.h"
5952784ac8d21de0557ded4225c65cad77226dae36Andreas Gampe#include "mirror/reference.h"
606a6563116638e8db683bbe0a39a26dbed8992adaAlex Light#include "primitive.h"
616a6563116638e8db683bbe0a39a26dbed8992adaAlex Light#include "reflection.h"
6270f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe#include "runtime.h"
63e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe#include "runtime_callbacks.h"
64e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe#include "ScopedLocalRef.h"
65e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe#include "scoped_thread_state_change-inl.h"
66e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe#include "thread-inl.h"
67e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe#include "thread_list.h"
68eb98b08b22b83aaaf72afac8e22f0108fe62310dAlex Light#include "ti_class_loader.h"
69d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light#include "ti_phase.h"
70440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light#include "ti_redefine.h"
71440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light#include "utils.h"
72a1d2f957a21319d1110bebb9a52f46fd1c67ffafAndreas Gampe#include "well_known_classes.h"
73e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe
74e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampenamespace openjdkjvmti {
75e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe
76440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Lightusing android::base::StringPrintf;
77440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light
78440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Lightstatic std::unique_ptr<const art::DexFile> MakeSingleDexFile(art::Thread* self,
79440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                             const char* descriptor,
80440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                             const std::string& orig_location,
81440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                             jint final_len,
82440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                             const unsigned char* final_dex_data)
83440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      REQUIRES_SHARED(art::Locks::mutator_lock_) {
84440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  // Make the mmap
85440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  std::string error_msg;
86b7354d5bc76ed3975af636f87aa953f8a4d308a9Alex Light  art::ArraySlice<const unsigned char> final_data(final_dex_data, final_len);
87440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  std::unique_ptr<art::MemMap> map(Redefiner::MoveDataToMemMap(orig_location,
88b7354d5bc76ed3975af636f87aa953f8a4d308a9Alex Light                                                               final_data,
89440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                               &error_msg));
90440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  if (map.get() == nullptr) {
91440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    LOG(WARNING) << "Unable to allocate mmap for redefined dex file! Error was: " << error_msg;
92440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    self->ThrowOutOfMemoryError(StringPrintf(
93440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        "Unable to allocate dex file for transformation of %s", descriptor).c_str());
94440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    return nullptr;
95440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  }
96440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light
97440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  // Make a dex-file
98440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  if (map->Size() < sizeof(art::DexFile::Header)) {
99440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    LOG(WARNING) << "Could not read dex file header because dex_data was too short";
100440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    art::ThrowClassFormatError(nullptr,
101440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                               "Unable to read transformed dex file of %s",
102440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                               descriptor);
103440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    return nullptr;
104440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  }
105440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  uint32_t checksum = reinterpret_cast<const art::DexFile::Header*>(map->Begin())->checksum_;
106440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  std::unique_ptr<const art::DexFile> dex_file(art::DexFile::Open(map->GetName(),
107440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                                  checksum,
108440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                                  std::move(map),
109440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                                  /*verify*/true,
110440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                                  /*verify_checksum*/true,
111440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                                  &error_msg));
112440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  if (dex_file.get() == nullptr) {
113440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    LOG(WARNING) << "Unable to load modified dex file for " << descriptor << ": " << error_msg;
114440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    art::ThrowClassFormatError(nullptr,
115440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                               "Unable to read transformed dex file of %s because %s",
116440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                               descriptor,
117440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                               error_msg.c_str());
118440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    return nullptr;
119440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  }
120440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  if (dex_file->NumClassDefs() != 1) {
121440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    LOG(WARNING) << "Dex file contains more than 1 class_def. Ignoring.";
122440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    // TODO Throw some other sort of error here maybe?
123440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    art::ThrowClassFormatError(
124440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        nullptr,
125440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        "Unable to use transformed dex file of %s because it contained too many classes",
126440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        descriptor);
127440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    return nullptr;
128440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  }
129440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  return dex_file;
130440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light}
131440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light
132e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampestruct ClassCallback : public art::ClassLoadCallback {
133440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  void ClassPreDefine(const char* descriptor,
134440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                      art::Handle<art::mirror::Class> klass,
135440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                      art::Handle<art::mirror::ClassLoader> class_loader,
136440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                      const art::DexFile& initial_dex_file,
137440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                      const art::DexFile::ClassDef& initial_class_def ATTRIBUTE_UNUSED,
138440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                      /*out*/art::DexFile const** final_dex_file,
139440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                      /*out*/art::DexFile::ClassDef const** final_class_def)
140440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
141440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    bool is_enabled =
142440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassFileLoadHookRetransformable) ||
143440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassFileLoadHookNonRetransformable);
144440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    if (!is_enabled) {
145440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      return;
146440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    }
147440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    if (descriptor[0] != 'L') {
148440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      // It is a primitive or array. Just return
149440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      return;
150440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    }
151d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light    jvmtiPhase phase = PhaseUtil::GetPhaseUnchecked();
152d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light    if (UNLIKELY(phase != JVMTI_PHASE_START && phase != JVMTI_PHASE_LIVE)) {
153d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light      // We want to wait until we are at least in the START phase so that all WellKnownClasses and
154d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light      // mirror classes have been initialized and loaded. The runtime relies on these classes having
155d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light      // specific fields and methods present. Since PreDefine hooks don't need to abide by this
156d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light      // restriction we will simply not send the event for these classes.
157d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light      LOG(WARNING) << "Ignoring load of class <" << descriptor << "> as it is being loaded during "
158d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light                   << "runtime initialization.";
159d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light      return;
160d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light    }
161d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light
162d8ce4e73ef9cbbe7cb58ab4ee3258558ee4e73a7Alex Light    // Strip the 'L' and ';' from the descriptor
16328027128200efc7cdfb44a6248fd48c1f57e5416Alex Light    std::string name(std::string(descriptor).substr(1, strlen(descriptor) - 2));
164440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light
165440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    art::Thread* self = art::Thread::Current();
166440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    art::JNIEnvExt* env = self->GetJniEnv();
167440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    ScopedLocalRef<jobject> loader(
168440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        env, class_loader.IsNull() ? nullptr : env->AddLocalReference<jobject>(class_loader.Get()));
169405284789d13dd1a1d15e2888a987591f5de6b12Alex Light    std::unique_ptr<FixedUpDexFile> dex_file_copy(FixedUpDexFile::Create(initial_dex_file));
170405284789d13dd1a1d15e2888a987591f5de6b12Alex Light
171440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    // Go back to native.
172440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    art::ScopedThreadSuspension sts(self, art::ThreadState::kNative);
173440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    // Call all Non-retransformable agents.
174440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    jint post_no_redefine_len = 0;
175440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    unsigned char* post_no_redefine_dex_data = nullptr;
176440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    std::unique_ptr<const unsigned char> post_no_redefine_unique_ptr(nullptr);
177440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    event_handler->DispatchEvent<ArtJvmtiEvent::kClassFileLoadHookNonRetransformable>(
178440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        self,
179440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        static_cast<JNIEnv*>(env),
180440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        static_cast<jclass>(nullptr),  // The class doesn't really exist yet so send null.
181440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        loader.get(),
182440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        name.c_str(),
183440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        static_cast<jobject>(nullptr),  // Android doesn't seem to have protection domains
184405284789d13dd1a1d15e2888a987591f5de6b12Alex Light        static_cast<jint>(dex_file_copy->Size()),
185405284789d13dd1a1d15e2888a987591f5de6b12Alex Light        static_cast<const unsigned char*>(dex_file_copy->Begin()),
186440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        static_cast<jint*>(&post_no_redefine_len),
187440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        static_cast<unsigned char**>(&post_no_redefine_dex_data));
188440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    if (post_no_redefine_dex_data == nullptr) {
189440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      DCHECK_EQ(post_no_redefine_len, 0);
190405284789d13dd1a1d15e2888a987591f5de6b12Alex Light      post_no_redefine_dex_data = const_cast<unsigned char*>(dex_file_copy->Begin());
191405284789d13dd1a1d15e2888a987591f5de6b12Alex Light      post_no_redefine_len = dex_file_copy->Size();
192440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    } else {
193440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      post_no_redefine_unique_ptr = std::unique_ptr<const unsigned char>(post_no_redefine_dex_data);
194440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      DCHECK_GT(post_no_redefine_len, 0);
195440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    }
196440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    // Call all retransformable agents.
197440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    jint final_len = 0;
198440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    unsigned char* final_dex_data = nullptr;
199440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    std::unique_ptr<const unsigned char> final_dex_unique_ptr(nullptr);
200440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    event_handler->DispatchEvent<ArtJvmtiEvent::kClassFileLoadHookRetransformable>(
201440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        self,
202440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        static_cast<JNIEnv*>(env),
203440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        static_cast<jclass>(nullptr),  // The class doesn't really exist yet so send null.
204440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        loader.get(),
205440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        name.c_str(),
206440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        static_cast<jobject>(nullptr),  // Android doesn't seem to have protection domains
207440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        static_cast<jint>(post_no_redefine_len),
208440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        static_cast<const unsigned char*>(post_no_redefine_dex_data),
209440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        static_cast<jint*>(&final_len),
210440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        static_cast<unsigned char**>(&final_dex_data));
211440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    if (final_dex_data == nullptr) {
212440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      DCHECK_EQ(final_len, 0);
213440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      final_dex_data = post_no_redefine_dex_data;
214440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      final_len = post_no_redefine_len;
215440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    } else {
216440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      final_dex_unique_ptr = std::unique_ptr<const unsigned char>(final_dex_data);
217440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      DCHECK_GT(final_len, 0);
218440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    }
219440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light
220405284789d13dd1a1d15e2888a987591f5de6b12Alex Light    if (final_dex_data != dex_file_copy->Begin()) {
221440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      LOG(WARNING) << "Changing class " << descriptor;
222440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      art::ScopedObjectAccess soa(self);
223440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      art::StackHandleScope<2> hs(self);
224440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      // Save the results of all the non-retransformable agents.
225440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      // First allocate the ClassExt
226440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      art::Handle<art::mirror::ClassExt> ext(hs.NewHandle(klass->EnsureExtDataPresent(self)));
227440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      // Make sure we have a ClassExt. This is fine even though we are a temporary since it will
228440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      // get copied.
229440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      if (ext.IsNull()) {
230440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        // We will just return failure if we fail to allocate
231440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        LOG(WARNING) << "Could not allocate ext-data for class '" << descriptor << "'. "
232440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                     << "Aborting transformation since we will be unable to store it.";
233440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        self->AssertPendingOOMException();
234440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        return;
235440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      }
236440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light
237440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      // Allocate the byte array to store the dex file bytes in.
2386a6563116638e8db683bbe0a39a26dbed8992adaAlex Light      art::MutableHandle<art::mirror::Object> arr(hs.NewHandle<art::mirror::Object>(nullptr));
2396a6563116638e8db683bbe0a39a26dbed8992adaAlex Light      if (post_no_redefine_dex_data == dex_file_copy->Begin() && name != "java/lang/Long") {
2406a6563116638e8db683bbe0a39a26dbed8992adaAlex Light        // we didn't have any non-retransformable agents. We can just cache a pointer to the
2416a6563116638e8db683bbe0a39a26dbed8992adaAlex Light        // initial_dex_file. It will be kept live by the class_loader.
2426a6563116638e8db683bbe0a39a26dbed8992adaAlex Light        jlong dex_ptr = reinterpret_cast<uintptr_t>(&initial_dex_file);
2436a6563116638e8db683bbe0a39a26dbed8992adaAlex Light        art::JValue val;
2446a6563116638e8db683bbe0a39a26dbed8992adaAlex Light        val.SetJ(dex_ptr);
2456a6563116638e8db683bbe0a39a26dbed8992adaAlex Light        arr.Assign(art::BoxPrimitive(art::Primitive::kPrimLong, val));
2466a6563116638e8db683bbe0a39a26dbed8992adaAlex Light      } else {
2476a6563116638e8db683bbe0a39a26dbed8992adaAlex Light        arr.Assign(art::mirror::ByteArray::AllocateAndFill(
2486a6563116638e8db683bbe0a39a26dbed8992adaAlex Light            self,
2496a6563116638e8db683bbe0a39a26dbed8992adaAlex Light            reinterpret_cast<const signed char*>(post_no_redefine_dex_data),
2506a6563116638e8db683bbe0a39a26dbed8992adaAlex Light            post_no_redefine_len));
2516a6563116638e8db683bbe0a39a26dbed8992adaAlex Light      }
252440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      if (arr.IsNull()) {
2536a6563116638e8db683bbe0a39a26dbed8992adaAlex Light        LOG(WARNING) << "Unable to allocate memory for initial dex-file. Aborting transformation";
254440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        self->AssertPendingOOMException();
255440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        return;
256440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      }
257440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light
258440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      std::unique_ptr<const art::DexFile> dex_file(MakeSingleDexFile(self,
259440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                                     descriptor,
260440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                                     initial_dex_file.GetLocation(),
261440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                                     final_len,
262440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                                                                     final_dex_data));
263440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      if (dex_file.get() == nullptr) {
264440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light        return;
265440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      }
266440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light
267eb98b08b22b83aaaf72afac8e22f0108fe62310dAlex Light      // TODO Check Redefined dex file for all invariants.
268440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      LOG(WARNING) << "Dex file created by class-definition time transformation of "
269440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light                   << descriptor << " is not checked for all retransformation invariants.";
270eb98b08b22b83aaaf72afac8e22f0108fe62310dAlex Light
271eb98b08b22b83aaaf72afac8e22f0108fe62310dAlex Light      if (!ClassLoaderHelper::AddToClassLoader(self, class_loader, dex_file.get())) {
272eb98b08b22b83aaaf72afac8e22f0108fe62310dAlex Light        LOG(ERROR) << "Unable to add " << descriptor << " to class loader!";
273eb98b08b22b83aaaf72afac8e22f0108fe62310dAlex Light        return;
274eb98b08b22b83aaaf72afac8e22f0108fe62310dAlex Light      }
275eb98b08b22b83aaaf72afac8e22f0108fe62310dAlex Light
276440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      // Actually set the ClassExt's original bytes once we have actually succeeded.
2772f814aab42591b7b4093d79851d9d2920538a5efAlex Light      ext->SetOriginalDexFile(arr.Get());
278440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      // Set the return values
279440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      *final_class_def = &dex_file->GetClassDef(0);
280440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      *final_dex_file = dex_file.release();
281440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light    }
282440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  }
283440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light
284e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  void ClassLoad(art::Handle<art::mirror::Class> klass) REQUIRES_SHARED(art::Locks::mutator_lock_) {
285e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe    if (event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassLoad)) {
286e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe      art::Thread* thread = art::Thread::Current();
287e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe      ScopedLocalRef<jclass> jklass(thread->GetJniEnv(),
288e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe                                    thread->GetJniEnv()->AddLocalReference<jclass>(klass.Get()));
289983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe      ScopedLocalRef<jthread> thread_jni(
290983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe          thread->GetJniEnv(), thread->GetJniEnv()->AddLocalReference<jthread>(thread->GetPeer()));
291e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe      {
292e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe        art::ScopedThreadSuspension sts(thread, art::ThreadState::kNative);
293983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe        event_handler->DispatchEvent<ArtJvmtiEvent::kClassLoad>(
294983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe            thread,
295983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe            static_cast<JNIEnv*>(thread->GetJniEnv()),
296983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe            thread_jni.get(),
297983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe            jklass.get());
298e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe      }
299691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      if (klass->IsTemp()) {
300691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe        AddTempClass(thread, jklass.get());
301691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      }
302e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe    }
303e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  }
304e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe
305691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe  void ClassPrepare(art::Handle<art::mirror::Class> temp_klass,
306e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe                    art::Handle<art::mirror::Class> klass)
307e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe      REQUIRES_SHARED(art::Locks::mutator_lock_) {
308e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe    if (event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassPrepare)) {
309e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe      art::Thread* thread = art::Thread::Current();
310691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      if (temp_klass.Get() != klass.Get()) {
311691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe        DCHECK(temp_klass->IsTemp());
312691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe        DCHECK(temp_klass->IsRetired());
313691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe        HandleTempClass(thread, temp_klass, klass);
314691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      }
315e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe      ScopedLocalRef<jclass> jklass(thread->GetJniEnv(),
316e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe                                    thread->GetJniEnv()->AddLocalReference<jclass>(klass.Get()));
317983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe      ScopedLocalRef<jthread> thread_jni(
318983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe          thread->GetJniEnv(), thread->GetJniEnv()->AddLocalReference<jthread>(thread->GetPeer()));
319e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe      art::ScopedThreadSuspension sts(thread, art::ThreadState::kNative);
320983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe      event_handler->DispatchEvent<ArtJvmtiEvent::kClassPrepare>(
321983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe          thread,
322983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe          static_cast<JNIEnv*>(thread->GetJniEnv()),
323983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe          thread_jni.get(),
324983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe          jklass.get());
325e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe    }
326e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  }
327e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe
3287619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe  // To support parallel class-loading, we need to perform some locking dances here. Namely,
3297619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe  // the fixup stage must not be holding the temp_classes lock when it fixes up the system
3307619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe  // (as that requires suspending all mutators).
3317619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe
332e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  void AddTempClass(art::Thread* self, jclass klass) {
333e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe    std::unique_lock<std::mutex> mu(temp_classes_lock);
334691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    jclass global_klass = reinterpret_cast<jclass>(self->GetJniEnv()->NewGlobalRef(klass));
335691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    temp_classes.push_back(global_klass);
336e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  }
337e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe
338691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe  void HandleTempClass(art::Thread* self,
339691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe                       art::Handle<art::mirror::Class> temp_klass,
340e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe                       art::Handle<art::mirror::Class> klass)
341e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe      REQUIRES_SHARED(art::Locks::mutator_lock_) {
3427619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe    bool requires_fixup = false;
3437619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe    {
3447619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe      std::unique_lock<std::mutex> mu(temp_classes_lock);
3457619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe      if (temp_classes.empty()) {
3467619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe        return;
3477619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe      }
348e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe
3497619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe      for (auto it = temp_classes.begin(); it != temp_classes.end(); ++it) {
3507619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe        if (temp_klass.Get() == art::ObjPtr<art::mirror::Class>::DownCast(self->DecodeJObject(*it))) {
3517619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe          self->GetJniEnv()->DeleteGlobalRef(*it);
3527619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe          temp_classes.erase(it);
3537619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe          requires_fixup = true;
3547619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe          break;
3557619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe        }
356e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe      }
357e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe    }
3587619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe    if (requires_fixup) {
3597619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe      FixupTempClass(self, temp_klass, klass);
3607619b5b5cf1dbef5d773f887cbe209f8e7efa072Andreas Gampe    }
361e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  }
362e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe
363691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe  void FixupTempClass(art::Thread* self,
364691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe                      art::Handle<art::mirror::Class> temp_klass,
365691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe                      art::Handle<art::mirror::Class> klass)
366e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe     REQUIRES_SHARED(art::Locks::mutator_lock_) {
367691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    // Suspend everything.
368691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    art::gc::Heap* heap = art::Runtime::Current()->GetHeap();
369691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    if (heap->IsGcConcurrentAndMoving()) {
370691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      // Need to take a heap dump while GC isn't running. See the
371691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      // comment in Heap::VisitObjects().
372691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      heap->IncrementDisableMovingGC(self);
373691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    }
374691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    {
375691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      art::ScopedThreadSuspension sts(self, art::kWaitingForVisitObjects);
376691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      art::ScopedSuspendAll ssa("FixupTempClass");
377691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe
378691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      art::mirror::Class* input = temp_klass.Get();
379691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      art::mirror::Class* output = klass.Get();
380691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe
381691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      FixupGlobalReferenceTables(input, output);
38294dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe      FixupLocalReferenceTables(self, input, output);
383a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe      FixupHeap(input, output);
384691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    }
385691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    if (heap->IsGcConcurrentAndMoving()) {
386691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      heap->DecrementDisableMovingGC(self);
387691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    }
388691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe  }
389691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe
39094dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe  class RootUpdater : public art::RootVisitor {
39194dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe   public:
39294dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    RootUpdater(const art::mirror::Class* input, art::mirror::Class* output)
39394dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe        : input_(input), output_(output) {}
39494dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe
39594dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    void VisitRoots(art::mirror::Object*** roots,
39694dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe                    size_t count,
39794dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe                    const art::RootInfo& info ATTRIBUTE_UNUSED)
39894dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe        OVERRIDE {
39994dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe      for (size_t i = 0; i != count; ++i) {
40094dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe        if (*roots[i] == input_) {
40194dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe          *roots[i] = output_;
402691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe        }
403691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      }
40494dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    }
405691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe
40694dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    void VisitRoots(art::mirror::CompressedReference<art::mirror::Object>** roots,
40794dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe                    size_t count,
40894dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe                    const art::RootInfo& info ATTRIBUTE_UNUSED)
40994dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe        OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
41094dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe      for (size_t i = 0; i != count; ++i) {
41194dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe        if (roots[i]->AsMirrorPtr() == input_) {
41294dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe          roots[i]->Assign(output_);
413691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe        }
414691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      }
41594dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    }
416691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe
41794dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe   private:
41894dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    const art::mirror::Class* input_;
41994dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    art::mirror::Class* output_;
42094dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe  };
42194dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe
422a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe  void FixupGlobalReferenceTables(art::mirror::Class* input, art::mirror::Class* output)
42394dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe      REQUIRES(art::Locks::mutator_lock_) {
42494dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    art::JavaVMExt* java_vm = art::Runtime::Current()->GetJavaVM();
42594dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe
42694dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    // Fix up the global table with a root visitor.
42794dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    RootUpdater global_update(input, output);
428691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    java_vm->VisitRoots(&global_update);
429691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe
430691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    class WeakGlobalUpdate : public art::IsMarkedVisitor {
431691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe     public:
432691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      WeakGlobalUpdate(art::mirror::Class* root_input, art::mirror::Class* root_output)
433691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe          : input_(root_input), output_(root_output) {}
434691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe
435691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      art::mirror::Object* IsMarked(art::mirror::Object* obj) OVERRIDE {
436691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe        if (obj == input_) {
437691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe          return output_;
438691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe        }
439691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe        return obj;
440691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      }
441691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe
442691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe     private:
443691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      const art::mirror::Class* input_;
444691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe      art::mirror::Class* output_;
445691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    };
446691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    WeakGlobalUpdate weak_global_update(input, output);
447691051b138e99f3aad5b95acfa5d2a434d80c777Andreas Gampe    java_vm->SweepJniWeakGlobals(&weak_global_update);
448e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  }
449e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe
45094dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe  void FixupLocalReferenceTables(art::Thread* self,
45194dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe                                 art::mirror::Class* input,
45294dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe                                 art::mirror::Class* output)
45394dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe      REQUIRES(art::Locks::mutator_lock_) {
45494dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    class LocalUpdate {
45594dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe     public:
45694dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe      LocalUpdate(const art::mirror::Class* root_input, art::mirror::Class* root_output)
45794dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe          : input_(root_input), output_(root_output) {}
45894dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe
45994dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe      static void Callback(art::Thread* t, void* arg) REQUIRES(art::Locks::mutator_lock_) {
46094dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe        LocalUpdate* local = reinterpret_cast<LocalUpdate*>(arg);
46194dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe
46294dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe        // Fix up the local table with a root visitor.
46394dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe        RootUpdater local_update(local->input_, local->output_);
46494dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe        t->GetJniEnv()->locals.VisitRoots(
46594dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe            &local_update, art::RootInfo(art::kRootJNILocal, t->GetThreadId()));
46694dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe      }
46794dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe
46894dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe     private:
46994dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe      const art::mirror::Class* input_;
47094dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe      art::mirror::Class* output_;
47194dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    };
47294dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    LocalUpdate local_upd(input, output);
47394dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    art::MutexLock mu(self, *art::Locks::thread_list_lock_);
47494dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe    art::Runtime::Current()->GetThreadList()->ForEach(LocalUpdate::Callback, &local_upd);
47594dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe  }
47694dda93b52a38656120022f0cd1095dc3994d4f2Andreas Gampe
477a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe  void FixupHeap(art::mirror::Class* input, art::mirror::Class* output)
478a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe        REQUIRES(art::Locks::mutator_lock_) {
479a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe    class HeapFixupVisitor {
480a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe     public:
481a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe      HeapFixupVisitor(const art::mirror::Class* root_input, art::mirror::Class* root_output)
482a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe                : input_(root_input), output_(root_output) {}
483a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe
484a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe      void operator()(art::mirror::Object* src,
485a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe                      art::MemberOffset field_offset,
486a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe                      bool is_static ATTRIBUTE_UNUSED) const
487a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe          REQUIRES_SHARED(art::Locks::mutator_lock_) {
488a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe        art::mirror::HeapReference<art::mirror::Object>* trg =
489a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe          src->GetFieldObjectReferenceAddr(field_offset);
490a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe        if (trg->AsMirrorPtr() == input_) {
491a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe          DCHECK_NE(field_offset.Uint32Value(), 0u);  // This shouldn't be the class field of
492a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe                                                      // an object.
493a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe          trg->Assign(output_);
494a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe        }
495a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe      }
496a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe
49752784ac8d21de0557ded4225c65cad77226dae36Andreas Gampe      void operator()(art::ObjPtr<art::mirror::Class> klass ATTRIBUTE_UNUSED,
49852784ac8d21de0557ded4225c65cad77226dae36Andreas Gampe                      art::ObjPtr<art::mirror::Reference> reference) const
49952784ac8d21de0557ded4225c65cad77226dae36Andreas Gampe          REQUIRES_SHARED(art::Locks::mutator_lock_) {
50052784ac8d21de0557ded4225c65cad77226dae36Andreas Gampe        art::mirror::Object* val = reference->GetReferent();
50152784ac8d21de0557ded4225c65cad77226dae36Andreas Gampe        if (val == input_) {
50252784ac8d21de0557ded4225c65cad77226dae36Andreas Gampe          reference->SetReferent<false>(output_);
50352784ac8d21de0557ded4225c65cad77226dae36Andreas Gampe        }
50452784ac8d21de0557ded4225c65cad77226dae36Andreas Gampe      }
50552784ac8d21de0557ded4225c65cad77226dae36Andreas Gampe
506a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe      void VisitRoot(art::mirror::CompressedReference<art::mirror::Object>* root ATTRIBUTE_UNUSED)
50752784ac8d21de0557ded4225c65cad77226dae36Andreas Gampe          const {
508a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe        LOG(FATAL) << "Unreachable";
509a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe      }
510a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe
511a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe      void VisitRootIfNonNull(
512a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe          art::mirror::CompressedReference<art::mirror::Object>* root ATTRIBUTE_UNUSED) const {
513a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe        LOG(FATAL) << "Unreachable";
514a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe      }
515a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe
516a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe      static void AllObjectsCallback(art::mirror::Object* obj, void* arg)
517a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe          REQUIRES_SHARED(art::Locks::mutator_lock_) {
518a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe        HeapFixupVisitor* hfv = reinterpret_cast<HeapFixupVisitor*>(arg);
519a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe
520a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe        // Visit references, not native roots.
52152784ac8d21de0557ded4225c65cad77226dae36Andreas Gampe        obj->VisitReferences<false>(*hfv, *hfv);
522a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe      }
523a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe
524a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe     private:
525a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe      const art::mirror::Class* input_;
526a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe      art::mirror::Class* output_;
527a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe    };
528a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe    HeapFixupVisitor hfv(input, output);
529a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe    art::Runtime::Current()->GetHeap()->VisitObjectsPaused(HeapFixupVisitor::AllObjectsCallback,
530a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe                                                           &hfv);
531a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe  }
532a67354bc353d6e55fc88b924ae0961caa633dfcaAndreas Gampe
533e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  // A set of all the temp classes we have handed out. We have to fix up references to these.
534e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  // For simplicity, we store the temp classes as JNI global references in a vector. Normally a
535e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  // Prepare event will closely follow, so the vector should be small.
536e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  std::mutex temp_classes_lock;
537e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  std::vector<jclass> temp_classes;
538e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe
539e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  EventHandler* event_handler = nullptr;
540e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe};
541e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe
542e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas GampeClassCallback gClassCallback;
543e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe
544e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampevoid ClassUtil::Register(EventHandler* handler) {
545e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  gClassCallback.event_handler = handler;
546e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  art::ScopedThreadStateChange stsc(art::Thread::Current(),
547e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe                                    art::ThreadState::kWaitingForDebuggerToAttach);
548e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  art::ScopedSuspendAll ssa("Add load callback");
549e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  art::Runtime::Current()->GetRuntimeCallbacks()->AddClassLoadCallback(&gClassCallback);
550e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe}
551e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe
552e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampevoid ClassUtil::Unregister() {
553e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  art::ScopedThreadStateChange stsc(art::Thread::Current(),
554e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe                                    art::ThreadState::kWaitingForDebuggerToAttach);
555e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  art::ScopedSuspendAll ssa("Remove thread callback");
556e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  art::Runtime* runtime = art::Runtime::Current();
557e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  runtime->GetRuntimeCallbacks()->RemoveClassLoadCallback(&gClassCallback);
558e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe}
559e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe
560ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas GampejvmtiError ClassUtil::GetClassFields(jvmtiEnv* env,
561ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe                                     jclass jklass,
562ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe                                     jint* field_count_ptr,
563ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe                                     jfieldID** fields_ptr) {
564ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
565ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass);
566ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  if (klass == nullptr) {
567ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe    return ERR(INVALID_CLASS);
568ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  }
569ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe
570ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  if (field_count_ptr == nullptr || fields_ptr == nullptr) {
571ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe    return ERR(NULL_POINTER);
572ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  }
573ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe
574ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  art::IterationRange<art::StrideIterator<art::ArtField>> ifields = klass->GetIFields();
575ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  art::IterationRange<art::StrideIterator<art::ArtField>> sfields = klass->GetSFields();
576ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  size_t array_size = klass->NumInstanceFields() + klass->NumStaticFields();
577ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe
578ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  unsigned char* out_ptr;
579ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  jvmtiError allocError = env->Allocate(array_size * sizeof(jfieldID), &out_ptr);
580ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  if (allocError != ERR(NONE)) {
581ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe    return allocError;
582ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  }
583ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  jfieldID* field_array = reinterpret_cast<jfieldID*>(out_ptr);
584ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe
585ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  size_t array_idx = 0;
586ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  for (art::ArtField& field : sfields) {
587ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe    field_array[array_idx] = art::jni::EncodeArtField(&field);
588ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe    ++array_idx;
589ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  }
590ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  for (art::ArtField& field : ifields) {
591ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe    field_array[array_idx] = art::jni::EncodeArtField(&field);
592ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe    ++array_idx;
593ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  }
594ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe
595ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  *field_count_ptr = static_cast<jint>(array_size);
596ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  *fields_ptr = field_array;
597ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe
598ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe  return ERR(NONE);
599ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe}
600ac58727f2602d1f8f5c7e5d401fa2e16e916958aAndreas Gampe
60118fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas GampejvmtiError ClassUtil::GetClassMethods(jvmtiEnv* env,
60218fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe                                      jclass jklass,
60318fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe                                      jint* method_count_ptr,
60418fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe                                      jmethodID** methods_ptr) {
60518fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
60618fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass);
60718fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  if (klass == nullptr) {
60818fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe    return ERR(INVALID_CLASS);
60918fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  }
61018fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe
61118fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  if (method_count_ptr == nullptr || methods_ptr == nullptr) {
61218fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe    return ERR(NULL_POINTER);
61318fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  }
61418fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe
61518fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  size_t array_size = klass->NumDeclaredVirtualMethods() + klass->NumDirectMethods();
61618fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  unsigned char* out_ptr;
61718fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  jvmtiError allocError = env->Allocate(array_size * sizeof(jmethodID), &out_ptr);
61818fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  if (allocError != ERR(NONE)) {
61918fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe    return allocError;
62018fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  }
62118fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  jmethodID* method_array = reinterpret_cast<jmethodID*>(out_ptr);
62218fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe
62318fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  if (art::kIsDebugBuild) {
62418fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe    size_t count = 0;
62518fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe    for (auto& m ATTRIBUTE_UNUSED : klass->GetDeclaredMethods(art::kRuntimePointerSize)) {
62618fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe      count++;
62718fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe    }
62818fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe    CHECK_EQ(count, klass->NumDirectMethods() + klass->NumDeclaredVirtualMethods());
62918fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  }
63018fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe
63118fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  size_t array_idx = 0;
63218fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  for (auto& m : klass->GetDeclaredMethods(art::kRuntimePointerSize)) {
63318fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe    method_array[array_idx] = art::jni::EncodeArtMethod(&m);
63418fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe    ++array_idx;
63518fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  }
63618fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe
63718fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  *method_count_ptr = static_cast<jint>(array_size);
63818fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  *methods_ptr = method_array;
63918fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe
64018fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe  return ERR(NONE);
64118fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe}
64218fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe
6438b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas GampejvmtiError ClassUtil::GetImplementedInterfaces(jvmtiEnv* env,
6448b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe                                               jclass jklass,
6458b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe                                               jint* interface_count_ptr,
6468b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe                                               jclass** interfaces_ptr) {
6478b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
6488b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass);
6498b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  if (klass == nullptr) {
6508b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe    return ERR(INVALID_CLASS);
6518b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  }
6528b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe
6538b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  if (interface_count_ptr == nullptr || interfaces_ptr == nullptr) {
6548b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe    return ERR(NULL_POINTER);
6558b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  }
6568b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe
6578b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  // Need to handle array specifically. Arrays implement Serializable and Cloneable, but the
6588b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  // spec says these should not be reported.
6598b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  if (klass->IsArrayClass()) {
6608b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe    *interface_count_ptr = 0;
6618b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe    *interfaces_ptr = nullptr;  // TODO: Should we allocate a dummy here?
6628b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe    return ERR(NONE);
6638b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  }
6648b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe
6658b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  size_t array_size = klass->NumDirectInterfaces();
6668b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  unsigned char* out_ptr;
6678b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  jvmtiError allocError = env->Allocate(array_size * sizeof(jclass), &out_ptr);
6688b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  if (allocError != ERR(NONE)) {
6698b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe    return allocError;
6708b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  }
6718b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  jclass* interface_array = reinterpret_cast<jclass*>(out_ptr);
6728b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe
6738b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  art::StackHandleScope<1> hs(soa.Self());
6748b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  art::Handle<art::mirror::Class> h_klass(hs.NewHandle(klass));
6758b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe
6768b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  for (uint32_t idx = 0; idx != array_size; ++idx) {
6778b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe    art::ObjPtr<art::mirror::Class> inf_klass =
6788b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe        art::mirror::Class::ResolveDirectInterface(soa.Self(), h_klass, idx);
6798b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe    if (inf_klass == nullptr) {
6808b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe      soa.Self()->ClearException();
6818b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe      env->Deallocate(out_ptr);
6828b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe      // TODO: What is the right error code here?
6838b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe      return ERR(INTERNAL);
6848b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe    }
6858b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe    interface_array[idx] = soa.AddLocalReference<jclass>(inf_klass);
6868b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  }
6878b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe
6888b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  *interface_count_ptr = static_cast<jint>(array_size);
6898b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  *interfaces_ptr = interface_array;
6908b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe
6918b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe  return ERR(NONE);
6928b07e4704f6150efdf1aed9591d9f7e4a4b0708bAndreas Gampe}
69318fee4d8e17625b4fe5e8c0439e2f259114e4099Andreas Gampe
694e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas GampejvmtiError ClassUtil::GetClassSignature(jvmtiEnv* env,
695e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe                                         jclass jklass,
696e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe                                         char** signature_ptr,
697e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe                                         char** generic_ptr) {
698e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
699e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe  art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass);
700e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe  if (klass == nullptr) {
701e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe    return ERR(INVALID_CLASS);
702e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe  }
703e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe
7045471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe  JvmtiUniquePtr<char[]> sig_copy;
705e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe  if (signature_ptr != nullptr) {
706e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe    std::string storage;
707e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe    const char* descriptor = klass->GetDescriptor(&storage);
708e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe
7095471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    jvmtiError ret;
7105471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    sig_copy = CopyString(env, descriptor, &ret);
7115471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    if (sig_copy == nullptr) {
712e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe      return ret;
713e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe    }
7145471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe    *signature_ptr = sig_copy.get();
715e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe  }
716e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe
717e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  if (generic_ptr != nullptr) {
718e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe    *generic_ptr = nullptr;
7190eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe    if (!klass->IsProxyClass() && klass->GetDexCache() != nullptr) {
7200eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe      art::StackHandleScope<1> hs(soa.Self());
7210eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe      art::Handle<art::mirror::Class> h_klass = hs.NewHandle(klass);
7220eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe      art::mirror::ObjectArray<art::mirror::String>* str_array =
7230eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe          art::annotations::GetSignatureAnnotationForClass(h_klass);
7240eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe      if (str_array != nullptr) {
7250eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe        std::ostringstream oss;
7260eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe        for (int32_t i = 0; i != str_array->GetLength(); ++i) {
7270eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe          oss << str_array->Get(i)->ToModifiedUtf8();
7280eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe        }
7290eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe        std::string output_string = oss.str();
7305471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe        jvmtiError ret;
7315471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe        JvmtiUniquePtr<char[]> copy = CopyString(env, output_string.c_str(), &ret);
7325471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe        if (copy == nullptr) {
7330eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe          return ret;
7340eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe        }
7355471141cf6631b4162b222540b531b9f493d3cb2Andreas Gampe        *generic_ptr = copy.release();
7360eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe      } else if (soa.Self()->IsExceptionPending()) {
7370eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe        // TODO: Should we report an error here?
7380eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe        soa.Self()->ClearException();
7390eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe      }
7400eb36438abb475aeffb8611cb99d1502e0df32fcAndreas Gampe    }
741e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe  }
742e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe
743e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe  // Everything is fine, release the buffers.
744e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe  sig_copy.release();
745e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe
746e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe  return ERR(NONE);
747e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe}
748e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe
749ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas GampejvmtiError ClassUtil::GetClassStatus(jvmtiEnv* env ATTRIBUTE_UNUSED,
750ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe                                     jclass jklass,
751ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe                                     jint* status_ptr) {
752ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
753ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe  art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass);
754ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe  if (klass == nullptr) {
755ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    return ERR(INVALID_CLASS);
756ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe  }
757ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe
758ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe  if (status_ptr == nullptr) {
759ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    return ERR(NULL_POINTER);
760ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe  }
761ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe
762ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe  if (klass->IsArrayClass()) {
763ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    *status_ptr = JVMTI_CLASS_STATUS_ARRAY;
764ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe  } else if (klass->IsPrimitive()) {
765ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    *status_ptr = JVMTI_CLASS_STATUS_PRIMITIVE;
766ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe  } else {
767ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    *status_ptr = JVMTI_CLASS_STATUS_VERIFIED;  // All loaded classes are structurally verified.
768ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    // This is finicky. If there's an error, we'll say it wasn't prepared.
769ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    if (klass->IsResolved()) {
770ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe      *status_ptr |= JVMTI_CLASS_STATUS_PREPARED;
771ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    }
772ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    if (klass->IsInitialized()) {
773ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe      *status_ptr |= JVMTI_CLASS_STATUS_INITIALIZED;
774ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    }
775ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    // Technically the class may be erroneous for other reasons, but we do not have enough info.
776ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    if (klass->IsErroneous()) {
777ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe      *status_ptr |= JVMTI_CLASS_STATUS_ERROR;
778ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe    }
779ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe  }
780ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe
781ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe  return ERR(NONE);
782ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe}
783ff9d209bc5bcc8355e4bdccca28672968f630e77Andreas Gampe
7844fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampetemplate <typename T>
7854fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampestatic jvmtiError ClassIsT(jclass jklass, T test, jboolean* is_t_ptr) {
7864fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
7874fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass);
7884fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  if (klass == nullptr) {
7894fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe    return ERR(INVALID_CLASS);
7904fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  }
7914fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe
7924fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  if (is_t_ptr == nullptr) {
7934fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe    return ERR(NULL_POINTER);
7944fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  }
7954fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe
7964fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  *is_t_ptr = test(klass) ? JNI_TRUE : JNI_FALSE;
7974fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  return ERR(NONE);
7984fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe}
7994fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe
8004fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas GampejvmtiError ClassUtil::IsInterface(jvmtiEnv* env ATTRIBUTE_UNUSED,
8014fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe                                  jclass jklass,
8024fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe                                  jboolean* is_interface_ptr) {
8034fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  auto test = [](art::ObjPtr<art::mirror::Class> klass) REQUIRES_SHARED(art::Locks::mutator_lock_) {
8044fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe    return klass->IsInterface();
8054fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  };
8064fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  return ClassIsT(jklass, test, is_interface_ptr);
8074fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe}
8084fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe
8094fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas GampejvmtiError ClassUtil::IsArrayClass(jvmtiEnv* env ATTRIBUTE_UNUSED,
8104fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe                                   jclass jklass,
8114fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe                                   jboolean* is_array_class_ptr) {
8124fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  auto test = [](art::ObjPtr<art::mirror::Class> klass) REQUIRES_SHARED(art::Locks::mutator_lock_) {
8134fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe    return klass->IsArrayClass();
8144fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  };
8154fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe  return ClassIsT(jklass, test, is_array_class_ptr);
8164fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe}
8174fd66ecf2e6cce6917a62c3133e7eeb35b905451Andreas Gampe
81864013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe// Keep this in sync with Class.getModifiers().
81964013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampestatic uint32_t ClassGetModifiers(art::Thread* self, art::ObjPtr<art::mirror::Class> klass)
82064013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe    REQUIRES_SHARED(art::Locks::mutator_lock_) {
82164013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  if (klass->IsArrayClass()) {
82264013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe    uint32_t component_modifiers = ClassGetModifiers(self, klass->GetComponentType());
82364013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe    if ((component_modifiers & art::kAccInterface) != 0) {
82464013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe      component_modifiers &= ~(art::kAccInterface | art::kAccStatic);
82564013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe    }
82664013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe    return art::kAccAbstract | art::kAccFinal | component_modifiers;
82764013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  }
82864013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe
82964013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  uint32_t modifiers = klass->GetAccessFlags() & art::kAccJavaFlagsMask;
83064013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe
83164013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  art::StackHandleScope<1> hs(self);
83264013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  art::Handle<art::mirror::Class> h_klass(hs.NewHandle(klass));
83364013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  return art::mirror::Class::GetInnerClassFlags(h_klass, modifiers);
83464013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe}
83564013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe
83664013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas GampejvmtiError ClassUtil::GetClassModifiers(jvmtiEnv* env ATTRIBUTE_UNUSED,
83764013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe                                        jclass jklass,
83864013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe                                        jint* modifiers_ptr) {
83964013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
84064013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass);
84164013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  if (klass == nullptr) {
84264013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe    return ERR(INVALID_CLASS);
84364013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  }
84464013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe
84564013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  if (modifiers_ptr == nullptr) {
84664013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe    return ERR(NULL_POINTER);
84764013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  }
84864013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe
84964013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  *modifiers_ptr = ClassGetModifiers(soa.Self(), klass);
85064013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe
85164013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe  return ERR(NONE);
85264013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe}
85364013e5b5a57761d9a6767b9b03ff4f15fac51c2Andreas Gampe
8548f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas GampejvmtiError ClassUtil::GetClassLoader(jvmtiEnv* env ATTRIBUTE_UNUSED,
8558f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe                                     jclass jklass,
8568f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe                                     jobject* classloader_ptr) {
8578f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
8588f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe  art::ObjPtr<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(jklass);
8598f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe  if (klass == nullptr) {
8608f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe    return ERR(INVALID_CLASS);
8618f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe  }
8628f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe
8638f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe  if (classloader_ptr == nullptr) {
8648f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe    return ERR(NULL_POINTER);
8658f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe  }
8668f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe
8678f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe  *classloader_ptr = soa.AddLocalReference<jobject>(klass->GetClassLoader());
8688f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe
8698f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe  return ERR(NONE);
8708f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe}
8718f5b603c7d1a373f2a00530f7cc8078a992e3dd7Andreas Gampe
87270f16393e7859f489e8403d2cc287db6a442455aAndreas GampejvmtiError ClassUtil::GetClassLoaderClasses(jvmtiEnv* env,
87370f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe                                            jobject initiating_loader,
87470f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe                                            jint* class_count_ptr,
87570f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe                                            jclass** classes_ptr) {
87670f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  UNUSED(env, initiating_loader, class_count_ptr, classes_ptr);
87770f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
87870f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  if (class_count_ptr == nullptr || classes_ptr == nullptr) {
87970f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    return ERR(NULL_POINTER);
88070f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  }
88170f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  art::Thread* self = art::Thread::Current();
88270f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  if (!self->GetJniEnv()->IsInstanceOf(initiating_loader,
88370f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe                                       art::WellKnownClasses::java_lang_ClassLoader)) {
88470f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    return ERR(ILLEGAL_ARGUMENT);
88570f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  }
88670f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  if (self->GetJniEnv()->IsInstanceOf(initiating_loader,
88770f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe                                      art::WellKnownClasses::java_lang_BootClassLoader)) {
88870f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    // Need to use null for the BootClassLoader.
88970f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    initiating_loader = nullptr;
89070f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  }
89170f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
89270f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  art::ScopedObjectAccess soa(self);
89370f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  art::ObjPtr<art::mirror::ClassLoader> class_loader =
89470f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe      soa.Decode<art::mirror::ClassLoader>(initiating_loader);
89570f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
89670f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
89770f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
89870f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  art::ReaderMutexLock mu(self, *art::Locks::classlinker_classes_lock_);
89970f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
90070f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  art::ClassTable* class_table = class_linker->ClassTableForClassLoader(class_loader);
90170f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  if (class_table == nullptr) {
90270f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    // Nothing loaded.
90370f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    *class_count_ptr = 0;
90470f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    *classes_ptr = nullptr;
90570f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    return ERR(NONE);
90670f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  }
90770f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
90870f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  struct ClassTableCount {
90970f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    bool operator()(art::ObjPtr<art::mirror::Class> klass) {
91070f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe      DCHECK(klass != nullptr);
91170f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe      ++count;
91270f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe      return true;
91370f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    }
91470f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
91570f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    size_t count = 0;
91670f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  };
91770f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  ClassTableCount ctc;
91870f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  class_table->Visit(ctc);
91970f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
92070f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  if (ctc.count == 0) {
92170f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    // Nothing loaded.
92270f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    *class_count_ptr = 0;
92370f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    *classes_ptr = nullptr;
92470f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    return ERR(NONE);
92570f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  }
92670f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
92770f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  unsigned char* data;
92870f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  jvmtiError data_result = env->Allocate(ctc.count * sizeof(jclass), &data);
92970f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  if (data_result != ERR(NONE)) {
93070f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    return data_result;
93170f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  }
93270f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  jclass* class_array = reinterpret_cast<jclass*>(data);
93370f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
93470f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  struct ClassTableFill {
93570f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    bool operator()(art::ObjPtr<art::mirror::Class> klass)
93670f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe        REQUIRES_SHARED(art::Locks::mutator_lock_) {
93770f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe      DCHECK(klass != nullptr);
93870f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe      DCHECK_LT(count, ctc_ref.count);
93970f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe      local_class_array[count++] = soa_ptr->AddLocalReference<jclass>(klass);
94070f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe      return true;
94170f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    }
94270f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
94370f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    jclass* local_class_array;
94470f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    const ClassTableCount& ctc_ref;
94570f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    art::ScopedObjectAccess* soa_ptr;
94670f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe    size_t count;
94770f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  };
94870f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  ClassTableFill ctf = { class_array, ctc, &soa, 0 };
94970f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  class_table->Visit(ctf);
95070f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  DCHECK_EQ(ctc.count, ctf.count);
95170f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
95270f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  *class_count_ptr = ctc.count;
95370f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  *classes_ptr = class_array;
95470f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
95570f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe  return ERR(NONE);
95670f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe}
95770f16393e7859f489e8403d2cc287db6a442455aAndreas Gampe
958812a244ff413a46ded2b87568fa88fc94561ea94Andreas GampejvmtiError ClassUtil::GetClassVersionNumbers(jvmtiEnv* env ATTRIBUTE_UNUSED,
959812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe                                             jclass jklass,
960812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe                                             jint* minor_version_ptr,
961812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe                                             jint* major_version_ptr) {
962812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  art::ScopedObjectAccess soa(art::Thread::Current());
963812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  if (jklass == nullptr) {
964812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe    return ERR(INVALID_CLASS);
965812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  }
966812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  art::ObjPtr<art::mirror::Object> jklass_obj = soa.Decode<art::mirror::Object>(jklass);
967812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  if (!jklass_obj->IsClass()) {
968812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe    return ERR(INVALID_CLASS);
969812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  }
970812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  art::ObjPtr<art::mirror::Class> klass = jklass_obj->AsClass();
971812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  if (klass->IsPrimitive() || klass->IsArrayClass()) {
972812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe    return ERR(INVALID_CLASS);
973812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  }
974812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe
975812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  if (minor_version_ptr == nullptr || major_version_ptr == nullptr) {
976812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe    return ERR(NULL_POINTER);
977812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  }
978812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe
979812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  // Note: proxies will show the dex file version of java.lang.reflect.Proxy, as that is
980812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  //       what their dex cache copies from.
981812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  uint32_t version = klass->GetDexFile().GetHeader().GetVersion();
982812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe
983812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  *major_version_ptr = static_cast<jint>(version);
984812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  *minor_version_ptr = 0;
985812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe
986812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe  return ERR(NONE);
987812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe}
988812a244ff413a46ded2b87568fa88fc94561ea94Andreas Gampe
989e492ae3e59849ee205c22cd15d3c4df2c4bc2d4cAndreas Gampe}  // namespace openjdkjvmti
990