• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
artGet32StaticFromCode(uint32_t field_idx,const mirror::ArtMethod * referrer,Thread * self,mirror::ArtMethod ** sp)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 
artGet64StaticFromCode(uint32_t field_idx,const mirror::ArtMethod * referrer,Thread * self,mirror::ArtMethod ** sp)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 
artGetObjStaticFromCode(uint32_t field_idx,const mirror::ArtMethod * referrer,Thread * self,mirror::ArtMethod ** sp)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 
artGet32InstanceFromCode(uint32_t field_idx,mirror::Object * obj,const mirror::ArtMethod * referrer,Thread * self,mirror::ArtMethod ** sp)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 
artGet64InstanceFromCode(uint32_t field_idx,mirror::Object * obj,const mirror::ArtMethod * referrer,Thread * self,mirror::ArtMethod ** sp)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 
artGetObjInstanceFromCode(uint32_t field_idx,mirror::Object * obj,const mirror::ArtMethod * referrer,Thread * self,mirror::ArtMethod ** sp)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 
artSet32StaticFromCode(uint32_t field_idx,uint32_t new_value,const mirror::ArtMethod * referrer,Thread * self,mirror::ArtMethod ** sp)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 
artSet64StaticFromCode(uint32_t field_idx,const mirror::ArtMethod * referrer,uint64_t new_value,Thread * self,mirror::ArtMethod ** sp)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 
artSetObjStaticFromCode(uint32_t field_idx,mirror::Object * new_value,const mirror::ArtMethod * referrer,Thread * self,mirror::ArtMethod ** sp)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 
artSet32InstanceFromCode(uint32_t field_idx,mirror::Object * obj,uint32_t new_value,const mirror::ArtMethod * referrer,Thread * self,mirror::ArtMethod ** sp)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 
artSet64InstanceFromCode(uint32_t field_idx,mirror::Object * obj,uint64_t new_value,Thread * self,mirror::ArtMethod ** sp)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 
artSetObjInstanceFromCode(uint32_t field_idx,mirror::Object * obj,mirror::Object * new_value,const mirror::ArtMethod * referrer,Thread * self,mirror::ArtMethod ** sp)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