blob: 5d62b88a0bb66745ee685ede3966d2464464af6a [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"
Vladimir Marko96c6ab92014-04-08 14:00:50 +010025#include "oat.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080026#include "runtime.h"
27
28namespace art {
29namespace mirror {
30
Ian Rogersef7d42f2014-01-06 12:55:46 -080031inline Class* ArtMethod::GetDeclaringClass() {
32 Class* result = GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, declaring_class_),
33 false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080034 DCHECK(result != NULL) << this;
35 DCHECK(result->IsIdxLoaded() || result->IsErroneous()) << this;
36 return result;
37}
38
Brian Carlstromea46f952013-07-30 01:26:50 -070039inline void ArtMethod::SetDeclaringClass(Class *new_declaring_class) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010040 SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, declaring_class_),
41 new_declaring_class, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080042}
43
Ian Rogersef7d42f2014-01-06 12:55:46 -080044inline uint32_t ArtMethod::GetAccessFlags() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080045 DCHECK(GetDeclaringClass()->IsIdxLoaded() || GetDeclaringClass()->IsErroneous());
Brian Carlstromea46f952013-07-30 01:26:50 -070046 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, access_flags_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080047}
48
Ian Rogersef7d42f2014-01-06 12:55:46 -080049inline uint16_t ArtMethod::GetMethodIndex() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080050 DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
Brian Carlstromea46f952013-07-30 01:26:50 -070051 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080052}
53
Ian Rogersef7d42f2014-01-06 12:55:46 -080054inline uint32_t ArtMethod::GetDexMethodIndex() {
Dragos Sbirlea90af14d2013-08-15 17:50:16 -070055#ifdef ART_SEA_IR_MODE
56 // TODO: Re-add this check for (PORTABLE + SMALL + ) SEA IR when PORTABLE IS fixed!
57 // DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
58#else
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080059 DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
Dragos Sbirlea90af14d2013-08-15 17:50:16 -070060#endif
Ian Rogersef7d42f2014-01-06 12:55:46 -080061 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_method_index_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080062}
63
Ian Rogersef7d42f2014-01-06 12:55:46 -080064inline ObjectArray<String>* ArtMethod::GetDexCacheStrings() {
65 return GetFieldObject<ObjectArray<String> >(
Brian Carlstromea46f952013-07-30 01:26:50 -070066 OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_strings_), false);
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070067}
68
Ian Rogersef7d42f2014-01-06 12:55:46 -080069inline ObjectArray<ArtMethod>* ArtMethod::GetDexCacheResolvedMethods() {
70 return GetFieldObject<ObjectArray<ArtMethod> >(
Brian Carlstromea46f952013-07-30 01:26:50 -070071 OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_methods_), false);
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070072}
73
Ian Rogersef7d42f2014-01-06 12:55:46 -080074inline ObjectArray<Class>* ArtMethod::GetDexCacheResolvedTypes() {
75 return GetFieldObject<ObjectArray<Class> >(
Brian Carlstromea46f952013-07-30 01:26:50 -070076 OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_), false);
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070077}
78
Ian Rogersef7d42f2014-01-06 12:55:46 -080079inline uint32_t ArtMethod::GetCodeSize() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080080 DCHECK(!IsRuntimeMethod() && !IsProxyMethod()) << PrettyMethod(this);
Ian Rogersef7d42f2014-01-06 12:55:46 -080081 uintptr_t code = reinterpret_cast<uintptr_t>(GetEntryPointFromQuickCompiledCode());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080082 if (code == 0) {
83 return 0;
84 }
85 // TODO: make this Thumb2 specific
86 code &= ~0x1;
Vladimir Marko96c6ab92014-04-08 14:00:50 +010087 return reinterpret_cast<OatMethodHeader*>(code)[-1].code_size_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080088}
89
Brian Carlstromea46f952013-07-30 01:26:50 -070090inline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080091 switch (type) {
92 case kStatic:
93 return !IsStatic();
94 case kDirect:
95 return !IsDirect() || IsStatic();
96 case kVirtual: {
97 Class* methods_class = GetDeclaringClass();
98 return IsDirect() || (methods_class->IsInterface() && !IsMiranda());
99 }
100 case kSuper:
101 return false; // TODO: appropriate checks for call to super class.
102 case kInterface: {
103 Class* methods_class = GetDeclaringClass();
104 return IsDirect() || !(methods_class->IsInterface() || methods_class->IsObjectClass());
105 }
106 default:
107 LOG(FATAL) << "Unreachable - invocation type: " << type;
108 return true;
109 }
110}
111
Ian Rogersef7d42f2014-01-06 12:55:46 -0800112inline void ArtMethod::AssertPcIsWithinQuickCode(uintptr_t pc) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800113 if (!kIsDebugBuild) {
114 return;
115 }
116 if (IsNative() || IsRuntimeMethod() || IsProxyMethod()) {
117 return;
118 }
Ian Rogers848871b2013-08-05 10:56:33 -0700119 if (pc == GetQuickInstrumentationExitPc()) {
Jeff Hao65d15d92013-07-16 16:39:33 -0700120 return;
121 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800122 const void* code = GetEntryPointFromQuickCompiledCode();
123 if (code == GetQuickToInterpreterBridge() || code == GetQuickInstrumentationEntryPoint()) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800124 return;
125 }
Jeff Hao0aba0ba2013-06-03 14:49:28 -0700126 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Ian Rogersef7d42f2014-01-06 12:55:46 -0800127 if (code == GetQuickResolutionTrampoline(class_linker)) {
Jeff Hao65d15d92013-07-16 16:39:33 -0700128 return;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800129 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800130 DCHECK(IsWithinQuickCode(pc))
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800131 << PrettyMethod(this)
132 << " pc=" << std::hex << pc
Jeff Hao65d15d92013-07-16 16:39:33 -0700133 << " code=" << code
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800134 << " size=" << GetCodeSize();
135}
136
Ian Rogersef7d42f2014-01-06 12:55:46 -0800137inline uint32_t ArtMethod::GetQuickOatCodeOffset() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800138 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800139 return PointerToLowMemUInt32(GetEntryPointFromQuickCompiledCode());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800140}
141
Ian Rogersef7d42f2014-01-06 12:55:46 -0800142inline uint32_t ArtMethod::GetPortableOatCodeOffset() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800143 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800144 return PointerToLowMemUInt32(GetEntryPointFromPortableCompiledCode());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800145}
146
Ian Rogersef7d42f2014-01-06 12:55:46 -0800147inline void ArtMethod::SetQuickOatCodeOffset(uint32_t code_offset) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800148 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800149 SetEntryPointFromQuickCompiledCode(reinterpret_cast<void*>(code_offset));
150}
151
152inline void ArtMethod::SetPortableOatCodeOffset(uint32_t code_offset) {
153 DCHECK(!Runtime::Current()->IsStarted());
154 SetEntryPointFromPortableCompiledCode(reinterpret_cast<void*>(code_offset));
155}
156
157inline uint32_t ArtMethod::GetOatMappingTableOffset() {
158 DCHECK(!Runtime::Current()->IsStarted());
159 return PointerToLowMemUInt32(GetMappingTable());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800160}
161
Brian Carlstromea46f952013-07-30 01:26:50 -0700162inline void ArtMethod::SetOatMappingTableOffset(uint32_t mapping_table_offset) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800163 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogers1809a722013-08-09 22:05:32 -0700164 SetMappingTable(reinterpret_cast<const uint8_t*>(mapping_table_offset));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800165}
166
Ian Rogersef7d42f2014-01-06 12:55:46 -0800167inline uint32_t ArtMethod::GetOatVmapTableOffset() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800168 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800169 return PointerToLowMemUInt32(GetVmapTable());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800170}
171
Brian Carlstromea46f952013-07-30 01:26:50 -0700172inline void ArtMethod::SetOatVmapTableOffset(uint32_t vmap_table_offset) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800173 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogers1809a722013-08-09 22:05:32 -0700174 SetVmapTable(reinterpret_cast<uint8_t*>(vmap_table_offset));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800175}
176
Brian Carlstromea46f952013-07-30 01:26:50 -0700177inline void ArtMethod::SetOatNativeGcMapOffset(uint32_t gc_map_offset) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800178 DCHECK(!Runtime::Current()->IsStarted());
179 SetNativeGcMap(reinterpret_cast<uint8_t*>(gc_map_offset));
180}
181
Ian Rogersef7d42f2014-01-06 12:55:46 -0800182inline uint32_t ArtMethod::GetOatNativeGcMapOffset() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800183 DCHECK(!Runtime::Current()->IsStarted());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800184 return PointerToLowMemUInt32(GetNativeGcMap());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800185}
186
Ian Rogersef7d42f2014-01-06 12:55:46 -0800187inline bool ArtMethod::IsRuntimeMethod() {
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700188 return GetDexMethodIndex() == DexFile::kDexNoIndex;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800189}
190
Ian Rogersef7d42f2014-01-06 12:55:46 -0800191inline bool ArtMethod::IsCalleeSaveMethod() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800192 if (!IsRuntimeMethod()) {
193 return false;
194 }
195 Runtime* runtime = Runtime::Current();
196 bool result = false;
197 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
198 if (this == runtime->GetCalleeSaveMethod(Runtime::CalleeSaveType(i))) {
199 result = true;
200 break;
201 }
202 }
203 return result;
204}
205
Ian Rogersef7d42f2014-01-06 12:55:46 -0800206inline bool ArtMethod::IsResolutionMethod() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800207 bool result = this == Runtime::Current()->GetResolutionMethod();
208 // Check that if we do think it is phony it looks like the resolution method.
209 DCHECK(!result || IsRuntimeMethod());
210 return result;
211}
Jeff Hao88474b42013-10-23 16:24:40 -0700212
Ian Rogersef7d42f2014-01-06 12:55:46 -0800213inline bool ArtMethod::IsImtConflictMethod() {
Jeff Hao88474b42013-10-23 16:24:40 -0700214 bool result = this == Runtime::Current()->GetImtConflictMethod();
215 // Check that if we do think it is phony it looks like the imt conflict method.
216 DCHECK(!result || IsRuntimeMethod());
217 return result;
218}
Mathieu Chartier4e305412014-02-19 10:54:44 -0800219
220template<VerifyObjectFlags kVerifyFlags>
221inline void ArtMethod::SetNativeMethod(const void* native_method) {
222 SetFieldPtr<false, true, kVerifyFlags>(
223 OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_jni_), native_method, false);
224}
225
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800226} // namespace mirror
227} // namespace art
228
Brian Carlstromea46f952013-07-30 01:26:50 -0700229#endif // ART_RUNTIME_MIRROR_ART_METHOD_INL_H_