| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 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 |  | 
| Mathieu Chartier | c785344 | 2015-03-27 14:35:38 -0700 | [diff] [blame] | 17 | #ifndef ART_RUNTIME_ART_FIELD_INL_H_ | 
 | 18 | #define ART_RUNTIME_ART_FIELD_INL_H_ | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 19 |  | 
| Brian Carlstrom | ea46f95 | 2013-07-30 01:26:50 -0700 | [diff] [blame] | 20 | #include "art_field.h" | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 21 |  | 
| Andreas Gampe | 5794381 | 2017-12-06 21:39:13 -0800 | [diff] [blame] | 22 | #include <android-base/logging.h> | 
 | 23 |  | 
| Vladimir Marko | 18090d1 | 2018-06-01 16:53:12 +0100 | [diff] [blame] | 24 | #include "class_linker-inl.h" | 
| David Sehr | 9e734c7 | 2018-01-04 17:56:19 -0800 | [diff] [blame] | 25 | #include "dex/dex_file-inl.h" | 
| David Sehr | 67bf42e | 2018-02-26 16:43:04 -0800 | [diff] [blame] | 26 | #include "dex/primitive.h" | 
| Ian Rogers | 1d54e73 | 2013-05-02 21:10:01 -0700 | [diff] [blame] | 27 | #include "gc/accounting/card_table-inl.h" | 
| Andreas Gampe | 8cf9cb3 | 2017-07-19 09:28:38 -0700 | [diff] [blame] | 28 | #include "gc_root-inl.h" | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 29 | #include "jvalue.h" | 
| Vladimir Marko | 05792b9 | 2015-08-03 11:56:49 +0100 | [diff] [blame] | 30 | #include "mirror/dex_cache-inl.h" | 
| Mathieu Chartier | c785344 | 2015-03-27 14:35:38 -0700 | [diff] [blame] | 31 | #include "mirror/object-inl.h" | 
| Vladimir Marko | c524e9e | 2019-03-26 10:54:50 +0000 | [diff] [blame] | 32 | #include "obj_ptr-inl.h" | 
| Andreas Gampe | 8cf9cb3 | 2017-07-19 09:28:38 -0700 | [diff] [blame] | 33 | #include "thread-current-inl.h" | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 34 |  | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 35 | namespace art { | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 36 |  | 
| Vladimir Marko | 09c5ca4 | 2018-05-31 15:15:31 +0100 | [diff] [blame] | 37 | inline bool ArtField::IsProxyField() { | 
| Vladimir Marko | 415ac85 | 2019-03-21 12:49:10 +0000 | [diff] [blame] | 38 |   // No read barrier needed, we're reading the constant declaring class only to read | 
 | 39 |   // the constant proxy flag. See ReadBarrierOption. | 
| Vladimir Marko | 09c5ca4 | 2018-05-31 15:15:31 +0100 | [diff] [blame] | 40 |   return GetDeclaringClass<kWithoutReadBarrier>()->IsProxyClass<kVerifyNone>(); | 
 | 41 | } | 
 | 42 |  | 
| Hiroshi Yamauchi | 7a62e67 | 2016-06-10 17:22:48 -0700 | [diff] [blame] | 43 | template<ReadBarrierOption kReadBarrierOption> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 44 | inline ObjPtr<mirror::Class> ArtField::GetDeclaringClass() { | 
| Hiroshi Yamauchi | 3f64f25 | 2015-06-12 18:35:06 -0700 | [diff] [blame] | 45 |   GcRootSource gc_root_source(this); | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 46 |   ObjPtr<mirror::Class> result = declaring_class_.Read<kReadBarrierOption>(&gc_root_source); | 
| Mathieu Chartier | c785344 | 2015-03-27 14:35:38 -0700 | [diff] [blame] | 47 |   DCHECK(result != nullptr); | 
| Vladimir Marko | 09c5ca4 | 2018-05-31 15:15:31 +0100 | [diff] [blame] | 48 |   DCHECK(result->IsIdxLoaded() || result->IsErroneous()) << result->GetStatus(); | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 49 |   return result; | 
 | 50 | } | 
 | 51 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 52 | inline void ArtField::SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_class) { | 
| Mathieu Chartier | c785344 | 2015-03-27 14:35:38 -0700 | [diff] [blame] | 53 |   declaring_class_ = GcRoot<mirror::Class>(new_declaring_class); | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 54 | } | 
 | 55 |  | 
