array.h revision 7940e44f4517de5e2634a7e07d58d0fb26160513
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_SRC_MIRROR_ARRAY_H_
18#define ART_SRC_MIRROR_ARRAY_H_
19
20#include "object.h"
21
22namespace art {
23namespace mirror {
24
25class 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
41  int32_t GetLength() const {
42    return GetField32(OFFSET_OF_OBJECT_MEMBER(Array, length_), false);
43  }
44
45  void SetLength(int32_t length) {
46    CHECK_GE(length, 0);
47    SetField32(OFFSET_OF_OBJECT_MEMBER(Array, length_), length, false);
48  }
49
50  static MemberOffset LengthOffset() {
51    return OFFSET_OF_OBJECT_MEMBER(Array, length_);
52  }
53
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
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
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
73  bool IsValidIndex(int32_t index) const
74      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
75    if (UNLIKELY(index < 0 || index >= 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
97template<class T>
98class 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
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
110  T* GetData() {
111    intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(sizeof(T)).Int32Value();
112    return reinterpret_cast<T*>(data);
113  }
114
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
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
128  static void SetArrayClass(Class* array_class) {
129    CHECK(array_class_ == NULL);
130    CHECK(array_class != NULL);
131    array_class_ = array_class;
132  }
133
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_SRC_MIRROR_ARRAY_H_
149