blob: 388eb85c55d9aadfc43f7061c4afb8129d38ad41 [file] [log] [blame]
Ian Rogers2fa6b2e2012-10-17 00:10:17 -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 "interpreter.h"
18
19#include <math.h>
20
21#include "common_throws.h"
22#include "dex_instruction.h"
23#include "invoke_arg_array_builder.h"
24#include "logging.h"
Ian Rogers64b6d142012-10-29 16:34:15 -070025#include "nth_caller_visitor.h"
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070026#include "object.h"
27#include "object_utils.h"
28#include "runtime_support.h"
29#include "ScopedLocalRef.h"
30#include "scoped_thread_state_change.h"
31#include "thread.h"
32
33namespace art {
34namespace interpreter {
35
Ian Rogers64b6d142012-10-29 16:34:15 -070036static void UnstartedRuntimeInvoke(Thread* self, AbstractMethod* target_method,
37 Object* receiver, JValue* args, JValue* result)
38 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
39 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
40 // problems in core libraries.
41 std::string name(PrettyMethod(target_method));
42 if (name == "java.lang.Class java.lang.Class.forName(java.lang.String)") {
43 std::string descriptor(DotToDescriptor(args[0].GetL()->AsString()->ToModifiedUtf8().c_str()));
44 ClassLoader* class_loader = NULL; // shadow_frame.GetMethod()->GetDeclaringClass()->GetClassLoader();
45 Class* found = Runtime::Current()->GetClassLinker()->FindClass(descriptor.c_str(),
46 class_loader);
47 CHECK(found != NULL) << "Class.forName failed in un-started runtime for class: "
48 << PrettyDescriptor(descriptor);
49 result->SetL(found);
50 } else if (name == "java.lang.Object java.lang.Class.newInstance()") {
51 Class* klass = receiver->AsClass();
52 AbstractMethod* c = klass->FindDeclaredDirectMethod("<init>", "()V");
53 CHECK(c != NULL);
54 Object* obj = klass->AllocObject(self);
55 CHECK(obj != NULL);
56 EnterInterpreterFromInvoke(self, c, obj, NULL, NULL);
57 result->SetL(obj);
58 } else if (name == "java.lang.reflect.Field java.lang.Class.getDeclaredField(java.lang.String)") {
59 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
60 // going the reflective Dex way.
61 Class* klass = receiver->AsClass();
62 String* name = args[0].GetL()->AsString();
63 Field* found = NULL;
64 FieldHelper fh;
65 ObjectArray<Field>* fields = klass->GetIFields();
66 for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) {
67 Field* f = fields->Get(i);
68 fh.ChangeField(f);
69 if (name->Equals(fh.GetName())) {
70 found = f;
71 }
72 }
73 if (found == NULL) {
74 fields = klass->GetSFields();
75 for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) {
76 Field* f = fields->Get(i);
77 fh.ChangeField(f);
78 if (name->Equals(fh.GetName())) {
79 found = f;
80 }
81 }
82 }
83 CHECK(found != NULL)
84 << "Failed to find field in Class.getDeclaredField in un-started runtime. name="
85 << name->ToModifiedUtf8() << " class=" << PrettyDescriptor(klass);
86 // TODO: getDeclaredField calls GetType once the field is found to ensure a
87 // NoClassDefFoundError is thrown if the field's type cannot be resolved.
88 result->SetL(found);
89 } else if (name == "void java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int)") {
90 // Special case array copying without initializing System.
91 Class* ctype = args[0].GetL()->GetClass()->GetComponentType();
92 jint srcPos = args[1].GetI();
93 jint dstPos = args[3].GetI();
94 jint length = args[4].GetI();
95 if (!ctype->IsPrimitive()) {
96 ObjectArray<Object>* src = args[0].GetL()->AsObjectArray<Object>();
97 ObjectArray<Object>* dst = args[2].GetL()->AsObjectArray<Object>();
98 for (jint i = 0; i < length; ++i) {
99 dst->Set(dstPos + i, src->Get(srcPos + i));
100 }
101 } else if (ctype->IsPrimitiveChar()) {
102 CharArray* src = args[0].GetL()->AsCharArray();
103 CharArray* dst = args[2].GetL()->AsCharArray();
104 for (jint i = 0; i < length; ++i) {
105 dst->Set(dstPos + i, src->Get(srcPos + i));
106 }
107 } else if (ctype->IsPrimitiveInt()) {
108 IntArray* src = args[0].GetL()->AsIntArray();
109 IntArray* dst = args[2].GetL()->AsIntArray();
110 for (jint i = 0; i < length; ++i) {
111 dst->Set(dstPos + i, src->Get(srcPos + i));
112 }
113 } else {
114 UNIMPLEMENTED(FATAL) << "System.arraycopy of unexpected type: " << PrettyDescriptor(ctype);
115 }
116 } else {
117 // Not special, continue with regular interpreter execution.
118 EnterInterpreterFromInvoke(self, target_method, receiver, args, result);
119 }
120}
121
122// Hand select a number of methods to be run in a not yet started runtime without using JNI.
123static void UnstartedRuntimeJni(Thread* self, AbstractMethod* method,
124 Object* receiver, JValue* args, JValue* result)
125 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
126 std::string name(PrettyMethod(method));
127 if (name == "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()") {
128 result->SetL(NULL);
129 } else if (name == "java.lang.Class dalvik.system.VMStack.getStackClass2()") {
130 NthCallerVisitor visitor(self->GetManagedStack(), NULL, 3);
131 visitor.WalkStack();
132 result->SetL(visitor.caller->GetDeclaringClass());
133 } else if (name == "double java.lang.Math.log(double)") {
134 result->SetD(log(args[0].GetD()));
135 } else if (name == "java.lang.String java.lang.Class.getNameNative()") {
136 result->SetL(receiver->AsClass()->ComputeName());
137 } else if (name == "int java.lang.Float.floatToRawIntBits(float)") {
138 result->SetI(args[0].GetI());
139 } else if (name == "float java.lang.Float.intBitsToFloat(int)") {
140 result->SetF(args[0].GetF());
141 } else if (name == "double java.lang.Math.exp(double)") {
142 result->SetD(exp(args[0].GetD()));
143 } else if (name == "java.lang.Object java.lang.Object.internalClone()") {
144 result->SetL(receiver->Clone(self));
145 } else if (name == "void java.lang.Object.notifyAll()") {
146 receiver->NotifyAll();
147 } else if (name == "int java.lang.String.compareTo(java.lang.String)") {
148 String* rhs = args[0].GetL()->AsString();
149 CHECK(rhs != NULL);
150 result->SetI(receiver->AsString()->CompareTo(rhs));
151 } else if (name == "java.lang.String java.lang.String.intern()") {
152 result->SetL(receiver->AsString()->Intern());
153 } else if (name == "int java.lang.String.fastIndexOf(int, int)") {
154 result->SetI(receiver->AsString()->FastIndexOf(args[0].GetI(), args[1].GetI()));
155 } else if (name == "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])") {
156 result->SetL(Array::CreateMultiArray(self, args[0].GetL()->AsClass(), args[1].GetL()->AsIntArray()));
157 } else if (name == "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()") {
158 ScopedObjectAccessUnchecked soa(self);
159 result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace(soa)));
160 } else if (name == "boolean java.nio.ByteOrder.isLittleEndian()") {
161 result->SetJ(JNI_TRUE);
162 } else if (name == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") {
163 Object* obj = args[0].GetL();
164 jlong offset = args[1].GetJ();
165 jint expectedValue = args[2].GetI();
166 jint newValue = args[3].GetI();
167 byte* raw_addr = reinterpret_cast<byte*>(obj) + offset;
168 volatile int32_t* address = reinterpret_cast<volatile int32_t*>(raw_addr);
169 // Note: android_atomic_release_cas() returns 0 on success, not failure.
170 int r = android_atomic_release_cas(expectedValue, newValue, address);
171 result->SetZ(r == 0);
172 } else if (name == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") {
173 Object* obj = args[0].GetL();
174 Object* newValue = args[2].GetL();
175 obj->SetFieldObject(MemberOffset(args[1].GetJ()), newValue, false);
176 } else {
177 LOG(FATAL) << "Attempt to invoke native method in non-started runtime: " << name;
178 }
179}
180
181static void InterpreterJni(Thread* self, AbstractMethod* method, StringPiece shorty,
182 Object* receiver, JValue* args, JValue* result)
183 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
184 // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler,
185 // it should be removed and JNI compiled stubs used instead.
186 ScopedObjectAccessUnchecked soa(self);
187 if (method->IsStatic()) {
188 if (shorty == "L") {
189 typedef jobject (fnptr)(JNIEnv*, jclass);
190 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
191 ScopedLocalRef<jclass> klass(soa.Env(),
192 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
193 ScopedThreadStateChange tsc(self, kNative);
194 result->SetL(soa.Decode<Object*>(fn(soa.Env(), klass.get())));
195 } else if (shorty == "V") {
196 typedef void (fnptr)(JNIEnv*, jclass);
197 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
198 ScopedLocalRef<jclass> klass(soa.Env(),
199 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
200 ScopedThreadStateChange tsc(self, kNative);
201 fn(soa.Env(), klass.get());
202 } else if (shorty == "Z") {
203 typedef jboolean (fnptr)(JNIEnv*, jclass);
204 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
205 ScopedLocalRef<jclass> klass(soa.Env(),
206 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
207 ScopedThreadStateChange tsc(self, kNative);
208 result->SetZ(fn(soa.Env(), klass.get()));
209 } else if (shorty == "BI") {
210 typedef jbyte (fnptr)(JNIEnv*, jclass, jint);
211 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
212 ScopedLocalRef<jclass> klass(soa.Env(),
213 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
214 ScopedThreadStateChange tsc(self, kNative);
215 result->SetB(fn(soa.Env(), klass.get(), args[0].GetI()));
216 } else if (shorty == "II") {
217 typedef jint (fnptr)(JNIEnv*, jclass, jint);
218 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
219 ScopedLocalRef<jclass> klass(soa.Env(),
220 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
221 ScopedThreadStateChange tsc(self, kNative);
222 result->SetI(fn(soa.Env(), klass.get(), args[0].GetI()));
223 } else if (shorty == "LL") {
224 typedef jobject (fnptr)(JNIEnv*, jclass, jobject);
225 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
226 ScopedLocalRef<jclass> klass(soa.Env(),
227 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
228 ScopedLocalRef<jobject> arg0(soa.Env(),
229 soa.AddLocalReference<jobject>(args[0].GetL()));
230 ScopedThreadStateChange tsc(self, kNative);
231 result->SetL(soa.Decode<Object*>(fn(soa.Env(), klass.get(), arg0.get())));
232 } else if (shorty == "IIZ") {
233 typedef jint (fnptr)(JNIEnv*, jclass, jint, jboolean);
234 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
235 ScopedLocalRef<jclass> klass(soa.Env(),
236 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
237 ScopedThreadStateChange tsc(self, kNative);
238 result->SetI(fn(soa.Env(), klass.get(), args[0].GetI(), args[1].GetZ()));
239 } else if (shorty == "ILI") {
240 typedef jint (fnptr)(JNIEnv*, jclass, jobject, jint);
241 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
242 ScopedLocalRef<jclass> klass(soa.Env(),
243 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
244 ScopedLocalRef<jobject> arg0(soa.Env(),
245 soa.AddLocalReference<jobject>(args[0].GetL()));
246 ScopedThreadStateChange tsc(self, kNative);
247 result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1].GetI()));
248 } else if (shorty == "SIZ") {
249 typedef jshort (fnptr)(JNIEnv*, jclass, jint, jboolean);
250 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
251 ScopedLocalRef<jclass> klass(soa.Env(),
252 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
253 ScopedThreadStateChange tsc(self, kNative);
254 result->SetS(fn(soa.Env(), klass.get(), args[0].GetI(), args[1].GetZ()));
255 } else if (shorty == "VIZ") {
256 typedef void (fnptr)(JNIEnv*, jclass, jint, jboolean);
257 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
258 ScopedLocalRef<jclass> klass(soa.Env(),
259 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
260 ScopedThreadStateChange tsc(self, kNative);
261 fn(soa.Env(), klass.get(), args[0].GetI(), args[1].GetZ());
262 } else if (shorty == "ZLL") {
263 typedef jboolean (fnptr)(JNIEnv*, jclass, jobject, jobject);
264 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
265 ScopedLocalRef<jclass> klass(soa.Env(),
266 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
267 ScopedLocalRef<jobject> arg0(soa.Env(),
268 soa.AddLocalReference<jobject>(args[0].GetL()));
269 ScopedLocalRef<jobject> arg1(soa.Env(),
270 soa.AddLocalReference<jobject>(args[1].GetL()));
271 ScopedThreadStateChange tsc(self, kNative);
272 result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get()));
273 } else if (shorty == "ZILL") {
274 typedef jboolean (fnptr)(JNIEnv*, jclass, jint, jobject, jobject);
275 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
276 ScopedLocalRef<jclass> klass(soa.Env(),
277 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
278 ScopedLocalRef<jobject> arg1(soa.Env(),
279 soa.AddLocalReference<jobject>(args[1].GetL()));
280 ScopedLocalRef<jobject> arg2(soa.Env(),
281 soa.AddLocalReference<jobject>(args[2].GetL()));
282 ScopedThreadStateChange tsc(self, kNative);
283 result->SetZ(fn(soa.Env(), klass.get(), args[0].GetI(), arg1.get(), arg2.get()));
284 } else if (shorty == "VILII") {
285 typedef void (fnptr)(JNIEnv*, jclass, jint, jobject, jint, jint);
286 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
287 ScopedLocalRef<jclass> klass(soa.Env(),
288 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
289 ScopedLocalRef<jobject> arg1(soa.Env(),
290 soa.AddLocalReference<jobject>(args[1].GetL()));
291 ScopedThreadStateChange tsc(self, kNative);
292 fn(soa.Env(), klass.get(), args[0].GetI(), arg1.get(), args[2].GetI(), args[3].GetI());
293 } else if (shorty == "VLILII") {
294 typedef void (fnptr)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint);
295 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
296 ScopedLocalRef<jclass> klass(soa.Env(),
297 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
298 ScopedLocalRef<jobject> arg0(soa.Env(),
299 soa.AddLocalReference<jobject>(args[0].GetL()));
300 ScopedLocalRef<jobject> arg2(soa.Env(),
301 soa.AddLocalReference<jobject>(args[2].GetL()));
302 ScopedThreadStateChange tsc(self, kNative);
303 fn(soa.Env(), klass.get(), arg0.get(), args[1].GetI(), arg2.get(), args[3].GetI(),
304 args[4].GetI());
305 } else {
306 LOG(FATAL) << "Do something with static native method: " << PrettyMethod(method)
307 << " shorty: " << shorty;
308 }
309 } else {
310 if (shorty == "L") {
311 typedef jobject (fnptr)(JNIEnv*, jobject);
312 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
313 ScopedLocalRef<jobject> rcvr(soa.Env(),
314 soa.AddLocalReference<jobject>(receiver));
315 ScopedThreadStateChange tsc(self, kNative);
316 result->SetL(soa.Decode<Object*>(fn(soa.Env(), rcvr.get())));
317 } else if (shorty == "LL") {
318 typedef jobject (fnptr)(JNIEnv*, jobject, jobject);
319 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
320 ScopedLocalRef<jobject> rcvr(soa.Env(),
321 soa.AddLocalReference<jobject>(receiver));
322 ScopedLocalRef<jobject> arg0(soa.Env(),
323 soa.AddLocalReference<jobject>(args[0].GetL()));
324 ScopedThreadStateChange tsc(self, kNative);
325 result->SetL(soa.Decode<Object*>(fn(soa.Env(), rcvr.get(), arg0.get())));
326 } else if (shorty == "III") {
327 typedef jint (fnptr)(JNIEnv*, jobject, jint, jint);
328 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
329 ScopedLocalRef<jobject> rcvr(soa.Env(),
330 soa.AddLocalReference<jobject>(receiver));
331 ScopedThreadStateChange tsc(self, kNative);
332 result->SetI(fn(soa.Env(), rcvr.get(), args[0].GetI(), args[1].GetI()));
333 } else {
334 LOG(FATAL) << "Do something with native method: " << PrettyMethod(method)
335 << " shorty: " << shorty;
336 }
337 }
338}
339
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700340static void DoMonitorEnter(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS {
341 ref->MonitorEnter(self);
342}
343
344static void DoMonitorExit(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS {
345 ref->MonitorExit(self);
346}
347
348static void DoInvoke(Thread* self, MethodHelper& mh, ShadowFrame& shadow_frame,
349 const DecodedInstruction& dec_insn, InvokeType type, bool is_range,
350 JValue* result)
351 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
352 Object* receiver;
353 if (type == kStatic) {
354 receiver = NULL;
355 } else {
356 receiver = shadow_frame.GetReference(dec_insn.vC);
357 if (UNLIKELY(receiver == NULL)) {
358 ThrowNullPointerExceptionForMethodAccess(shadow_frame.GetMethod(), dec_insn.vB, type);
359 result->SetJ(0);
360 return;
361 }
362 }
363 uint32_t method_idx = dec_insn.vB;
364 AbstractMethod* target_method = FindMethodFromCode(method_idx, receiver,
365 shadow_frame.GetMethod(), self, true,
366 type);
367 if (UNLIKELY(target_method == NULL)) {
368 CHECK(self->IsExceptionPending());
369 result->SetJ(0);
370 return;
371 }
372 mh.ChangeMethod(target_method);
373 ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
374 if (is_range) {
375 arg_array.BuildArgArray(shadow_frame, dec_insn.vC + (type != kStatic ? 1 : 0));
376 } else {
377 arg_array.BuildArgArray(shadow_frame, dec_insn.arg + (type != kStatic ? 1 : 0));
378 }
Ian Rogers64b6d142012-10-29 16:34:15 -0700379 if (LIKELY(Runtime::Current()->IsStarted())) {
380 target_method->Invoke(self, receiver, arg_array.get(), result);
381 } else {
382 UnstartedRuntimeInvoke(self, target_method, receiver, arg_array.get(), result);
383 }
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700384 if (!mh.GetReturnType()->IsPrimitive() && result->GetL() != NULL) {
385 CHECK(mh.GetReturnType()->IsAssignableFrom(result->GetL()->GetClass()));
386 }
387 mh.ChangeMethod(shadow_frame.GetMethod());
388}
389
390static void DoFieldGet(Thread* self, ShadowFrame& shadow_frame,
391 const DecodedInstruction& dec_insn, FindFieldType find_type,
392 Primitive::Type field_type)
393 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
394 bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead);
395 uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC;
396 Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
397 find_type, Primitive::FieldSize(field_type));
398 if (LIKELY(f != NULL)) {
399 Object* obj;
400 if (is_static) {
401 obj = f->GetDeclaringClass();
402 } else {
403 obj = shadow_frame.GetReference(dec_insn.vB);
404 if (UNLIKELY(obj == NULL)) {
405 ThrowNullPointerExceptionForFieldAccess(f, true);
406 }
407 }
408 switch (field_type) {
409 case Primitive::kPrimBoolean:
410 shadow_frame.SetVReg(dec_insn.vA, f->GetBoolean(obj));
411 break;
412 case Primitive::kPrimByte:
413 shadow_frame.SetVReg(dec_insn.vA, f->GetByte(obj));
414 break;
415 case Primitive::kPrimChar:
416 shadow_frame.SetVReg(dec_insn.vA, f->GetChar(obj));
417 break;
418 case Primitive::kPrimShort:
419 shadow_frame.SetVReg(dec_insn.vA, f->GetShort(obj));
420 break;
421 case Primitive::kPrimInt:
422 shadow_frame.SetVReg(dec_insn.vA, f->GetInt(obj));
423 break;
424 case Primitive::kPrimLong:
425 shadow_frame.SetVRegLong(dec_insn.vA, f->GetLong(obj));
426 break;
427 case Primitive::kPrimNot:
428 shadow_frame.SetReferenceAndVReg(dec_insn.vA, f->GetObject(obj));
429 break;
430 default:
431 LOG(FATAL) << "Unreachable: " << field_type;
432 }
433 }
434}
435
436static void DoFieldPut(Thread* self, ShadowFrame& shadow_frame,
437 const DecodedInstruction& dec_insn, FindFieldType find_type,
438 Primitive::Type field_type)
439 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
440 bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite);
441 uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC;
442 Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
443 find_type, Primitive::FieldSize(field_type));
444 if (LIKELY(f != NULL)) {
445 Object* obj;
446 if (is_static) {
447 obj = f->GetDeclaringClass();
448 } else {
449 obj = shadow_frame.GetReference(dec_insn.vB);
450 if (UNLIKELY(obj == NULL)) {
451 ThrowNullPointerExceptionForFieldAccess(f, false);
452 }
453 }
454 switch (field_type) {
455 case Primitive::kPrimBoolean:
456 f->SetBoolean(obj, shadow_frame.GetVReg(dec_insn.vA));
457 break;
458 case Primitive::kPrimByte:
459 f->SetByte(obj, shadow_frame.GetVReg(dec_insn.vA));
460 shadow_frame.SetVReg(dec_insn.vA, f->GetByte(obj));
461 break;
462 case Primitive::kPrimChar:
463 f->SetChar(obj, shadow_frame.GetVReg(dec_insn.vA));
464 shadow_frame.SetVReg(dec_insn.vA, f->GetChar(obj));
465 break;
466 case Primitive::kPrimShort:
467 f->SetShort(obj, shadow_frame.GetVReg(dec_insn.vA));
468 shadow_frame.SetVReg(dec_insn.vA, f->GetShort(obj));
469 break;
470 case Primitive::kPrimInt:
471 f->SetInt(obj, shadow_frame.GetVReg(dec_insn.vA));
472 shadow_frame.SetVReg(dec_insn.vA, f->GetInt(obj));
473 break;
474 case Primitive::kPrimLong:
475 f->SetLong(obj, shadow_frame.GetVRegLong(dec_insn.vA));
476 shadow_frame.SetVRegLong(dec_insn.vA, f->GetLong(obj));
477 break;
478 case Primitive::kPrimNot:
479 f->SetObj(obj, shadow_frame.GetReference(dec_insn.vA));
480 break;
481 default:
482 LOG(FATAL) << "Unreachable: " << field_type;
483 }
484 }
485}
486
487static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
488 ShadowFrame& shadow_frame) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
489 const uint16_t* insns = code_item->insns_;
490 const Instruction* inst = Instruction::At(insns + shadow_frame.GetDexPC());
491 JValue result_register;
492 while (true) {
493 shadow_frame.SetDexPC(inst->GetDexPc(insns));
494 DecodedInstruction dec_insn(inst);
Ian Rogers64b6d142012-10-29 16:34:15 -0700495 const bool kTracing = false;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700496 if (kTracing) {
497 LOG(INFO) << PrettyMethod(shadow_frame.GetMethod())
498 << StringPrintf("\n0x%x: %s\nReferences:",
499 inst->GetDexPc(insns), inst->DumpString(&mh.GetDexFile()).c_str());
500 for (size_t i = 0; i < shadow_frame.NumberOfReferences(); ++i) {
501 Object* o = shadow_frame.GetReference(i);
502 if (o != NULL) {
503 if (o->GetClass()->IsStringClass() && o->AsString()->GetCharArray() != NULL) {
504 LOG(INFO) << i << ": java.lang.String " << static_cast<void*>(o)
505 << " \"" << o->AsString()->ToModifiedUtf8() << "\"";
506 } else {
507 LOG(INFO) << i << ": " << PrettyTypeOf(o) << " " << static_cast<void*>(o);
508 }
509 } else {
510 LOG(INFO) << i << ": null";
511 }
512 }
513 LOG(INFO) << "vregs:";
514 for (size_t i = 0; i < shadow_frame.NumberOfReferences(); ++i) {
515 LOG(INFO) << StringPrintf("%d: %08x", i, shadow_frame.GetVReg(i));
516 }
517 }
518 const Instruction* next_inst = inst->Next();
519 switch (dec_insn.opcode) {
520 case Instruction::NOP:
521 break;
522 case Instruction::MOVE:
523 case Instruction::MOVE_FROM16:
524 case Instruction::MOVE_16:
525 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
526 break;
527 case Instruction::MOVE_WIDE:
528 case Instruction::MOVE_WIDE_FROM16:
529 case Instruction::MOVE_WIDE_16:
530 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
531 break;
532 case Instruction::MOVE_OBJECT:
533 case Instruction::MOVE_OBJECT_FROM16:
534 case Instruction::MOVE_OBJECT_16:
535 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
536 shadow_frame.SetReference(dec_insn.vA, shadow_frame.GetReference(dec_insn.vB));
537 break;
538 case Instruction::MOVE_RESULT:
539 shadow_frame.SetVReg(dec_insn.vA, result_register.GetI());
540 break;
541 case Instruction::MOVE_RESULT_WIDE:
542 shadow_frame.SetVRegLong(dec_insn.vA, result_register.GetJ());
543 break;
544 case Instruction::MOVE_RESULT_OBJECT:
545 shadow_frame.SetReferenceAndVReg(dec_insn.vA, result_register.GetL());
546 break;
547 case Instruction::MOVE_EXCEPTION: {
548 Throwable* exception = self->GetException();
549 self->ClearException();
550 shadow_frame.SetReferenceAndVReg(dec_insn.vA, exception);
551 break;
552 }
553 case Instruction::RETURN_VOID: {
554 JValue result;
555 result.SetJ(0);
556 return result;
557 }
558 case Instruction::RETURN: {
559 JValue result;
560 result.SetJ(0);
561 result.SetI(shadow_frame.GetVReg(dec_insn.vA));
562 return result;
563 }
564 case Instruction::RETURN_WIDE: {
565 JValue result;
566 result.SetJ(shadow_frame.GetVRegLong(dec_insn.vA));
567 return result;
568 }
569 case Instruction::RETURN_OBJECT: {
570 JValue result;
571 result.SetJ(0);
572 result.SetL(shadow_frame.GetReference(dec_insn.vA));
573 return result;
574 }
575 case Instruction::CONST_4: {
Ian Rogers64b6d142012-10-29 16:34:15 -0700576 int32_t val = static_cast<int32_t>(dec_insn.vB << 28) >> 28;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700577 shadow_frame.SetVReg(dec_insn.vA, val);
578 if (val == 0) {
579 shadow_frame.SetReference(dec_insn.vA, NULL);
580 }
581 break;
582 }
583 case Instruction::CONST_16: {
584 int32_t val = static_cast<int16_t>(dec_insn.vB);
585 shadow_frame.SetVReg(dec_insn.vA, val);
586 if (val == 0) {
587 shadow_frame.SetReference(dec_insn.vA, NULL);
588 }
589 break;
590 }
591 case Instruction::CONST: {
592 int32_t val = dec_insn.vB;
593 shadow_frame.SetVReg(dec_insn.vA, val);
594 if (val == 0) {
595 shadow_frame.SetReference(dec_insn.vA, NULL);
596 }
597 break;
598 }
599 case Instruction::CONST_HIGH16: {
600 int32_t val = dec_insn.vB << 16;
601 shadow_frame.SetVReg(dec_insn.vA, val);
602 if (val == 0) {
603 shadow_frame.SetReference(dec_insn.vA, NULL);
604 }
605 break;
606 }
Ian Rogers64b6d142012-10-29 16:34:15 -0700607 case Instruction::CONST_WIDE_16:
608 shadow_frame.SetVRegLong(dec_insn.vA, static_cast<int16_t>(dec_insn.vB));
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700609 break;
Ian Rogers64b6d142012-10-29 16:34:15 -0700610 case Instruction::CONST_WIDE_32:
611 shadow_frame.SetVRegLong(dec_insn.vA, static_cast<int32_t>(dec_insn.vB));
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700612 break;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700613 case Instruction::CONST_WIDE:
Ian Rogers64b6d142012-10-29 16:34:15 -0700614 shadow_frame.SetVRegLong(dec_insn.vA, dec_insn.vB_wide);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700615 break;
616 case Instruction::CONST_WIDE_HIGH16:
Ian Rogers64b6d142012-10-29 16:34:15 -0700617 shadow_frame.SetVRegLong(dec_insn.vA, static_cast<uint64_t>(dec_insn.vB) << 48);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700618 break;
619 case Instruction::CONST_STRING:
620 case Instruction::CONST_STRING_JUMBO: {
621 if (UNLIKELY(!String::GetJavaLangString()->IsInitialized())) {
622 Runtime::Current()->GetClassLinker()->EnsureInitialized(String::GetJavaLangString(),
623 true, true);
624 }
625 String* s = mh.ResolveString(dec_insn.vB);
626 shadow_frame.SetReferenceAndVReg(dec_insn.vA, s);
627 break;
628 }
629 case Instruction::CONST_CLASS:
630 shadow_frame.SetReference(dec_insn.vA, mh.ResolveClass(dec_insn.vB));
631 break;
632 case Instruction::MONITOR_ENTER:
633 DoMonitorEnter(self, shadow_frame.GetReference(dec_insn.vA));
634 break;
635 case Instruction::MONITOR_EXIT:
636 DoMonitorExit(self, shadow_frame.GetReference(dec_insn.vA));
637 break;
638 case Instruction::CHECK_CAST: {
639 Class* c = mh.ResolveClass(dec_insn.vB);
640 Object* obj = shadow_frame.GetReference(dec_insn.vA);
641 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
642 self->ThrowNewExceptionF("Ljava/lang/ClassCastException;",
643 "%s cannot be cast to %s",
644 PrettyDescriptor(obj->GetClass()).c_str(),
645 PrettyDescriptor(c).c_str());
646 }
647 break;
648 }
649 case Instruction::INSTANCE_OF: {
650 Class* c = mh.ResolveClass(dec_insn.vC);
651 Object* obj = shadow_frame.GetReference(dec_insn.vB);
652 shadow_frame.SetVReg(dec_insn.vA, (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
653 break;
654 }
655 case Instruction::ARRAY_LENGTH: {
Ian Rogers64b6d142012-10-29 16:34:15 -0700656 Object* array = shadow_frame.GetReference(dec_insn.vB);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700657 if (UNLIKELY(array == NULL)) {
658 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
659 break;
660 }
Ian Rogers64b6d142012-10-29 16:34:15 -0700661 shadow_frame.SetVReg(dec_insn.vA, array->AsArray()->GetLength());
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700662 break;
663 }
664 case Instruction::NEW_INSTANCE: {
665 Object* obj = AllocObjectFromCode(dec_insn.vB, shadow_frame.GetMethod(), self, true);
666 shadow_frame.SetReferenceAndVReg(dec_insn.vA, obj);
667 break;
668 }
669 case Instruction::NEW_ARRAY: {
670 int32_t length = shadow_frame.GetVReg(dec_insn.vB);
671 Object* obj = AllocArrayFromCode(dec_insn.vC, shadow_frame.GetMethod(), length, self, true);
672 shadow_frame.SetReferenceAndVReg(dec_insn.vA, obj);
673 break;
674 }
675 case Instruction::FILLED_NEW_ARRAY:
Ian Rogers64b6d142012-10-29 16:34:15 -0700676 case Instruction::FILLED_NEW_ARRAY_RANGE: {
677 bool is_range = (dec_insn.opcode == Instruction::FILLED_NEW_ARRAY_RANGE);
678 int32_t length = dec_insn.vA;
679 CHECK(is_range || length <= 5);
680 Class* arrayClass = mh.ResolveClass(dec_insn.vB);
681 CHECK(arrayClass->IsArrayClass());
682 if (arrayClass->GetComponentType()->IsPrimitiveInt()) {
683 IntArray* newArray = IntArray::Alloc(self, length);
684 if (newArray != NULL) {
685 for (int32_t i = 0; i < length; ++i) {
686 if (is_range) {
687 newArray->Set(i, shadow_frame.GetVReg(dec_insn.vC + i));
688 } else {
689 newArray->Set(i, shadow_frame.GetVReg(dec_insn.arg[i]));
690 }
691 }
692 }
693 result_register.SetL(newArray);
694 } else {
695 UNIMPLEMENTED(FATAL) << inst->DumpString(&mh.GetDexFile())
696 << " for array type: " << PrettyDescriptor(arrayClass);
697 }
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700698 break;
Ian Rogers64b6d142012-10-29 16:34:15 -0700699 }
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700700 case Instruction::CMPL_FLOAT: {
701 float val1 = shadow_frame.GetVRegFloat(dec_insn.vB);
702 float val2 = shadow_frame.GetVRegFloat(dec_insn.vC);
703 int32_t result;
704 if (val1 == val2) {
705 result = 0;
706 } else if (val1 > val2) {
707 result = 1;
708 } else {
709 result = -1;
710 }
711 shadow_frame.SetVReg(dec_insn.vA, result);
712 break;
713 }
714 case Instruction::CMPG_FLOAT: {
715 float val1 = shadow_frame.GetVRegFloat(dec_insn.vB);
716 float val2 = shadow_frame.GetVRegFloat(dec_insn.vC);
717 int32_t result;
718 if (val1 == val2) {
719 result = 0;
720 } else if (val1 < val2) {
721 result = -1;
722 } else {
723 result = 1;
724 }
725 shadow_frame.SetVReg(dec_insn.vA, result);
726 break;
727 }
728 case Instruction::CMPL_DOUBLE: {
729 double val1 = shadow_frame.GetVRegDouble(dec_insn.vB);
730 double val2 = shadow_frame.GetVRegDouble(dec_insn.vC);
731 int32_t result;
732 if (val1 == val2) {
733 result = 0;
Ian Rogers64b6d142012-10-29 16:34:15 -0700734 } else if (val1 < val2) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700735 result = 1;
736 } else {
737 result = -1;
738 }
739 shadow_frame.SetVReg(dec_insn.vA, result);
740 break;
741 }
742
743 case Instruction::CMPG_DOUBLE: {
744 double val1 = shadow_frame.GetVRegDouble(dec_insn.vB);
745 double val2 = shadow_frame.GetVRegDouble(dec_insn.vC);
746 int32_t result;
747 if (val1 == val2) {
748 result = 0;
Ian Rogers64b6d142012-10-29 16:34:15 -0700749 } else if (val1 > val2) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700750 result = -1;
751 } else {
752 result = 1;
753 }
754 shadow_frame.SetVReg(dec_insn.vA, result);
755 break;
756 }
757 case Instruction::CMP_LONG: {
758 int64_t val1 = shadow_frame.GetVRegLong(dec_insn.vB);
759 int64_t val2 = shadow_frame.GetVRegLong(dec_insn.vC);
760 int32_t result;
761 if (val1 < val2) {
Ian Rogers64b6d142012-10-29 16:34:15 -0700762 result = 1;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700763 } else if (val1 == val2) {
764 result = 0;
765 } else {
Ian Rogers64b6d142012-10-29 16:34:15 -0700766 result = -1;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700767 }
768 shadow_frame.SetVReg(dec_insn.vA, result);
769 break;
770 }
771 case Instruction::THROW: {
772 Throwable* t = shadow_frame.GetReference(dec_insn.vA)->AsThrowable();
773 self->SetException(t);
774 break;
775 }
776 case Instruction::GOTO:
777 case Instruction::GOTO_16:
778 case Instruction::GOTO_32: {
779 uint32_t dex_pc = inst->GetDexPc(insns);
780 next_inst = Instruction::At(insns + dex_pc + dec_insn.vA);
781 break;
782 }
783 case Instruction::PACKED_SWITCH:
784 UNIMPLEMENTED(FATAL) << inst->DumpString(&mh.GetDexFile());
785 break;
786 case Instruction::SPARSE_SWITCH: {
787 uint32_t dex_pc = inst->GetDexPc(insns);
788 const uint16_t* switchData = insns + dex_pc + dec_insn.vB;
789 int32_t testVal = shadow_frame.GetVReg(dec_insn.vA);
790 CHECK_EQ(switchData[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature));
791 uint16_t size = switchData[1];
792 CHECK_GT(size, 0);
793 const int32_t* keys = reinterpret_cast<const int32_t*>(&switchData[2]);
794 CHECK(IsAligned<4>(keys));
795 const int32_t* entries = keys + size;
796 CHECK(IsAligned<4>(entries));
797 int lo = 0;
798 int hi = size - 1;
799 while (lo <= hi) {
800 int mid = (lo + hi) / 2;
801 int32_t foundVal = keys[mid];
802 if (testVal < foundVal) {
803 hi = mid - 1;
804 } else if (testVal > foundVal) {
805 lo = mid + 1;
806 } else {
807 next_inst = Instruction::At(insns + dex_pc + entries[mid]);
808 break;
809 }
810 }
811 break;
812 }
813 case Instruction::FILL_ARRAY_DATA: {
814 Array* array = shadow_frame.GetReference(dec_insn.vA)->AsArray();
815 if (UNLIKELY(array == NULL)) {
816 Thread::Current()->ThrowNewExceptionF("Ljava/lang/NullPointerException;",
817 "null array in FILL_ARRAY_DATA");
818 break;
819 }
820 DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
821 uint32_t dex_pc = inst->GetDexPc(insns);
822 const Instruction::ArrayDataPayload* payload =
823 reinterpret_cast<const Instruction::ArrayDataPayload*>(insns + dex_pc + dec_insn.vB);
824 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
825 Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
826 "failed FILL_ARRAY_DATA; length=%d, index=%d",
827 array->GetLength(), payload->element_count);
828 break;
829 }
830 uint32_t size_in_bytes = payload->element_count * payload->element_width;
831 memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes);
832 break;
833 }
834 case Instruction::IF_EQ: {
835 if (shadow_frame.GetVReg(dec_insn.vA) == shadow_frame.GetVReg(dec_insn.vB)) {
836 uint32_t dex_pc = inst->GetDexPc(insns);
837 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
838 }
839 break;
840 }
841 case Instruction::IF_NE: {
842 if (shadow_frame.GetVReg(dec_insn.vA) != shadow_frame.GetVReg(dec_insn.vB)) {
843 uint32_t dex_pc = inst->GetDexPc(insns);
844 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
845 }
846 break;
847 }
848 case Instruction::IF_LT: {
849 if (shadow_frame.GetVReg(dec_insn.vA) < shadow_frame.GetVReg(dec_insn.vB)) {
850 uint32_t dex_pc = inst->GetDexPc(insns);
851 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
852 }
853 break;
854 }
855 case Instruction::IF_GE: {
856 if (shadow_frame.GetVReg(dec_insn.vA) >= shadow_frame.GetVReg(dec_insn.vB)) {
857 uint32_t dex_pc = inst->GetDexPc(insns);
858 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
859 }
860 break;
861 }
862 case Instruction::IF_GT: {
863 if (shadow_frame.GetVReg(dec_insn.vA) > shadow_frame.GetVReg(dec_insn.vB)) {
864 uint32_t dex_pc = inst->GetDexPc(insns);
865 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
866 }
867 break;
868 }
869 case Instruction::IF_LE: {
870 if (shadow_frame.GetVReg(dec_insn.vA) <= shadow_frame.GetVReg(dec_insn.vB)) {
871 uint32_t dex_pc = inst->GetDexPc(insns);
872 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
873 }
874 break;
875 }
876 case Instruction::IF_EQZ: {
877 if (shadow_frame.GetVReg(dec_insn.vA) == 0) {
878 uint32_t dex_pc = inst->GetDexPc(insns);
879 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
880 }
881 break;
882 }
883 case Instruction::IF_NEZ: {
884 if (shadow_frame.GetVReg(dec_insn.vA) != 0) {
885 uint32_t dex_pc = inst->GetDexPc(insns);
886 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
887 }
888 break;
889 }
890 case Instruction::IF_LTZ: {
891 if (shadow_frame.GetVReg(dec_insn.vA) < 0) {
892 uint32_t dex_pc = inst->GetDexPc(insns);
893 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
894 }
895 break;
896 }
897 case Instruction::IF_GEZ: {
898 if (shadow_frame.GetVReg(dec_insn.vA) >= 0) {
899 uint32_t dex_pc = inst->GetDexPc(insns);
900 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
901 }
902 break;
903 }
904 case Instruction::IF_GTZ: {
905 if (shadow_frame.GetVReg(dec_insn.vA) > 0) {
906 uint32_t dex_pc = inst->GetDexPc(insns);
907 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
908 }
909 break;
910 }
911 case Instruction::IF_LEZ: {
912 if (shadow_frame.GetVReg(dec_insn.vA) <= 0) {
913 uint32_t dex_pc = inst->GetDexPc(insns);
914 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
915 }
916 break;
917 }
918 case Instruction::AGET_BOOLEAN: {
919 BooleanArray* a = shadow_frame.GetReference(dec_insn.vB)->AsBooleanArray();
920 if (UNLIKELY(a == NULL)) {
921 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
922 break;
923 }
924 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
925 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
926 break;
927 }
928 case Instruction::AGET_BYTE: {
929 ByteArray* a = shadow_frame.GetReference(dec_insn.vB)->AsByteArray();
930 if (UNLIKELY(a == NULL)) {
931 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
932 break;
933 }
934 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
935 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
936 break;
937 }
938 case Instruction::AGET_CHAR: {
939 CharArray* a = shadow_frame.GetReference(dec_insn.vB)->AsCharArray();
940 if (UNLIKELY(a == NULL)) {
941 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
942 break;
943 }
944 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
945 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
946 break;
947 }
948 case Instruction::AGET_SHORT: {
949 ShortArray* a = shadow_frame.GetReference(dec_insn.vB)->AsShortArray();
950 if (UNLIKELY(a == NULL)) {
951 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
952 break;
953 }
954 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
955 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
956 break;
957 }
958 case Instruction::AGET: {
959 IntArray* a = shadow_frame.GetReference(dec_insn.vB)->AsIntArray();
960 if (UNLIKELY(a == NULL)) {
961 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
962 break;
963 }
964 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
965 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
966 break;
967 }
968 case Instruction::AGET_WIDE: {
969 LongArray* a = shadow_frame.GetReference(dec_insn.vB)->AsLongArray();
970 if (UNLIKELY(a == NULL)) {
971 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
972 break;
973 }
974 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
975 shadow_frame.SetVRegLong(dec_insn.vA, a->Get(index));
976 break;
977 }
978 case Instruction::AGET_OBJECT: {
979 ObjectArray<Object>* a = shadow_frame.GetReference(dec_insn.vB)->AsObjectArray<Object>();
980 if (UNLIKELY(a == NULL)) {
981 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
982 break;
983 }
984 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
985 Object* o = a->Get(index);
986 shadow_frame.SetReferenceAndVReg(dec_insn.vA, o);
987 break;
988 }
989 case Instruction::APUT_BOOLEAN: {
990 uint8_t val = shadow_frame.GetVReg(dec_insn.vA);
991 BooleanArray* a = shadow_frame.GetReference(dec_insn.vB)->AsBooleanArray();
992 if (UNLIKELY(a == NULL)) {
993 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
994 break;
995 }
996 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
997 a->Set(index, val);
998 break;
999 }
1000 case Instruction::APUT_BYTE: {
1001 int8_t val = shadow_frame.GetVReg(dec_insn.vA);
1002 ByteArray* a = shadow_frame.GetReference(dec_insn.vB)->AsByteArray();
1003 if (UNLIKELY(a == NULL)) {
1004 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
1005 break;
1006 }
1007 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
1008 a->Set(index, val);
1009 break;
1010 }
1011 case Instruction::APUT_CHAR: {
1012 uint16_t val = shadow_frame.GetVReg(dec_insn.vA);
1013 CharArray* a = shadow_frame.GetReference(dec_insn.vB)->AsCharArray();
1014 if (UNLIKELY(a == NULL)) {
1015 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
1016 break;
1017 }
1018 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
1019 a->Set(index, val);
1020 break;
1021 }
1022 case Instruction::APUT_SHORT: {
1023 int16_t val = shadow_frame.GetVReg(dec_insn.vA);
1024 ShortArray* a = shadow_frame.GetReference(dec_insn.vB)->AsShortArray();
1025 if (UNLIKELY(a == NULL)) {
1026 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
1027 break;
1028 }
1029 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
1030 a->Set(index, val);
1031 break;
1032 }
1033 case Instruction::APUT: {
1034 int32_t val = shadow_frame.GetVReg(dec_insn.vA);
1035 IntArray* a = shadow_frame.GetReference(dec_insn.vB)->AsIntArray();
1036 if (UNLIKELY(a == NULL)) {
1037 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
1038 break;
1039 }
1040 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
1041 a->Set(index, val);
1042 break;
1043 }
1044 case Instruction::APUT_WIDE: {
1045 int64_t val = shadow_frame.GetVRegLong(dec_insn.vA);
1046 LongArray* a = shadow_frame.GetReference(dec_insn.vB)->AsLongArray();
1047 if (UNLIKELY(a == NULL)) {
1048 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
1049 break;
1050 }
1051 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
1052 a->Set(index, val);
1053 break;
1054 }
1055 case Instruction::APUT_OBJECT: {
1056 Object* val = shadow_frame.GetReference(dec_insn.vA);
1057 ObjectArray<Object>* a = shadow_frame.GetReference(dec_insn.vB)->AsObjectArray<Object>();
1058 if (UNLIKELY(a == NULL)) {
1059 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
1060 break;
1061 }
1062 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
1063 a->Set(index, val);
1064 break;
1065 }
1066 case Instruction::IGET_BOOLEAN:
1067 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimBoolean);
1068 break;
1069 case Instruction::IGET_BYTE:
1070 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimByte);
1071 break;
1072 case Instruction::IGET_CHAR:
1073 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimChar);
1074 break;
1075 case Instruction::IGET_SHORT:
1076 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimShort);
1077 break;
1078 case Instruction::IGET:
1079 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimInt);
1080 break;
1081 case Instruction::IGET_WIDE:
1082 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimLong);
1083 break;
1084 case Instruction::IGET_OBJECT:
1085 DoFieldGet(self, shadow_frame, dec_insn, InstanceObjectRead, Primitive::kPrimNot);
1086 break;
1087 case Instruction::SGET_BOOLEAN:
1088 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimBoolean);
1089 break;
1090 case Instruction::SGET_BYTE:
1091 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimByte);
1092 break;
1093 case Instruction::SGET_CHAR:
1094 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimChar);
1095 break;
1096 case Instruction::SGET_SHORT:
1097 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimShort);
1098 break;
1099 case Instruction::SGET:
1100 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimInt);
1101 break;
1102 case Instruction::SGET_WIDE:
1103 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimLong);
1104 break;
1105 case Instruction::SGET_OBJECT:
1106 DoFieldGet(self, shadow_frame, dec_insn, StaticObjectRead, Primitive::kPrimNot);
1107 break;
1108 case Instruction::IPUT_BOOLEAN:
1109 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimBoolean);
1110 break;
1111 case Instruction::IPUT_BYTE:
1112 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimByte);
1113 break;
1114 case Instruction::IPUT_CHAR:
1115 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimChar);
1116 break;
1117 case Instruction::IPUT_SHORT:
1118 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimShort);
1119 break;
1120 case Instruction::IPUT:
1121 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimInt);
1122 break;
1123 case Instruction::IPUT_WIDE:
1124 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimLong);
1125 break;
1126 case Instruction::IPUT_OBJECT:
1127 DoFieldPut(self, shadow_frame, dec_insn, InstanceObjectWrite, Primitive::kPrimNot);
1128 break;
1129 case Instruction::SPUT_BOOLEAN:
1130 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimBoolean);
1131 break;
1132 case Instruction::SPUT_BYTE:
1133 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimByte);
1134 break;
1135 case Instruction::SPUT_CHAR:
1136 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimChar);
1137 break;
1138 case Instruction::SPUT_SHORT:
1139 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimShort);
1140 break;
1141 case Instruction::SPUT:
1142 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimInt);
1143 break;
1144 case Instruction::SPUT_WIDE:
1145 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimLong);
1146 break;
1147 case Instruction::SPUT_OBJECT:
1148 DoFieldPut(self, shadow_frame, dec_insn, StaticObjectWrite, Primitive::kPrimNot);
1149 break;
1150 case Instruction::INVOKE_VIRTUAL:
1151 DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, false, &result_register);
1152 break;
1153 case Instruction::INVOKE_VIRTUAL_RANGE:
1154 DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, true, &result_register);
1155 break;
1156 case Instruction::INVOKE_SUPER:
1157 DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, false, &result_register);
1158 break;
1159 case Instruction::INVOKE_SUPER_RANGE:
1160 DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, true, &result_register);
1161 break;
1162 case Instruction::INVOKE_DIRECT:
1163 DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, false, &result_register);
1164 break;
1165 case Instruction::INVOKE_DIRECT_RANGE:
1166 DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, true, &result_register);
1167 break;
1168 case Instruction::INVOKE_INTERFACE:
1169 DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, false, &result_register);
1170 break;
1171 case Instruction::INVOKE_INTERFACE_RANGE:
1172 DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, true, &result_register);
1173 break;
1174 case Instruction::INVOKE_STATIC:
1175 DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, false, &result_register);
1176 break;
1177 case Instruction::INVOKE_STATIC_RANGE:
1178 DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, true, &result_register);
1179 break;
1180 case Instruction::NEG_INT:
1181 shadow_frame.SetVReg(dec_insn.vA, -shadow_frame.GetVReg(dec_insn.vB));
1182 break;
1183 case Instruction::NOT_INT:
1184 shadow_frame.SetVReg(dec_insn.vA, 0 ^ shadow_frame.GetVReg(dec_insn.vB));
1185 break;
1186 case Instruction::NEG_LONG:
1187 shadow_frame.SetVRegLong(dec_insn.vA, -shadow_frame.GetVRegLong(dec_insn.vB));
1188 break;
1189 case Instruction::NOT_LONG:
1190 shadow_frame.SetVRegLong(dec_insn.vA, 0 ^ shadow_frame.GetVRegLong(dec_insn.vB));
1191 break;
1192 case Instruction::NEG_FLOAT:
1193 shadow_frame.SetVRegFloat(dec_insn.vA, -shadow_frame.GetVRegFloat(dec_insn.vB));
1194 break;
1195 case Instruction::NEG_DOUBLE:
1196 shadow_frame.SetVRegDouble(dec_insn.vA, -shadow_frame.GetVRegDouble(dec_insn.vB));
1197 break;
1198 case Instruction::INT_TO_LONG:
1199 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
1200 break;
1201 case Instruction::INT_TO_FLOAT:
1202 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
1203 break;
1204 case Instruction::INT_TO_DOUBLE:
1205 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
1206 break;
1207 case Instruction::LONG_TO_INT:
1208 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
1209 break;
1210 case Instruction::LONG_TO_FLOAT:
1211 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
1212 break;
1213 case Instruction::LONG_TO_DOUBLE:
1214 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
1215 break;
1216 case Instruction::FLOAT_TO_INT:
1217 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB));
1218 break;
1219 case Instruction::FLOAT_TO_LONG:
1220 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB));
1221 break;
1222 case Instruction::FLOAT_TO_DOUBLE:
1223 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB));
1224 break;
1225 case Instruction::DOUBLE_TO_INT:
1226 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB));
1227 break;
1228 case Instruction::DOUBLE_TO_LONG:
1229 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB));
1230 break;
1231 case Instruction::DOUBLE_TO_FLOAT:
1232 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB));
1233 break;
1234 case Instruction::INT_TO_BYTE:
1235 shadow_frame.SetVReg(dec_insn.vA, static_cast<int8_t>(shadow_frame.GetVReg(dec_insn.vB)));
1236 break;
1237 case Instruction::INT_TO_CHAR:
1238 shadow_frame.SetVReg(dec_insn.vA, static_cast<uint16_t>(shadow_frame.GetVReg(dec_insn.vB)));
1239 break;
1240 case Instruction::INT_TO_SHORT:
1241 shadow_frame.SetVReg(dec_insn.vA, static_cast<int16_t>(shadow_frame.GetVReg(dec_insn.vB)));
1242 break;
1243 case Instruction::ADD_INT:
1244 shadow_frame.SetVReg(dec_insn.vA,
1245 shadow_frame.GetVReg(dec_insn.vB) + shadow_frame.GetVReg(dec_insn.vC));
1246 break;
1247 case Instruction::SUB_INT:
1248 shadow_frame.SetVReg(dec_insn.vA,
1249 shadow_frame.GetVReg(dec_insn.vB) - shadow_frame.GetVReg(dec_insn.vC));
1250 break;
1251 case Instruction::MUL_INT:
1252 shadow_frame.SetVReg(dec_insn.vA,
1253 shadow_frame.GetVReg(dec_insn.vB) * shadow_frame.GetVReg(dec_insn.vC));
1254 break;
1255 case Instruction::REM_INT:
1256 shadow_frame.SetVReg(dec_insn.vA,
1257 shadow_frame.GetVReg(dec_insn.vB) % shadow_frame.GetVReg(dec_insn.vC));
1258 break;
1259 case Instruction::DIV_INT:
1260 shadow_frame.SetVReg(dec_insn.vA,
1261 shadow_frame.GetVReg(dec_insn.vB) / shadow_frame.GetVReg(dec_insn.vC));
1262 break;
1263 case Instruction::SHL_INT:
1264 shadow_frame.SetVReg(dec_insn.vA,
1265 shadow_frame.GetVReg(dec_insn.vB) << shadow_frame.GetVReg(dec_insn.vC));
1266 break;
1267 case Instruction::SHR_INT:
1268 shadow_frame.SetVReg(dec_insn.vA,
1269 shadow_frame.GetVReg(dec_insn.vB) >> shadow_frame.GetVReg(dec_insn.vC));
1270 break;
1271 case Instruction::USHR_INT:
1272 shadow_frame.SetVReg(dec_insn.vA,
1273 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >>
1274 shadow_frame.GetVReg(dec_insn.vC));
1275 break;
1276 case Instruction::AND_INT:
1277 shadow_frame.SetVReg(dec_insn.vA,
1278 shadow_frame.GetVReg(dec_insn.vB) & shadow_frame.GetVReg(dec_insn.vC));
1279 break;
1280 case Instruction::OR_INT:
1281 shadow_frame.SetVReg(dec_insn.vA,
1282 shadow_frame.GetVReg(dec_insn.vB) | shadow_frame.GetVReg(dec_insn.vC));
1283 break;
1284 case Instruction::XOR_INT:
1285 shadow_frame.SetVReg(dec_insn.vA,
1286 shadow_frame.GetVReg(dec_insn.vB) ^ shadow_frame.GetVReg(dec_insn.vC));
1287 break;
1288 case Instruction::ADD_LONG:
1289 shadow_frame.SetVRegLong(dec_insn.vA,
1290 shadow_frame.GetVRegLong(dec_insn.vB) +
1291 shadow_frame.GetVRegLong(dec_insn.vC));
1292 break;
1293 case Instruction::SUB_LONG:
1294 shadow_frame.SetVRegLong(dec_insn.vA,
1295 shadow_frame.GetVRegLong(dec_insn.vB) -
1296 shadow_frame.GetVRegLong(dec_insn.vC));
1297 break;
1298 case Instruction::MUL_LONG:
1299 shadow_frame.SetVRegLong(dec_insn.vA,
1300 shadow_frame.GetVRegLong(dec_insn.vB) *
1301 shadow_frame.GetVRegLong(dec_insn.vC));
1302 break;
1303 case Instruction::DIV_LONG:
1304 shadow_frame.SetVRegLong(dec_insn.vA,
1305 shadow_frame.GetVRegLong(dec_insn.vB) /
1306 shadow_frame.GetVRegLong(dec_insn.vC));
1307 break;
1308 case Instruction::REM_LONG:
1309 shadow_frame.SetVRegLong(dec_insn.vA,
1310 shadow_frame.GetVRegLong(dec_insn.vB) %
1311 shadow_frame.GetVRegLong(dec_insn.vC));
1312 break;
1313 case Instruction::AND_LONG:
1314 shadow_frame.SetVRegLong(dec_insn.vA,
1315 shadow_frame.GetVRegLong(dec_insn.vB) &
1316 shadow_frame.GetVRegLong(dec_insn.vC));
1317 break;
1318 case Instruction::OR_LONG:
1319 shadow_frame.SetVRegLong(dec_insn.vA,
1320 shadow_frame.GetVRegLong(dec_insn.vB) |
1321 shadow_frame.GetVRegLong(dec_insn.vC));
1322 break;
1323 case Instruction::XOR_LONG:
1324 shadow_frame.SetVRegLong(dec_insn.vA,
1325 shadow_frame.GetVRegLong(dec_insn.vB) ^
1326 shadow_frame.GetVRegLong(dec_insn.vC));
1327 break;
1328 case Instruction::SHL_LONG:
1329 shadow_frame.SetVRegLong(dec_insn.vA,
1330 shadow_frame.GetVRegLong(dec_insn.vB) <<
1331 shadow_frame.GetVReg(dec_insn.vC));
1332 break;
1333 case Instruction::SHR_LONG:
1334 shadow_frame.SetVRegLong(dec_insn.vA,
1335 shadow_frame.GetVRegLong(dec_insn.vB) >>
1336 shadow_frame.GetVReg(dec_insn.vC));
1337 break;
1338 case Instruction::USHR_LONG:
1339 shadow_frame.SetVRegLong(dec_insn.vA,
1340 static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vB)) >>
1341 shadow_frame.GetVReg(dec_insn.vC));
1342 break;
1343 case Instruction::ADD_FLOAT:
1344 shadow_frame.SetVRegFloat(dec_insn.vA,
1345 shadow_frame.GetVRegFloat(dec_insn.vB) +
1346 shadow_frame.GetVRegFloat(dec_insn.vC));
1347 break;
1348 case Instruction::SUB_FLOAT:
1349 shadow_frame.SetVRegFloat(dec_insn.vA,
1350 shadow_frame.GetVRegFloat(dec_insn.vB) -
1351 shadow_frame.GetVRegFloat(dec_insn.vC));
1352 break;
1353 case Instruction::MUL_FLOAT:
1354 shadow_frame.SetVRegFloat(dec_insn.vA,
1355 shadow_frame.GetVRegFloat(dec_insn.vB) *
1356 shadow_frame.GetVRegFloat(dec_insn.vC));
1357 break;
1358 case Instruction::DIV_FLOAT:
1359 shadow_frame.SetVRegFloat(dec_insn.vA,
1360 shadow_frame.GetVRegFloat(dec_insn.vB) /
1361 shadow_frame.GetVRegFloat(dec_insn.vC));
1362 break;
1363 case Instruction::REM_FLOAT:
1364 shadow_frame.SetVRegFloat(dec_insn.vA,
1365 fmodf(shadow_frame.GetVRegFloat(dec_insn.vB),
1366 shadow_frame.GetVRegFloat(dec_insn.vC)));
1367 break;
1368 case Instruction::ADD_DOUBLE:
1369 shadow_frame.SetVRegDouble(dec_insn.vA,
1370 shadow_frame.GetVRegDouble(dec_insn.vB) +
1371 shadow_frame.GetVRegDouble(dec_insn.vC));
1372 break;
1373 case Instruction::SUB_DOUBLE:
1374 shadow_frame.SetVRegDouble(dec_insn.vA,
1375 shadow_frame.GetVRegDouble(dec_insn.vB) -
1376 shadow_frame.GetVRegDouble(dec_insn.vC));
1377 break;
1378 case Instruction::MUL_DOUBLE:
1379 shadow_frame.SetVRegDouble(dec_insn.vA,
1380 shadow_frame.GetVRegDouble(dec_insn.vB) *
1381 shadow_frame.GetVRegDouble(dec_insn.vC));
1382 break;
1383 case Instruction::DIV_DOUBLE:
1384 shadow_frame.SetVRegDouble(dec_insn.vA,
1385 shadow_frame.GetVRegDouble(dec_insn.vB) /
1386 shadow_frame.GetVRegDouble(dec_insn.vC));
1387 break;
1388 case Instruction::REM_DOUBLE:
1389 shadow_frame.SetVRegDouble(dec_insn.vA,
1390 fmod(shadow_frame.GetVRegDouble(dec_insn.vB),
1391 shadow_frame.GetVRegDouble(dec_insn.vC)));
1392 break;
1393 case Instruction::ADD_INT_2ADDR:
1394 shadow_frame.SetVReg(dec_insn.vA,
1395 shadow_frame.GetVReg(dec_insn.vA) + shadow_frame.GetVReg(dec_insn.vB));
1396 break;
1397 case Instruction::SUB_INT_2ADDR:
1398 shadow_frame.SetVReg(dec_insn.vA,
1399 shadow_frame.GetVReg(dec_insn.vA) - shadow_frame.GetVReg(dec_insn.vB));
1400 break;
1401 case Instruction::MUL_INT_2ADDR:
1402 shadow_frame.SetVReg(dec_insn.vA,
1403 shadow_frame.GetVReg(dec_insn.vA) * shadow_frame.GetVReg(dec_insn.vB));
1404 break;
1405 case Instruction::REM_INT_2ADDR:
1406 shadow_frame.SetVReg(dec_insn.vA,
1407 shadow_frame.GetVReg(dec_insn.vA) % shadow_frame.GetVReg(dec_insn.vB));
1408 break;
1409 case Instruction::SHL_INT_2ADDR:
1410 shadow_frame.SetVReg(dec_insn.vA,
1411 shadow_frame.GetVReg(dec_insn.vA) << shadow_frame.GetVReg(dec_insn.vB));
1412 break;
1413 case Instruction::SHR_INT_2ADDR:
1414 shadow_frame.SetVReg(dec_insn.vA,
1415 shadow_frame.GetVReg(dec_insn.vA) >> shadow_frame.GetVReg(dec_insn.vB));
1416 break;
1417 case Instruction::USHR_INT_2ADDR:
1418 shadow_frame.SetVReg(dec_insn.vA,
1419 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vA)) >>
1420 shadow_frame.GetVReg(dec_insn.vB));
1421 break;
1422 case Instruction::AND_INT_2ADDR:
1423 shadow_frame.SetVReg(dec_insn.vA,
1424 shadow_frame.GetVReg(dec_insn.vA) & shadow_frame.GetVReg(dec_insn.vB));
1425 break;
1426 case Instruction::OR_INT_2ADDR:
1427 shadow_frame.SetVReg(dec_insn.vA,
1428 shadow_frame.GetVReg(dec_insn.vA) | shadow_frame.GetVReg(dec_insn.vB));
1429 break;
1430 case Instruction::XOR_INT_2ADDR:
1431 shadow_frame.SetVReg(dec_insn.vA,
1432 shadow_frame.GetVReg(dec_insn.vA) ^ shadow_frame.GetVReg(dec_insn.vB));
1433 break;
1434 case Instruction::DIV_INT_2ADDR:
1435 shadow_frame.SetVReg(dec_insn.vA,
1436 shadow_frame.GetVReg(dec_insn.vA) / shadow_frame.GetVReg(dec_insn.vB));
1437 break;
1438 case Instruction::ADD_LONG_2ADDR:
1439 shadow_frame.SetVRegLong(dec_insn.vA,
1440 shadow_frame.GetVRegLong(dec_insn.vA) +
1441 shadow_frame.GetVRegLong(dec_insn.vB));
1442 break;
1443 case Instruction::SUB_LONG_2ADDR:
1444 shadow_frame.SetVRegLong(dec_insn.vA,
1445 shadow_frame.GetVRegLong(dec_insn.vA) -
1446 shadow_frame.GetVRegLong(dec_insn.vB));
1447 break;
1448 case Instruction::MUL_LONG_2ADDR:
1449 shadow_frame.SetVRegLong(dec_insn.vA,
Ian Rogers64b6d142012-10-29 16:34:15 -07001450 shadow_frame.GetVRegLong(dec_insn.vA) *
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001451 shadow_frame.GetVRegLong(dec_insn.vB));
1452 break;
1453 case Instruction::DIV_LONG_2ADDR:
1454 shadow_frame.SetVRegLong(dec_insn.vA,
1455 shadow_frame.GetVRegLong(dec_insn.vA) /
1456 shadow_frame.GetVRegLong(dec_insn.vB));
1457 break;
1458 case Instruction::REM_LONG_2ADDR:
1459 shadow_frame.SetVRegLong(dec_insn.vA,
1460 shadow_frame.GetVRegLong(dec_insn.vA) %
1461 shadow_frame.GetVRegLong(dec_insn.vB));
1462 break;
1463 case Instruction::AND_LONG_2ADDR:
1464 shadow_frame.SetVRegLong(dec_insn.vA,
1465 shadow_frame.GetVRegLong(dec_insn.vA) &
1466 shadow_frame.GetVRegLong(dec_insn.vB));
1467 break;
1468 case Instruction::OR_LONG_2ADDR:
1469 shadow_frame.SetVRegLong(dec_insn.vA,
1470 shadow_frame.GetVRegLong(dec_insn.vA) |
1471 shadow_frame.GetVRegLong(dec_insn.vB));
1472 break;
1473 case Instruction::XOR_LONG_2ADDR:
1474 shadow_frame.SetVRegLong(dec_insn.vA,
1475 shadow_frame.GetVRegLong(dec_insn.vA) ^
1476 shadow_frame.GetVRegLong(dec_insn.vB));
1477 break;
1478 case Instruction::SHL_LONG_2ADDR:
1479 shadow_frame.SetVRegLong(dec_insn.vA,
1480 shadow_frame.GetVRegLong(dec_insn.vA) <<
1481 shadow_frame.GetVReg(dec_insn.vB));
1482 break;
1483 case Instruction::SHR_LONG_2ADDR:
1484 shadow_frame.SetVRegLong(dec_insn.vA,
1485 shadow_frame.GetVRegLong(dec_insn.vA) >>
1486 shadow_frame.GetVReg(dec_insn.vB));
1487 break;
1488 case Instruction::USHR_LONG_2ADDR:
1489 shadow_frame.SetVRegLong(dec_insn.vA,
1490 static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vA)) >>
1491 shadow_frame.GetVReg(dec_insn.vB));
1492 break;
1493 case Instruction::ADD_FLOAT_2ADDR:
1494 shadow_frame.SetVRegFloat(dec_insn.vA,
1495 shadow_frame.GetVRegFloat(dec_insn.vA) +
1496 shadow_frame.GetVRegFloat(dec_insn.vB));
1497 break;
1498 case Instruction::SUB_FLOAT_2ADDR:
1499 shadow_frame.SetVRegFloat(dec_insn.vA,
1500 shadow_frame.GetVRegFloat(dec_insn.vA) -
1501 shadow_frame.GetVRegFloat(dec_insn.vB));
1502 break;
1503 case Instruction::MUL_FLOAT_2ADDR:
1504 shadow_frame.SetVRegFloat(dec_insn.vA,
1505 shadow_frame.GetVRegFloat(dec_insn.vA) *
1506 shadow_frame.GetVRegFloat(dec_insn.vB));
1507 break;
1508 case Instruction::DIV_FLOAT_2ADDR:
1509 shadow_frame.SetVRegFloat(dec_insn.vA,
1510 shadow_frame.GetVRegFloat(dec_insn.vA) /
1511 shadow_frame.GetVRegFloat(dec_insn.vB));
1512 break;
1513 case Instruction::REM_FLOAT_2ADDR:
1514 shadow_frame.SetVRegFloat(dec_insn.vA,
1515 fmodf(shadow_frame.GetVRegFloat(dec_insn.vA),
1516 shadow_frame.GetVRegFloat(dec_insn.vB)));
1517 break;
1518 case Instruction::ADD_DOUBLE_2ADDR:
1519 shadow_frame.SetVRegDouble(dec_insn.vA,
1520 shadow_frame.GetVRegDouble(dec_insn.vA) +
1521 shadow_frame.GetVRegDouble(dec_insn.vB));
1522 break;
1523 case Instruction::SUB_DOUBLE_2ADDR:
1524 shadow_frame.SetVRegDouble(dec_insn.vA,
1525 shadow_frame.GetVRegDouble(dec_insn.vA) -
1526 shadow_frame.GetVRegDouble(dec_insn.vB));
1527 break;
1528 case Instruction::MUL_DOUBLE_2ADDR:
1529 shadow_frame.SetVRegDouble(dec_insn.vA,
1530 shadow_frame.GetVRegDouble(dec_insn.vA) *
1531 shadow_frame.GetVRegDouble(dec_insn.vB));
1532 break;
1533 case Instruction::DIV_DOUBLE_2ADDR:
1534 shadow_frame.SetVRegDouble(dec_insn.vA,
1535 shadow_frame.GetVRegDouble(dec_insn.vA) /
1536 shadow_frame.GetVRegDouble(dec_insn.vB));
1537 break;
1538 case Instruction::REM_DOUBLE_2ADDR:
1539 shadow_frame.SetVRegDouble(dec_insn.vA,
1540 fmod(shadow_frame.GetVRegDouble(dec_insn.vA),
1541 shadow_frame.GetVRegDouble(dec_insn.vB)));
1542 break;
1543 case Instruction::ADD_INT_LIT16:
1544 case Instruction::ADD_INT_LIT8:
1545 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) + dec_insn.vC);
1546 break;
1547 case Instruction::RSUB_INT:
1548 case Instruction::RSUB_INT_LIT8:
1549 shadow_frame.SetVReg(dec_insn.vA, dec_insn.vC - shadow_frame.GetVReg(dec_insn.vB));
1550 break;
1551 case Instruction::MUL_INT_LIT16:
1552 case Instruction::MUL_INT_LIT8:
1553 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) * dec_insn.vC);
1554 break;
1555 case Instruction::DIV_INT_LIT16:
1556 case Instruction::DIV_INT_LIT8:
1557 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) / dec_insn.vC);
1558 break;
1559 case Instruction::REM_INT_LIT16:
1560 case Instruction::REM_INT_LIT8:
1561 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) % dec_insn.vC);
1562 break;
1563 case Instruction::AND_INT_LIT16:
1564 case Instruction::AND_INT_LIT8:
1565 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) & dec_insn.vC);
1566 break;
1567 case Instruction::OR_INT_LIT16:
1568 case Instruction::OR_INT_LIT8:
1569 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) | dec_insn.vC);
1570 break;
1571 case Instruction::XOR_INT_LIT16:
1572 case Instruction::XOR_INT_LIT8:
1573 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) ^ dec_insn.vC);
1574 break;
1575 case Instruction::SHL_INT_LIT8:
1576 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) << dec_insn.vC);
1577 break;
1578 case Instruction::SHR_INT_LIT8:
1579 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) >> dec_insn.vC);
1580 break;
1581 case Instruction::USHR_INT_LIT8:
1582 shadow_frame.SetVReg(dec_insn.vA,
1583 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >>
1584 dec_insn.vC);
1585 break;
1586 default:
1587 LOG(FATAL) << "Unexpected instruction: " << inst->DumpString(&mh.GetDexFile());
1588 break;
1589 }
1590 if (UNLIKELY(self->IsExceptionPending())) {
1591 uint32_t found_dex_pc =
1592 shadow_frame.GetMethod()->FindCatchBlock(self->GetException()->GetClass(),
1593 inst->GetDexPc(insns));
1594 if (found_dex_pc == DexFile::kDexNoIndex) {
1595 JValue result;
1596 result.SetJ(0);
1597 return result; // Handler in caller.
1598 } else {
1599 next_inst = Instruction::At(insns + found_dex_pc);
1600 }
1601 }
1602 inst = next_inst;
1603 }
1604}
1605
1606void EnterInterpreterFromInvoke(Thread* self, AbstractMethod* method, Object* receiver,
1607 JValue* args, JValue* result) {
Ian Rogers64b6d142012-10-29 16:34:15 -07001608 DCHECK_EQ(self, Thread::Current());
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001609 MethodHelper mh(method);
1610 const DexFile::CodeItem* code_item = mh.GetCodeItem();
1611 uint16_t num_regs;
1612 uint16_t num_ins;
1613 if (code_item != NULL) {
1614 num_regs = code_item->registers_size_;
1615 num_ins = code_item->ins_size_;
1616 } else {
1617 DCHECK(method->IsNative());
1618 num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty());
1619 if (!method->IsStatic()) {
1620 num_regs++;
1621 num_ins++;
1622 }
1623 }
1624 // Set up shadow frame with matching number of reference slots to vregs.
1625 ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame();
1626 UniquePtr<ShadowFrame> shadow_frame(ShadowFrame::Create(num_regs, num_regs,
1627 (last_shadow_frame == NULL) ? NULL : last_shadow_frame->GetLink(),
1628 method, 0));
1629 self->PushShadowFrame(shadow_frame.get());
1630 size_t cur_reg = num_regs - num_ins;
1631 if (!method->IsStatic()) {
1632 CHECK(receiver != NULL);
1633 shadow_frame->SetReferenceAndVReg(cur_reg, receiver);
1634 ++cur_reg;
1635 } else if (!method->GetDeclaringClass()->IsInitializing()) {
1636 Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(),
1637 true, true);
1638 CHECK(method->GetDeclaringClass()->IsInitializing());
1639 }
Ian Rogers64b6d142012-10-29 16:34:15 -07001640 const char* shorty = mh.GetShorty();
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001641 size_t arg_pos = 0;
1642 for (; cur_reg < num_regs; ++cur_reg, ++arg_pos) {
1643 DCHECK_LT(arg_pos + 1, mh.GetShortyLength());
1644 switch (shorty[arg_pos + 1]) {
1645 case 'L': {
1646 Object* o = args[arg_pos].GetL();
1647 shadow_frame->SetReferenceAndVReg(cur_reg, o);
1648 break;
1649 }
1650 case 'J': case 'D':
1651 shadow_frame->SetVRegLong(cur_reg, args[arg_pos].GetJ());
1652 cur_reg++;
1653 break;
1654 default:
1655 shadow_frame->SetVReg(cur_reg, args[arg_pos].GetI());
1656 break;
1657 }
1658 }
Ian Rogers64b6d142012-10-29 16:34:15 -07001659 if (LIKELY(!method->IsNative())) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001660 JValue r = Execute(self, mh, code_item, *shadow_frame.get());
1661 if (result != NULL) {
1662 *result = r;
1663 }
1664 } else {
Ian Rogers64b6d142012-10-29 16:34:15 -07001665 // We don't expect to be asked to interpret native code (which is entered via a JNI compiler
1666 // generated stub) except during testing and image writing.
1667 if (!Runtime::Current()->IsStarted()) {
1668 UnstartedRuntimeJni(self, method, receiver, args, result);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001669 } else {
Ian Rogers64b6d142012-10-29 16:34:15 -07001670 InterpreterJni(self, method, shorty, receiver, args, result);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001671 }
1672 }
1673 self->PopShadowFrame();
1674}
1675
1676} // namespace interpreter
1677} // namespace art