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 "entrypoints/entrypoint_utils-inl.h"
18 #include "mirror/art_field-inl.h"
19 #include "mirror/art_method-inl.h"
20 #include "mirror/object-inl.h"
21 
22 namespace art {
23 
art_portable_set32_static_from_code(uint32_t field_idx,mirror::ArtMethod * referrer,int32_t new_value)24 extern "C" int32_t art_portable_set32_static_from_code(uint32_t field_idx,
25                                                        mirror::ArtMethod* referrer,
26                                                        int32_t new_value)
27     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
28   mirror::ArtField* field = FindFieldFast(field_idx,
29                                referrer,
30                                StaticPrimitiveWrite,
31                                sizeof(uint32_t));
32   if (LIKELY(field != NULL)) {
33     // Compiled code can't use transactional mode.
34     field->Set32<false>(field->GetDeclaringClass(), new_value);
35     return 0;
36   }
37   field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, Thread::Current(),
38                                                         sizeof(uint32_t));
39   if (LIKELY(field != NULL)) {
40     // Compiled code can't use transactional mode.
41     field->Set32<false>(field->GetDeclaringClass(), new_value);
42     return 0;
43   }
44   return -1;
45 }
46 
art_portable_set64_static_from_code(uint32_t field_idx,mirror::ArtMethod * referrer,int64_t new_value)47 extern "C" int32_t art_portable_set64_static_from_code(uint32_t field_idx,
48                                                        mirror::ArtMethod* referrer,
49                                                        int64_t new_value)
50     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
51   mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(uint64_t));
52   if (LIKELY(field != NULL)) {
53     // Compiled code can't use transactional mode.
54     field->Set64<false>(field->GetDeclaringClass(), new_value);
55     return 0;
56   }
57   field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, Thread::Current(),
58                                                         sizeof(uint64_t));
59   if (LIKELY(field != NULL)) {
60     // Compiled code can't use transactional mode.
61     field->Set64<false>(field->GetDeclaringClass(), new_value);
62     return 0;
63   }
64   return -1;
65 }
66 
art_portable_set_obj_static_from_code(uint32_t field_idx,mirror::ArtMethod * referrer,mirror::Object * new_value)67 extern "C" int32_t art_portable_set_obj_static_from_code(uint32_t field_idx,
68                                                          mirror::ArtMethod* referrer,
69                                                          mirror::Object* new_value)
70     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
71   mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectWrite,
72                                           sizeof(mirror::HeapReference<mirror::Object>));
73   if (LIKELY(field != NULL)) {
74     // Compiled code can't use transactional mode.
75     field->SetObj<false>(field->GetDeclaringClass(), new_value);
76     return 0;
77   }
78   field = FindFieldFromCode<StaticObjectWrite, true>(field_idx, referrer, Thread::Current(),
79                                                      sizeof(mirror::HeapReference<mirror::Object>));
80   if (LIKELY(field != NULL)) {
81     // Compiled code can't use transactional mode.
82     field->SetObj<false>(field->GetDeclaringClass(), new_value);
83     return 0;
84   }
85   return -1;
86 }
87 
art_portable_get32_static_from_code(uint32_t field_idx,mirror::ArtMethod * referrer)88 extern "C" int32_t art_portable_get32_static_from_code(uint32_t field_idx,
89                                                        mirror::ArtMethod* referrer)
90     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
91   mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(uint32_t));
92   if (LIKELY(field != NULL)) {
93     return field->Get32(field->GetDeclaringClass());
94   }
95   field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, Thread::Current(),
96                                                        sizeof(uint32_t));
97   if (LIKELY(field != NULL)) {
98     return field->Get32(field->GetDeclaringClass());
99   }
100   return 0;
101 }
102 
art_portable_get64_static_from_code(uint32_t field_idx,mirror::ArtMethod * referrer)103 extern "C" int64_t art_portable_get64_static_from_code(uint32_t field_idx,
104                                                        mirror::ArtMethod* referrer)
105     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
106   mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(uint64_t));
107   if (LIKELY(field != NULL)) {
108     return field->Get64(field->GetDeclaringClass());
109   }
110   field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, Thread::Current(),
111                                                        sizeof(uint64_t));
112   if (LIKELY(field != NULL)) {
113     return field->Get64(field->GetDeclaringClass());
114   }
115   return 0;
116 }
117 
art_portable_get_obj_static_from_code(uint32_t field_idx,mirror::ArtMethod * referrer)118 extern "C" mirror::Object* art_portable_get_obj_static_from_code(uint32_t field_idx,
119                                                                  mirror::ArtMethod* referrer)
120     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
121   mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectRead,
122                                           sizeof(mirror::HeapReference<mirror::Object>));
123   if (LIKELY(field != NULL)) {
124     return field->GetObj(field->GetDeclaringClass());
125   }
126   field = FindFieldFromCode<StaticObjectRead, true>(field_idx, referrer, Thread::Current(),
127                                                     sizeof(mirror::HeapReference<mirror::Object>));
128   if (LIKELY(field != NULL)) {
129     return field->GetObj(field->GetDeclaringClass());
130   }
131   return 0;
132 }
133 
art_portable_set32_instance_from_code(uint32_t field_idx,mirror::ArtMethod * referrer,mirror::Object * obj,uint32_t new_value)134 extern "C" int32_t art_portable_set32_instance_from_code(uint32_t field_idx,
135                                                          mirror::ArtMethod* referrer,
136                                                          mirror::Object* obj, uint32_t new_value)
137     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
138   mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(uint32_t));
139   if (LIKELY(field != NULL)) {
140     // Compiled code can't use transactional mode.
141     field->Set32<false>(obj, new_value);
142     return 0;
143   }
144   field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, Thread::Current(),
145                                                           sizeof(uint32_t));
146   if (LIKELY(field != NULL)) {
147     // Compiled code can't use transactional mode.
148     field->Set32<false>(obj, new_value);
149     return 0;
150   }
151   return -1;
152 }
153 
art_portable_set64_instance_from_code(uint32_t field_idx,mirror::ArtMethod * referrer,mirror::Object * obj,int64_t new_value)154 extern "C" int32_t art_portable_set64_instance_from_code(uint32_t field_idx,
155                                                          mirror::ArtMethod* referrer,
156                                                          mirror::Object* obj, int64_t new_value)
157     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
158   mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(uint64_t));
159   if (LIKELY(field != NULL)) {
160     // Compiled code can't use transactional mode.
161     field->Set64<false>(obj, new_value);
162     return 0;
163   }
164   field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, Thread::Current(),
165                                                           sizeof(uint64_t));
166   if (LIKELY(field != NULL)) {
167     // Compiled code can't use transactional mode.
168     field->Set64<false>(obj, new_value);
169     return 0;
170   }
171   return -1;
172 }
173 
art_portable_set_obj_instance_from_code(uint32_t field_idx,mirror::ArtMethod * referrer,mirror::Object * obj,mirror::Object * new_value)174 extern "C" int32_t art_portable_set_obj_instance_from_code(uint32_t field_idx,
175                                                            mirror::ArtMethod* referrer,
176                                                            mirror::Object* obj,
177                                                            mirror::Object* new_value)
178     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
179   mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
180                                           sizeof(mirror::HeapReference<mirror::Object>));
181   if (LIKELY(field != NULL)) {
182     // Compiled code can't use transactional mode.
183     field->SetObj<false>(obj, new_value);
184     return 0;
185   }
186   field = FindFieldFromCode<InstanceObjectWrite, true>(field_idx, referrer, Thread::Current(),
187                                                        sizeof(mirror::HeapReference<mirror::Object>));
188   if (LIKELY(field != NULL)) {
189     // Compiled code can't use transactional mode.
190     field->SetObj<false>(obj, new_value);
191     return 0;
192   }
193   return -1;
194 }
195 
art_portable_get32_instance_from_code(uint32_t field_idx,mirror::ArtMethod * referrer,mirror::Object * obj)196 extern "C" int32_t art_portable_get32_instance_from_code(uint32_t field_idx,
197                                                          mirror::ArtMethod* referrer,
198                                                          mirror::Object* obj)
199     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
200   mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(uint32_t));
201   if (LIKELY(field != NULL)) {
202     return field->Get32(obj);
203   }
204   field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, Thread::Current(),
205                                                          sizeof(uint32_t));
206   if (LIKELY(field != NULL)) {
207     return field->Get32(obj);
208   }
209   return 0;
210 }
211 
art_portable_get64_instance_from_code(uint32_t field_idx,mirror::ArtMethod * referrer,mirror::Object * obj)212 extern "C" int64_t art_portable_get64_instance_from_code(uint32_t field_idx,
213                                                          mirror::ArtMethod* referrer,
214                                                          mirror::Object* obj)
215     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
216   mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(uint64_t));
217   if (LIKELY(field != NULL)) {
218     return field->Get64(obj);
219   }
220   field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, Thread::Current(),
221                                                          sizeof(uint64_t));
222   if (LIKELY(field != NULL)) {
223     return field->Get64(obj);
224   }
225   return 0;
226 }
227 
art_portable_get_obj_instance_from_code(uint32_t field_idx,mirror::ArtMethod * referrer,mirror::Object * obj)228 extern "C" mirror::Object* art_portable_get_obj_instance_from_code(uint32_t field_idx,
229                                                                    mirror::ArtMethod* referrer,
230                                                                    mirror::Object* obj)
231     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
232   mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectRead,
233                                           sizeof(mirror::HeapReference<mirror::Object>));
234   if (LIKELY(field != NULL)) {
235     return field->GetObj(obj);
236   }
237   field = FindFieldFromCode<InstanceObjectRead, true>(field_idx, referrer, Thread::Current(),
238                                                       sizeof(mirror::HeapReference<mirror::Object>));
239   if (LIKELY(field != NULL)) {
240     return field->GetObj(obj);
241   }
242   return 0;
243 }
244 
245 }  // namespace art
246