| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef ART_RUNTIME_ART_FIELD_H_ |
| #define ART_RUNTIME_ART_FIELD_H_ |
| |
| #include <jni.h> |
| |
| #include "gc_root.h" |
| #include "modifiers.h" |
| #include "offsets.h" |
| #include "primitive.h" |
| #include "read_barrier_option.h" |
| |
| namespace art { |
| |
| class DexFile; |
| class ScopedObjectAccessAlreadyRunnable; |
| |
| namespace mirror { |
| class Class; |
| class DexCache; |
| class Object; |
| class String; |
| } // namespace mirror |
| |
| class ArtField FINAL { |
| public: |
| ArtField(); |
| |
| mirror::Class* GetDeclaringClass() SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| void SetDeclaringClass(mirror::Class *new_declaring_class) |
| SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| uint32_t GetAccessFlags() SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| void SetAccessFlags(uint32_t new_access_flags) SHARED_REQUIRES(Locks::mutator_lock_) { |
| // Not called within a transaction. |
| access_flags_ = new_access_flags; |
| } |
| |
| bool IsPublic() SHARED_REQUIRES(Locks::mutator_lock_) { |
| return (GetAccessFlags() & kAccPublic) != 0; |
| } |
| |
| bool IsStatic() SHARED_REQUIRES(Locks::mutator_lock_) { |
| return (GetAccessFlags() & kAccStatic) != 0; |
| } |
| |
| bool IsFinal() SHARED_REQUIRES(Locks::mutator_lock_) { |
| return (GetAccessFlags() & kAccFinal) != 0; |
| } |
| |
| uint32_t GetDexFieldIndex() { |
| return field_dex_idx_; |
| } |
| |
| void SetDexFieldIndex(uint32_t new_idx) { |
| // Not called within a transaction. |
| field_dex_idx_ = new_idx; |
| } |
| |
| // Offset to field within an Object. |
| MemberOffset GetOffset() SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| static MemberOffset OffsetOffset() { |
| return MemberOffset(OFFSETOF_MEMBER(ArtField, offset_)); |
| } |
| |
| MemberOffset GetOffsetDuringLinking() SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| void SetOffset(MemberOffset num_bytes) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| // field access, null object for static fields |
| uint8_t GetBoolean(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template<bool kTransactionActive> |
| void SetBoolean(mirror::Object* object, uint8_t z) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| int8_t GetByte(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template<bool kTransactionActive> |
| void SetByte(mirror::Object* object, int8_t b) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| uint16_t GetChar(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template<bool kTransactionActive> |
| void SetChar(mirror::Object* object, uint16_t c) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| int16_t GetShort(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template<bool kTransactionActive> |
| void SetShort(mirror::Object* object, int16_t s) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| int32_t GetInt(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template<bool kTransactionActive> |
| void SetInt(mirror::Object* object, int32_t i) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| int64_t GetLong(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template<bool kTransactionActive> |
| void SetLong(mirror::Object* object, int64_t j) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| float GetFloat(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template<bool kTransactionActive> |
| void SetFloat(mirror::Object* object, float f) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| double GetDouble(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template<bool kTransactionActive> |
| void SetDouble(mirror::Object* object, double d) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| mirror::Object* GetObject(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template<bool kTransactionActive> |
| void SetObject(mirror::Object* object, mirror::Object* l) |
| SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| // Raw field accesses. |
| uint32_t Get32(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template<bool kTransactionActive> |
| void Set32(mirror::Object* object, uint32_t new_value) |
| SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| uint64_t Get64(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template<bool kTransactionActive> |
| void Set64(mirror::Object* object, uint64_t new_value) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| mirror::Object* GetObj(mirror::Object* object) SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template<bool kTransactionActive> |
| void SetObj(mirror::Object* object, mirror::Object* new_value) |
| SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| // NO_THREAD_SAFETY_ANALYSIS since we don't know what the callback requires. |
| template<typename RootVisitorType> |
| void VisitRoots(RootVisitorType& visitor) NO_THREAD_SAFETY_ANALYSIS; |
| |
| bool IsVolatile() SHARED_REQUIRES(Locks::mutator_lock_) { |
| return (GetAccessFlags() & kAccVolatile) != 0; |
| } |
| |
| // Returns an instance field with this offset in the given class or null if not found. |
| static ArtField* FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset) |
| SHARED_REQUIRES(Locks::mutator_lock_); |
| // Returns a static field with this offset in the given class or null if not found. |
| static ArtField* FindStaticFieldWithOffset(mirror::Class* klass, uint32_t field_offset) |
| SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| const char* GetName() SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| // Resolves / returns the name from the dex cache. |
| mirror::String* GetStringName(Thread* self, bool resolve) |
| SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| const char* GetTypeDescriptor() SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| Primitive::Type GetTypeAsPrimitiveType() SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| bool IsPrimitiveType() SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| template <bool kResolve> |
| mirror::Class* GetType() SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| size_t FieldSize() SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| mirror::DexCache* GetDexCache() SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| const DexFile* GetDexFile() SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| GcRoot<mirror::Class>& DeclaringClassRoot() { |
| return declaring_class_; |
| } |
| |
| // Update the declaring class with the passed in visitor. Does not use read barrier. |
| template <typename Visitor> |
| ALWAYS_INLINE void UpdateObjects(const Visitor& visitor) |
| SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| private: |
| mirror::Class* ProxyFindSystemClass(const char* descriptor) |
| SHARED_REQUIRES(Locks::mutator_lock_); |
| mirror::Class* ResolveGetType(uint32_t type_idx) SHARED_REQUIRES(Locks::mutator_lock_); |
| mirror::String* ResolveGetStringName(Thread* self, const DexFile& dex_file, uint32_t string_idx, |
| mirror::DexCache* dex_cache) |
| SHARED_REQUIRES(Locks::mutator_lock_); |
| |
| GcRoot<mirror::Class> declaring_class_; |
| |
| uint32_t access_flags_; |
| |
| // Dex cache index of field id |
| uint32_t field_dex_idx_; |
| |
| // Offset of field within an instance or in the Class' static fields |
| uint32_t offset_; |
| }; |
| |
| } // namespace art |
| |
| #endif // ART_RUNTIME_ART_FIELD_H_ |