• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_RUNTIME_MIRROR_ART_METHOD_H_
18 #define ART_RUNTIME_MIRROR_ART_METHOD_H_
19 
20 #include "class.h"
21 #include "dex_file.h"
22 #include "invoke_type.h"
23 #include "locks.h"
24 #include "modifiers.h"
25 #include "object.h"
26 
27 namespace art {
28 
29 struct ArtMethodOffsets;
30 struct ConstructorMethodOffsets;
31 union JValue;
32 struct MethodClassOffsets;
33 class MethodHelper;
34 class StringPiece;
35 class ShadowFrame;
36 
37 namespace mirror {
38 
39 class StaticStorageBase;
40 
41 typedef void (EntryPointFromInterpreter)(Thread* self, MethodHelper& mh,
42     const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame, JValue* result);
43 
44 // C++ mirror of java.lang.reflect.Method and java.lang.reflect.Constructor
45 class MANAGED ArtMethod : public Object {
46  public:
47   Class* GetDeclaringClass() const;
48 
49   void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
50 
DeclaringClassOffset()51   static MemberOffset DeclaringClassOffset() {
52     return MemberOffset(OFFSETOF_MEMBER(ArtMethod, declaring_class_));
53   }
54 
EntryPointFromCompiledCodeOffset()55   static MemberOffset EntryPointFromCompiledCodeOffset() {
56     return MemberOffset(OFFSETOF_MEMBER(ArtMethod, entry_point_from_compiled_code_));
57   }
58 
59   uint32_t GetAccessFlags() const;
60 
SetAccessFlags(uint32_t new_access_flags)61   void SetAccessFlags(uint32_t new_access_flags) {
62     SetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, access_flags_), new_access_flags, false);
63   }
64 
65   // Approximate what kind of method call would be used for this method.
66   InvokeType GetInvokeType() const;
67 
68   // Returns true if the method is declared public.
IsPublic()69   bool IsPublic() const {
70     return (GetAccessFlags() & kAccPublic) != 0;
71   }
72 
73   // Returns true if the method is declared private.
IsPrivate()74   bool IsPrivate() const {
75     return (GetAccessFlags() & kAccPrivate) != 0;
76   }
77 
78   // Returns true if the method is declared static.
IsStatic()79   bool IsStatic() const {
80     return (GetAccessFlags() & kAccStatic) != 0;
81   }
82 
83   // Returns true if the method is a constructor.
IsConstructor()84   bool IsConstructor() const {
85     return (GetAccessFlags() & kAccConstructor) != 0;
86   }
87 
88   // Returns true if the method is static, private, or a constructor.
IsDirect()89   bool IsDirect() const {
90     return IsDirect(GetAccessFlags());
91   }
92 
IsDirect(uint32_t access_flags)93   static bool IsDirect(uint32_t access_flags) {
94     return (access_flags & (kAccStatic | kAccPrivate | kAccConstructor)) != 0;
95   }
96 
97   // Returns true if the method is declared synchronized.
IsSynchronized()98   bool IsSynchronized() const {
99     uint32_t synchonized = kAccSynchronized | kAccDeclaredSynchronized;
100     return (GetAccessFlags() & synchonized) != 0;
101   }
102 
IsFinal()103   bool IsFinal() const {
104     return (GetAccessFlags() & kAccFinal) != 0;
105   }
106 
IsMiranda()107   bool IsMiranda() const {
108     return (GetAccessFlags() & kAccMiranda) != 0;
109   }
110 
IsNative()111   bool IsNative() const {
112     return (GetAccessFlags() & kAccNative) != 0;
113   }
114 
IsAbstract()115   bool IsAbstract() const {
116     return (GetAccessFlags() & kAccAbstract) != 0;
117   }
118 
IsSynthetic()119   bool IsSynthetic() const {
120     return (GetAccessFlags() & kAccSynthetic) != 0;
121   }
122 
123   bool IsProxyMethod() const;
124 
IsPreverified()125   bool IsPreverified() const {
126     return (GetAccessFlags() & kAccPreverified) != 0;
127   }
128 
SetPreverified()129   void SetPreverified() {
130     SetAccessFlags(GetAccessFlags() | kAccPreverified);
131   }
132 
133   bool CheckIncompatibleClassChange(InvokeType type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
134 
135   uint16_t GetMethodIndex() const;
136 
GetVtableIndex()137   size_t GetVtableIndex() const {
138     return GetMethodIndex();
139   }
140 
SetMethodIndex(uint16_t new_method_index)141   void SetMethodIndex(uint16_t new_method_index) {
142     SetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_), new_method_index, false);
143   }
144 
MethodIndexOffset()145   static MemberOffset MethodIndexOffset() {
146     return OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_);
147   }
148 
GetCodeItemOffset()149   uint32_t GetCodeItemOffset() const {
150     return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, code_item_offset_), false);
151   }
152 
SetCodeItemOffset(uint32_t new_code_off)153   void SetCodeItemOffset(uint32_t new_code_off) {
154     SetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, code_item_offset_), new_code_off, false);
155   }
156 
157   // Number of 32bit registers that would be required to hold all the arguments
158   static size_t NumArgRegisters(const StringPiece& shorty);
159 
160   uint32_t GetDexMethodIndex() const;
161 
SetDexMethodIndex(uint32_t new_idx)162   void SetDexMethodIndex(uint32_t new_idx) {
163     SetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_dex_index_), new_idx, false);
164   }
165 
166   ObjectArray<String>* GetDexCacheStrings() const;
167   void SetDexCacheStrings(ObjectArray<String>* new_dex_cache_strings)
168       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
169 
DexCacheStringsOffset()170   static MemberOffset DexCacheStringsOffset() {
171     return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_strings_);
172   }
173 
DexCacheResolvedMethodsOffset()174   static MemberOffset DexCacheResolvedMethodsOffset() {
175     return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_methods_);
176   }
177 
DexCacheResolvedTypesOffset()178   static MemberOffset DexCacheResolvedTypesOffset() {
179     return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_);
180   }
181 
DexCacheInitializedStaticStorageOffset()182   static MemberOffset DexCacheInitializedStaticStorageOffset() {
183     return OFFSET_OF_OBJECT_MEMBER(ArtMethod,
184         dex_cache_initialized_static_storage_);
185   }
186 
187   ObjectArray<ArtMethod>* GetDexCacheResolvedMethods() const;
188   void SetDexCacheResolvedMethods(ObjectArray<ArtMethod>* new_dex_cache_methods)
189       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
190 
191   ObjectArray<Class>* GetDexCacheResolvedTypes() const;
192   void SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_types)
193       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
194 
195   ObjectArray<StaticStorageBase>* GetDexCacheInitializedStaticStorage() const;
196   void SetDexCacheInitializedStaticStorage(ObjectArray<StaticStorageBase>* new_value)
197       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
198 
199   // Find the method that this method overrides
200   ArtMethod* FindOverriddenMethod() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
201 
202   void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result, char result_type)
203       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
204 
GetEntryPointFromInterpreter()205   EntryPointFromInterpreter* GetEntryPointFromInterpreter() const {
206     return GetFieldPtr<EntryPointFromInterpreter*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_interpreter_), false);
207   }
208 
SetEntryPointFromInterpreter(EntryPointFromInterpreter * entry_point_from_interpreter)209   void SetEntryPointFromInterpreter(EntryPointFromInterpreter* entry_point_from_interpreter) {
210     SetFieldPtr<EntryPointFromInterpreter*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_interpreter_), entry_point_from_interpreter, false);
211   }
212 
GetEntryPointFromCompiledCode()213   const void* GetEntryPointFromCompiledCode() const {
214     return GetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_compiled_code_), false);
215   }
216 
SetEntryPointFromCompiledCode(const void * entry_point_from_compiled_code)217   void SetEntryPointFromCompiledCode(const void* entry_point_from_compiled_code) {
218     SetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_compiled_code_), entry_point_from_compiled_code, false);
219   }
220 
221   uint32_t GetCodeSize() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
222 
IsWithinCode(uintptr_t pc)223   bool IsWithinCode(uintptr_t pc) const
224       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
225     uintptr_t code = reinterpret_cast<uintptr_t>(GetEntryPointFromCompiledCode());
226     if (code == 0) {
227       return pc == 0;
228     }
229     /*
230      * During a stack walk, a return PC may point to the end of the code + 1
231      * (in the case that the last instruction is a call that isn't expected to
232      * return.  Thus, we check <= code + GetCodeSize().
233      */
234     return (code <= pc && pc <= code + GetCodeSize());
235   }
236 
237   void AssertPcIsWithinCode(uintptr_t pc) const
238       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
239 
240   uint32_t GetOatCodeOffset() const;
241 
242   void SetOatCodeOffset(uint32_t code_offset);
243 
GetEntryPointFromCompiledCodeOffset()244   static MemberOffset GetEntryPointFromCompiledCodeOffset() {
245     return OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_compiled_code_);
246   }
247 
248   // Callers should wrap the uint8_t* in a MappingTable instance for convenient access.
GetMappingTable()249   const uint8_t* GetMappingTable() const {
250     return GetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, mapping_table_), false);
251   }
252 
SetMappingTable(const uint8_t * mapping_table)253   void SetMappingTable(const uint8_t* mapping_table) {
254     SetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, mapping_table_),
255                                  mapping_table, false);
256   }
257 
258   uint32_t GetOatMappingTableOffset() const;
259 
260   void SetOatMappingTableOffset(uint32_t mapping_table_offset);
261 
262   // Callers should wrap the uint8_t* in a VmapTable instance for convenient access.
GetVmapTable()263   const uint8_t* GetVmapTable() const {
264     return GetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, vmap_table_), false);
265   }
266 
SetVmapTable(const uint8_t * vmap_table)267   void SetVmapTable(const uint8_t* vmap_table) {
268     SetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, vmap_table_), vmap_table, false);
269   }
270 
271   uint32_t GetOatVmapTableOffset() const;
272 
273   void SetOatVmapTableOffset(uint32_t vmap_table_offset);
274 
GetNativeGcMap()275   const uint8_t* GetNativeGcMap() const {
276     return GetFieldPtr<uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, gc_map_), false);
277   }
SetNativeGcMap(const uint8_t * data)278   void SetNativeGcMap(const uint8_t* data) {
279     SetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, gc_map_), data, false);
280   }
281 
282   // When building the oat need a convenient place to stuff the offset of the native GC map.
283   void SetOatNativeGcMapOffset(uint32_t gc_map_offset);
284   uint32_t GetOatNativeGcMapOffset() const;
285 
GetFrameSizeInBytes()286   size_t GetFrameSizeInBytes() const {
287     DCHECK_EQ(sizeof(size_t), sizeof(uint32_t));
288     size_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, frame_size_in_bytes_), false);
289     DCHECK_LE(static_cast<size_t>(kStackAlignment), result);
290     return result;
291   }
292 
SetFrameSizeInBytes(size_t new_frame_size_in_bytes)293   void SetFrameSizeInBytes(size_t new_frame_size_in_bytes) {
294     DCHECK_EQ(sizeof(size_t), sizeof(uint32_t));
295     SetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, frame_size_in_bytes_),
296                new_frame_size_in_bytes, false);
297   }
298 
GetReturnPcOffsetInBytes()299   size_t GetReturnPcOffsetInBytes() const {
300     return GetFrameSizeInBytes() - kPointerSize;
301   }
302 
GetSirtOffsetInBytes()303   size_t GetSirtOffsetInBytes() const {
304     CHECK(IsNative());
305     return kPointerSize;
306   }
307 
308   bool IsRegistered() const;
309 
310   void RegisterNative(Thread* self, const void* native_method)
311       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
312 
313   void UnregisterNative(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
314 
NativeMethodOffset()315   static MemberOffset NativeMethodOffset() {
316     return OFFSET_OF_OBJECT_MEMBER(ArtMethod, native_method_);
317   }
318 
GetNativeMethod()319   const void* GetNativeMethod() const {
320     return reinterpret_cast<const void*>(GetField32(NativeMethodOffset(), false));
321   }
322 
323   void SetNativeMethod(const void*);
324 
GetMethodIndexOffset()325   static MemberOffset GetMethodIndexOffset() {
326     return OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_);
327   }
328 
GetCoreSpillMask()329   uint32_t GetCoreSpillMask() const {
330     return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, core_spill_mask_), false);
331   }
332 
SetCoreSpillMask(uint32_t core_spill_mask)333   void SetCoreSpillMask(uint32_t core_spill_mask) {
334     // Computed during compilation
335     SetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, core_spill_mask_), core_spill_mask, false);
336   }
337 
GetFpSpillMask()338   uint32_t GetFpSpillMask() const {
339     return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, fp_spill_mask_), false);
340   }
341 
SetFpSpillMask(uint32_t fp_spill_mask)342   void SetFpSpillMask(uint32_t fp_spill_mask) {
343     // Computed during compilation
344     SetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, fp_spill_mask_), fp_spill_mask, false);
345   }
346 
347   // Is this a CalleSaveMethod or ResolutionMethod and therefore doesn't adhere to normal
348   // conventions for a method of managed code. Returns false for Proxy methods.
349   bool IsRuntimeMethod() const;
350 
351   // Is this a hand crafted method used for something like describing callee saves?
352   bool IsCalleeSaveMethod() const;
353 
354   bool IsResolutionMethod() const;
355 
356   uintptr_t NativePcOffset(const uintptr_t pc) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
357 
358   // Converts a native PC to a dex PC.
359   uint32_t ToDexPc(const uintptr_t pc) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
360 
361   // Converts a dex PC to a native PC.
362   uintptr_t ToNativePc(const uint32_t dex_pc) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
363 
364   // Find the catch block for the given exception type and dex_pc. When a catch block is found,
365   // indicates whether the found catch block is responsible for clearing the exception or whether
366   // a move-exception instruction is present.
367   uint32_t FindCatchBlock(Class* exception_type, uint32_t dex_pc, bool* has_no_move_exception) const
368       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
369 
370   static void SetClass(Class* java_lang_reflect_ArtMethod);
371 
GetJavaLangReflectArtMethod()372   static Class* GetJavaLangReflectArtMethod() {
373     return java_lang_reflect_ArtMethod_;
374   }
375 
376   static void ResetClass();
377 
378  protected:
379   // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
380   // The class we are a part of
381   Class* declaring_class_;
382 
383   // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
384   ObjectArray<StaticStorageBase>* dex_cache_initialized_static_storage_;
385 
386   // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
387   ObjectArray<ArtMethod>* dex_cache_resolved_methods_;
388 
389   // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
390   ObjectArray<Class>* dex_cache_resolved_types_;
391 
392   // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
393   ObjectArray<String>* dex_cache_strings_;
394 
395   // Access flags; low 16 bits are defined by spec.
396   uint32_t access_flags_;
397 
398   // Offset to the CodeItem.
399   uint32_t code_item_offset_;
400 
401   // Architecture-dependent register spill mask
402   uint32_t core_spill_mask_;
403 
404   // Compiled code associated with this method for callers from managed code.
405   // May be compiled managed code or a bridge for invoking a native method.
406   // TODO: Break apart this into portable and quick.
407   const void* entry_point_from_compiled_code_;
408 
409   // Called by the interpreter to execute this method.
410   EntryPointFromInterpreter* entry_point_from_interpreter_;
411 
412   // Architecture-dependent register spill mask
413   uint32_t fp_spill_mask_;
414 
415   // Total size in bytes of the frame
416   size_t frame_size_in_bytes_;
417 
418   // Garbage collection map of native PC offsets (quick) or dex PCs (portable) to reference bitmaps.
419   const uint8_t* gc_map_;
420 
421   // Mapping from native pc to dex pc
422   const uint32_t* mapping_table_;
423 
424   // Index into method_ids of the dex file associated with this method
425   uint32_t method_dex_index_;
426 
427   // For concrete virtual methods, this is the offset of the method in Class::vtable_.
428   //
429   // For abstract methods in an interface class, this is the offset of the method in
430   // "iftable_->Get(n)->GetMethodArray()".
431   //
432   // For static and direct methods this is the index in the direct methods table.
433   uint32_t method_index_;
434 
435   // The target native method registered with this method
436   const void* native_method_;
437 
438   // When a register is promoted into a register, the spill mask holds which registers hold dex
439   // registers. The first promoted register's corresponding dex register is vmap_table_[1], the Nth
440   // is vmap_table_[N]. vmap_table_[0] holds the length of the table.
441   const uint16_t* vmap_table_;
442 
443   static Class* java_lang_reflect_ArtMethod_;
444 
445  private:
446   friend struct art::ArtMethodOffsets;  // for verifying offset information
447   DISALLOW_IMPLICIT_CONSTRUCTORS(ArtMethod);
448 };
449 
450 class MANAGED ArtMethodClass : public Class {
451  private:
452   DISALLOW_IMPLICIT_CONSTRUCTORS(ArtMethodClass);
453 };
454 
455 }  // namespace mirror
456 }  // namespace art
457 
458 #endif  // ART_RUNTIME_MIRROR_ART_METHOD_H_
459