quick_field_entrypoints.cc revision 2fa6b2e2fc3d2a2fc27808ce518dc76b80ce369a
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 "runtime_support.h" 19 20#include <stdint.h> 21 22namespace art { 23 24extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx, const AbstractMethod* referrer, 25 Thread* self, AbstractMethod** sp) 26 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 27 Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int32_t)); 28 if (LIKELY(field != NULL)) { 29 return field->Get32(field->GetDeclaringClass()); 30 } 31 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 32 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveRead, sizeof(int32_t)); 33 if (LIKELY(field != NULL)) { 34 return field->Get32(field->GetDeclaringClass()); 35 } 36 return 0; // Will throw exception by checking with Thread::Current 37} 38 39extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx, const AbstractMethod* referrer, 40 Thread* self, AbstractMethod** sp) 41 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 42 Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int64_t)); 43 if (LIKELY(field != NULL)) { 44 return field->Get64(field->GetDeclaringClass()); 45 } 46 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 47 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveRead, sizeof(int64_t)); 48 if (LIKELY(field != NULL)) { 49 return field->Get64(field->GetDeclaringClass()); 50 } 51 return 0; // Will throw exception by checking with Thread::Current 52} 53 54extern "C" Object* artGetObjStaticFromCode(uint32_t field_idx, const AbstractMethod* referrer, 55 Thread* self, AbstractMethod** sp) 56 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 57 Field* field = FindFieldFast(field_idx, referrer, StaticObjectRead, sizeof(Object*)); 58 if (LIKELY(field != NULL)) { 59 return field->GetObj(field->GetDeclaringClass()); 60 } 61 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 62 field = FindFieldFromCode(field_idx, referrer, self, StaticObjectRead, sizeof(Object*)); 63 if (LIKELY(field != NULL)) { 64 return field->GetObj(field->GetDeclaringClass()); 65 } 66 return NULL; // Will throw exception by checking with Thread::Current 67} 68 69extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, Object* obj, 70 const AbstractMethod* referrer, Thread* self, 71 AbstractMethod** sp) 72 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 73 Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int32_t)); 74 if (LIKELY(field != NULL && obj != NULL)) { 75 return field->Get32(obj); 76 } 77 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 78 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int32_t)); 79 if (LIKELY(field != NULL)) { 80 if (UNLIKELY(obj == NULL)) { 81 ThrowNullPointerExceptionForFieldAccess(field, true); 82 } else { 83 return field->Get32(obj); 84 } 85 } 86 return 0; // Will throw exception by checking with Thread::Current 87} 88 89extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, Object* obj, 90 const AbstractMethod* referrer, Thread* self, 91 AbstractMethod** sp) 92 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 93 Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int64_t)); 94 if (LIKELY(field != NULL && obj != NULL)) { 95 return field->Get64(obj); 96 } 97 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 98 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int64_t)); 99 if (LIKELY(field != NULL)) { 100 if (UNLIKELY(obj == NULL)) { 101 ThrowNullPointerExceptionForFieldAccess(field, true); 102 } else { 103 return field->Get64(obj); 104 } 105 } 106 return 0; // Will throw exception by checking with Thread::Current 107} 108 109extern "C" Object* artGetObjInstanceFromCode(uint32_t field_idx, Object* obj, 110 const AbstractMethod* referrer, Thread* self, 111 AbstractMethod** sp) 112 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 113 Field* field = FindFieldFast(field_idx, referrer, InstanceObjectRead, sizeof(Object*)); 114 if (LIKELY(field != NULL && obj != NULL)) { 115 return field->GetObj(obj); 116 } 117 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 118 field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectRead, sizeof(Object*)); 119 if (LIKELY(field != NULL)) { 120 if (UNLIKELY(obj == NULL)) { 121 ThrowNullPointerExceptionForFieldAccess(field, true); 122 } else { 123 return field->GetObj(obj); 124 } 125 } 126 return NULL; // Will throw exception by checking with Thread::Current 127} 128 129extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value, 130 const AbstractMethod* referrer, Thread* self, 131 AbstractMethod** sp) 132 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 133 Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int32_t)); 134 if (LIKELY(field != NULL)) { 135 field->Set32(field->GetDeclaringClass(), new_value); 136 return 0; // success 137 } 138 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 139 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int32_t)); 140 if (LIKELY(field != NULL)) { 141 field->Set32(field->GetDeclaringClass(), new_value); 142 return 0; // success 143 } 144 return -1; // failure 145} 146 147extern "C" int artSet64StaticFromCode(uint32_t field_idx, const AbstractMethod* referrer, 148 uint64_t new_value, Thread* self, AbstractMethod** sp) 149 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 150 Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t)); 151 if (LIKELY(field != NULL)) { 152 field->Set64(field->GetDeclaringClass(), new_value); 153 return 0; // success 154 } 155 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 156 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int64_t)); 157 if (LIKELY(field != NULL)) { 158 field->Set64(field->GetDeclaringClass(), new_value); 159 return 0; // success 160 } 161 return -1; // failure 162} 163 164extern "C" int artSetObjStaticFromCode(uint32_t field_idx, Object* new_value, 165 const AbstractMethod* referrer, Thread* self, 166 AbstractMethod** sp) 167 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 168 Field* field = FindFieldFast(field_idx, referrer, StaticObjectWrite, sizeof(Object*)); 169 if (LIKELY(field != NULL)) { 170 if (LIKELY(!FieldHelper(field).IsPrimitiveType())) { 171 field->SetObj(field->GetDeclaringClass(), new_value); 172 return 0; // success 173 } 174 } 175 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 176 field = FindFieldFromCode(field_idx, referrer, self, StaticObjectWrite, sizeof(Object*)); 177 if (LIKELY(field != NULL)) { 178 field->SetObj(field->GetDeclaringClass(), new_value); 179 return 0; // success 180 } 181 return -1; // failure 182} 183 184extern "C" int artSet32InstanceFromCode(uint32_t field_idx, Object* obj, uint32_t new_value, 185 const AbstractMethod* referrer, Thread* self, 186 AbstractMethod** sp) 187 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 188 Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int32_t)); 189 if (LIKELY(field != NULL && obj != NULL)) { 190 field->Set32(obj, new_value); 191 return 0; // success 192 } 193 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 194 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int32_t)); 195 if (LIKELY(field != NULL)) { 196 if (UNLIKELY(obj == NULL)) { 197 ThrowNullPointerExceptionForFieldAccess(field, false); 198 } else { 199 field->Set32(obj, new_value); 200 return 0; // success 201 } 202 } 203 return -1; // failure 204} 205 206extern "C" int artSet64InstanceFromCode(uint32_t field_idx, Object* obj, uint64_t new_value, 207 Thread* self, AbstractMethod** sp) 208 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 209 AbstractMethod* callee_save = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsOnly); 210 AbstractMethod* referrer = sp[callee_save->GetFrameSizeInBytes() / sizeof(AbstractMethod*)]; 211 Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int64_t)); 212 if (LIKELY(field != NULL && obj != NULL)) { 213 field->Set64(obj, new_value); 214 return 0; // success 215 } 216 *sp = callee_save; 217 self->SetTopOfStack(sp, 0); 218 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int64_t)); 219 if (LIKELY(field != NULL)) { 220 if (UNLIKELY(obj == NULL)) { 221 ThrowNullPointerExceptionForFieldAccess(field, false); 222 } else { 223 field->Set64(obj, new_value); 224 return 0; // success 225 } 226 } 227 return -1; // failure 228} 229 230extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, Object* obj, Object* new_value, 231 const AbstractMethod* referrer, Thread* self, 232 AbstractMethod** sp) 233 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 234 Field* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite, sizeof(Object*)); 235 if (LIKELY(field != NULL && obj != NULL)) { 236 field->SetObj(obj, new_value); 237 return 0; // success 238 } 239 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); 240 field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectWrite, sizeof(Object*)); 241 if (LIKELY(field != NULL)) { 242 if (UNLIKELY(obj == NULL)) { 243 ThrowNullPointerExceptionForFieldAccess(field, false); 244 } else { 245 field->SetObj(obj, new_value); 246 return 0; // success 247 } 248 } 249 return -1; // failure 250} 251 252} // namespace art 253