/* * 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 inline ObjPtr 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(!kCheckAddFinalizer || !IsFinalizable()); break; } // Note that the `this` pointer may be invalidated after the allocation. ObjPtr obj = heap->AllocObjectWithAllocator( 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 Class::AllocObject(Thread* self) { return Alloc(self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); } inline ObjPtr Class::AllocNonMovableObject(Thread* self) { return Alloc(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator()); } } // namespace mirror } // namespace art #endif // ART_RUNTIME_MIRROR_CLASS_ALLOC_INL_H_