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_CLASS_ALLOC_INL_H_ 18 #define ART_RUNTIME_MIRROR_CLASS_ALLOC_INL_H_ 19 20 #include "class-inl.h" 21 22 #include "gc/allocator_type.h" 23 #include "gc/heap-inl.h" 24 #include "object-inl.h" 25 #include "runtime.h" 26 27 namespace art { 28 namespace mirror { 29 CheckObjectAlloc()30 inline void Class::CheckObjectAlloc() { 31 DCHECK(!IsArrayClass()) 32 << PrettyClass() 33 << "A array shouldn't be allocated through this " 34 << "as it requires a pre-fence visitor that sets the class size."; 35 DCHECK(!IsClassClass()) 36 << PrettyClass() 37 << "A class object shouldn't be allocated through this " 38 << "as it requires a pre-fence visitor that sets the class size."; 39 DCHECK(!IsStringClass()) 40 << PrettyClass() 41 << "A string shouldn't be allocated through this " 42 << "as it requires a pre-fence visitor that sets the class size."; 43 DCHECK(IsInstantiable()) << PrettyClass(); 44 // TODO: decide whether we want this check. It currently fails during bootstrap. 45 // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(); 46 DCHECK_GE(this->object_size_, sizeof(Object)); 47 } 48 49 template<bool kIsInstrumented, Class::AddFinalizer kAddFinalizer, bool kCheckAddFinalizer> Alloc(Thread * self,gc::AllocatorType allocator_type)50 inline ObjPtr<Object> Class::Alloc(Thread* self, gc::AllocatorType allocator_type) { 51 CheckObjectAlloc(); 52 gc::Heap* heap = Runtime::Current()->GetHeap(); 53 bool add_finalizer; 54 switch (kAddFinalizer) { 55 case Class::AddFinalizer::kUseClassTag: 56 add_finalizer = IsFinalizable(); 57 break; 58 case Class::AddFinalizer::kNoAddFinalizer: 59 add_finalizer = false; 60 DCHECK_IMPLIES(kCheckAddFinalizer, !IsFinalizable()); 61 break; 62 } 63 // Note that the `this` pointer may be invalidated after the allocation. 64 ObjPtr<Object> obj = 65 heap->AllocObjectWithAllocator<kIsInstrumented, /*kCheckLargeObject=*/ false>( 66 self, this, this->object_size_, allocator_type, VoidFunctor()); 67 if (add_finalizer && LIKELY(obj != nullptr)) { 68 heap->AddFinalizerReference(self, &obj); 69 if (UNLIKELY(self->IsExceptionPending())) { 70 // Failed to allocate finalizer reference, it means that the whole allocation failed. 71 obj = nullptr; 72 } 73 } 74 return obj; 75 } 76 AllocObject(Thread * self)77 inline ObjPtr<Object> Class::AllocObject(Thread* self) { 78 return Alloc(self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); 79 } 80 AllocNonMovableObject(Thread * self)81 inline ObjPtr<Object> Class::AllocNonMovableObject(Thread* self) { 82 return Alloc(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator()); 83 } 84 85 } // namespace mirror 86 } // namespace art 87 88 #endif // ART_RUNTIME_MIRROR_CLASS_ALLOC_INL_H_ 89