| /* |
| * 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_CLASS_ALLOC_INL_H_ |
| #define ART_RUNTIME_MIRROR_CLASS_ALLOC_INL_H_ |
| |
| #include "class-inl.h" |
| |
| #include "gc/allocator_type.h" |
| #include "gc/heap-inl.h" |
| #include "object-inl.h" |
| #include "runtime.h" |
| |
| namespace art { |
| namespace mirror { |
| |
| inline void Class::CheckObjectAlloc() { |
| DCHECK(!IsArrayClass()) |
| << PrettyClass() |
| << "A array shouldn't be allocated through this " |
| << "as it requires a pre-fence visitor that sets the class size."; |
| DCHECK(!IsClassClass()) |
| << PrettyClass() |
| << "A class object shouldn't be allocated through this " |
| << "as it requires a pre-fence visitor that sets the class size."; |
| DCHECK(!IsStringClass()) |
| << PrettyClass() |
| << "A string shouldn't be allocated through this " |
| << "as it requires a pre-fence visitor that sets the class size."; |
| DCHECK(IsInstantiable()) << PrettyClass(); |
| // TODO: decide whether we want this check. It currently fails during bootstrap. |
| // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(); |
| DCHECK_GE(this->object_size_, sizeof(Object)); |
| } |
| |
| template<bool kIsInstrumented, Class::AddFinalizer kAddFinalizer, bool kCheckAddFinalizer> |
| inline ObjPtr<Object> Class::Alloc(Thread* self, gc::AllocatorType allocator_type) { |
| CheckObjectAlloc(); |
| gc::Heap* heap = Runtime::Current()->GetHeap(); |
| bool add_finalizer; |
| switch (kAddFinalizer) { |
| case Class::AddFinalizer::kUseClassTag: |
| add_finalizer = IsFinalizable(); |
| break; |
| case Class::AddFinalizer::kNoAddFinalizer: |
| add_finalizer = false; |
| DCHECK_IMPLIES(kCheckAddFinalizer, !IsFinalizable()); |
| break; |
| } |
| // Note that the `this` pointer may be invalidated after the allocation. |
| ObjPtr<Object> obj = |
| heap->AllocObjectWithAllocator<kIsInstrumented, /*kCheckLargeObject=*/ false>( |
| self, this, this->object_size_, allocator_type, VoidFunctor()); |
| if (add_finalizer && LIKELY(obj != nullptr)) { |
| heap->AddFinalizerReference(self, &obj); |
| if (UNLIKELY(self->IsExceptionPending())) { |
| // Failed to allocate finalizer reference, it means that the whole allocation failed. |
| obj = nullptr; |
| } |
| } |
| return obj; |
| } |
| |
| inline ObjPtr<Object> Class::AllocObject(Thread* self) { |
| return Alloc(self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); |
| } |
| |
| inline ObjPtr<Object> Class::AllocNonMovableObject(Thread* self) { |
| return Alloc(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator()); |
| } |
| |
| } // namespace mirror |
| } // namespace art |
| |
| #endif // ART_RUNTIME_MIRROR_CLASS_ALLOC_INL_H_ |