• 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_ARRAY_H_
18 #define ART_RUNTIME_MIRROR_ARRAY_H_
19 
20 #include "object.h"
21 
22 namespace art {
23 namespace mirror {
24 
25 class MANAGED Array : public Object {
26  public:
27   // A convenience for code that doesn't know the component size,
28   // and doesn't want to have to work it out itself.
29   static Array* Alloc(Thread* self, Class* array_class, int32_t component_count)
30       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
31 
32   static Array* Alloc(Thread* self, Class* array_class, int32_t component_count,
33                       size_t component_size)
34       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
35 
36   static Array* CreateMultiArray(Thread* self, Class* element_class, IntArray* dimensions)
37       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
38 
39   size_t SizeOf() const;
40 
GetLength()41   int32_t GetLength() const {
42     return GetField32(OFFSET_OF_OBJECT_MEMBER(Array, length_), false);
43   }
44 
SetLength(int32_t length)45   void SetLength(int32_t length) {
46     CHECK_GE(length, 0);
47     SetField32(OFFSET_OF_OBJECT_MEMBER(Array, length_), length, false);
48   }
49 
LengthOffset()50   static MemberOffset LengthOffset() {
51     return OFFSET_OF_OBJECT_MEMBER(Array, length_);
52   }
53 
DataOffset(size_t component_size)54   static MemberOffset DataOffset(size_t component_size) {
55     if (component_size != sizeof(int64_t)) {
56       return OFFSET_OF_OBJECT_MEMBER(Array, first_element_);
57     } else {
58       // Align longs and doubles.
59       return MemberOffset(OFFSETOF_MEMBER(Array, first_element_) + 4);
60     }
61   }
62 
GetRawData(size_t component_size)63   void* GetRawData(size_t component_size) {
64     intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(component_size).Int32Value();
65     return reinterpret_cast<void*>(data);
66   }
67 
GetRawData(size_t component_size)68   const void* GetRawData(size_t component_size) const {
69     intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(component_size).Int32Value();
70     return reinterpret_cast<const void*>(data);
71   }
72 
IsValidIndex(int32_t index)73   bool IsValidIndex(int32_t index) const
74       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
75     if (UNLIKELY(static_cast<uint32_t>(index) >= static_cast<uint32_t>(GetLength()))) {
76       ThrowArrayIndexOutOfBoundsException(index);
77       return false;
78     }
79     return true;
80   }
81 
82  protected:
83   void ThrowArrayIndexOutOfBoundsException(int32_t index) const
84       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
85   void ThrowArrayStoreException(Object* object) const
86       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
87 
88  private:
89   // The number of array elements.
90   int32_t length_;
91   // Marker for the data (used by generated code)
92   uint32_t first_element_[0];
93 
94   DISALLOW_IMPLICIT_CONSTRUCTORS(Array);
95 };
96 
97 template<class T>
98 class MANAGED PrimitiveArray : public Array {
99  public:
100   typedef T ElementType;
101 
102   static PrimitiveArray<T>* Alloc(Thread* self, size_t length)
103       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
104 
GetData()105   const T* GetData() const {
106     intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(sizeof(T)).Int32Value();
107     return reinterpret_cast<T*>(data);
108   }
109 
GetData()110   T* GetData() {
111     intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(sizeof(T)).Int32Value();
112     return reinterpret_cast<T*>(data);
113   }
114 
Get(int32_t i)115   T Get(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
116     if (!IsValidIndex(i)) {
117       return T(0);
118     }
119     return GetData()[i];
120   }
121 
Set(int32_t i,T value)122   void Set(int32_t i, T value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
123     if (IsValidIndex(i)) {
124       GetData()[i] = value;
125     }
126   }
127 
SetArrayClass(Class * array_class)128   static void SetArrayClass(Class* array_class) {
129     CHECK(array_class_ == NULL);
130     CHECK(array_class != NULL);
131     array_class_ = array_class;
132   }
133 
ResetArrayClass()134   static void ResetArrayClass() {
135     CHECK(array_class_ != NULL);
136     array_class_ = NULL;
137   }
138 
139  private:
140   static Class* array_class_;
141 
142   DISALLOW_IMPLICIT_CONSTRUCTORS(PrimitiveArray);
143 };
144 
145 }  // namespace mirror
146 }  // namespace art
147 
148 #endif  // ART_RUNTIME_MIRROR_ARRAY_H_
149