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