quick_field_entrypoints.cc revision 98d1cc8033251c93786e2fa8c59a2e555a9493be
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 "callee_save_frame.h" 18#include "dex_file-inl.h" 19#include "entrypoints/entrypoint_utils-inl.h" 20#include "mirror/art_field-inl.h" 21#include "mirror/art_method-inl.h" 22#include "mirror/class-inl.h" 23 24#include <stdint.h> 25 26namespace art { 27 28extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx, 29 mirror::ArtMethod* referrer, 30 Thread* self, StackReference<mirror::ArtMethod>* sp) 31 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 32 mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, 33 sizeof(int32_t)); 34 if (LIKELY(field != NULL)) { 35 return field->Get32(field->GetDeclaringClass()); 36 } 37 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 38 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int32_t)); 39 if (LIKELY(field != NULL)) { 40 return field->Get32(field->GetDeclaringClass()); 41 } 42 return 0; // Will throw exception by checking with Thread::Current 43} 44 45extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx, 46 mirror::ArtMethod* referrer, 47 Thread* self, StackReference<mirror::ArtMethod>* sp) 48 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 49 mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, 50 sizeof(int64_t)); 51 if (LIKELY(field != NULL)) { 52 return field->Get64(field->GetDeclaringClass()); 53 } 54 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 55 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int64_t)); 56 if (LIKELY(field != NULL)) { 57 return field->Get64(field->GetDeclaringClass()); 58 } 59 return 0; // Will throw exception by checking with Thread::Current 60} 61 62extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx, 63 mirror::ArtMethod* referrer, 64 Thread* self, 65 StackReference<mirror::ArtMethod>* sp) 66 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 67 mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectRead, 68 sizeof(mirror::HeapReference<mirror::Object>)); 69 if (LIKELY(field != NULL)) { 70 return field->GetObj(field->GetDeclaringClass()); 71 } 72 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 73 field = FindFieldFromCode<StaticObjectRead, true>(field_idx, referrer, self, 74 sizeof(mirror::HeapReference<mirror::Object>)); 75 if (LIKELY(field != NULL)) { 76 return field->GetObj(field->GetDeclaringClass()); 77 } 78 return NULL; // Will throw exception by checking with Thread::Current 79} 80 81extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, 82 mirror::ArtMethod* referrer, Thread* self, 83 StackReference<mirror::ArtMethod>* sp) 84 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 85 mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, 86 sizeof(int32_t)); 87 if (LIKELY(field != NULL && obj != NULL)) { 88 return field->Get32(obj); 89 } 90 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 91 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self, 92 sizeof(int32_t)); 93 if (LIKELY(field != NULL)) { 94 if (UNLIKELY(obj == NULL)) { 95 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 96 ThrowNullPointerExceptionForFieldAccess(throw_location, field, true); 97 } else { 98 return field->Get32(obj); 99 } 100 } 101 return 0; // Will throw exception by checking with Thread::Current 102} 103 104extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, 105 mirror::ArtMethod* referrer, Thread* self, 106 StackReference<mirror::ArtMethod>* sp) 107 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 108 mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, 109 sizeof(int64_t)); 110 if (LIKELY(field != NULL && obj != NULL)) { 111 return field->Get64(obj); 112 } 113 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 114 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self, 115 sizeof(int64_t)); 116 if (LIKELY(field != NULL)) { 117 if (UNLIKELY(obj == NULL)) { 118 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 119 ThrowNullPointerExceptionForFieldAccess(throw_location, field, true); 120 } else { 121 return field->Get64(obj); 122 } 123 } 124 return 0; // Will throw exception by checking with Thread::Current 125} 126 127extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj, 128 mirror::ArtMethod* referrer, 129 Thread* self, 130 StackReference<mirror::ArtMethod>* sp) 131 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 132 mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectRead, 133 sizeof(mirror::HeapReference<mirror::Object>)); 134 if (LIKELY(field != NULL && obj != NULL)) { 135 return field->GetObj(obj); 136 } 137 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 138 field = FindFieldFromCode<InstanceObjectRead, true>(field_idx, referrer, self, 139 sizeof(mirror::HeapReference<mirror::Object>)); 140 if (LIKELY(field != NULL)) { 141 if (UNLIKELY(obj == NULL)) { 142 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 143 ThrowNullPointerExceptionForFieldAccess(throw_location, field, true); 144 } else { 145 return field->GetObj(obj); 146 } 147 } 148 return NULL; // Will throw exception by checking with Thread::Current 149} 150 151extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value, 152 mirror::ArtMethod* referrer, Thread* self, 153 StackReference<mirror::ArtMethod>* sp) 154 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 155 mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, 156 sizeof(int32_t)); 157 if (LIKELY(field != NULL)) { 158 // Compiled code can't use transactional mode. 159 field->Set32<false>(field->GetDeclaringClass(), new_value); 160 return 0; // success 161 } 162 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 163 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int32_t)); 164 if (LIKELY(field != NULL)) { 165 // Compiled code can't use transactional mode. 166 field->Set32<false>(field->GetDeclaringClass(), new_value); 167 return 0; // success 168 } 169 return -1; // failure 170} 171 172extern "C" int artSet64StaticFromCode(uint32_t field_idx, mirror::ArtMethod* referrer, 173 uint64_t new_value, Thread* self, 174 StackReference<mirror::ArtMethod>* sp) 175 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 176 mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, 177 sizeof(int64_t)); 178 if (LIKELY(field != NULL)) { 179 // Compiled code can't use transactional mode. 180 field->Set64<false>(field->GetDeclaringClass(), new_value); 181 return 0; // success 182 } 183 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 184 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int64_t)); 185 if (LIKELY(field != NULL)) { 186 // Compiled code can't use transactional mode. 187 field->Set64<false>(field->GetDeclaringClass(), new_value); 188 return 0; // success 189 } 190 return -1; // failure 191} 192 193extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_value, 194 mirror::ArtMethod* referrer, Thread* self, 195 StackReference<mirror::ArtMethod>* sp) 196 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 197 mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectWrite, 198 sizeof(mirror::HeapReference<mirror::Object>)); 199 if (LIKELY(field != NULL)) { 200 if (LIKELY(!field->IsPrimitiveType())) { 201 // Compiled code can't use transactional mode. 202 field->SetObj<false>(field->GetDeclaringClass(), new_value); 203 return 0; // success 204 } 205 } 206 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 207 field = FindFieldFromCode<StaticObjectWrite, true>(field_idx, referrer, self, 208 sizeof(mirror::HeapReference<mirror::Object>)); 209 if (LIKELY(field != NULL)) { 210 // Compiled code can't use transactional mode. 211 field->SetObj<false>(field->GetDeclaringClass(), new_value); 212 return 0; // success 213 } 214 return -1; // failure 215} 216 217extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint32_t new_value, 218 mirror::ArtMethod* referrer, Thread* self, 219 StackReference<mirror::ArtMethod>* sp) 220 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 221 mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, 222 sizeof(int32_t)); 223 if (LIKELY(field != NULL && obj != NULL)) { 224 // Compiled code can't use transactional mode. 225 field->Set32<false>(obj, new_value); 226 return 0; // success 227 } 228 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 229 { 230 StackHandleScope<1> hs(self); 231 HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj)); 232 field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self, 233 sizeof(int32_t)); 234 } 235 if (LIKELY(field != NULL)) { 236 if (UNLIKELY(obj == NULL)) { 237 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 238 ThrowNullPointerExceptionForFieldAccess(throw_location, field, false); 239 } else { 240 // Compiled code can't use transactional mode. 241 field->Set32<false>(obj, new_value); 242 return 0; // success 243 } 244 } 245 return -1; // failure 246} 247 248extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint64_t new_value, 249 Thread* self, StackReference<mirror::ArtMethod>* sp) 250 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 251 constexpr size_t frame_size = GetCalleeSaveFrameSize(kRuntimeISA, Runtime::kRefsOnly); 252 mirror::ArtMethod* referrer = 253 reinterpret_cast<StackReference<mirror::ArtMethod>*>( 254 reinterpret_cast<uint8_t*>(sp) + frame_size)->AsMirrorPtr(); 255 mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, 256 sizeof(int64_t)); 257 if (LIKELY(field != NULL && obj != NULL)) { 258 // Compiled code can't use transactional mode. 259 field->Set64<false>(obj, new_value); 260 return 0; // success 261 } 262 sp->Assign(Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsOnly)); 263 self->SetTopOfStack(sp, 0); 264 field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self, 265 sizeof(int64_t)); 266 if (LIKELY(field != NULL)) { 267 if (UNLIKELY(obj == NULL)) { 268 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 269 ThrowNullPointerExceptionForFieldAccess(throw_location, field, false); 270 } else { 271 // Compiled code can't use transactional mode. 272 field->Set64<false>(obj, new_value); 273 return 0; // success 274 } 275 } 276 return -1; // failure 277} 278 279extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj, 280 mirror::Object* new_value, 281 mirror::ArtMethod* referrer, Thread* self, 282 StackReference<mirror::ArtMethod>* sp) 283 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 284 mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite, 285 sizeof(mirror::HeapReference<mirror::Object>)); 286 if (LIKELY(field != NULL && obj != NULL)) { 287 // Compiled code can't use transactional mode. 288 field->SetObj<false>(obj, new_value); 289 return 0; // success 290 } 291 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 292 field = FindFieldFromCode<InstanceObjectWrite, true>(field_idx, referrer, self, 293 sizeof(mirror::HeapReference<mirror::Object>)); 294 if (LIKELY(field != NULL)) { 295 if (UNLIKELY(obj == NULL)) { 296 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 297 ThrowNullPointerExceptionForFieldAccess(throw_location, field, false); 298 } else { 299 // Compiled code can't use transactional mode. 300 field->SetObj<false>(obj, new_value); 301 return 0; // success 302 } 303 } 304 return -1; // failure 305} 306 307} // namespace art 308