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.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 26 namespace art { 27 28 extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx, 29 const mirror::ArtMethod* referrer, 30 Thread* self, 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(field_idx, referrer, self, StaticPrimitiveRead, sizeof(int32_t), true); 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 45 extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx, 46 const mirror::ArtMethod* referrer, 47 Thread* self, 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(field_idx, referrer, self, StaticPrimitiveRead, sizeof(int64_t), true); 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 62 extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx, 63 const mirror::ArtMethod* referrer, 64 Thread* self, mirror::ArtMethod** sp) 65 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 66 mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectRead, 67 sizeof(mirror::Object*)); 68 if (LIKELY(field != NULL)) { 69 return field->GetObj(field->GetDeclaringClass()); 70 } 71 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 72 field = FindFieldFromCode(field_idx, referrer, self, StaticObjectRead, sizeof(mirror::Object*), 73 true); 74 if (LIKELY(field != NULL)) { 75 return field->GetObj(field->GetDeclaringClass()); 76 } 77 return NULL; // Will throw exception by checking with Thread::Current 78 } 79 80 extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, 81 const mirror::ArtMethod* referrer, Thread* self, 82 mirror::ArtMethod** sp) 83 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 84 mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, 85 sizeof(int32_t)); 86 if (LIKELY(field != NULL && obj != NULL)) { 87 return field->Get32(obj); 88 } 89 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 90 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int32_t), 91 true); 92 if (LIKELY(field != NULL)) { 93 if (UNLIKELY(obj == NULL)) { 94 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 95 ThrowNullPointerExceptionForFieldAccess(throw_location, field, true); 96 } else { 97 return field->Get32(obj); 98 } 99 } 100 return 0; // Will throw exception by checking with Thread::Current 101 } 102 103 extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, 104 const mirror::ArtMethod* referrer, Thread* self, 105 mirror::ArtMethod** sp) 106 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 107 mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, 108 sizeof(int64_t)); 109 if (LIKELY(field != NULL && obj != NULL)) { 110 return field->Get64(obj); 111 } 112 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 113 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int64_t), 114 true); 115 if (LIKELY(field != NULL)) { 116 if (UNLIKELY(obj == NULL)) { 117 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 118 ThrowNullPointerExceptionForFieldAccess(throw_location, field, true); 119 } else { 120 return field->Get64(obj); 121 } 122 } 123 return 0; // Will throw exception by checking with Thread::Current 124 } 125 126 extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj, 127 const mirror::ArtMethod* referrer, 128 Thread* self, 129 mirror::ArtMethod** sp) 130 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 131 mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectRead, 132 sizeof(mirror::Object*)); 133 if (LIKELY(field != NULL && obj != NULL)) { 134 return field->GetObj(obj); 135 } 136 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 137 field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectRead, sizeof(mirror::Object*), 138 true); 139 if (LIKELY(field != NULL)) { 140 if (UNLIKELY(obj == NULL)) { 141 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 142 ThrowNullPointerExceptionForFieldAccess(throw_location, field, true); 143 } else { 144 return field->GetObj(obj); 145 } 146 } 147 return NULL; // Will throw exception by checking with Thread::Current 148 } 149 150 extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value, 151 const mirror::ArtMethod* referrer, Thread* self, 152 mirror::ArtMethod** sp) 153 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 154 mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, 155 sizeof(int32_t)); 156 if (LIKELY(field != NULL)) { 157 field->Set32(field->GetDeclaringClass(), new_value); 158 return 0; // success 159 } 160 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 161 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int32_t), true); 162 if (LIKELY(field != NULL)) { 163 field->Set32(field->GetDeclaringClass(), new_value); 164 return 0; // success 165 } 166 return -1; // failure 167 } 168 169 extern "C" int artSet64StaticFromCode(uint32_t field_idx, const mirror::ArtMethod* referrer, 170 uint64_t new_value, Thread* self, mirror::ArtMethod** sp) 171 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 172 mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, 173 sizeof(int64_t)); 174 if (LIKELY(field != NULL)) { 175 field->Set64(field->GetDeclaringClass(), new_value); 176 return 0; // success 177 } 178 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 179 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int64_t), true); 180 if (LIKELY(field != NULL)) { 181 field->Set64(field->GetDeclaringClass(), new_value); 182 return 0; // success 183 } 184 return -1; // failure 185 } 186 187 extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_value, 188 const mirror::ArtMethod* referrer, Thread* self, 189 mirror::ArtMethod** sp) 190 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 191 mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectWrite, 192 sizeof(mirror::Object*)); 193 if (LIKELY(field != NULL)) { 194 if (LIKELY(!FieldHelper(field).IsPrimitiveType())) { 195 field->SetObj(field->GetDeclaringClass(), new_value); 196 return 0; // success 197 } 198 } 199 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 200 field = FindFieldFromCode(field_idx, referrer, self, StaticObjectWrite, sizeof(mirror::Object*), true); 201 if (LIKELY(field != NULL)) { 202 field->SetObj(field->GetDeclaringClass(), new_value); 203 return 0; // success 204 } 205 return -1; // failure 206 } 207 208 extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint32_t new_value, 209 const mirror::ArtMethod* referrer, Thread* self, 210 mirror::ArtMethod** sp) 211 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 212 mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, 213 sizeof(int32_t)); 214 if (LIKELY(field != NULL && obj != NULL)) { 215 field->Set32(obj, new_value); 216 return 0; // success 217 } 218 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 219 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int32_t), 220 true); 221 if (LIKELY(field != NULL)) { 222 if (UNLIKELY(obj == NULL)) { 223 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 224 ThrowNullPointerExceptionForFieldAccess(throw_location, field, false); 225 } else { 226 field->Set32(obj, new_value); 227 return 0; // success 228 } 229 } 230 return -1; // failure 231 } 232 233 extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint64_t new_value, 234 Thread* self, mirror::ArtMethod** sp) 235 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 236 mirror::ArtMethod* callee_save = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsOnly); 237 mirror::ArtMethod* referrer = 238 sp[callee_save->GetFrameSizeInBytes() / sizeof(mirror::ArtMethod*)]; 239 mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, 240 sizeof(int64_t)); 241 if (LIKELY(field != NULL && obj != NULL)) { 242 field->Set64(obj, new_value); 243 return 0; // success 244 } 245 *sp = callee_save; 246 self->SetTopOfStack(sp, 0); 247 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int64_t), 248 true); 249 if (LIKELY(field != NULL)) { 250 if (UNLIKELY(obj == NULL)) { 251 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 252 ThrowNullPointerExceptionForFieldAccess(throw_location, field, false); 253 } else { 254 field->Set64(obj, new_value); 255 return 0; // success 256 } 257 } 258 return -1; // failure 259 } 260 261 extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj, 262 mirror::Object* new_value, 263 const mirror::ArtMethod* referrer, Thread* self, 264 mirror::ArtMethod** sp) 265 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 266 mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite, 267 sizeof(mirror::Object*)); 268 if (LIKELY(field != NULL && obj != NULL)) { 269 field->SetObj(obj, new_value); 270 return 0; // success 271 } 272 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 273 field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectWrite, 274 sizeof(mirror::Object*), true); 275 if (LIKELY(field != NULL)) { 276 if (UNLIKELY(obj == NULL)) { 277 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 278 ThrowNullPointerExceptionForFieldAccess(throw_location, field, false); 279 } else { 280 field->SetObj(obj, new_value); 281 return 0; // success 282 } 283 } 284 return -1; // failure 285 } 286 287 } // namespace art 288