| Ian Rogers | ef7d42f | 2014-01-06 12:55:46 -0800 | [diff] [blame] | 56 | inline MemberOffset ArtField::GetOffsetDuringLinking() { | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 57 |   DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous()); | 
| Mathieu Chartier | c785344 | 2015-03-27 14:35:38 -0700 | [diff] [blame] | 58 |   return MemberOffset(offset_); | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 59 | } | 
 | 60 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 61 | inline uint32_t ArtField::Get32(ObjPtr<mirror::Object> object) { | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 62 |   DCHECK(object != nullptr) << PrettyField(); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 63 |   DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); | 
| Ian Rogers | b0fa5dc | 2014-04-28 16:47:08 -0700 | [diff] [blame] | 64 |   if (UNLIKELY(IsVolatile())) { | 
 | 65 |     return object->GetField32Volatile(GetOffset()); | 
 | 66 |   } | 
 | 67 |   return object->GetField32(GetOffset()); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 68 | } | 
 | 69 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 70 | template<bool kTransactionActive> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 71 | inline void ArtField::Set32(ObjPtr<mirror::Object> object, uint32_t new_value) { | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 72 |   DCHECK(object != nullptr) << PrettyField(); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 73 |   DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); | 
| Ian Rogers | b0fa5dc | 2014-04-28 16:47:08 -0700 | [diff] [blame] | 74 |   if (UNLIKELY(IsVolatile())) { | 
 | 75 |     object->SetField32Volatile<kTransactionActive>(GetOffset(), new_value); | 
 | 76 |   } else { | 
 | 77 |     object->SetField32<kTransactionActive>(GetOffset(), new_value); | 
 | 78 |   } | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 79 | } | 
 | 80 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 81 | inline uint64_t ArtField::Get64(ObjPtr<mirror::Object> object) { | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 82 |   DCHECK(object != nullptr) << PrettyField(); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 83 |   DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); | 
| Ian Rogers | b0fa5dc | 2014-04-28 16:47:08 -0700 | [diff] [blame] | 84 |   if (UNLIKELY(IsVolatile())) { | 
 | 85 |     return object->GetField64Volatile(GetOffset()); | 
 | 86 |   } | 
 | 87 |   return object->GetField64(GetOffset()); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 88 | } | 
 | 89 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 90 | template<bool kTransactionActive> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 91 | inline void ArtField::Set64(ObjPtr<mirror::Object> object, uint64_t new_value) { | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 92 |   DCHECK(object != nullptr) << PrettyField(); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 93 |   DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); | 
| Ian Rogers | b0fa5dc | 2014-04-28 16:47:08 -0700 | [diff] [blame] | 94 |   if (UNLIKELY(IsVolatile())) { | 
 | 95 |     object->SetField64Volatile<kTransactionActive>(GetOffset(), new_value); | 
 | 96 |   } else { | 
 | 97 |     object->SetField64<kTransactionActive>(GetOffset(), new_value); | 
 | 98 |   } | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 99 | } | 
 | 100 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 101 | template<class MirrorType> | 
 | 102 | inline ObjPtr<MirrorType> ArtField::GetObj(ObjPtr<mirror::Object> object) { | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 103 |   DCHECK(object != nullptr) << PrettyField(); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 104 |   DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); | 
