blob: d5eccaffdc8d9ff724e0a63f13ad4b319ab01d35 [file] [log] [blame]
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001/*
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
Brian Carlstromea46f952013-07-30 01:26:50 -070017#ifndef ART_RUNTIME_MIRROR_ART_METHOD_INL_H_
18#define ART_RUNTIME_MIRROR_ART_METHOD_INL_H_
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080019
Brian Carlstromea46f952013-07-30 01:26:50 -070020#include "art_method.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080021
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080022#include "dex_file.h"
Ian Rogers7655f292013-07-29 11:07:13 -070023#include "entrypoints/entrypoint_utils.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070024#include "object_array.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080025#include "runtime.h"
26
27namespace art {
28namespace mirror {
29
Ian Rogersef7d42f2014-01-06 12:55:46 -080030inline Class* ArtMethod::GetDeclaringClass() {
31 Class* result = GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, declaring_class_),
32 false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080033 DCHECK(result != NULL) << this;
34 DCHECK(result->IsIdxLoaded() || result->IsErroneous()) << this;
35 return result;
36}
37
Brian Carlstromea46f952013-07-30 01:26:50 -070038inline void ArtMethod::SetDeclaringClass(Class *new_declaring_class) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010039 SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, declaring_class_),
40 new_declaring_class, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080041}
42
Ian Rogersef7d42f2014-01-06 12:55:46 -080043inline uint32_t ArtMethod::GetAccessFlags() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080044 DCHECK(GetDeclaringClass()->IsIdxLoaded() || GetDeclaringClass()->IsErroneous());
Brian Carlstromea46f952013-07-30 01:26:50 -070045 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, access_flags_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080046}
47
Ian Rogersef7d42f2014-01-06 12:55:46 -080048inline uint16_t ArtMethod::GetMethodIndex() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080049 DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
Brian Carlstromea46f952013-07-30 01:26:50 -070050 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080051}
52
Ian Rogersef7d42f2014-01-06 12:55:46 -080053inline uint32_t ArtMethod::GetDexMethodIndex() {
Dragos Sbirlea90af14d2013-08-15 17:50:16 -070054#ifdef ART_SEA_IR_MODE
55 // TODO: Re-add this check for (PORTABLE + SMALL + ) SEA IR when PORTABLE IS fixed!
56 // DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
57#else
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080058 DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
Dragos Sbirlea90af14d2013-08-15 17:50:16 -070059#endif
Ian Rogersef7d42f2014-01-06 12:55:46 -080060 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_method_index_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080061}
62
Ian Rogersef7d42f2014-01-06 12:55:46 -080063inline ObjectArray<String>* ArtMethod::GetDexCacheStrings() {
64 return GetFieldObject<ObjectArray<String> >(
Brian Carlstromea46f952013-07-30 01:26:50 -070065 OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_strings_), false);
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070066}
67
Ian Rogersef7d42f2014-01-06 12:55:46 -080068inline ObjectArray<ArtMethod>* ArtMethod::GetDexCacheResolvedMethods() {
69 return GetFieldObject<ObjectArray<ArtMethod> >(
Brian Carlstromea46f952013-07-30 01:26:50 -070070 OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_methods_), false);
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070071}
72
Ian Rogersef7d42f2014-01-06 12:55:46 -080073inline ObjectArray<Class>* ArtMethod::GetDexCacheResolvedTypes() {
74 return GetFieldObject<ObjectArray<Class> >(
Brian Carlstromea46f952013-07-30 01:26:50 -070075 OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_), false);
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070076}
77
Ian Rogersef7d42f2014-01-06 12:55:46 -080078inline uint32_t ArtMethod::GetCodeSize() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080079 DCHECK(!IsRuntimeMethod() && !IsProxyMethod()) << PrettyMethod(this);
Ian Rogersef7d42f2014-01-06 12:55:46 -080080 uintptr_t code = reinterpret_cast<uintptr_t>(GetEntryPointFromQuickCompiledCode());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080081 if (code == 0) {
82 return 0;
83 }
84 // TODO: make this Thumb2 specific
85 code &= ~0x1;
86 return reinterpret_cast<uint32_t*>(code)[-1];
87}
88
Brian Carlstromea46f952013-07-30 01:26:50 -070089inline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080090 switch (type) {
91 case kStatic:
92 return !IsStatic();
93 case kDirect:
94 return !IsDirect() || IsStatic();
95 case kVirtual: {
96 Class* methods_class = GetDeclaringClass();
97 return IsDirect() || (methods_class->IsInterface() && !IsMiranda());
98 }
99 case kSuper:
100 return false; // TODO: appropriate checks for call to super class.
101 case kInterface: {
102 Class* methods_class = GetDeclaringClass();
103 return IsDirect() || !(methods_class->IsInterface() || methods_class->IsObjectClass());
104 }
105 default:
106 LOG(FATAL) << "Unreachable - invocation type: " << type;
107 return true;
108 }
109}
110
Ian Rogersef7d42f2014-01-06 12:55:46 -0800111inline void ArtMethod::AssertPcIsWithinQuickCode(uintptr_t pc) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800112 if (!kIsDebugBuild) {
113 return;
114 }
115 if (IsNative() || IsRuntimeMethod() || IsProxyMethod()) {
116 return;
117 }
Ian Rogers848871b2013-08-05 10:56:33 -0700118 if (pc == GetQuickInstrumentationExitPc()) {
Jeff Hao65d15d92013-07-16 16:39:33 -0700119 return;
120 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800121 const void* code = GetEntryPointFromQuickCompiledCode();
122 if (code == GetQuickToInterpreterBridge() || code == GetQuickInstrumentationEntryPoint()) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800123 return;
124 }
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700125 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Ian Rogersef7d42f2014-01-06 12:55:46 -0800126 if (code == GetQuickResolutionTrampoline(class_linker)) {
Jeff Hao65d15d92013-07-16 16:39:33 -0700127 return;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800128 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800129 DCHECK(IsWithinQuickCode(pc))
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800130 << PrettyMethod(this)
131 << " pc=" << std::hex << pc
Jeff Hao65d15d92013-07-16 16:39:33 -0700132 << " code=" << code
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800133 << " size=" << GetCodeSize();
134}
135
Ian Rogersef7d42f2014-01-06 12:55:46 -0800136inline uint32_t ArtMethod::GetQuickOatCodeOffset() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800137 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800138 return PointerToLowMemUInt32(GetEntryPointFromQuickCompiledCode());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800139}
140
Ian Rogersef7d42f2014-01-06 12:55:46 -0800141inline uint32_t ArtMethod::GetPortableOatCodeOffset() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800142 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800143 return PointerToLowMemUInt32(GetEntryPointFromPortableCompiledCode());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800144}
145
Ian Rogersef7d42f2014-01-06 12:55:46 -0800146inline void ArtMethod::SetQuickOatCodeOffset(uint32_t code_offset) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800147 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800148 SetEntryPointFromQuickCompiledCode(reinterpret_cast<void*>(code_offset));
149}
150
151inline void ArtMethod::SetPortableOatCodeOffset(uint32_t code_offset) {
152 DCHECK(!Runtime::Current()->IsStarted());
153 SetEntryPointFromPortableCompiledCode(reinterpret_cast<void*>(code_offset));
154}
155
156inline uint32_t ArtMethod::GetOatMappingTableOffset() {
157 DCHECK(!Runtime::Current()->IsStarted());
158 return PointerToLowMemUInt32(GetMappingTable());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800159}
160
Brian Carlstromea46f952013-07-30 01:26:50 -0700161inline void ArtMethod::SetOatMappingTableOffset(uint32_t mapping_table_offset) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800162 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogers1809a722013-08-09 22:05:32 -0700163 SetMappingTable(reinterpret_cast<const uint8_t*>(mapping_table_offset));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800164}
165
Ian Rogersef7d42f2014-01-06 12:55:46 -0800166inline uint32_t ArtMethod::GetOatVmapTableOffset() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800167 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800168 return PointerToLowMemUInt32(GetVmapTable());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800169}
170
Brian Carlstromea46f952013-07-30 01:26:50 -0700171inline void ArtMethod::SetOatVmapTableOffset(uint32_t vmap_table_offset) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800172 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogers1809a722013-08-09 22:05:32 -0700173 SetVmapTable(reinterpret_cast<uint8_t*>(vmap_table_offset));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800174}
175
Brian Carlstromea46f952013-07-30 01:26:50 -0700176inline void ArtMethod::SetOatNativeGcMapOffset(uint32_t gc_map_offset) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800177 DCHECK(!Runtime::Current()->IsStarted());
178 SetNativeGcMap(reinterpret_cast<uint8_t*>(gc_map_offset));
179}
180
Ian Rogersef7d42f2014-01-06 12:55:46 -0800181inline uint32_t ArtMethod::GetOatNativeGcMapOffset() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800182 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800183 return PointerToLowMemUInt32(GetNativeGcMap());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800184}
185
Ian Rogersef7d42f2014-01-06 12:55:46 -0800186inline bool ArtMethod::IsRuntimeMethod() {
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700187 return GetDexMethodIndex() == DexFile::kDexNoIndex;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800188}
189
Ian Rogersef7d42f2014-01-06 12:55:46 -0800190inline bool ArtMethod::IsCalleeSaveMethod() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800191 if (!IsRuntimeMethod()) {
192 return false;
193 }
194 Runtime* runtime = Runtime::Current();
195 bool result = false;
196 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
197 if (this == runtime->GetCalleeSaveMethod(Runtime::CalleeSaveType(i))) {
198 result = true;
199 break;
200 }
201 }
202 return result;
203}
204
Ian Rogersef7d42f2014-01-06 12:55:46 -0800205inline bool ArtMethod::IsResolutionMethod() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800206 bool result = this == Runtime::Current()->GetResolutionMethod();
207 // Check that if we do think it is phony it looks like the resolution method.
208 DCHECK(!result || IsRuntimeMethod());
209 return result;
210}
Jeff Hao88474b42013-10-23 16:24:40 -0700211
Ian Rogersef7d42f2014-01-06 12:55:46 -0800212inline bool ArtMethod::IsImtConflictMethod() {
Jeff Hao88474b42013-10-23 16:24:40 -0700213 bool result = this == Runtime::Current()->GetImtConflictMethod();
214 // Check that if we do think it is phony it looks like the imt conflict method.
215 DCHECK(!result || IsRuntimeMethod());
216 return result;
217}
Mathieu Chartier4e305412014-02-19 10:54:44 -0800218
219template<VerifyObjectFlags kVerifyFlags>
220inline void ArtMethod::SetNativeMethod(const void* native_method) {
221 SetFieldPtr<false, true, kVerifyFlags>(
222 OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_jni_), native_method, false);
223}
224
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800225} // namespace mirror
226} // namespace art
227
Brian Carlstromea46f952013-07-30 01:26:50 -0700228#endif // ART_RUNTIME_MIRROR_ART_METHOD_INL_H_