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_OBJECT_ARRAY_ALLOC_INL_H_
18 #define ART_RUNTIME_MIRROR_OBJECT_ARRAY_ALLOC_INL_H_
19 
20 #include "object_array.h"
21 
22 #include "array-alloc-inl.h"
23 #include "array-inl.h"
24 #include "class.h"
25 #include "dex/primitive.h"
26 #include "gc/heap-inl.h"
27 #include "handle_scope-inl.h"
28 #include "obj_ptr-inl.h"
29 #include "object-inl.h"
30 #include "runtime.h"
31 
32 namespace art {
33 namespace mirror {
34 
35 template<class T>
Alloc(Thread * self,ObjPtr<Class> object_array_class,int32_t length,gc::AllocatorType allocator_type)36 inline ObjPtr<ObjectArray<T>> ObjectArray<T>::Alloc(Thread* self,
37                                                     ObjPtr<Class> object_array_class,
38                                                     int32_t length,
39                                                     gc::AllocatorType allocator_type) {
40   ObjPtr<Array> array = Array::Alloc(self,
41                                      object_array_class,
42                                      length,
43                                      ComponentSizeShiftWidth(kHeapReferenceSize),
44                                      allocator_type);
45   if (UNLIKELY(array == nullptr)) {
46     return nullptr;
47   }
48   DCHECK_EQ(array->GetClass()->GetComponentSizeShift(),
49             ComponentSizeShiftWidth(kHeapReferenceSize));
50   return array->AsObjectArray<T>();
51 }
52 
53 template<class T>
Alloc(Thread * self,ObjPtr<Class> object_array_class,int32_t length)54 inline ObjPtr<ObjectArray<T>> ObjectArray<T>::Alloc(Thread* self,
55                                                     ObjPtr<Class> object_array_class,
56                                                     int32_t length) {
57   return Alloc(self,
58                object_array_class,
59                length,
60                Runtime::Current()->GetHeap()->GetCurrentAllocator());
61 }
62 
63 template<class T>
CopyOf(Handle<ObjectArray<T>> h_this,Thread * self,int32_t new_length)64 inline ObjPtr<ObjectArray<T>> ObjectArray<T>::CopyOf(Handle<ObjectArray<T>> h_this,
65                                                      Thread* self,
66                                                      int32_t new_length) {
67   DCHECK_GE(new_length, 0);
68   gc::Heap* heap = Runtime::Current()->GetHeap();
69   gc::AllocatorType allocator_type = heap->IsMovableObject(h_this.Get())
70       ? heap->GetCurrentAllocator()
71       : heap->GetCurrentNonMovingAllocator();
72   ObjPtr<ObjectArray<T>> new_array = Alloc(self, h_this->GetClass(), new_length, allocator_type);
73   if (LIKELY(new_array != nullptr)) {
74     new_array->AssignableMemcpy(0, h_this.Get(), 0, std::min(h_this->GetLength(), new_length));
75   }
76   return new_array;
77 }
78 
79 }  // namespace mirror
80 }  // namespace art
81 
82 #endif  // ART_RUNTIME_MIRROR_OBJECT_ARRAY_ALLOC_INL_H_
83