| Ian Rogers | b0fa5dc | 2014-04-28 16:47:08 -0700 | [diff] [blame] | 105 |   if (UNLIKELY(IsVolatile())) { | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 106 |     return object->GetFieldObjectVolatile<MirrorType>(GetOffset()); | 
| Ian Rogers | b0fa5dc | 2014-04-28 16:47:08 -0700 | [diff] [blame] | 107 |   } | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 108 |   return object->GetFieldObject<MirrorType>(GetOffset()); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 109 | } | 
 | 110 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 111 | template<bool kTransactionActive> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 112 | inline void ArtField::SetObj(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> new_value) { | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 113 |   DCHECK(object != nullptr) << PrettyField(); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 114 |   DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); | 
| Ian Rogers | b0fa5dc | 2014-04-28 16:47:08 -0700 | [diff] [blame] | 115 |   if (UNLIKELY(IsVolatile())) { | 
| Mathieu Chartier | 1a5337f | 2016-10-13 13:48:23 -0700 | [diff] [blame] | 116 |     object->SetFieldObjectVolatile<kTransactionActive>(GetOffset(), new_value); | 
| Ian Rogers | b0fa5dc | 2014-04-28 16:47:08 -0700 | [diff] [blame] | 117 |   } else { | 
| Mathieu Chartier | 1a5337f | 2016-10-13 13:48:23 -0700 | [diff] [blame] | 118 |     object->SetFieldObject<kTransactionActive>(GetOffset(), new_value); | 
| Ian Rogers | b0fa5dc | 2014-04-28 16:47:08 -0700 | [diff] [blame] | 119 |   } | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 120 | } | 
 | 121 |  | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 122 | #define FIELD_GET(object, type) \ | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 123 |   DCHECK_EQ(Primitive::kPrim ## type, GetTypeAsPrimitiveType()) << PrettyField(); \ | 
 | 124 |   DCHECK((object) != nullptr) << PrettyField(); \ | 
