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