xref: /aosp_15_r20/art/openjdkjvmti/ti_redefine.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /* Copyright (C) 2016 The Android Open Source Project
2*795d594fSAndroid Build Coastguard Worker  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * This file implements interfaces from the file jvmti.h. This implementation
5*795d594fSAndroid Build Coastguard Worker  * is licensed under the same terms as the file jvmti.h.  The
6*795d594fSAndroid Build Coastguard Worker  * copyright and license information for the file jvmti.h follows.
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
9*795d594fSAndroid Build Coastguard Worker  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10*795d594fSAndroid Build Coastguard Worker  *
11*795d594fSAndroid Build Coastguard Worker  * This code is free software; you can redistribute it and/or modify it
12*795d594fSAndroid Build Coastguard Worker  * under the terms of the GNU General Public License version 2 only, as
13*795d594fSAndroid Build Coastguard Worker  * published by the Free Software Foundation.  Oracle designates this
14*795d594fSAndroid Build Coastguard Worker  * particular file as subject to the "Classpath" exception as provided
15*795d594fSAndroid Build Coastguard Worker  * by Oracle in the LICENSE file that accompanied this code.
16*795d594fSAndroid Build Coastguard Worker  *
17*795d594fSAndroid Build Coastguard Worker  * This code is distributed in the hope that it will be useful, but WITHOUT
18*795d594fSAndroid Build Coastguard Worker  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19*795d594fSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20*795d594fSAndroid Build Coastguard Worker  * version 2 for more details (a copy is included in the LICENSE file that
21*795d594fSAndroid Build Coastguard Worker  * accompanied this code).
22*795d594fSAndroid Build Coastguard Worker  *
23*795d594fSAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License version
24*795d594fSAndroid Build Coastguard Worker  * 2 along with this work; if not, write to the Free Software Foundation,
25*795d594fSAndroid Build Coastguard Worker  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26*795d594fSAndroid Build Coastguard Worker  *
27*795d594fSAndroid Build Coastguard Worker  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28*795d594fSAndroid Build Coastguard Worker  * or visit www.oracle.com if you need additional information or have any
29*795d594fSAndroid Build Coastguard Worker  * questions.
30*795d594fSAndroid Build Coastguard Worker  */
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker #ifndef ART_OPENJDKJVMTI_TI_REDEFINE_H_
33*795d594fSAndroid Build Coastguard Worker #define ART_OPENJDKJVMTI_TI_REDEFINE_H_
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker #include <functional>
36*795d594fSAndroid Build Coastguard Worker #include <string>
37*795d594fSAndroid Build Coastguard Worker 
38*795d594fSAndroid Build Coastguard Worker #include <jni.h>
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker #include "art_field.h"
41*795d594fSAndroid Build Coastguard Worker #include "art_jvmti.h"
42*795d594fSAndroid Build Coastguard Worker #include "base/array_ref.h"
43*795d594fSAndroid Build Coastguard Worker #include "base/globals.h"
44*795d594fSAndroid Build Coastguard Worker #include "dex/class_accessor.h"
45*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file.h"
46*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_structs.h"
47*795d594fSAndroid Build Coastguard Worker #include "jni/jni_env_ext-inl.h"
48*795d594fSAndroid Build Coastguard Worker #include "jvmti.h"
49*795d594fSAndroid Build Coastguard Worker #include "mirror/array.h"
50*795d594fSAndroid Build Coastguard Worker #include "mirror/class.h"
51*795d594fSAndroid Build Coastguard Worker #include "mirror/dex_cache.h"
52*795d594fSAndroid Build Coastguard Worker #include "obj_ptr.h"
53*795d594fSAndroid Build Coastguard Worker 
54*795d594fSAndroid Build Coastguard Worker namespace art {
55*795d594fSAndroid Build Coastguard Worker class ClassAccessor;
56*795d594fSAndroid Build Coastguard Worker namespace dex {
57*795d594fSAndroid Build Coastguard Worker struct ClassDef;
58*795d594fSAndroid Build Coastguard Worker }  // namespace dex
59*795d594fSAndroid Build Coastguard Worker }  // namespace art
60*795d594fSAndroid Build Coastguard Worker 
61*795d594fSAndroid Build Coastguard Worker namespace openjdkjvmti {
62*795d594fSAndroid Build Coastguard Worker 
63*795d594fSAndroid Build Coastguard Worker class ArtClassDefinition;
64*795d594fSAndroid Build Coastguard Worker class RedefinitionDataHolder;
65*795d594fSAndroid Build Coastguard Worker class RedefinitionDataIter;
66*795d594fSAndroid Build Coastguard Worker 
67*795d594fSAndroid Build Coastguard Worker enum class RedefinitionType {
68*795d594fSAndroid Build Coastguard Worker   kStructural,
69*795d594fSAndroid Build Coastguard Worker   kNormal,
70*795d594fSAndroid Build Coastguard Worker };
71*795d594fSAndroid Build Coastguard Worker 
72*795d594fSAndroid Build Coastguard Worker // Class that can redefine a single class's methods.
73*795d594fSAndroid Build Coastguard Worker class Redefiner {
74*795d594fSAndroid Build Coastguard Worker  public:
75*795d594fSAndroid Build Coastguard Worker   // Redefine the given classes with the given dex data. Note this function does not take ownership
76*795d594fSAndroid Build Coastguard Worker   // of the dex_data pointers. It is not used after this call however and may be freed if desired.
77*795d594fSAndroid Build Coastguard Worker   // The caller is responsible for freeing it. The runtime makes its own copy of the data. This
78*795d594fSAndroid Build Coastguard Worker   // function does not call the transformation events.
79*795d594fSAndroid Build Coastguard Worker   static jvmtiError RedefineClassesDirect(ArtJvmTiEnv* env,
80*795d594fSAndroid Build Coastguard Worker                                           art::Runtime* runtime,
81*795d594fSAndroid Build Coastguard Worker                                           art::Thread* self,
82*795d594fSAndroid Build Coastguard Worker                                           const std::vector<ArtClassDefinition>& definitions,
83*795d594fSAndroid Build Coastguard Worker                                           RedefinitionType type,
84*795d594fSAndroid Build Coastguard Worker                                           /*out*/std::string* error_msg);
85*795d594fSAndroid Build Coastguard Worker 
86*795d594fSAndroid Build Coastguard Worker   // Redefine the given classes with the given dex data. Note this function does not take ownership
87*795d594fSAndroid Build Coastguard Worker   // of the dex_data pointers. It is not used after this call however and may be freed if desired.
88*795d594fSAndroid Build Coastguard Worker   // The caller is responsible for freeing it. The runtime makes its own copy of the data.
89*795d594fSAndroid Build Coastguard Worker   static jvmtiError RedefineClasses(jvmtiEnv* env,
90*795d594fSAndroid Build Coastguard Worker                                     jint class_count,
91*795d594fSAndroid Build Coastguard Worker                                     const jvmtiClassDefinition* definitions);
92*795d594fSAndroid Build Coastguard Worker   static jvmtiError StructurallyRedefineClasses(jvmtiEnv* env,
93*795d594fSAndroid Build Coastguard Worker                                                 jint class_count,
94*795d594fSAndroid Build Coastguard Worker                                                 const jvmtiClassDefinition* definitions);
95*795d594fSAndroid Build Coastguard Worker 
96*795d594fSAndroid Build Coastguard Worker   static jvmtiError IsModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_redefinable);
97*795d594fSAndroid Build Coastguard Worker   static jvmtiError IsStructurallyModifiableClass(jvmtiEnv* env,
98*795d594fSAndroid Build Coastguard Worker                                                   jclass klass,
99*795d594fSAndroid Build Coastguard Worker                                                   jboolean* is_redefinable);
100*795d594fSAndroid Build Coastguard Worker 
101*795d594fSAndroid Build Coastguard Worker   static art::MemMap MoveDataToMemMap(const std::string& original_location,
102*795d594fSAndroid Build Coastguard Worker                                       art::ArrayRef<const unsigned char> data,
103*795d594fSAndroid Build Coastguard Worker                                       std::string* error_msg);
104*795d594fSAndroid Build Coastguard Worker 
105*795d594fSAndroid Build Coastguard Worker   // Helper for checking if redefinition/retransformation is allowed.
106*795d594fSAndroid Build Coastguard Worker   template <RedefinitionType kType = RedefinitionType::kNormal>
107*795d594fSAndroid Build Coastguard Worker   static jvmtiError CanRedefineClass(jclass klass, /*out*/ std::string* error_msg)
108*795d594fSAndroid Build Coastguard Worker       REQUIRES(!art::Locks::mutator_lock_);
109*795d594fSAndroid Build Coastguard Worker 
110*795d594fSAndroid Build Coastguard Worker   static jvmtiError StructurallyRedefineClassDirect(jvmtiEnv* env,
111*795d594fSAndroid Build Coastguard Worker                                                     jclass klass,
112*795d594fSAndroid Build Coastguard Worker                                                     const unsigned char* data,
113*795d594fSAndroid Build Coastguard Worker                                                     jint data_size);
114*795d594fSAndroid Build Coastguard Worker 
115*795d594fSAndroid Build Coastguard Worker  private:
116*795d594fSAndroid Build Coastguard Worker   class ClassRedefinition {
117*795d594fSAndroid Build Coastguard Worker    public:
118*795d594fSAndroid Build Coastguard Worker     ClassRedefinition(Redefiner* driver,
119*795d594fSAndroid Build Coastguard Worker                       jclass klass,
120*795d594fSAndroid Build Coastguard Worker                       const art::DexFile* redefined_dex_file,
121*795d594fSAndroid Build Coastguard Worker                       const char* class_sig,
122*795d594fSAndroid Build Coastguard Worker                       art::ArrayRef<const unsigned char> orig_dex_file)
123*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(art::Locks::mutator_lock_);
124*795d594fSAndroid Build Coastguard Worker 
125*795d594fSAndroid Build Coastguard Worker     // NO_THREAD_SAFETY_ANALYSIS so we can unlock the class in the destructor.
126*795d594fSAndroid Build Coastguard Worker     ~ClassRedefinition() NO_THREAD_SAFETY_ANALYSIS;
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker     // Move assignment so we can sort these in a vector.
129*795d594fSAndroid Build Coastguard Worker     ClassRedefinition& operator=(ClassRedefinition&& other) noexcept {
130*795d594fSAndroid Build Coastguard Worker       driver_ = other.driver_;
131*795d594fSAndroid Build Coastguard Worker       klass_ = other.klass_;
132*795d594fSAndroid Build Coastguard Worker       dex_file_ = std::move(other.dex_file_);
133*795d594fSAndroid Build Coastguard Worker       class_sig_ = std::move(other.class_sig_);
134*795d594fSAndroid Build Coastguard Worker       original_dex_file_ = other.original_dex_file_;
135*795d594fSAndroid Build Coastguard Worker       other.driver_ = nullptr;
136*795d594fSAndroid Build Coastguard Worker       return *this;
137*795d594fSAndroid Build Coastguard Worker     }
138*795d594fSAndroid Build Coastguard Worker 
139*795d594fSAndroid Build Coastguard Worker     // Move constructor so we can put these into a vector.
ClassRedefinition(ClassRedefinition && other)140*795d594fSAndroid Build Coastguard Worker     ClassRedefinition(ClassRedefinition&& other) noexcept
141*795d594fSAndroid Build Coastguard Worker         : driver_(other.driver_),
142*795d594fSAndroid Build Coastguard Worker           klass_(other.klass_),
143*795d594fSAndroid Build Coastguard Worker           dex_file_(std::move(other.dex_file_)),
144*795d594fSAndroid Build Coastguard Worker           class_sig_(std::move(other.class_sig_)),
145*795d594fSAndroid Build Coastguard Worker           original_dex_file_(other.original_dex_file_) {
146*795d594fSAndroid Build Coastguard Worker       other.driver_ = nullptr;
147*795d594fSAndroid Build Coastguard Worker     }
148*795d594fSAndroid Build Coastguard Worker 
149*795d594fSAndroid Build Coastguard Worker     // No copy!
150*795d594fSAndroid Build Coastguard Worker     ClassRedefinition(ClassRedefinition&) = delete;
151*795d594fSAndroid Build Coastguard Worker     ClassRedefinition& operator=(ClassRedefinition&) = delete;
152*795d594fSAndroid Build Coastguard Worker 
153*795d594fSAndroid Build Coastguard Worker     art::ObjPtr<art::mirror::Class> GetMirrorClass() REQUIRES_SHARED(art::Locks::mutator_lock_);
154*795d594fSAndroid Build Coastguard Worker     art::ObjPtr<art::mirror::ClassLoader> GetClassLoader()
155*795d594fSAndroid Build Coastguard Worker         REQUIRES_SHARED(art::Locks::mutator_lock_);
156*795d594fSAndroid Build Coastguard Worker 
GetDexFile()157*795d594fSAndroid Build Coastguard Worker     const art::DexFile& GetDexFile() {
158*795d594fSAndroid Build Coastguard Worker       return *dex_file_;
159*795d594fSAndroid Build Coastguard Worker     }
160*795d594fSAndroid Build Coastguard Worker 
161*795d594fSAndroid Build Coastguard Worker     art::mirror::DexCache* CreateNewDexCache(art::Handle<art::mirror::ClassLoader> loader)
162*795d594fSAndroid Build Coastguard Worker         REQUIRES_SHARED(art::Locks::mutator_lock_);
163*795d594fSAndroid Build Coastguard Worker 
164*795d594fSAndroid Build Coastguard Worker     // This may return nullptr with a OOME pending if allocation fails.
165*795d594fSAndroid Build Coastguard Worker     art::mirror::Object* AllocateOrGetOriginalDexFile()
166*795d594fSAndroid Build Coastguard Worker         REQUIRES_SHARED(art::Locks::mutator_lock_);
167*795d594fSAndroid Build Coastguard Worker 
RecordFailure(jvmtiError e,const std::string & err)168*795d594fSAndroid Build Coastguard Worker     void RecordFailure(jvmtiError e, const std::string& err) {
169*795d594fSAndroid Build Coastguard Worker       driver_->RecordFailure(e, class_sig_, err);
170*795d594fSAndroid Build Coastguard Worker     }
171*795d594fSAndroid Build Coastguard Worker 
172*795d594fSAndroid Build Coastguard Worker     bool FinishRemainingCommonAllocations(/*out*/RedefinitionDataIter* cur_data)
173*795d594fSAndroid Build Coastguard Worker         REQUIRES_SHARED(art::Locks::mutator_lock_);
174*795d594fSAndroid Build Coastguard Worker 
175*795d594fSAndroid Build Coastguard Worker     bool FinishNewClassAllocations(RedefinitionDataHolder& holder,
176*795d594fSAndroid Build Coastguard Worker                                    /*out*/RedefinitionDataIter* cur_data)
177*795d594fSAndroid Build Coastguard Worker         REQUIRES_SHARED(art::Locks::mutator_lock_);
178*795d594fSAndroid Build Coastguard Worker     bool CollectAndCreateNewInstances(/*out*/RedefinitionDataIter* cur_data)
179*795d594fSAndroid Build Coastguard Worker         REQUIRES_SHARED(art::Locks::mutator_lock_);
180*795d594fSAndroid Build Coastguard Worker 
181*795d594fSAndroid Build Coastguard Worker     bool AllocateAndRememberNewDexFileCookie(
182*795d594fSAndroid Build Coastguard Worker         art::Handle<art::mirror::ClassLoader> source_class_loader,
183*795d594fSAndroid Build Coastguard Worker         art::Handle<art::mirror::Object> dex_file_obj,
184*795d594fSAndroid Build Coastguard Worker         /*out*/RedefinitionDataIter* cur_data)
185*795d594fSAndroid Build Coastguard Worker           REQUIRES_SHARED(art::Locks::mutator_lock_);
186*795d594fSAndroid Build Coastguard Worker 
187*795d594fSAndroid Build Coastguard Worker     void FindAndAllocateObsoleteMethods(art::ObjPtr<art::mirror::Class> art_klass)
188*795d594fSAndroid Build Coastguard Worker         REQUIRES(art::Locks::mutator_lock_);
189*795d594fSAndroid Build Coastguard Worker 
190*795d594fSAndroid Build Coastguard Worker     art::ObjPtr<art::mirror::Class> AllocateNewClassObject(
191*795d594fSAndroid Build Coastguard Worker         art::Handle<art::mirror::Class> old_class,
192*795d594fSAndroid Build Coastguard Worker         art::Handle<art::mirror::Class> super_class,
193*795d594fSAndroid Build Coastguard Worker         art::Handle<art::mirror::DexCache> cache,
194*795d594fSAndroid Build Coastguard Worker         uint16_t dex_class_def_index) REQUIRES_SHARED(art::Locks::mutator_lock_);
195*795d594fSAndroid Build Coastguard Worker     art::ObjPtr<art::mirror::Class> AllocateNewClassObject(art::Handle<art::mirror::DexCache> cache)
196*795d594fSAndroid Build Coastguard Worker         REQUIRES_SHARED(art::Locks::mutator_lock_);
197*795d594fSAndroid Build Coastguard Worker 
198*795d594fSAndroid Build Coastguard Worker     uint32_t GetNewClassSize(art::ClassAccessor& accessor)
199*795d594fSAndroid Build Coastguard Worker         REQUIRES_SHARED(art::Locks::mutator_lock_);
200*795d594fSAndroid Build Coastguard Worker 
201*795d594fSAndroid Build Coastguard Worker     // Checks that the dex file contains only the single expected class and that the top-level class
202*795d594fSAndroid Build Coastguard Worker     // data has not been modified in an incompatible manner.
203*795d594fSAndroid Build Coastguard Worker     bool CheckClass() REQUIRES_SHARED(art::Locks::mutator_lock_);
204*795d594fSAndroid Build Coastguard Worker 
205*795d594fSAndroid Build Coastguard Worker     // Checks that the contained class can be successfully verified.
206*795d594fSAndroid Build Coastguard Worker     bool CheckVerification(const RedefinitionDataIter& holder)
207*795d594fSAndroid Build Coastguard Worker         REQUIRES_SHARED(art::Locks::mutator_lock_);
208*795d594fSAndroid Build Coastguard Worker 
209*795d594fSAndroid Build Coastguard Worker     // Preallocates all needed allocations in klass so that we can pause execution safely.
210*795d594fSAndroid Build Coastguard Worker     bool EnsureClassAllocationsFinished(/*out*/RedefinitionDataIter* data)
211*795d594fSAndroid Build Coastguard Worker         REQUIRES_SHARED(art::Locks::mutator_lock_);
212*795d594fSAndroid Build Coastguard Worker 
213*795d594fSAndroid Build Coastguard Worker     // This will check that no constraints are violated (more than 1 class in dex file, any changes
214*795d594fSAndroid Build Coastguard Worker     // in number/declaration of methods & fields, changes in access flags, etc.)
215*795d594fSAndroid Build Coastguard Worker     bool CheckRedefinitionIsValid() REQUIRES_SHARED(art::Locks::mutator_lock_);
216*795d594fSAndroid Build Coastguard Worker 
217*795d594fSAndroid Build Coastguard Worker     // Checks that the class can even be redefined.
218*795d594fSAndroid Build Coastguard Worker     bool CheckRedefinable() REQUIRES_SHARED(art::Locks::mutator_lock_);
219*795d594fSAndroid Build Coastguard Worker 
220*795d594fSAndroid Build Coastguard Worker     // Checks that the dex file does not add/remove methods, or change their modifiers or types in
221*795d594fSAndroid Build Coastguard Worker     // illegal ways.
222*795d594fSAndroid Build Coastguard Worker     bool CheckMethods() REQUIRES_SHARED(art::Locks::mutator_lock_);
223*795d594fSAndroid Build Coastguard Worker 
224*795d594fSAndroid Build Coastguard Worker     // Checks that the dex file does not modify fields types or modifiers in illegal ways.
225*795d594fSAndroid Build Coastguard Worker     bool CheckFields() REQUIRES_SHARED(art::Locks::mutator_lock_);
226*795d594fSAndroid Build Coastguard Worker 
227*795d594fSAndroid Build Coastguard Worker     // Temporary check that a class undergoing structural redefinition has no instances. This
228*795d594fSAndroid Build Coastguard Worker     // requirement will be removed in time.
229*795d594fSAndroid Build Coastguard Worker     void UpdateJavaDexFile(art::ObjPtr<art::mirror::Object> java_dex_file,
230*795d594fSAndroid Build Coastguard Worker                            art::ObjPtr<art::mirror::LongArray> new_cookie)
231*795d594fSAndroid Build Coastguard Worker         REQUIRES(art::Locks::mutator_lock_);
232*795d594fSAndroid Build Coastguard Worker 
233*795d594fSAndroid Build Coastguard Worker     void UpdateFields(art::ObjPtr<art::mirror::Class> mclass)
234*795d594fSAndroid Build Coastguard Worker         REQUIRES(art::Locks::mutator_lock_);
235*795d594fSAndroid Build Coastguard Worker 
236*795d594fSAndroid Build Coastguard Worker     void UpdateMethods(art::ObjPtr<art::mirror::Class> mclass,
237*795d594fSAndroid Build Coastguard Worker                        const art::dex::ClassDef& class_def)
238*795d594fSAndroid Build Coastguard Worker         REQUIRES(art::Locks::mutator_lock_);
239*795d594fSAndroid Build Coastguard Worker 
240*795d594fSAndroid Build Coastguard Worker     void UpdateClass(const RedefinitionDataIter& cur_data)
241*795d594fSAndroid Build Coastguard Worker         REQUIRES(art::Locks::mutator_lock_);
242*795d594fSAndroid Build Coastguard Worker 
243*795d594fSAndroid Build Coastguard Worker     void CollectNewFieldAndMethodMappings(const RedefinitionDataIter& data,
244*795d594fSAndroid Build Coastguard Worker                                           std::map<art::ArtMethod*, art::ArtMethod*>* method_map,
245*795d594fSAndroid Build Coastguard Worker                                           std::map<art::ArtField*, art::ArtField*>* field_map)
246*795d594fSAndroid Build Coastguard Worker         REQUIRES(art::Locks::mutator_lock_);
247*795d594fSAndroid Build Coastguard Worker 
248*795d594fSAndroid Build Coastguard Worker     void RestoreObsoleteMethodMapsIfUnneeded(const RedefinitionDataIter* cur_data)
249*795d594fSAndroid Build Coastguard Worker         REQUIRES(art::Locks::mutator_lock_);
250*795d594fSAndroid Build Coastguard Worker 
251*795d594fSAndroid Build Coastguard Worker     void ReleaseDexFile() REQUIRES_SHARED(art::Locks::mutator_lock_);
252*795d594fSAndroid Build Coastguard Worker 
253*795d594fSAndroid Build Coastguard Worker     // This should be done with all threads suspended.
254*795d594fSAndroid Build Coastguard Worker     void UnregisterJvmtiBreakpoints() REQUIRES_SHARED(art::Locks::mutator_lock_);
255*795d594fSAndroid Build Coastguard Worker 
256*795d594fSAndroid Build Coastguard Worker     void RecordNewMethodAdded();
257*795d594fSAndroid Build Coastguard Worker     void RecordNewFieldAdded();
RecordHasVirtualMembers()258*795d594fSAndroid Build Coastguard Worker     void RecordHasVirtualMembers() {
259*795d594fSAndroid Build Coastguard Worker       has_virtuals_ = true;
260*795d594fSAndroid Build Coastguard Worker     }
261*795d594fSAndroid Build Coastguard Worker 
HasVirtualMembers()262*795d594fSAndroid Build Coastguard Worker     bool HasVirtualMembers() const {
263*795d594fSAndroid Build Coastguard Worker       return has_virtuals_;
264*795d594fSAndroid Build Coastguard Worker     }
265*795d594fSAndroid Build Coastguard Worker 
IsStructuralRedefinition()266*795d594fSAndroid Build Coastguard Worker     bool IsStructuralRedefinition() const {
267*795d594fSAndroid Build Coastguard Worker       DCHECK(!(added_fields_ || added_methods_) || driver_->IsStructuralRedefinition())
268*795d594fSAndroid Build Coastguard Worker           << "added_fields_: " << added_fields_ << " added_methods_: " << added_methods_
269*795d594fSAndroid Build Coastguard Worker           << " driver_->IsStructuralRedefinition(): " << driver_->IsStructuralRedefinition();
270*795d594fSAndroid Build Coastguard Worker       return driver_->IsStructuralRedefinition() && (added_fields_ || added_methods_);
271*795d594fSAndroid Build Coastguard Worker     }
272*795d594fSAndroid Build Coastguard Worker 
273*795d594fSAndroid Build Coastguard Worker    private:
274*795d594fSAndroid Build Coastguard Worker     void UpdateClassStructurally(const RedefinitionDataIter& cur_data)
275*795d594fSAndroid Build Coastguard Worker         REQUIRES(art::Locks::mutator_lock_);
276*795d594fSAndroid Build Coastguard Worker 
277*795d594fSAndroid Build Coastguard Worker     void UpdateClassInPlace(const RedefinitionDataIter& cur_data)
278*795d594fSAndroid Build Coastguard Worker         REQUIRES(art::Locks::mutator_lock_);
279*795d594fSAndroid Build Coastguard Worker 
280*795d594fSAndroid Build Coastguard Worker     Redefiner* driver_;
281*795d594fSAndroid Build Coastguard Worker     jclass klass_;
282*795d594fSAndroid Build Coastguard Worker     std::unique_ptr<const art::DexFile> dex_file_;
283*795d594fSAndroid Build Coastguard Worker     std::string class_sig_;
284*795d594fSAndroid Build Coastguard Worker     art::ArrayRef<const unsigned char> original_dex_file_;
285*795d594fSAndroid Build Coastguard Worker 
286*795d594fSAndroid Build Coastguard Worker     bool added_fields_ = false;
287*795d594fSAndroid Build Coastguard Worker     bool added_methods_ = false;
288*795d594fSAndroid Build Coastguard Worker     bool has_virtuals_ = false;
289*795d594fSAndroid Build Coastguard Worker   };
290*795d594fSAndroid Build Coastguard Worker 
291*795d594fSAndroid Build Coastguard Worker   ArtJvmTiEnv* env_;
292*795d594fSAndroid Build Coastguard Worker   jvmtiError result_;
293*795d594fSAndroid Build Coastguard Worker   art::Runtime* runtime_;
294*795d594fSAndroid Build Coastguard Worker   art::Thread* self_;
295*795d594fSAndroid Build Coastguard Worker   RedefinitionType type_;
296*795d594fSAndroid Build Coastguard Worker   std::vector<ClassRedefinition> redefinitions_;
297*795d594fSAndroid Build Coastguard Worker   // Kept as a jclass since we have weird run-state changes that make keeping it around as a
298*795d594fSAndroid Build Coastguard Worker   // mirror::Class difficult and confusing.
299*795d594fSAndroid Build Coastguard Worker   std::string* error_msg_;
300*795d594fSAndroid Build Coastguard Worker 
Redefiner(ArtJvmTiEnv * env,art::Runtime * runtime,art::Thread * self,RedefinitionType type,std::string * error_msg)301*795d594fSAndroid Build Coastguard Worker   Redefiner(ArtJvmTiEnv* env,
302*795d594fSAndroid Build Coastguard Worker             art::Runtime* runtime,
303*795d594fSAndroid Build Coastguard Worker             art::Thread* self,
304*795d594fSAndroid Build Coastguard Worker             RedefinitionType type,
305*795d594fSAndroid Build Coastguard Worker             std::string* error_msg)
306*795d594fSAndroid Build Coastguard Worker       : env_(env),
307*795d594fSAndroid Build Coastguard Worker         result_(ERR(INTERNAL)),
308*795d594fSAndroid Build Coastguard Worker         runtime_(runtime),
309*795d594fSAndroid Build Coastguard Worker         self_(self),
310*795d594fSAndroid Build Coastguard Worker         type_(type),
311*795d594fSAndroid Build Coastguard Worker         redefinitions_(),
312*795d594fSAndroid Build Coastguard Worker         error_msg_(error_msg) { }
313*795d594fSAndroid Build Coastguard Worker 
314*795d594fSAndroid Build Coastguard Worker   jvmtiError AddRedefinition(ArtJvmTiEnv* env, const ArtClassDefinition& def)
315*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(art::Locks::mutator_lock_);
316*795d594fSAndroid Build Coastguard Worker 
317*795d594fSAndroid Build Coastguard Worker   template<RedefinitionType kType = RedefinitionType::kNormal>
318*795d594fSAndroid Build Coastguard Worker   static jvmtiError RedefineClassesGeneric(jvmtiEnv* env,
319*795d594fSAndroid Build Coastguard Worker                                            jint class_count,
320*795d594fSAndroid Build Coastguard Worker                                            const jvmtiClassDefinition* definitions);
321*795d594fSAndroid Build Coastguard Worker 
322*795d594fSAndroid Build Coastguard Worker   template<RedefinitionType kType = RedefinitionType::kNormal>
323*795d594fSAndroid Build Coastguard Worker   static jvmtiError IsModifiableClassGeneric(jvmtiEnv* env, jclass klass, jboolean* is_redefinable);
324*795d594fSAndroid Build Coastguard Worker 
325*795d594fSAndroid Build Coastguard Worker   template <RedefinitionType kType = RedefinitionType::kNormal>
326*795d594fSAndroid Build Coastguard Worker   static jvmtiError CanRedefineClass(art::Handle<art::mirror::Class> klass,
327*795d594fSAndroid Build Coastguard Worker                                      /*out*/ std::string* error_msg)
328*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(art::Locks::mutator_lock_);
329*795d594fSAndroid Build Coastguard Worker 
330*795d594fSAndroid Build Coastguard Worker   jvmtiError Run() REQUIRES_SHARED(art::Locks::mutator_lock_);
331*795d594fSAndroid Build Coastguard Worker 
332*795d594fSAndroid Build Coastguard Worker   bool CheckAllRedefinitionAreValid() REQUIRES_SHARED(art::Locks::mutator_lock_);
333*795d594fSAndroid Build Coastguard Worker   bool CheckAllClassesAreVerified(RedefinitionDataHolder& holder)
334*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(art::Locks::mutator_lock_);
335*795d594fSAndroid Build Coastguard Worker   void MarkStructuralChanges(RedefinitionDataHolder& holder)
336*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(art::Locks::mutator_lock_);
337*795d594fSAndroid Build Coastguard Worker   bool EnsureAllClassAllocationsFinished(RedefinitionDataHolder& holder)
338*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(art::Locks::mutator_lock_);
339*795d594fSAndroid Build Coastguard Worker   bool FinishAllRemainingCommonAllocations(RedefinitionDataHolder& holder)
340*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(art::Locks::mutator_lock_);
341*795d594fSAndroid Build Coastguard Worker   bool FinishAllNewClassAllocations(RedefinitionDataHolder& holder)
342*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(art::Locks::mutator_lock_);
343*795d594fSAndroid Build Coastguard Worker   bool CollectAndCreateNewInstances(RedefinitionDataHolder& holder)
344*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(art::Locks::mutator_lock_);
345*795d594fSAndroid Build Coastguard Worker   void ReleaseAllDexFiles() REQUIRES_SHARED(art::Locks::mutator_lock_);
346*795d594fSAndroid Build Coastguard Worker   void ReverifyClasses(RedefinitionDataHolder& holder) REQUIRES_SHARED(art::Locks::mutator_lock_);
347*795d594fSAndroid Build Coastguard Worker   void UnregisterAllBreakpoints() REQUIRES_SHARED(art::Locks::mutator_lock_);
348*795d594fSAndroid Build Coastguard Worker   // Restores the old obsolete methods maps if it turns out they weren't needed (ie there were no
349*795d594fSAndroid Build Coastguard Worker   // new obsolete methods).
350*795d594fSAndroid Build Coastguard Worker   void RestoreObsoleteMethodMapsIfUnneeded(RedefinitionDataHolder& holder)
351*795d594fSAndroid Build Coastguard Worker       REQUIRES(art::Locks::mutator_lock_);
352*795d594fSAndroid Build Coastguard Worker 
IsStructuralRedefinition()353*795d594fSAndroid Build Coastguard Worker   bool IsStructuralRedefinition() const {
354*795d594fSAndroid Build Coastguard Worker     return type_ == RedefinitionType::kStructural;
355*795d594fSAndroid Build Coastguard Worker   }
356*795d594fSAndroid Build Coastguard Worker 
357*795d594fSAndroid Build Coastguard Worker   void RecordFailure(jvmtiError result, const std::string& class_sig, const std::string& error_msg);
RecordFailure(jvmtiError result,const std::string & error_msg)358*795d594fSAndroid Build Coastguard Worker   void RecordFailure(jvmtiError result, const std::string& error_msg) {
359*795d594fSAndroid Build Coastguard Worker     RecordFailure(result, "NO CLASS", error_msg);
360*795d594fSAndroid Build Coastguard Worker   }
361*795d594fSAndroid Build Coastguard Worker 
362*795d594fSAndroid Build Coastguard Worker   friend struct CallbackCtx;
363*795d594fSAndroid Build Coastguard Worker   friend class RedefinitionDataHolder;
364*795d594fSAndroid Build Coastguard Worker   friend class RedefinitionDataIter;
365*795d594fSAndroid Build Coastguard Worker };
366*795d594fSAndroid Build Coastguard Worker 
367*795d594fSAndroid Build Coastguard Worker }  // namespace openjdkjvmti
368*795d594fSAndroid Build Coastguard Worker 
369*795d594fSAndroid Build Coastguard Worker #endif  // ART_OPENJDKJVMTI_TI_REDEFINE_H_
370