| Chih-Hung Hsieh | fba3997 | 2016-05-11 11:26:48 -0700 | [diff] [blame] | 125 |   DCHECK(!IsStatic() || ((object) == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \ | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 126 |   if (UNLIKELY(IsVolatile())) { \ | 
| Chih-Hung Hsieh | fba3997 | 2016-05-11 11:26:48 -0700 | [diff] [blame] | 127 |     return (object)->GetField ## type ## Volatile(GetOffset()); \ | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 128 |   } \ | 
| Chih-Hung Hsieh | fba3997 | 2016-05-11 11:26:48 -0700 | [diff] [blame] | 129 |   return (object)->GetField ## type(GetOffset()); | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 130 |  | 
 | 131 | #define FIELD_SET(object, type, value) \ | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 132 |   DCHECK((object) != nullptr) << PrettyField(); \ | 
| Chih-Hung Hsieh | fba3997 | 2016-05-11 11:26:48 -0700 | [diff] [blame] | 133 |   DCHECK(!IsStatic() || ((object) == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \ | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 134 |   if (UNLIKELY(IsVolatile())) { \ | 
| Chih-Hung Hsieh | fba3997 | 2016-05-11 11:26:48 -0700 | [diff] [blame] | 135 |     (object)->SetField ## type ## Volatile<kTransactionActive>(GetOffset(), value); \ | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 136 |   } else { \ | 
| Chih-Hung Hsieh | fba3997 | 2016-05-11 11:26:48 -0700 | [diff] [blame] | 137 |     (object)->SetField ## type<kTransactionActive>(GetOffset(), value); \ | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 138 |   } | 
 | 139 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 140 | inline uint8_t ArtField::GetBoolean(ObjPtr<mirror::Object> object) { | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 141 |   FIELD_GET(object, Boolean); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 142 | } | 
 | 143 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 144 | template<bool kTransactionActive> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 145 | inline void ArtField::SetBoolean(ObjPtr<mirror::Object> object, uint8_t z) { | 
| Nicolas Geoffray | 5b3c6c0 | 2017-01-19 14:22:26 +0000 | [diff] [blame] | 146 |   if (kIsDebugBuild) { | 
 | 147 |     // For simplicity, this method is being called by the compiler entrypoint for | 
 | 148 |     // both boolean and byte fields. | 
 | 149 |     Primitive::Type type = GetTypeAsPrimitiveType(); | 
 | 150 |     DCHECK(type == Primitive::kPrimBoolean || type == Primitive::kPrimByte) << PrettyField(); | 
 | 151 |   } | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 152 |   FIELD_SET(object, Boolean, z); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 153 | } | 
 | 154 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 155 | inline int8_t ArtField::GetByte(ObjPtr<mirror::Object> object) { | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 156 |   FIELD_GET(object, Byte); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 157 | } | 
 | 158 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 159 | template<bool kTransactionActive> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 160 | inline void ArtField::SetByte(ObjPtr<mirror::Object> object, int8_t b) { | 
| Nicolas Geoffray | 5b3c6c0 | 2017-01-19 14:22:26 +0000 | [diff] [blame] | 161 |   DCHECK_EQ(Primitive::kPrimByte, GetTypeAsPrimitiveType()) << PrettyField(); | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 162 |   FIELD_SET(object, Byte, b); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 163 | } | 
 | 164 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 165 | inline uint16_t ArtField::GetChar(ObjPtr<mirror::Object> object) { | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 166 |   FIELD_GET(object, Char); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 167 | } | 
 | 168 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 169 | template<bool kTransactionActive> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 170 | inline void ArtField::SetChar(ObjPtr<mirror::Object> object, uint16_t c) { | 
| Nicolas Geoffray | 5b3c6c0 | 2017-01-19 14:22:26 +0000 | [diff] [blame] | 171 |   if (kIsDebugBuild) { | 
 | 172 |     // For simplicity, this method is being called by the compiler entrypoint for | 
 | 173 |     // both char and short fields. | 
 | 174 |     Primitive::Type type = GetTypeAsPrimitiveType(); | 
 | 175 |     DCHECK(type == Primitive::kPrimChar || type == Primitive::kPrimShort) << PrettyField(); | 
 | 176 |   } | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 177 |   FIELD_SET(object, Char, c); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 178 | } | 
 | 179 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 180 | inline int16_t ArtField::GetShort(ObjPtr<mirror::Object> object) { | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 181 |   FIELD_GET(object, Short); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 182 | } | 
 | 183 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 184 | template<bool kTransactionActive> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 185 | inline void ArtField::SetShort(ObjPtr<mirror::Object> object, int16_t s) { | 
| Nicolas Geoffray | 5b3c6c0 | 2017-01-19 14:22:26 +0000 | [diff] [blame] | 186 |   DCHECK_EQ(Primitive::kPrimShort, GetTypeAsPrimitiveType()) << PrettyField(); | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 187 |   FIELD_SET(object, Short, s); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 188 | } | 
 | 189 |  | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 190 | #undef FIELD_GET | 
 | 191 | #undef FIELD_SET | 
 | 192 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 193 | inline int32_t ArtField::GetInt(ObjPtr<mirror::Object> object) { | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 194 |   if (kIsDebugBuild) { | 
| Nicolas Geoffray | 5b3c6c0 | 2017-01-19 14:22:26 +0000 | [diff] [blame] | 195 |     // For simplicity, this method is being called by the compiler entrypoint for | 
 | 196 |     // both int and float fields. | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 197 |     Primitive::Type type = GetTypeAsPrimitiveType(); | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 198 |     CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(); | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 199 |   } | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 200 |   return Get32(object); | 
 | 201 | } | 
 | 202 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 203 | template<bool kTransactionActive> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 204 | inline void ArtField::SetInt(ObjPtr<mirror::Object> object, int32_t i) { | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 205 |   if (kIsDebugBuild) { | 
| Nicolas Geoffray | 5b3c6c0 | 2017-01-19 14:22:26 +0000 | [diff] [blame] | 206 |     // For simplicity, this method is being called by the compiler entrypoint for | 
 | 207 |     // both int and float fields. | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 208 |     Primitive::Type type = GetTypeAsPrimitiveType(); | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 209 |     CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(); | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 210 |   } | 
 | 211 |   Set32<kTransactionActive>(object, i); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 212 | } | 
 | 213 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 214 | inline int64_t ArtField::GetLong(ObjPtr<mirror::Object> object) { | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 215 |   if (kIsDebugBuild) { | 
| Nicolas Geoffray | 5b3c6c0 | 2017-01-19 14:22:26 +0000 | [diff] [blame] | 216 |     // For simplicity, this method is being called by the compiler entrypoint for | 
 | 217 |     // both long and double fields. | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 218 |     Primitive::Type type = GetTypeAsPrimitiveType(); | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 219 |     CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(); | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 220 |   } | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 221 |   return Get64(object); | 
 | 222 | } | 
 | 223 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 224 | template<bool kTransactionActive> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 225 | inline void ArtField::SetLong(ObjPtr<mirror::Object> object, int64_t j) { | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 226 |   if (kIsDebugBuild) { | 
| Nicolas Geoffray | 5b3c6c0 | 2017-01-19 14:22:26 +0000 | [diff] [blame] | 227 |     // For simplicity, this method is being called by the compiler entrypoint for | 
 | 228 |     // both long and double fields. | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 229 |     Primitive::Type type = GetTypeAsPrimitiveType(); | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 230 |     CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(); | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 231 |   } | 
 | 232 |   Set64<kTransactionActive>(object, j); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 233 | } | 
 | 234 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 235 | inline float ArtField::GetFloat(ObjPtr<mirror::Object> object) { | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 236 |   DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 237 |   JValue bits; | 
 | 238 |   bits.SetI(Get32(object)); | 
 | 239 |   return bits.GetF(); | 
 | 240 | } | 
 | 241 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 242 | template<bool kTransactionActive> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 243 | inline void ArtField::SetFloat(ObjPtr<mirror::Object> object, float f) { | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 244 |   DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 245 |   JValue bits; | 
 | 246 |   bits.SetF(f); | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 247 |   Set32<kTransactionActive>(object, bits.GetI()); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 248 | } | 
 | 249 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 250 | inline double ArtField::GetDouble(ObjPtr<mirror::Object> object) { | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 251 |   DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 252 |   JValue bits; | 
 | 253 |   bits.SetJ(Get64(object)); | 
 | 254 |   return bits.GetD(); | 
 | 255 | } | 
 | 256 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 257 | template<bool kTransactionActive> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 258 | inline void ArtField::SetDouble(ObjPtr<mirror::Object> object, double d) { | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 259 |   DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 260 |   JValue bits; | 
 | 261 |   bits.SetD(d); | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 262 |   Set64<kTransactionActive>(object, bits.GetJ()); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 263 | } | 
 | 264 |  | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 265 | inline ObjPtr<mirror::Object> ArtField::GetObject(ObjPtr<mirror::Object> object) { | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 266 |   DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 267 |   return GetObj(object); | 
 | 268 | } | 
 | 269 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 270 | template<bool kTransactionActive> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 271 | inline void ArtField::SetObject(ObjPtr<mirror::Object> object, ObjPtr<mirror::Object> l) { | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 272 |   DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(); | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 273 |   SetObj<kTransactionActive>(object, l); | 
| Ian Rogers | c0fa3ad | 2013-02-05 00:11:55 -0800 | [diff] [blame] | 274 | } | 
 | 275 |  | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 276 | inline const char* ArtField::GetName() REQUIRES_SHARED(Locks::mutator_lock_) { | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 277 |   uint32_t field_index = GetDexFieldIndex(); | 
| Vladimir Marko | 415ac85 | 2019-03-21 12:49:10 +0000 | [diff] [blame] | 278 |   if (UNLIKELY(IsProxyField())) { | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 279 |     DCHECK(IsStatic()); | 
 | 280 |     DCHECK_LT(field_index, 2U); | 
 | 281 |     return field_index == 0 ? "interfaces" : "throws"; | 
 | 282 |   } | 
 | 283 |   const DexFile* dex_file = GetDexFile(); | 
 | 284 |   return dex_file->GetFieldName(dex_file->GetFieldId(field_index)); | 
 | 285 | } | 
 | 286 |  | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 287 | inline const char* ArtField::GetTypeDescriptor() REQUIRES_SHARED(Locks::mutator_lock_) { | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 288 |   uint32_t field_index = GetDexFieldIndex(); | 
| Vladimir Marko | 415ac85 | 2019-03-21 12:49:10 +0000 | [diff] [blame] | 289 |   if (UNLIKELY(IsProxyField())) { | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 290 |     DCHECK(IsStatic()); | 
 | 291 |     DCHECK_LT(field_index, 2U); | 
 | 292 |     // 0 == Class[] interfaces; 1 == Class[][] throws; | 
 | 293 |     return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;"; | 
 | 294 |   } | 
 | 295 |   const DexFile* dex_file = GetDexFile(); | 
| Andreas Gampe | 3f1dcd3 | 2018-12-28 09:39:56 -0800 | [diff] [blame] | 296 |   const dex::FieldId& field_id = dex_file->GetFieldId(field_index); | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 297 |   return dex_file->GetFieldTypeDescriptor(field_id); | 
 | 298 | } | 
 | 299 |  | 
 | 300 | inline Primitive::Type ArtField::GetTypeAsPrimitiveType() | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 301 |     REQUIRES_SHARED(Locks::mutator_lock_) { | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 302 |   return Primitive::GetType(GetTypeDescriptor()[0]); | 
 | 303 | } | 
 | 304 |  | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 305 | inline bool ArtField::IsPrimitiveType() REQUIRES_SHARED(Locks::mutator_lock_) { | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 306 |   return GetTypeAsPrimitiveType() != Primitive::kPrimNot; | 
 | 307 | } | 
 | 308 |  | 
| Vladimir Marko | 208f670 | 2017-12-08 12:00:50 +0000 | [diff] [blame] | 309 | inline ObjPtr<mirror::Class> ArtField::LookupResolvedType() { | 
| Vladimir Marko | 4098a7a | 2017-11-06 16:00:51 +0000 | [diff] [blame] | 310 |   ScopedAssertNoThreadSuspension ants(__FUNCTION__); | 
| Vladimir Marko | 09c5ca4 | 2018-05-31 15:15:31 +0100 | [diff] [blame] | 311 |   if (UNLIKELY(IsProxyField())) { | 
| Vladimir Marko | 4098a7a | 2017-11-06 16:00:51 +0000 | [diff] [blame] | 312 |     return ProxyFindSystemClass(GetTypeDescriptor()); | 
 | 313 |   } | 
| Vladimir Marko | 666ee3d | 2017-12-11 18:37:36 +0000 | [diff] [blame] | 314 |   ObjPtr<mirror::Class> type = Runtime::Current()->GetClassLinker()->LookupResolvedType( | 
| Vladimir Marko | 09c5ca4 | 2018-05-31 15:15:31 +0100 | [diff] [blame] | 315 |       GetDexFile()->GetFieldId(GetDexFieldIndex()).type_idx_, this); | 
| Vladimir Marko | 666ee3d | 2017-12-11 18:37:36 +0000 | [diff] [blame] | 316 |   DCHECK(!Thread::Current()->IsExceptionPending()); | 
 | 317 |   return type; | 
| Vladimir Marko | 4098a7a | 2017-11-06 16:00:51 +0000 | [diff] [blame] | 318 | } | 
 | 319 |  | 
 | 320 | inline ObjPtr<mirror::Class> ArtField::ResolveType() { | 
| Vladimir Marko | 09c5ca4 | 2018-05-31 15:15:31 +0100 | [diff] [blame] | 321 |   if (UNLIKELY(IsProxyField())) { | 
| Nicolas Geoffray | 3a09092 | 2015-11-24 09:17:30 +0000 | [diff] [blame] | 322 |     return ProxyFindSystemClass(GetTypeDescriptor()); | 
| Ian Rogers | 08f1f50 | 2014-12-02 15:04:37 -0800 | [diff] [blame] | 323 |   } | 
| Vladimir Marko | 666ee3d | 2017-12-11 18:37:36 +0000 | [diff] [blame] | 324 |   ObjPtr<mirror::Class> type = Runtime::Current()->GetClassLinker()->ResolveType( | 
| Vladimir Marko | 09c5ca4 | 2018-05-31 15:15:31 +0100 | [diff] [blame] | 325 |       GetDexFile()->GetFieldId(GetDexFieldIndex()).type_idx_, this); | 
| Vladimir Marko | 666ee3d | 2017-12-11 18:37:36 +0000 | [diff] [blame] | 326 |   DCHECK_EQ(type == nullptr, Thread::Current()->IsExceptionPending()); | 
| Ian Rogers | 08f1f50 | 2014-12-02 15:04:37 -0800 | [diff] [blame] | 327 |   return type; | 
 | 328 | } | 
 | 329 |  | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 330 | inline size_t ArtField::FieldSize() REQUIRES_SHARED(Locks::mutator_lock_) { | 
| Fred Shih | 37f05ef | 2014-07-16 18:38:08 -0700 | [diff] [blame] | 331 |   return Primitive::ComponentSize(GetTypeAsPrimitiveType()); | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 332 | } | 
 | 333 |  | 
| Vladimir Marko | 09c5ca4 | 2018-05-31 15:15:31 +0100 | [diff] [blame] | 334 | template <ReadBarrierOption kReadBarrierOption> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 335 | inline ObjPtr<mirror::DexCache> ArtField::GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_) { | 
| Vladimir Marko | 09c5ca4 | 2018-05-31 15:15:31 +0100 | [diff] [blame] | 336 |   ObjPtr<mirror::Class> klass = GetDeclaringClass<kReadBarrierOption>(); | 
 | 337 |   return klass->GetDexCache<kDefaultVerifyFlags, kReadBarrierOption>(); | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 338 | } | 
 | 339 |  | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 340 | inline const DexFile* ArtField::GetDexFile() REQUIRES_SHARED(Locks::mutator_lock_) { | 
| Vladimir Marko | 09c5ca4 | 2018-05-31 15:15:31 +0100 | [diff] [blame] | 341 |   return GetDexCache<kWithoutReadBarrier>()->GetDexFile(); | 
| Mathieu Chartier | 61c5ebc | 2014-06-05 17:42:53 -0700 | [diff] [blame] | 342 | } | 
 | 343 |  | 
| Vladimir Marko | 18090d1 | 2018-06-01 16:53:12 +0100 | [diff] [blame] | 344 | inline ObjPtr<mirror::String> ArtField::ResolveNameString() { | 
 | 345 |   uint32_t dex_field_index = GetDexFieldIndex(); | 
| Andreas Gampe | e2abbc6 | 2017-09-15 11:59:26 -0700 | [diff] [blame] | 346 |   CHECK_NE(dex_field_index, dex::kDexNoIndex); | 
| Andreas Gampe | 3f1dcd3 | 2018-12-28 09:39:56 -0800 | [diff] [blame] | 347 |   const dex::FieldId& field_id = GetDexFile()->GetFieldId(dex_field_index); | 
| Vladimir Marko | 18090d1 | 2018-06-01 16:53:12 +0100 | [diff] [blame] | 348 |   return Runtime::Current()->GetClassLinker()->ResolveString(field_id.name_idx_, this); | 
| Mathieu Chartier | 7643327 | 2014-09-26 14:32:37 -0700 | [diff] [blame] | 349 | } | 
 | 350 |  | 
| Mathieu Chartier | cb044bc | 2016-04-01 13:56:41 -0700 | [diff] [blame] | 351 | // If kExactOffset is true then we only find the matching offset, not the field containing the | 
 | 352 | // offset. | 
 | 353 | template <bool kExactOffset> | 
 | 354 | static inline ArtField* FindFieldWithOffset( | 
 | 355 |     const IterationRange<StrideIterator<ArtField>>& fields, | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 356 |     uint32_t field_offset) REQUIRES_SHARED(Locks::mutator_lock_) { | 
| Mathieu Chartier | cb044bc | 2016-04-01 13:56:41 -0700 | [diff] [blame] | 357 |   for (ArtField& field : fields) { | 
 | 358 |     if (kExactOffset) { | 
 | 359 |       if (field.GetOffset().Uint32Value() == field_offset) { | 
 | 360 |         return &field; | 
 | 361 |       } | 
 | 362 |     } else { | 
 | 363 |       const uint32_t offset = field.GetOffset().Uint32Value(); | 
 | 364 |       Primitive::Type type = field.GetTypeAsPrimitiveType(); | 
 | 365 |       const size_t field_size = Primitive::ComponentSize(type); | 
 | 366 |       DCHECK_GT(field_size, 0u); | 
 | 367 |       if (offset <= field_offset && field_offset < offset + field_size) { | 
 | 368 |         return &field; | 
 | 369 |       } | 
 | 370 |     } | 
 | 371 |   } | 
 | 372 |   return nullptr; | 
 | 373 | } | 
 | 374 |  | 
 | 375 | template <bool kExactOffset> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 376 | inline ArtField* ArtField::FindInstanceFieldWithOffset(ObjPtr<mirror::Class> klass, | 
| Mathieu Chartier | cb044bc | 2016-04-01 13:56:41 -0700 | [diff] [blame] | 377 |                                                        uint32_t field_offset) { | 
 | 378 |   DCHECK(klass != nullptr); | 
 | 379 |   ArtField* field = FindFieldWithOffset<kExactOffset>(klass->GetIFields(), field_offset); | 
 | 380 |   if (field != nullptr) { | 
 | 381 |     return field; | 
 | 382 |   } | 
 | 383 |   // We did not find field in the class: look into superclass. | 
 | 384 |   return (klass->GetSuperClass() != nullptr) ? | 
 | 385 |       FindInstanceFieldWithOffset<kExactOffset>(klass->GetSuperClass(), field_offset) : nullptr; | 
 | 386 | } | 
 | 387 |  | 
 | 388 | template <bool kExactOffset> | 
| Mathieu Chartier | 3398c78 | 2016-09-30 10:27:43 -0700 | [diff] [blame] | 389 | inline ArtField* ArtField::FindStaticFieldWithOffset(ObjPtr<mirror::Class> klass, | 
 | 390 |                                                      uint32_t field_offset) { | 
| Mathieu Chartier | cb044bc | 2016-04-01 13:56:41 -0700 | [diff] [blame] | 391 |   DCHECK(klass != nullptr); | 
 | 392 |   return FindFieldWithOffset<kExactOffset>(klass->GetSFields(), field_offset); | 
 | 393 | } | 
 | 394 |  | 
| Vladimir Marko | c524e9e | 2019-03-26 10:54:50 +0000 | [diff] [blame] | 395 | inline ObjPtr<mirror::ClassLoader> ArtField::GetClassLoader() { | 
| Andreas Gampe | 4835d21 | 2018-11-21 14:55:10 -0800 | [diff] [blame] | 396 |   return GetDeclaringClass()->GetClassLoader(); | 
 | 397 | } | 
 | 398 |  | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 399 | }  // namespace art | 
 | 400 |  | 
| Mathieu Chartier | c785344 | 2015-03-27 14:35:38 -0700 | [diff] [blame] | 401 | #endif  // ART_RUNTIME_ART_FIELD_INL_H_ |