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<true>(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(Thread * self,int32_t new_length)64 inline ObjPtr<ObjectArray<T>> ObjectArray<T>::CopyOf(Thread* self, int32_t new_length) {
65   DCHECK_GE(new_length, 0);
66   // We may get copied by a compacting GC.
67   StackHandleScope<1> hs(self);
68   Handle<ObjectArray<T>> h_this(hs.NewHandle(this));
69   gc::Heap* heap = Runtime::Current()->GetHeap();
70   gc::AllocatorType allocator_type = heap->IsMovableObject(this) ? heap->GetCurrentAllocator() :
71       heap->GetCurrentNonMovingAllocator();
72   ObjPtr<ObjectArray<T>> new_array = Alloc(self, 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