1 /* 2 * Copyright (C) 2012 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 #include <string.h> 18 19 #include "atomic.h" 20 #include "entrypoints/jni/jni_entrypoints.h" 21 #include "entrypoints/quick/quick_alloc_entrypoints.h" 22 #include "entrypoints/quick/quick_default_externs.h" 23 #include "entrypoints/quick/quick_entrypoints.h" 24 #include "entrypoints/entrypoint_utils.h" 25 #include "entrypoints/math_entrypoints.h" 26 #include "entrypoints/runtime_asm_entrypoints.h" 27 #include "entrypoints_direct_mips.h" 28 #include "interpreter/interpreter.h" 29 30 namespace art { 31 32 // Cast entrypoints. 33 extern "C" size_t artInstanceOfFromCode(mirror::Object* obj, mirror::Class* ref_class); 34 35 // Read barrier entrypoints. 36 // art_quick_read_barrier_mark_regXX uses a non-standard calling 37 // convention: it expects its input in register XX+1 and returns its 38 // result in that same register, and saves and restores all 39 // caller-save registers. 40 extern "C" mirror::Object* art_quick_read_barrier_mark_reg01(mirror::Object*); 41 extern "C" mirror::Object* art_quick_read_barrier_mark_reg02(mirror::Object*); 42 extern "C" mirror::Object* art_quick_read_barrier_mark_reg03(mirror::Object*); 43 extern "C" mirror::Object* art_quick_read_barrier_mark_reg04(mirror::Object*); 44 extern "C" mirror::Object* art_quick_read_barrier_mark_reg05(mirror::Object*); 45 extern "C" mirror::Object* art_quick_read_barrier_mark_reg06(mirror::Object*); 46 extern "C" mirror::Object* art_quick_read_barrier_mark_reg07(mirror::Object*); 47 extern "C" mirror::Object* art_quick_read_barrier_mark_reg08(mirror::Object*); 48 extern "C" mirror::Object* art_quick_read_barrier_mark_reg09(mirror::Object*); 49 extern "C" mirror::Object* art_quick_read_barrier_mark_reg10(mirror::Object*); 50 extern "C" mirror::Object* art_quick_read_barrier_mark_reg11(mirror::Object*); 51 extern "C" mirror::Object* art_quick_read_barrier_mark_reg12(mirror::Object*); 52 extern "C" mirror::Object* art_quick_read_barrier_mark_reg13(mirror::Object*); 53 extern "C" mirror::Object* art_quick_read_barrier_mark_reg14(mirror::Object*); 54 extern "C" mirror::Object* art_quick_read_barrier_mark_reg17(mirror::Object*); 55 extern "C" mirror::Object* art_quick_read_barrier_mark_reg18(mirror::Object*); 56 extern "C" mirror::Object* art_quick_read_barrier_mark_reg19(mirror::Object*); 57 extern "C" mirror::Object* art_quick_read_barrier_mark_reg20(mirror::Object*); 58 extern "C" mirror::Object* art_quick_read_barrier_mark_reg21(mirror::Object*); 59 extern "C" mirror::Object* art_quick_read_barrier_mark_reg22(mirror::Object*); 60 extern "C" mirror::Object* art_quick_read_barrier_mark_reg29(mirror::Object*); 61 62 // Math entrypoints. 63 extern int32_t CmpgDouble(double a, double b); 64 extern int32_t CmplDouble(double a, double b); 65 extern int32_t CmpgFloat(float a, float b); 66 extern int32_t CmplFloat(float a, float b); 67 extern "C" int64_t artLmul(int64_t a, int64_t b); 68 extern "C" int64_t artLdiv(int64_t a, int64_t b); 69 extern "C" int64_t artLmod(int64_t a, int64_t b); 70 71 // Math conversions. 72 extern "C" int32_t __fixsfsi(float op1); // FLOAT_TO_INT 73 extern "C" int32_t __fixdfsi(double op1); // DOUBLE_TO_INT 74 extern "C" float __floatdisf(int64_t op1); // LONG_TO_FLOAT 75 extern "C" double __floatdidf(int64_t op1); // LONG_TO_DOUBLE 76 extern "C" int64_t __fixsfdi(float op1); // FLOAT_TO_LONG 77 extern "C" int64_t __fixdfdi(double op1); // DOUBLE_TO_LONG 78 79 // Single-precision FP arithmetics. 80 extern "C" float fmodf(float a, float b); // REM_FLOAT[_2ADDR] 81 82 // Double-precision FP arithmetics. 83 extern "C" double fmod(double a, double b); // REM_DOUBLE[_2ADDR] 84 85 // Long long arithmetics - REM_LONG[_2ADDR] and DIV_LONG[_2ADDR] 86 extern "C" int64_t __divdi3(int64_t, int64_t); 87 extern "C" int64_t __moddi3(int64_t, int64_t); 88 89 void UpdateReadBarrierEntrypoints(QuickEntryPoints* qpoints, bool is_active) { 90 qpoints->pReadBarrierMarkReg01 = is_active ? art_quick_read_barrier_mark_reg01 : nullptr; 91 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg01), 92 "Non-direct C stub marked direct."); 93 qpoints->pReadBarrierMarkReg02 = is_active ? art_quick_read_barrier_mark_reg02 : nullptr; 94 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg02), 95 "Non-direct C stub marked direct."); 96 qpoints->pReadBarrierMarkReg03 = is_active ? art_quick_read_barrier_mark_reg03 : nullptr; 97 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg03), 98 "Non-direct C stub marked direct."); 99 qpoints->pReadBarrierMarkReg04 = is_active ? art_quick_read_barrier_mark_reg04 : nullptr; 100 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg04), 101 "Non-direct C stub marked direct."); 102 qpoints->pReadBarrierMarkReg05 = is_active ? art_quick_read_barrier_mark_reg05 : nullptr; 103 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg05), 104 "Non-direct C stub marked direct."); 105 qpoints->pReadBarrierMarkReg06 = is_active ? art_quick_read_barrier_mark_reg06 : nullptr; 106 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg06), 107 "Non-direct C stub marked direct."); 108 qpoints->pReadBarrierMarkReg07 = is_active ? art_quick_read_barrier_mark_reg07 : nullptr; 109 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg07), 110 "Non-direct C stub marked direct."); 111 qpoints->pReadBarrierMarkReg08 = is_active ? art_quick_read_barrier_mark_reg08 : nullptr; 112 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg08), 113 "Non-direct C stub marked direct."); 114 qpoints->pReadBarrierMarkReg09 = is_active ? art_quick_read_barrier_mark_reg09 : nullptr; 115 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg09), 116 "Non-direct C stub marked direct."); 117 qpoints->pReadBarrierMarkReg10 = is_active ? art_quick_read_barrier_mark_reg10 : nullptr; 118 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg10), 119 "Non-direct C stub marked direct."); 120 qpoints->pReadBarrierMarkReg11 = is_active ? art_quick_read_barrier_mark_reg11 : nullptr; 121 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg11), 122 "Non-direct C stub marked direct."); 123 qpoints->pReadBarrierMarkReg12 = is_active ? art_quick_read_barrier_mark_reg12 : nullptr; 124 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg12), 125 "Non-direct C stub marked direct."); 126 qpoints->pReadBarrierMarkReg13 = is_active ? art_quick_read_barrier_mark_reg13 : nullptr; 127 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg13), 128 "Non-direct C stub marked direct."); 129 qpoints->pReadBarrierMarkReg14 = is_active ? art_quick_read_barrier_mark_reg14 : nullptr; 130 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg14), 131 "Non-direct C stub marked direct."); 132 qpoints->pReadBarrierMarkReg17 = is_active ? art_quick_read_barrier_mark_reg17 : nullptr; 133 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg17), 134 "Non-direct C stub marked direct."); 135 qpoints->pReadBarrierMarkReg18 = is_active ? art_quick_read_barrier_mark_reg18 : nullptr; 136 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg18), 137 "Non-direct C stub marked direct."); 138 qpoints->pReadBarrierMarkReg19 = is_active ? art_quick_read_barrier_mark_reg19 : nullptr; 139 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg19), 140 "Non-direct C stub marked direct."); 141 qpoints->pReadBarrierMarkReg20 = is_active ? art_quick_read_barrier_mark_reg20 : nullptr; 142 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg20), 143 "Non-direct C stub marked direct."); 144 qpoints->pReadBarrierMarkReg21 = is_active ? art_quick_read_barrier_mark_reg21 : nullptr; 145 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg21), 146 "Non-direct C stub marked direct."); 147 qpoints->pReadBarrierMarkReg22 = is_active ? art_quick_read_barrier_mark_reg22 : nullptr; 148 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg22), 149 "Non-direct C stub marked direct."); 150 qpoints->pReadBarrierMarkReg29 = is_active ? art_quick_read_barrier_mark_reg29 : nullptr; 151 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg29), 152 "Non-direct C stub marked direct."); 153 } 154 155 void InitEntryPoints(JniEntryPoints* jpoints, QuickEntryPoints* qpoints) { 156 // Note: MIPS has asserts checking for the type of entrypoint. Don't move it 157 // to InitDefaultEntryPoints(). 158 159 // JNI 160 jpoints->pDlsymLookup = art_jni_dlsym_lookup_stub; 161 162 // Alloc 163 ResetQuickAllocEntryPoints(qpoints, /*is_active*/ false); 164 165 // Cast 166 qpoints->pInstanceofNonTrivial = artInstanceOfFromCode; 167 static_assert(IsDirectEntrypoint(kQuickInstanceofNonTrivial), "Direct C stub not marked direct."); 168 qpoints->pCheckInstanceOf = art_quick_check_instance_of; 169 static_assert(!IsDirectEntrypoint(kQuickCheckInstanceOf), "Non-direct C stub marked direct."); 170 171 // DexCache 172 qpoints->pInitializeStaticStorage = art_quick_initialize_static_storage; 173 static_assert(!IsDirectEntrypoint(kQuickInitializeStaticStorage), 174 "Non-direct C stub marked direct."); 175 qpoints->pInitializeTypeAndVerifyAccess = art_quick_initialize_type_and_verify_access; 176 static_assert(!IsDirectEntrypoint(kQuickInitializeTypeAndVerifyAccess), 177 "Non-direct C stub marked direct."); 178 qpoints->pInitializeType = art_quick_initialize_type; 179 static_assert(!IsDirectEntrypoint(kQuickInitializeType), "Non-direct C stub marked direct."); 180 qpoints->pResolveString = art_quick_resolve_string; 181 static_assert(!IsDirectEntrypoint(kQuickResolveString), "Non-direct C stub marked direct."); 182 183 // Field 184 qpoints->pSet8Instance = art_quick_set8_instance; 185 static_assert(!IsDirectEntrypoint(kQuickSet8Instance), "Non-direct C stub marked direct."); 186 qpoints->pSet8Static = art_quick_set8_static; 187 static_assert(!IsDirectEntrypoint(kQuickSet8Static), "Non-direct C stub marked direct."); 188 qpoints->pSet16Instance = art_quick_set16_instance; 189 static_assert(!IsDirectEntrypoint(kQuickSet16Instance), "Non-direct C stub marked direct."); 190 qpoints->pSet16Static = art_quick_set16_static; 191 static_assert(!IsDirectEntrypoint(kQuickSet16Static), "Non-direct C stub marked direct."); 192 qpoints->pSet32Instance = art_quick_set32_instance; 193 static_assert(!IsDirectEntrypoint(kQuickSet32Instance), "Non-direct C stub marked direct."); 194 qpoints->pSet32Static = art_quick_set32_static; 195 static_assert(!IsDirectEntrypoint(kQuickSet32Static), "Non-direct C stub marked direct."); 196 qpoints->pSet64Instance = art_quick_set64_instance; 197 static_assert(!IsDirectEntrypoint(kQuickSet64Instance), "Non-direct C stub marked direct."); 198 qpoints->pSet64Static = art_quick_set64_static; 199 static_assert(!IsDirectEntrypoint(kQuickSet64Static), "Non-direct C stub marked direct."); 200 qpoints->pSetObjInstance = art_quick_set_obj_instance; 201 static_assert(!IsDirectEntrypoint(kQuickSetObjInstance), "Non-direct C stub marked direct."); 202 qpoints->pSetObjStatic = art_quick_set_obj_static; 203 static_assert(!IsDirectEntrypoint(kQuickSetObjStatic), "Non-direct C stub marked direct."); 204 qpoints->pGetBooleanInstance = art_quick_get_boolean_instance; 205 static_assert(!IsDirectEntrypoint(kQuickGetBooleanInstance), "Non-direct C stub marked direct."); 206 qpoints->pGetByteInstance = art_quick_get_byte_instance; 207 static_assert(!IsDirectEntrypoint(kQuickGetByteInstance), "Non-direct C stub marked direct."); 208 qpoints->pGetCharInstance = art_quick_get_char_instance; 209 static_assert(!IsDirectEntrypoint(kQuickGetCharInstance), "Non-direct C stub marked direct."); 210 qpoints->pGetShortInstance = art_quick_get_short_instance; 211 static_assert(!IsDirectEntrypoint(kQuickGetShortInstance), "Non-direct C stub marked direct."); 212 qpoints->pGet32Instance = art_quick_get32_instance; 213 static_assert(!IsDirectEntrypoint(kQuickGet32Instance), "Non-direct C stub marked direct."); 214 qpoints->pGet64Instance = art_quick_get64_instance; 215 static_assert(!IsDirectEntrypoint(kQuickGet64Instance), "Non-direct C stub marked direct."); 216 qpoints->pGetObjInstance = art_quick_get_obj_instance; 217 static_assert(!IsDirectEntrypoint(kQuickGetObjInstance), "Non-direct C stub marked direct."); 218 qpoints->pGetBooleanStatic = art_quick_get_boolean_static; 219 static_assert(!IsDirectEntrypoint(kQuickGetBooleanStatic), "Non-direct C stub marked direct."); 220 qpoints->pGetByteStatic = art_quick_get_byte_static; 221 static_assert(!IsDirectEntrypoint(kQuickGetByteStatic), "Non-direct C stub marked direct."); 222 qpoints->pGetCharStatic = art_quick_get_char_static; 223 static_assert(!IsDirectEntrypoint(kQuickGetCharStatic), "Non-direct C stub marked direct."); 224 qpoints->pGetShortStatic = art_quick_get_short_static; 225 static_assert(!IsDirectEntrypoint(kQuickGetShortStatic), "Non-direct C stub marked direct."); 226 qpoints->pGet32Static = art_quick_get32_static; 227 static_assert(!IsDirectEntrypoint(kQuickGet32Static), "Non-direct C stub marked direct."); 228 qpoints->pGet64Static = art_quick_get64_static; 229 static_assert(!IsDirectEntrypoint(kQuickGet64Static), "Non-direct C stub marked direct."); 230 qpoints->pGetObjStatic = art_quick_get_obj_static; 231 static_assert(!IsDirectEntrypoint(kQuickGetObjStatic), "Non-direct C stub marked direct."); 232 233 // Array 234 qpoints->pAputObject = art_quick_aput_obj; 235 static_assert(!IsDirectEntrypoint(kQuickAputObject), "Non-direct C stub marked direct."); 236 237 // JNI 238 qpoints->pJniMethodStart = JniMethodStart; 239 static_assert(!IsDirectEntrypoint(kQuickJniMethodStart), "Non-direct C stub marked direct."); 240 qpoints->pJniMethodFastStart = JniMethodFastStart; 241 static_assert(!IsDirectEntrypoint(kQuickJniMethodFastStart), "Non-direct C stub marked direct."); 242 qpoints->pJniMethodStartSynchronized = JniMethodStartSynchronized; 243 static_assert(!IsDirectEntrypoint(kQuickJniMethodStartSynchronized), 244 "Non-direct C stub marked direct."); 245 qpoints->pJniMethodEnd = JniMethodEnd; 246 static_assert(!IsDirectEntrypoint(kQuickJniMethodEnd), "Non-direct C stub marked direct."); 247 qpoints->pJniMethodFastEnd = JniMethodFastEnd; 248 static_assert(!IsDirectEntrypoint(kQuickJniMethodFastEnd), "Non-direct C stub marked direct."); 249 qpoints->pJniMethodEndSynchronized = JniMethodEndSynchronized; 250 static_assert(!IsDirectEntrypoint(kQuickJniMethodEndSynchronized), 251 "Non-direct C stub marked direct."); 252 qpoints->pJniMethodEndWithReference = JniMethodEndWithReference; 253 static_assert(!IsDirectEntrypoint(kQuickJniMethodEndWithReference), 254 "Non-direct C stub marked direct."); 255 qpoints->pJniMethodFastEndWithReference = JniMethodFastEndWithReference; 256 static_assert(!IsDirectEntrypoint(kQuickJniMethodFastEndWithReference), 257 "Non-direct C stub marked direct."); 258 qpoints->pJniMethodEndWithReferenceSynchronized = JniMethodEndWithReferenceSynchronized; 259 static_assert(!IsDirectEntrypoint(kQuickJniMethodEndWithReferenceSynchronized), 260 "Non-direct C stub marked direct."); 261 qpoints->pQuickGenericJniTrampoline = art_quick_generic_jni_trampoline; 262 static_assert(!IsDirectEntrypoint(kQuickQuickGenericJniTrampoline), 263 "Non-direct C stub marked direct."); 264 265 // Locks 266 if (UNLIKELY(VLOG_IS_ON(systrace_lock_logging))) { 267 qpoints->pLockObject = art_quick_lock_object_no_inline; 268 qpoints->pUnlockObject = art_quick_unlock_object_no_inline; 269 } else { 270 qpoints->pLockObject = art_quick_lock_object; 271 qpoints->pUnlockObject = art_quick_unlock_object; 272 } 273 static_assert(!IsDirectEntrypoint(kQuickLockObject), "Non-direct C stub marked direct."); 274 static_assert(!IsDirectEntrypoint(kQuickUnlockObject), "Non-direct C stub marked direct."); 275 276 // Math 277 qpoints->pCmpgDouble = CmpgDouble; 278 static_assert(IsDirectEntrypoint(kQuickCmpgDouble), "Direct C stub not marked direct."); 279 qpoints->pCmpgFloat = CmpgFloat; 280 static_assert(IsDirectEntrypoint(kQuickCmpgFloat), "Direct C stub not marked direct."); 281 qpoints->pCmplDouble = CmplDouble; 282 static_assert(IsDirectEntrypoint(kQuickCmplDouble), "Direct C stub not marked direct."); 283 qpoints->pCmplFloat = CmplFloat; 284 static_assert(IsDirectEntrypoint(kQuickCmplFloat), "Direct C stub not marked direct."); 285 qpoints->pFmod = fmod; 286 static_assert(IsDirectEntrypoint(kQuickFmod), "Direct C stub not marked direct."); 287 qpoints->pL2d = art_l2d; 288 static_assert(IsDirectEntrypoint(kQuickL2d), "Direct C stub not marked direct."); 289 qpoints->pFmodf = fmodf; 290 static_assert(IsDirectEntrypoint(kQuickFmodf), "Direct C stub not marked direct."); 291 qpoints->pL2f = art_l2f; 292 static_assert(IsDirectEntrypoint(kQuickL2f), "Direct C stub not marked direct."); 293 qpoints->pD2iz = art_d2i; 294 static_assert(IsDirectEntrypoint(kQuickD2iz), "Direct C stub not marked direct."); 295 qpoints->pF2iz = art_f2i; 296 static_assert(IsDirectEntrypoint(kQuickF2iz), "Direct C stub not marked direct."); 297 qpoints->pIdivmod = nullptr; 298 qpoints->pD2l = art_d2l; 299 static_assert(IsDirectEntrypoint(kQuickD2l), "Direct C stub not marked direct."); 300 qpoints->pF2l = art_f2l; 301 static_assert(IsDirectEntrypoint(kQuickF2l), "Direct C stub not marked direct."); 302 qpoints->pLdiv = artLdiv; 303 static_assert(IsDirectEntrypoint(kQuickLdiv), "Direct C stub not marked direct."); 304 qpoints->pLmod = artLmod; 305 static_assert(IsDirectEntrypoint(kQuickLmod), "Direct C stub not marked direct."); 306 qpoints->pLmul = artLmul; 307 static_assert(IsDirectEntrypoint(kQuickLmul), "Direct C stub not marked direct."); 308 qpoints->pShlLong = art_quick_shl_long; 309 static_assert(!IsDirectEntrypoint(kQuickShlLong), "Non-direct C stub marked direct."); 310 qpoints->pShrLong = art_quick_shr_long; 311 static_assert(!IsDirectEntrypoint(kQuickShrLong), "Non-direct C stub marked direct."); 312 qpoints->pUshrLong = art_quick_ushr_long; 313 static_assert(!IsDirectEntrypoint(kQuickUshrLong), "Non-direct C stub marked direct."); 314 315 // More math. 316 qpoints->pCos = cos; 317 static_assert(IsDirectEntrypoint(kQuickCos), "Direct C stub marked non-direct."); 318 qpoints->pSin = sin; 319 static_assert(IsDirectEntrypoint(kQuickSin), "Direct C stub marked non-direct."); 320 qpoints->pAcos = acos; 321 static_assert(IsDirectEntrypoint(kQuickAcos), "Direct C stub marked non-direct."); 322 qpoints->pAsin = asin; 323 static_assert(IsDirectEntrypoint(kQuickAsin), "Direct C stub marked non-direct."); 324 qpoints->pAtan = atan; 325 static_assert(IsDirectEntrypoint(kQuickAtan), "Direct C stub marked non-direct."); 326 qpoints->pAtan2 = atan2; 327 static_assert(IsDirectEntrypoint(kQuickAtan2), "Direct C stub marked non-direct."); 328 qpoints->pCbrt = cbrt; 329 static_assert(IsDirectEntrypoint(kQuickCbrt), "Direct C stub marked non-direct."); 330 qpoints->pCosh = cosh; 331 static_assert(IsDirectEntrypoint(kQuickCosh), "Direct C stub marked non-direct."); 332 qpoints->pExp = exp; 333 static_assert(IsDirectEntrypoint(kQuickExp), "Direct C stub marked non-direct."); 334 qpoints->pExpm1 = expm1; 335 static_assert(IsDirectEntrypoint(kQuickExpm1), "Direct C stub marked non-direct."); 336 qpoints->pHypot = hypot; 337 static_assert(IsDirectEntrypoint(kQuickHypot), "Direct C stub marked non-direct."); 338 qpoints->pLog = log; 339 static_assert(IsDirectEntrypoint(kQuickLog), "Direct C stub marked non-direct."); 340 qpoints->pLog10 = log10; 341 static_assert(IsDirectEntrypoint(kQuickLog10), "Direct C stub marked non-direct."); 342 qpoints->pNextAfter = nextafter; 343 static_assert(IsDirectEntrypoint(kQuickNextAfter), "Direct C stub marked non-direct."); 344 qpoints->pSinh = sinh; 345 static_assert(IsDirectEntrypoint(kQuickSinh), "Direct C stub marked non-direct."); 346 qpoints->pTan = tan; 347 static_assert(IsDirectEntrypoint(kQuickTan), "Direct C stub marked non-direct."); 348 qpoints->pTanh = tanh; 349 static_assert(IsDirectEntrypoint(kQuickTanh), "Direct C stub marked non-direct."); 350 351 // Intrinsics 352 qpoints->pIndexOf = art_quick_indexof; 353 static_assert(!IsDirectEntrypoint(kQuickIndexOf), "Non-direct C stub marked direct."); 354 qpoints->pStringCompareTo = art_quick_string_compareto; 355 static_assert(!IsDirectEntrypoint(kQuickStringCompareTo), "Non-direct C stub marked direct."); 356 qpoints->pMemcpy = memcpy; 357 358 // Invocation 359 qpoints->pQuickImtConflictTrampoline = art_quick_imt_conflict_trampoline; 360 qpoints->pQuickResolutionTrampoline = art_quick_resolution_trampoline; 361 qpoints->pQuickToInterpreterBridge = art_quick_to_interpreter_bridge; 362 qpoints->pInvokeDirectTrampolineWithAccessCheck = 363 art_quick_invoke_direct_trampoline_with_access_check; 364 static_assert(!IsDirectEntrypoint(kQuickInvokeDirectTrampolineWithAccessCheck), 365 "Non-direct C stub marked direct."); 366 qpoints->pInvokeInterfaceTrampolineWithAccessCheck = 367 art_quick_invoke_interface_trampoline_with_access_check; 368 static_assert(!IsDirectEntrypoint(kQuickInvokeInterfaceTrampolineWithAccessCheck), 369 "Non-direct C stub marked direct."); 370 qpoints->pInvokeStaticTrampolineWithAccessCheck = 371 art_quick_invoke_static_trampoline_with_access_check; 372 static_assert(!IsDirectEntrypoint(kQuickInvokeStaticTrampolineWithAccessCheck), 373 "Non-direct C stub marked direct."); 374 qpoints->pInvokeSuperTrampolineWithAccessCheck = 375 art_quick_invoke_super_trampoline_with_access_check; 376 static_assert(!IsDirectEntrypoint(kQuickInvokeSuperTrampolineWithAccessCheck), 377 "Non-direct C stub marked direct."); 378 qpoints->pInvokeVirtualTrampolineWithAccessCheck = 379 art_quick_invoke_virtual_trampoline_with_access_check; 380 static_assert(!IsDirectEntrypoint(kQuickInvokeVirtualTrampolineWithAccessCheck), 381 "Non-direct C stub marked direct."); 382 qpoints->pInvokePolymorphic = art_quick_invoke_polymorphic; 383 384 // Thread 385 qpoints->pTestSuspend = art_quick_test_suspend; 386 static_assert(!IsDirectEntrypoint(kQuickTestSuspend), "Non-direct C stub marked direct."); 387 388 // Throws 389 qpoints->pDeliverException = art_quick_deliver_exception; 390 static_assert(!IsDirectEntrypoint(kQuickDeliverException), "Non-direct C stub marked direct."); 391 qpoints->pThrowArrayBounds = art_quick_throw_array_bounds; 392 static_assert(!IsDirectEntrypoint(kQuickThrowArrayBounds), "Non-direct C stub marked direct."); 393 qpoints->pThrowDivZero = art_quick_throw_div_zero; 394 static_assert(!IsDirectEntrypoint(kQuickThrowDivZero), "Non-direct C stub marked direct."); 395 qpoints->pThrowNullPointer = art_quick_throw_null_pointer_exception; 396 static_assert(!IsDirectEntrypoint(kQuickThrowNullPointer), "Non-direct C stub marked direct."); 397 qpoints->pThrowStackOverflow = art_quick_throw_stack_overflow; 398 static_assert(!IsDirectEntrypoint(kQuickThrowStackOverflow), "Non-direct C stub marked direct."); 399 qpoints->pThrowStringBounds = art_quick_throw_string_bounds; 400 static_assert(!IsDirectEntrypoint(kQuickThrowStringBounds), "Non-direct C stub marked direct."); 401 402 // Deoptimization from compiled code. 403 qpoints->pDeoptimize = art_quick_deoptimize_from_compiled_code; 404 static_assert(!IsDirectEntrypoint(kQuickDeoptimize), "Non-direct C stub marked direct."); 405 406 // Atomic 64-bit load/store 407 qpoints->pA64Load = QuasiAtomic::Read64; 408 static_assert(IsDirectEntrypoint(kQuickA64Load), "Non-direct C stub marked direct."); 409 qpoints->pA64Store = QuasiAtomic::Write64; 410 static_assert(IsDirectEntrypoint(kQuickA64Store), "Non-direct C stub marked direct."); 411 412 // Read barrier. 413 qpoints->pReadBarrierJni = ReadBarrierJni; 414 static_assert(IsDirectEntrypoint(kQuickReadBarrierJni), "Direct C stub not marked direct."); 415 UpdateReadBarrierEntrypoints(qpoints, /*is_active*/ false); 416 // Cannot use the following registers to pass arguments: 417 // 0(ZERO), 1(AT), 16(S0), 17(S1), 24(T8), 25(T9), 26(K0), 27(K1), 28(GP), 29(SP), 31(RA). 418 // Note that there are 30 entry points only: 00 for register 1(AT), ..., 29 for register 30(S8). 419 qpoints->pReadBarrierMarkReg00 = nullptr; 420 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg00), 421 "Non-direct C stub marked direct."); 422 qpoints->pReadBarrierMarkReg15 = nullptr; 423 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg15), 424 "Non-direct C stub marked direct."); 425 qpoints->pReadBarrierMarkReg16 = nullptr; 426 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg16), 427 "Non-direct C stub marked direct."); 428 qpoints->pReadBarrierMarkReg23 = nullptr; 429 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg23), 430 "Non-direct C stub marked direct."); 431 qpoints->pReadBarrierMarkReg24 = nullptr; 432 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg24), 433 "Non-direct C stub marked direct."); 434 qpoints->pReadBarrierMarkReg25 = nullptr; 435 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg25), 436 "Non-direct C stub marked direct."); 437 qpoints->pReadBarrierMarkReg26 = nullptr; 438 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg26), 439 "Non-direct C stub marked direct."); 440 qpoints->pReadBarrierMarkReg27 = nullptr; 441 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg27), 442 "Non-direct C stub marked direct."); 443 qpoints->pReadBarrierMarkReg28 = nullptr; 444 static_assert(!IsDirectEntrypoint(kQuickReadBarrierMarkReg28), 445 "Non-direct C stub marked direct."); 446 qpoints->pReadBarrierSlow = artReadBarrierSlow; 447 static_assert(IsDirectEntrypoint(kQuickReadBarrierSlow), "Direct C stub not marked direct."); 448 qpoints->pReadBarrierForRootSlow = artReadBarrierForRootSlow; 449 static_assert(IsDirectEntrypoint(kQuickReadBarrierForRootSlow), 450 "Direct C stub not marked direct."); 451 }; 452 453 } // namespace art 454