/*
 * 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_MIRROR_OBJECT_ARRAY_ALLOC_INL_H_
#define ART_RUNTIME_MIRROR_OBJECT_ARRAY_ALLOC_INL_H_

#include "object_array.h"

#include "array-alloc-inl.h"
#include "array-inl.h"
#include "class.h"
#include "dex/primitive.h"
#include "gc/heap-inl.h"
#include "handle_scope-inl.h"
#include "obj_ptr-inl.h"
#include "object-inl.h"
#include "runtime.h"

namespace art HIDDEN {
namespace mirror {

template<class T>
inline ObjPtr<ObjectArray<T>> ObjectArray<T>::Alloc(Thread* self,
                                                    ObjPtr<Class> object_array_class,
                                                    int32_t length,
                                                    gc::AllocatorType allocator_type) {
  ObjPtr<Array> array = Array::Alloc(self,
                                     object_array_class,
                                     length,
                                     ComponentSizeShiftWidth(kHeapReferenceSize),
                                     allocator_type);
  if (UNLIKELY(array == nullptr)) {
    return nullptr;
  }
  DCHECK_EQ(array->GetClass()->GetComponentSizeShift(),
            ComponentSizeShiftWidth(kHeapReferenceSize));
  return array->AsObjectArray<T>();
}

template<class T>
inline ObjPtr<ObjectArray<T>> ObjectArray<T>::Alloc(Thread* self,
                                                    ObjPtr<Class> object_array_class,
                                                    int32_t length) {
  return Alloc(self,
               object_array_class,
               length,
               Runtime::Current()->GetHeap()->GetCurrentAllocator());
}

template<class T>
inline ObjPtr<ObjectArray<T>> ObjectArray<T>::CopyOf(Handle<ObjectArray<T>> h_this,
                                                     Thread* self,
                                                     int32_t new_length) {
  DCHECK_GE(new_length, 0);
  gc::Heap* heap = Runtime::Current()->GetHeap();
  gc::AllocatorType allocator_type = heap->IsMovableObject(h_this.Get())
      ? heap->GetCurrentAllocator()
      : heap->GetCurrentNonMovingAllocator();
  ObjPtr<ObjectArray<T>> new_array = Alloc(self, h_this->GetClass(), new_length, allocator_type);
  if (LIKELY(new_array != nullptr)) {
    new_array->AssignableMemcpy(0, h_this.Get(), 0, std::min(h_this->GetLength(), new_length));
  }
  return new_array;
}

}  // namespace mirror
}  // namespace art

#endif  // ART_RUNTIME_MIRROR_OBJECT_ARRAY_ALLOC_INL_H_
