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