157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers/* 257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * Copyright (C) 2012 The Android Open Source Project 357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * 457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * you may not use this file except in compliance with the License. 657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * You may obtain a copy of the License at 757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * 857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * http://www.apache.org/licenses/LICENSE-2.0 957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * 1057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * Unless required by applicable law or agreed to in writing, software 1157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * distributed under the License is distributed on an "AS IS" BASIS, 1257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * See the License for the specific language governing permissions and 1457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * limitations under the License. 1557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers */ 1657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 17d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier#include "entrypoints/quick/quick_alloc_entrypoints.h" 18d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier 19e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method-inl.h" 2057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers#include "callee_save_frame.h" 2198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang#include "entrypoints/entrypoint_utils-inl.h" 222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h" 232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h" 244f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "mirror/object-inl.h" 2557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 2657b86d47b66322693a070185fadfb43cb9c12eabIan Rogersnamespace art { 2757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 28eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchistatic constexpr bool kUseTlabFastPath = true; 29eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi 30cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier#define GENERATE_ENTRYPOINTS_FOR_ALLOCATOR_INST(suffix, suffix2, instrumented_bool, allocator_type) \ 31cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartierextern "C" mirror::Object* artAllocObjectFromCode ##suffix##suffix2( \ 32e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier uint32_t type_idx, ArtMethod* method, Thread* self) \ 3390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 341d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers ScopedQuickEntrypointChecks sqec(self); \ 35eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (kUseTlabFastPath && !instrumented_bool && allocator_type == gc::kAllocatorTypeTLAB) { \ 3605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko mirror::Class* klass = method->GetDexCacheResolvedType<false>(type_idx, sizeof(void*)); \ 37eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (LIKELY(klass != nullptr && klass->IsInitialized() && !klass->IsFinalizable())) { \ 38eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi size_t byte_count = klass->GetObjectSize(); \ 39eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi byte_count = RoundUp(byte_count, gc::space::BumpPointerSpace::kAlignment); \ 40eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi mirror::Object* obj; \ 41eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (LIKELY(byte_count < self->TlabSize())) { \ 42eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi obj = self->AllocTlab(byte_count); \ 43eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi DCHECK(obj != nullptr) << "AllocTlab can't fail"; \ 44eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi obj->SetClass(klass); \ 45eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (kUseBakerOrBrooksReadBarrier) { \ 46eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (kUseBrooksReadBarrier) { \ 47eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi obj->SetReadBarrierPointer(obj); \ 48eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 49eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi obj->AssertReadBarrierPointer(); \ 50eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 51eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi QuasiAtomic::ThreadFenceForConstructor(); \ 52eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi return obj; \ 53eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 54eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 55eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 56cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier return AllocObjectFromCode<false, instrumented_bool>(type_idx, method, self, allocator_type); \ 57cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier} \ 58be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchiextern "C" mirror::Object* artAllocObjectFromCodeResolved##suffix##suffix2( \ 594b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain mirror::Class* klass, ArtMethod* method ATTRIBUTE_UNUSED, Thread* self) \ 6090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 611d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers ScopedQuickEntrypointChecks sqec(self); \ 62eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (kUseTlabFastPath && !instrumented_bool && allocator_type == gc::kAllocatorTypeTLAB) { \ 63eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (LIKELY(klass->IsInitialized())) { \ 64eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi size_t byte_count = klass->GetObjectSize(); \ 65eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi byte_count = RoundUp(byte_count, gc::space::BumpPointerSpace::kAlignment); \ 66eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi mirror::Object* obj; \ 67eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (LIKELY(byte_count < self->TlabSize())) { \ 68eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi obj = self->AllocTlab(byte_count); \ 69eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi DCHECK(obj != nullptr) << "AllocTlab can't fail"; \ 70eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi obj->SetClass(klass); \ 71eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (kUseBakerOrBrooksReadBarrier) { \ 72eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (kUseBrooksReadBarrier) { \ 73eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi obj->SetReadBarrierPointer(obj); \ 74eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 75eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi obj->AssertReadBarrierPointer(); \ 76eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 77eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi QuasiAtomic::ThreadFenceForConstructor(); \ 78eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi return obj; \ 79eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 80eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 81eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 826a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return AllocObjectFromCodeResolved<instrumented_bool>(klass, self, allocator_type); \ 83be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi} \ 84be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchiextern "C" mirror::Object* artAllocObjectFromCodeInitialized##suffix##suffix2( \ 854b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain mirror::Class* klass, ArtMethod* method ATTRIBUTE_UNUSED, Thread* self) \ 8690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 871d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers ScopedQuickEntrypointChecks sqec(self); \ 88eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (kUseTlabFastPath && !instrumented_bool && allocator_type == gc::kAllocatorTypeTLAB) { \ 89eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi size_t byte_count = klass->GetObjectSize(); \ 90eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi byte_count = RoundUp(byte_count, gc::space::BumpPointerSpace::kAlignment); \ 91eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi mirror::Object* obj; \ 92eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (LIKELY(byte_count < self->TlabSize())) { \ 93eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi obj = self->AllocTlab(byte_count); \ 94eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi DCHECK(obj != nullptr) << "AllocTlab can't fail"; \ 95eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi obj->SetClass(klass); \ 96eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (kUseBakerOrBrooksReadBarrier) { \ 97eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi if (kUseBrooksReadBarrier) { \ 98eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi obj->SetReadBarrierPointer(obj); \ 99eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 100eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi obj->AssertReadBarrierPointer(); \ 101eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 102eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi QuasiAtomic::ThreadFenceForConstructor(); \ 103eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi return obj; \ 104eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 105eb1e929c0d6e312beb313ec108e611f1e74ff45cHiroshi Yamauchi } \ 1066a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return AllocObjectFromCodeInitialized<instrumented_bool>(klass, self, allocator_type); \ 107be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi} \ 108cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartierextern "C" mirror::Object* artAllocObjectFromCodeWithAccessCheck##suffix##suffix2( \ 109e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier uint32_t type_idx, ArtMethod* method, Thread* self) \ 11090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 1111d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers ScopedQuickEntrypointChecks sqec(self); \ 112cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier return AllocObjectFromCode<true, instrumented_bool>(type_idx, method, self, allocator_type); \ 113cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier} \ 114cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartierextern "C" mirror::Array* artAllocArrayFromCode##suffix##suffix2( \ 115e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier uint32_t type_idx, int32_t component_count, ArtMethod* method, Thread* self) \ 11690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 1171d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers ScopedQuickEntrypointChecks sqec(self); \ 1181cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe return AllocArrayFromCode<false, instrumented_bool>(type_idx, component_count, method, self, \ 119cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier allocator_type); \ 120cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier} \ 121bb8f0ab736b61db8f543e433859272e83f96ee9bHiroshi Yamauchiextern "C" mirror::Array* artAllocArrayFromCodeResolved##suffix##suffix2( \ 122e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier mirror::Class* klass, int32_t component_count, ArtMethod* method, Thread* self) \ 12390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 1241d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers ScopedQuickEntrypointChecks sqec(self); \ 1251cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe return AllocArrayFromCodeResolved<false, instrumented_bool>(klass, component_count, method, self, \ 126bb8f0ab736b61db8f543e433859272e83f96ee9bHiroshi Yamauchi allocator_type); \ 127bb8f0ab736b61db8f543e433859272e83f96ee9bHiroshi Yamauchi} \ 128cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartierextern "C" mirror::Array* artAllocArrayFromCodeWithAccessCheck##suffix##suffix2( \ 129e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier uint32_t type_idx, int32_t component_count, ArtMethod* method, Thread* self) \ 13090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 1311d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers ScopedQuickEntrypointChecks sqec(self); \ 1321cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe return AllocArrayFromCode<true, instrumented_bool>(type_idx, component_count, method, self, \ 133cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier allocator_type); \ 134cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier} \ 135cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartierextern "C" mirror::Array* artCheckAndAllocArrayFromCode##suffix##suffix2( \ 136e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier uint32_t type_idx, int32_t component_count, ArtMethod* method, Thread* self) \ 13790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 1381d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers ScopedQuickEntrypointChecks sqec(self); \ 139cbbb080e8b45e46ea43af521ba2a0b3d432702a7Hiroshi Yamauchi if (!instrumented_bool) { \ 1401cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe return CheckAndAllocArrayFromCode(type_idx, component_count, method, self, false, allocator_type); \ 141cbbb080e8b45e46ea43af521ba2a0b3d432702a7Hiroshi Yamauchi } else { \ 1421cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe return CheckAndAllocArrayFromCodeInstrumented(type_idx, component_count, method, self, false, allocator_type); \ 143cbbb080e8b45e46ea43af521ba2a0b3d432702a7Hiroshi Yamauchi } \ 144cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier} \ 145cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartierextern "C" mirror::Array* artCheckAndAllocArrayFromCodeWithAccessCheck##suffix##suffix2( \ 146e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier uint32_t type_idx, int32_t component_count, ArtMethod* method, Thread* self) \ 14790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 1481d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers ScopedQuickEntrypointChecks sqec(self); \ 149cbbb080e8b45e46ea43af521ba2a0b3d432702a7Hiroshi Yamauchi if (!instrumented_bool) { \ 1501cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe return CheckAndAllocArrayFromCode(type_idx, component_count, method, self, true, allocator_type); \ 151cbbb080e8b45e46ea43af521ba2a0b3d432702a7Hiroshi Yamauchi } else { \ 1521cc7dbabd03e0a6c09d68161417a21bd6f9df371Andreas Gampe return CheckAndAllocArrayFromCodeInstrumented(type_idx, component_count, method, self, true, allocator_type); \ 153cbbb080e8b45e46ea43af521ba2a0b3d432702a7Hiroshi Yamauchi } \ 154848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} \ 155848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoextern "C" mirror::String* artAllocStringFromBytesFromCode##suffix##suffix2( \ 156848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao mirror::ByteArray* byte_array, int32_t high, int32_t offset, int32_t byte_count, \ 157848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao Thread* self) \ 15890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 159848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ScopedQuickEntrypointChecks sqec(self); \ 160848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao StackHandleScope<1> hs(self); \ 161848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao Handle<mirror::ByteArray> handle_array(hs.NewHandle(byte_array)); \ 162848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return mirror::String::AllocFromByteArray<instrumented_bool>(self, byte_count, handle_array, \ 163848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao offset, high, allocator_type); \ 164848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} \ 165848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoextern "C" mirror::String* artAllocStringFromCharsFromCode##suffix##suffix2( \ 166848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao int32_t offset, int32_t char_count, mirror::CharArray* char_array, Thread* self) \ 16790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 168848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao StackHandleScope<1> hs(self); \ 169848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao Handle<mirror::CharArray> handle_array(hs.NewHandle(char_array)); \ 170848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return mirror::String::AllocFromCharArray<instrumented_bool>(self, char_count, handle_array, \ 171848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao offset, allocator_type); \ 172848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} \ 173848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoextern "C" mirror::String* artAllocStringFromStringFromCode##suffix##suffix2( \ 174848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao mirror::String* string, Thread* self) \ 17590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 176848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao StackHandleScope<1> hs(self); \ 177848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao Handle<mirror::String> handle_string(hs.NewHandle(string)); \ 178848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return mirror::String::AllocFromString<instrumented_bool>(self, handle_string->GetLength(), \ 179848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao handle_string, 0, allocator_type); \ 18057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers} 18157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 182cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier#define GENERATE_ENTRYPOINTS_FOR_ALLOCATOR(suffix, allocator_type) \ 183cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier GENERATE_ENTRYPOINTS_FOR_ALLOCATOR_INST(suffix, Instrumented, true, allocator_type) \ 184cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier GENERATE_ENTRYPOINTS_FOR_ALLOCATOR_INST(suffix, , false, allocator_type) 1853b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi 186e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu ChartierGENERATE_ENTRYPOINTS_FOR_ALLOCATOR(DlMalloc, gc::kAllocatorTypeDlMalloc) 187e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu ChartierGENERATE_ENTRYPOINTS_FOR_ALLOCATOR(RosAlloc, gc::kAllocatorTypeRosAlloc) 188cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu ChartierGENERATE_ENTRYPOINTS_FOR_ALLOCATOR(BumpPointer, gc::kAllocatorTypeBumpPointer) 189692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu ChartierGENERATE_ENTRYPOINTS_FOR_ALLOCATOR(TLAB, gc::kAllocatorTypeTLAB) 1902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi YamauchiGENERATE_ENTRYPOINTS_FOR_ALLOCATOR(Region, gc::kAllocatorTypeRegion) 1912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi YamauchiGENERATE_ENTRYPOINTS_FOR_ALLOCATOR(RegionTLAB, gc::kAllocatorTypeRegionTLAB) 1923b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi 193d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier#define GENERATE_ENTRYPOINTS(suffix) \ 194e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_array##suffix(uint32_t, int32_t, ArtMethod* ref); \ 195e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_array_resolved##suffix(mirror::Class* klass, int32_t, ArtMethod* ref); \ 196e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_array_with_access_check##suffix(uint32_t, int32_t, ArtMethod* ref); \ 197e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_object##suffix(uint32_t type_idx, ArtMethod* ref); \ 198e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_object_resolved##suffix(mirror::Class* klass, ArtMethod* ref); \ 199e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_object_initialized##suffix(mirror::Class* klass, ArtMethod* ref); \ 200e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_object_with_access_check##suffix(uint32_t type_idx, ArtMethod* ref); \ 201e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_check_and_alloc_array##suffix(uint32_t, int32_t, ArtMethod* ref); \ 202e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_check_and_alloc_array_with_access_check##suffix(uint32_t, int32_t, ArtMethod* ref); \ 203848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoextern "C" void* art_quick_alloc_string_from_bytes##suffix(void*, int32_t, int32_t, int32_t); \ 204848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoextern "C" void* art_quick_alloc_string_from_chars##suffix(int32_t, int32_t, void*); \ 205848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoextern "C" void* art_quick_alloc_string_from_string##suffix(void*); \ 206e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_array##suffix##_instrumented(uint32_t, int32_t, ArtMethod* ref); \ 207e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_array_resolved##suffix##_instrumented(mirror::Class* klass, int32_t, ArtMethod* ref); \ 208e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_array_with_access_check##suffix##_instrumented(uint32_t, int32_t, ArtMethod* ref); \ 209e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_object##suffix##_instrumented(uint32_t type_idx, ArtMethod* ref); \ 210e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_object_resolved##suffix##_instrumented(mirror::Class* klass, ArtMethod* ref); \ 211e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_object_initialized##suffix##_instrumented(mirror::Class* klass, ArtMethod* ref); \ 212e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_alloc_object_with_access_check##suffix##_instrumented(uint32_t type_idx, ArtMethod* ref); \ 213e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_check_and_alloc_array##suffix##_instrumented(uint32_t, int32_t, ArtMethod* ref); \ 214e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" void* art_quick_check_and_alloc_array_with_access_check##suffix##_instrumented(uint32_t, int32_t, ArtMethod* ref); \ 215848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoextern "C" void* art_quick_alloc_string_from_bytes##suffix##_instrumented(void*, int32_t, int32_t, int32_t); \ 216848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoextern "C" void* art_quick_alloc_string_from_chars##suffix##_instrumented(int32_t, int32_t, void*); \ 217848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoextern "C" void* art_quick_alloc_string_from_string##suffix##_instrumented(void*); \ 218d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartiervoid SetQuickAllocEntryPoints##suffix(QuickEntryPoints* qpoints, bool instrumented) { \ 219d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier if (instrumented) { \ 220d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocArray = art_quick_alloc_array##suffix##_instrumented; \ 221d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocArrayResolved = art_quick_alloc_array_resolved##suffix##_instrumented; \ 222d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocArrayWithAccessCheck = art_quick_alloc_array_with_access_check##suffix##_instrumented; \ 223d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocObject = art_quick_alloc_object##suffix##_instrumented; \ 224d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocObjectResolved = art_quick_alloc_object_resolved##suffix##_instrumented; \ 225d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocObjectInitialized = art_quick_alloc_object_initialized##suffix##_instrumented; \ 226d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocObjectWithAccessCheck = art_quick_alloc_object_with_access_check##suffix##_instrumented; \ 227d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pCheckAndAllocArray = art_quick_check_and_alloc_array##suffix##_instrumented; \ 228d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pCheckAndAllocArrayWithAccessCheck = art_quick_check_and_alloc_array_with_access_check##suffix##_instrumented; \ 229848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pAllocStringFromBytes = art_quick_alloc_string_from_bytes##suffix##_instrumented; \ 230848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pAllocStringFromChars = art_quick_alloc_string_from_chars##suffix##_instrumented; \ 231848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pAllocStringFromString = art_quick_alloc_string_from_string##suffix##_instrumented; \ 232d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier } else { \ 233d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocArray = art_quick_alloc_array##suffix; \ 234d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocArrayResolved = art_quick_alloc_array_resolved##suffix; \ 235d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocArrayWithAccessCheck = art_quick_alloc_array_with_access_check##suffix; \ 236d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocObject = art_quick_alloc_object##suffix; \ 237d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocObjectResolved = art_quick_alloc_object_resolved##suffix; \ 238d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocObjectInitialized = art_quick_alloc_object_initialized##suffix; \ 239d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pAllocObjectWithAccessCheck = art_quick_alloc_object_with_access_check##suffix; \ 240d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pCheckAndAllocArray = art_quick_check_and_alloc_array##suffix; \ 241d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier qpoints->pCheckAndAllocArrayWithAccessCheck = art_quick_check_and_alloc_array_with_access_check##suffix; \ 242848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pAllocStringFromBytes = art_quick_alloc_string_from_bytes##suffix; \ 243848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pAllocStringFromChars = art_quick_alloc_string_from_chars##suffix; \ 244848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao qpoints->pAllocStringFromString = art_quick_alloc_string_from_string##suffix; \ 245d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier } \ 246d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier} 247d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier 248d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier// Generate the entrypoint functions. 249c3ccc1039e0bbc0744f958cb8719cf96bce5b853Ian Rogers#if !defined(__APPLE__) || !defined(__LP64__) 250c8ccf68b805c92674545f63e0341ba47e8d9701cAndreas GampeGENERATE_ENTRYPOINTS(_dlmalloc) 251c8ccf68b805c92674545f63e0341ba47e8d9701cAndreas GampeGENERATE_ENTRYPOINTS(_rosalloc) 252c8ccf68b805c92674545f63e0341ba47e8d9701cAndreas GampeGENERATE_ENTRYPOINTS(_bump_pointer) 253c8ccf68b805c92674545f63e0341ba47e8d9701cAndreas GampeGENERATE_ENTRYPOINTS(_tlab) 2542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi YamauchiGENERATE_ENTRYPOINTS(_region) 2552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi YamauchiGENERATE_ENTRYPOINTS(_region_tlab) 256c3ccc1039e0bbc0744f958cb8719cf96bce5b853Ian Rogers#endif 257d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier 258d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartierstatic bool entry_points_instrumented = false; 259d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartierstatic gc::AllocatorType entry_points_allocator = gc::kAllocatorTypeDlMalloc; 260d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier 261d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartiervoid SetQuickAllocEntryPointsAllocator(gc::AllocatorType allocator) { 262d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier entry_points_allocator = allocator; 263d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier} 264d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier 265d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartiervoid SetQuickAllocEntryPointsInstrumented(bool instrumented) { 266d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier entry_points_instrumented = instrumented; 267d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier} 268d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier 269d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartiervoid ResetQuickAllocEntryPoints(QuickEntryPoints* qpoints) { 27048cc32c05efaaba5d97e1b83a9f9d8172a8ca352Andreas Gampe#if !defined(__APPLE__) || !defined(__LP64__) 271de2db523960444ca8abd175814374cb3782f1632Ian Rogers switch (entry_points_allocator) { 272d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier case gc::kAllocatorTypeDlMalloc: { 273d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier SetQuickAllocEntryPoints_dlmalloc(qpoints, entry_points_instrumented); 2747dc9c81aee48928bd7a723fd9a4caed63d196f8fIan Rogers return; 275d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier } 276d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier case gc::kAllocatorTypeRosAlloc: { 277d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier SetQuickAllocEntryPoints_rosalloc(qpoints, entry_points_instrumented); 2787dc9c81aee48928bd7a723fd9a4caed63d196f8fIan Rogers return; 279d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier } 280d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier case gc::kAllocatorTypeBumpPointer: { 281d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier CHECK(kMovingCollector); 282d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier SetQuickAllocEntryPoints_bump_pointer(qpoints, entry_points_instrumented); 2837dc9c81aee48928bd7a723fd9a4caed63d196f8fIan Rogers return; 284d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier } 285d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier case gc::kAllocatorTypeTLAB: { 286d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier CHECK(kMovingCollector); 287d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier SetQuickAllocEntryPoints_tlab(qpoints, entry_points_instrumented); 2887dc9c81aee48928bd7a723fd9a4caed63d196f8fIan Rogers return; 289d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier } 2902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi case gc::kAllocatorTypeRegion: { 2912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi CHECK(kMovingCollector); 2922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi SetQuickAllocEntryPoints_region(qpoints, entry_points_instrumented); 2932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return; 2942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi case gc::kAllocatorTypeRegionTLAB: { 2962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi CHECK(kMovingCollector); 2972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi SetQuickAllocEntryPoints_region_tlab(qpoints, entry_points_instrumented); 2982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return; 2992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 30048cc32c05efaaba5d97e1b83a9f9d8172a8ca352Andreas Gampe default: 30148cc32c05efaaba5d97e1b83a9f9d8172a8ca352Andreas Gampe break; 302d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier } 30348cc32c05efaaba5d97e1b83a9f9d8172a8ca352Andreas Gampe#else 30448cc32c05efaaba5d97e1b83a9f9d8172a8ca352Andreas Gampe UNUSED(qpoints); 30548cc32c05efaaba5d97e1b83a9f9d8172a8ca352Andreas Gampe#endif 30648cc32c05efaaba5d97e1b83a9f9d8172a8ca352Andreas Gampe UNIMPLEMENTED(FATAL); 307de2db523960444ca8abd175814374cb3782f1632Ian Rogers UNREACHABLE(); 308d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier} 309d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier 31057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers} // namespace art 311