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