blob: 757639e14407ea48655cf345b93cf9612324df45 [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()));
Ian Rogers556d6372012-11-20 12:19:36 -0800193 jobject jresult;
194 {
195 ScopedThreadStateChange tsc(self, kNative);
196 jresult = fn(soa.Env(), klass.get());
197 }
198 result->SetL(soa.Decode<Object*>(jresult));
Ian Rogers64b6d142012-10-29 16:34:15 -0700199 } else if (shorty == "V") {
200 typedef void (fnptr)(JNIEnv*, jclass);
201 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
202 ScopedLocalRef<jclass> klass(soa.Env(),
203 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
204 ScopedThreadStateChange tsc(self, kNative);
205 fn(soa.Env(), klass.get());
206 } else if (shorty == "Z") {
207 typedef jboolean (fnptr)(JNIEnv*, jclass);
208 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
209 ScopedLocalRef<jclass> klass(soa.Env(),
210 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
211 ScopedThreadStateChange tsc(self, kNative);
212 result->SetZ(fn(soa.Env(), klass.get()));
213 } else if (shorty == "BI") {
214 typedef jbyte (fnptr)(JNIEnv*, jclass, jint);
215 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
216 ScopedLocalRef<jclass> klass(soa.Env(),
217 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
218 ScopedThreadStateChange tsc(self, kNative);
219 result->SetB(fn(soa.Env(), klass.get(), args[0].GetI()));
220 } else if (shorty == "II") {
221 typedef jint (fnptr)(JNIEnv*, jclass, jint);
222 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
223 ScopedLocalRef<jclass> klass(soa.Env(),
224 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
225 ScopedThreadStateChange tsc(self, kNative);
226 result->SetI(fn(soa.Env(), klass.get(), args[0].GetI()));
227 } else if (shorty == "LL") {
228 typedef jobject (fnptr)(JNIEnv*, jclass, jobject);
229 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
230 ScopedLocalRef<jclass> klass(soa.Env(),
231 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
232 ScopedLocalRef<jobject> arg0(soa.Env(),
233 soa.AddLocalReference<jobject>(args[0].GetL()));
Ian Rogers556d6372012-11-20 12:19:36 -0800234 jobject jresult;
235 {
236 ScopedThreadStateChange tsc(self, kNative);
237 jresult = fn(soa.Env(), klass.get(), arg0.get());
238 }
239 result->SetL(soa.Decode<Object*>(jresult));
Ian Rogers64b6d142012-10-29 16:34:15 -0700240 } else if (shorty == "IIZ") {
241 typedef jint (fnptr)(JNIEnv*, jclass, jint, jboolean);
242 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
243 ScopedLocalRef<jclass> klass(soa.Env(),
244 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
245 ScopedThreadStateChange tsc(self, kNative);
246 result->SetI(fn(soa.Env(), klass.get(), args[0].GetI(), args[1].GetZ()));
247 } else if (shorty == "ILI") {
248 typedef jint (fnptr)(JNIEnv*, jclass, jobject, jint);
249 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
250 ScopedLocalRef<jclass> klass(soa.Env(),
251 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
252 ScopedLocalRef<jobject> arg0(soa.Env(),
253 soa.AddLocalReference<jobject>(args[0].GetL()));
254 ScopedThreadStateChange tsc(self, kNative);
255 result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1].GetI()));
256 } else if (shorty == "SIZ") {
257 typedef jshort (fnptr)(JNIEnv*, jclass, jint, jboolean);
258 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
259 ScopedLocalRef<jclass> klass(soa.Env(),
260 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
261 ScopedThreadStateChange tsc(self, kNative);
262 result->SetS(fn(soa.Env(), klass.get(), args[0].GetI(), args[1].GetZ()));
263 } else if (shorty == "VIZ") {
264 typedef void (fnptr)(JNIEnv*, jclass, jint, jboolean);
265 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
266 ScopedLocalRef<jclass> klass(soa.Env(),
267 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
268 ScopedThreadStateChange tsc(self, kNative);
269 fn(soa.Env(), klass.get(), args[0].GetI(), args[1].GetZ());
270 } else if (shorty == "ZLL") {
271 typedef jboolean (fnptr)(JNIEnv*, jclass, jobject, jobject);
272 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
273 ScopedLocalRef<jclass> klass(soa.Env(),
274 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
275 ScopedLocalRef<jobject> arg0(soa.Env(),
276 soa.AddLocalReference<jobject>(args[0].GetL()));
277 ScopedLocalRef<jobject> arg1(soa.Env(),
278 soa.AddLocalReference<jobject>(args[1].GetL()));
279 ScopedThreadStateChange tsc(self, kNative);
280 result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get()));
281 } else if (shorty == "ZILL") {
282 typedef jboolean (fnptr)(JNIEnv*, jclass, jint, jobject, jobject);
283 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
284 ScopedLocalRef<jclass> klass(soa.Env(),
285 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
286 ScopedLocalRef<jobject> arg1(soa.Env(),
287 soa.AddLocalReference<jobject>(args[1].GetL()));
288 ScopedLocalRef<jobject> arg2(soa.Env(),
289 soa.AddLocalReference<jobject>(args[2].GetL()));
290 ScopedThreadStateChange tsc(self, kNative);
291 result->SetZ(fn(soa.Env(), klass.get(), args[0].GetI(), arg1.get(), arg2.get()));
292 } else if (shorty == "VILII") {
293 typedef void (fnptr)(JNIEnv*, jclass, jint, jobject, jint, jint);
294 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
295 ScopedLocalRef<jclass> klass(soa.Env(),
296 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
297 ScopedLocalRef<jobject> arg1(soa.Env(),
298 soa.AddLocalReference<jobject>(args[1].GetL()));
299 ScopedThreadStateChange tsc(self, kNative);
300 fn(soa.Env(), klass.get(), args[0].GetI(), arg1.get(), args[2].GetI(), args[3].GetI());
301 } else if (shorty == "VLILII") {
302 typedef void (fnptr)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint);
303 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
304 ScopedLocalRef<jclass> klass(soa.Env(),
305 soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
306 ScopedLocalRef<jobject> arg0(soa.Env(),
307 soa.AddLocalReference<jobject>(args[0].GetL()));
308 ScopedLocalRef<jobject> arg2(soa.Env(),
309 soa.AddLocalReference<jobject>(args[2].GetL()));
310 ScopedThreadStateChange tsc(self, kNative);
311 fn(soa.Env(), klass.get(), arg0.get(), args[1].GetI(), arg2.get(), args[3].GetI(),
312 args[4].GetI());
313 } else {
314 LOG(FATAL) << "Do something with static native method: " << PrettyMethod(method)
315 << " shorty: " << shorty;
316 }
317 } else {
318 if (shorty == "L") {
319 typedef jobject (fnptr)(JNIEnv*, jobject);
320 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
321 ScopedLocalRef<jobject> rcvr(soa.Env(),
322 soa.AddLocalReference<jobject>(receiver));
Ian Rogers556d6372012-11-20 12:19:36 -0800323 jobject jresult;
324 {
325 ScopedThreadStateChange tsc(self, kNative);
326 jresult = fn(soa.Env(), rcvr.get());
327 }
328 result->SetL(soa.Decode<Object*>(jresult));
Ian Rogers64b6d142012-10-29 16:34:15 -0700329 } else if (shorty == "LL") {
330 typedef jobject (fnptr)(JNIEnv*, jobject, jobject);
331 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
332 ScopedLocalRef<jobject> rcvr(soa.Env(),
333 soa.AddLocalReference<jobject>(receiver));
334 ScopedLocalRef<jobject> arg0(soa.Env(),
335 soa.AddLocalReference<jobject>(args[0].GetL()));
Ian Rogers556d6372012-11-20 12:19:36 -0800336 jobject jresult;
337 {
338 ScopedThreadStateChange tsc(self, kNative);
339 jresult = fn(soa.Env(), rcvr.get(), arg0.get());
340
341 }
342 result->SetL(soa.Decode<Object*>(jresult));
Ian Rogers64b6d142012-10-29 16:34:15 -0700343 ScopedThreadStateChange tsc(self, kNative);
Ian Rogers64b6d142012-10-29 16:34:15 -0700344 } else if (shorty == "III") {
345 typedef jint (fnptr)(JNIEnv*, jobject, jint, jint);
346 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
347 ScopedLocalRef<jobject> rcvr(soa.Env(),
348 soa.AddLocalReference<jobject>(receiver));
349 ScopedThreadStateChange tsc(self, kNative);
350 result->SetI(fn(soa.Env(), rcvr.get(), args[0].GetI(), args[1].GetI()));
351 } else {
352 LOG(FATAL) << "Do something with native method: " << PrettyMethod(method)
353 << " shorty: " << shorty;
354 }
355 }
356}
357
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700358static void DoMonitorEnter(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS {
359 ref->MonitorEnter(self);
360}
361
362static void DoMonitorExit(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS {
363 ref->MonitorExit(self);
364}
365
366static void DoInvoke(Thread* self, MethodHelper& mh, ShadowFrame& shadow_frame,
367 const DecodedInstruction& dec_insn, InvokeType type, bool is_range,
368 JValue* result)
369 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
370 Object* receiver;
371 if (type == kStatic) {
372 receiver = NULL;
373 } else {
374 receiver = shadow_frame.GetReference(dec_insn.vC);
375 if (UNLIKELY(receiver == NULL)) {
376 ThrowNullPointerExceptionForMethodAccess(shadow_frame.GetMethod(), dec_insn.vB, type);
377 result->SetJ(0);
378 return;
379 }
380 }
381 uint32_t method_idx = dec_insn.vB;
382 AbstractMethod* target_method = FindMethodFromCode(method_idx, receiver,
383 shadow_frame.GetMethod(), self, true,
384 type);
385 if (UNLIKELY(target_method == NULL)) {
386 CHECK(self->IsExceptionPending());
387 result->SetJ(0);
388 return;
389 }
390 mh.ChangeMethod(target_method);
391 ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
392 if (is_range) {
393 arg_array.BuildArgArray(shadow_frame, dec_insn.vC + (type != kStatic ? 1 : 0));
394 } else {
395 arg_array.BuildArgArray(shadow_frame, dec_insn.arg + (type != kStatic ? 1 : 0));
396 }
Ian Rogers64b6d142012-10-29 16:34:15 -0700397 if (LIKELY(Runtime::Current()->IsStarted())) {
398 target_method->Invoke(self, receiver, arg_array.get(), result);
399 } else {
400 UnstartedRuntimeInvoke(self, target_method, receiver, arg_array.get(), result);
401 }
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700402 if (!mh.GetReturnType()->IsPrimitive() && result->GetL() != NULL) {
403 CHECK(mh.GetReturnType()->IsAssignableFrom(result->GetL()->GetClass()));
404 }
405 mh.ChangeMethod(shadow_frame.GetMethod());
406}
407
408static void DoFieldGet(Thread* self, ShadowFrame& shadow_frame,
409 const DecodedInstruction& dec_insn, FindFieldType find_type,
410 Primitive::Type field_type)
411 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
412 bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead);
413 uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC;
414 Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
415 find_type, Primitive::FieldSize(field_type));
416 if (LIKELY(f != NULL)) {
417 Object* obj;
418 if (is_static) {
419 obj = f->GetDeclaringClass();
420 } else {
421 obj = shadow_frame.GetReference(dec_insn.vB);
422 if (UNLIKELY(obj == NULL)) {
423 ThrowNullPointerExceptionForFieldAccess(f, true);
424 }
425 }
426 switch (field_type) {
427 case Primitive::kPrimBoolean:
428 shadow_frame.SetVReg(dec_insn.vA, f->GetBoolean(obj));
429 break;
430 case Primitive::kPrimByte:
431 shadow_frame.SetVReg(dec_insn.vA, f->GetByte(obj));
432 break;
433 case Primitive::kPrimChar:
434 shadow_frame.SetVReg(dec_insn.vA, f->GetChar(obj));
435 break;
436 case Primitive::kPrimShort:
437 shadow_frame.SetVReg(dec_insn.vA, f->GetShort(obj));
438 break;
439 case Primitive::kPrimInt:
440 shadow_frame.SetVReg(dec_insn.vA, f->GetInt(obj));
441 break;
442 case Primitive::kPrimLong:
443 shadow_frame.SetVRegLong(dec_insn.vA, f->GetLong(obj));
444 break;
445 case Primitive::kPrimNot:
446 shadow_frame.SetReferenceAndVReg(dec_insn.vA, f->GetObject(obj));
447 break;
448 default:
449 LOG(FATAL) << "Unreachable: " << field_type;
450 }
451 }
452}
453
454static void DoFieldPut(Thread* self, ShadowFrame& shadow_frame,
455 const DecodedInstruction& dec_insn, FindFieldType find_type,
456 Primitive::Type field_type)
457 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
458 bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite);
459 uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC;
460 Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
461 find_type, Primitive::FieldSize(field_type));
462 if (LIKELY(f != NULL)) {
463 Object* obj;
464 if (is_static) {
465 obj = f->GetDeclaringClass();
466 } else {
467 obj = shadow_frame.GetReference(dec_insn.vB);
468 if (UNLIKELY(obj == NULL)) {
469 ThrowNullPointerExceptionForFieldAccess(f, false);
470 }
471 }
472 switch (field_type) {
473 case Primitive::kPrimBoolean:
474 f->SetBoolean(obj, shadow_frame.GetVReg(dec_insn.vA));
475 break;
476 case Primitive::kPrimByte:
477 f->SetByte(obj, shadow_frame.GetVReg(dec_insn.vA));
478 shadow_frame.SetVReg(dec_insn.vA, f->GetByte(obj));
479 break;
480 case Primitive::kPrimChar:
481 f->SetChar(obj, shadow_frame.GetVReg(dec_insn.vA));
482 shadow_frame.SetVReg(dec_insn.vA, f->GetChar(obj));
483 break;
484 case Primitive::kPrimShort:
485 f->SetShort(obj, shadow_frame.GetVReg(dec_insn.vA));
486 shadow_frame.SetVReg(dec_insn.vA, f->GetShort(obj));
487 break;
488 case Primitive::kPrimInt:
489 f->SetInt(obj, shadow_frame.GetVReg(dec_insn.vA));
490 shadow_frame.SetVReg(dec_insn.vA, f->GetInt(obj));
491 break;
492 case Primitive::kPrimLong:
493 f->SetLong(obj, shadow_frame.GetVRegLong(dec_insn.vA));
494 shadow_frame.SetVRegLong(dec_insn.vA, f->GetLong(obj));
495 break;
496 case Primitive::kPrimNot:
497 f->SetObj(obj, shadow_frame.GetReference(dec_insn.vA));
498 break;
499 default:
500 LOG(FATAL) << "Unreachable: " << field_type;
501 }
502 }
503}
504
505static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
506 ShadowFrame& shadow_frame) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
507 const uint16_t* insns = code_item->insns_;
508 const Instruction* inst = Instruction::At(insns + shadow_frame.GetDexPC());
509 JValue result_register;
510 while (true) {
511 shadow_frame.SetDexPC(inst->GetDexPc(insns));
512 DecodedInstruction dec_insn(inst);
Ian Rogers64b6d142012-10-29 16:34:15 -0700513 const bool kTracing = false;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700514 if (kTracing) {
515 LOG(INFO) << PrettyMethod(shadow_frame.GetMethod())
516 << StringPrintf("\n0x%x: %s\nReferences:",
517 inst->GetDexPc(insns), inst->DumpString(&mh.GetDexFile()).c_str());
518 for (size_t i = 0; i < shadow_frame.NumberOfReferences(); ++i) {
519 Object* o = shadow_frame.GetReference(i);
520 if (o != NULL) {
521 if (o->GetClass()->IsStringClass() && o->AsString()->GetCharArray() != NULL) {
522 LOG(INFO) << i << ": java.lang.String " << static_cast<void*>(o)
523 << " \"" << o->AsString()->ToModifiedUtf8() << "\"";
524 } else {
525 LOG(INFO) << i << ": " << PrettyTypeOf(o) << " " << static_cast<void*>(o);
526 }
527 } else {
528 LOG(INFO) << i << ": null";
529 }
530 }
531 LOG(INFO) << "vregs:";
532 for (size_t i = 0; i < shadow_frame.NumberOfReferences(); ++i) {
533 LOG(INFO) << StringPrintf("%d: %08x", i, shadow_frame.GetVReg(i));
534 }
535 }
536 const Instruction* next_inst = inst->Next();
537 switch (dec_insn.opcode) {
538 case Instruction::NOP:
539 break;
540 case Instruction::MOVE:
541 case Instruction::MOVE_FROM16:
542 case Instruction::MOVE_16:
543 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
544 break;
545 case Instruction::MOVE_WIDE:
546 case Instruction::MOVE_WIDE_FROM16:
547 case Instruction::MOVE_WIDE_16:
548 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
549 break;
550 case Instruction::MOVE_OBJECT:
551 case Instruction::MOVE_OBJECT_FROM16:
552 case Instruction::MOVE_OBJECT_16:
553 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
554 shadow_frame.SetReference(dec_insn.vA, shadow_frame.GetReference(dec_insn.vB));
555 break;
556 case Instruction::MOVE_RESULT:
557 shadow_frame.SetVReg(dec_insn.vA, result_register.GetI());
558 break;
559 case Instruction::MOVE_RESULT_WIDE:
560 shadow_frame.SetVRegLong(dec_insn.vA, result_register.GetJ());
561 break;
562 case Instruction::MOVE_RESULT_OBJECT:
563 shadow_frame.SetReferenceAndVReg(dec_insn.vA, result_register.GetL());
564 break;
565 case Instruction::MOVE_EXCEPTION: {
566 Throwable* exception = self->GetException();
567 self->ClearException();
568 shadow_frame.SetReferenceAndVReg(dec_insn.vA, exception);
569 break;
570 }
571 case Instruction::RETURN_VOID: {
572 JValue result;
573 result.SetJ(0);
574 return result;
575 }
576 case Instruction::RETURN: {
577 JValue result;
578 result.SetJ(0);
579 result.SetI(shadow_frame.GetVReg(dec_insn.vA));
580 return result;
581 }
582 case Instruction::RETURN_WIDE: {
583 JValue result;
584 result.SetJ(shadow_frame.GetVRegLong(dec_insn.vA));
585 return result;
586 }
587 case Instruction::RETURN_OBJECT: {
588 JValue result;
589 result.SetJ(0);
590 result.SetL(shadow_frame.GetReference(dec_insn.vA));
591 return result;
592 }
593 case Instruction::CONST_4: {
Ian Rogers64b6d142012-10-29 16:34:15 -0700594 int32_t val = static_cast<int32_t>(dec_insn.vB << 28) >> 28;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700595 shadow_frame.SetVReg(dec_insn.vA, val);
596 if (val == 0) {
597 shadow_frame.SetReference(dec_insn.vA, NULL);
598 }
599 break;
600 }
601 case Instruction::CONST_16: {
602 int32_t val = static_cast<int16_t>(dec_insn.vB);
603 shadow_frame.SetVReg(dec_insn.vA, val);
604 if (val == 0) {
605 shadow_frame.SetReference(dec_insn.vA, NULL);
606 }
607 break;
608 }
609 case Instruction::CONST: {
610 int32_t val = dec_insn.vB;
611 shadow_frame.SetVReg(dec_insn.vA, val);
612 if (val == 0) {
613 shadow_frame.SetReference(dec_insn.vA, NULL);
614 }
615 break;
616 }
617 case Instruction::CONST_HIGH16: {
618 int32_t val = dec_insn.vB << 16;
619 shadow_frame.SetVReg(dec_insn.vA, val);
620 if (val == 0) {
621 shadow_frame.SetReference(dec_insn.vA, NULL);
622 }
623 break;
624 }
Ian Rogers64b6d142012-10-29 16:34:15 -0700625 case Instruction::CONST_WIDE_16:
626 shadow_frame.SetVRegLong(dec_insn.vA, static_cast<int16_t>(dec_insn.vB));
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700627 break;
Ian Rogers64b6d142012-10-29 16:34:15 -0700628 case Instruction::CONST_WIDE_32:
629 shadow_frame.SetVRegLong(dec_insn.vA, static_cast<int32_t>(dec_insn.vB));
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700630 break;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700631 case Instruction::CONST_WIDE:
Ian Rogers64b6d142012-10-29 16:34:15 -0700632 shadow_frame.SetVRegLong(dec_insn.vA, dec_insn.vB_wide);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700633 break;
634 case Instruction::CONST_WIDE_HIGH16:
Ian Rogers64b6d142012-10-29 16:34:15 -0700635 shadow_frame.SetVRegLong(dec_insn.vA, static_cast<uint64_t>(dec_insn.vB) << 48);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700636 break;
637 case Instruction::CONST_STRING:
638 case Instruction::CONST_STRING_JUMBO: {
639 if (UNLIKELY(!String::GetJavaLangString()->IsInitialized())) {
640 Runtime::Current()->GetClassLinker()->EnsureInitialized(String::GetJavaLangString(),
641 true, true);
642 }
643 String* s = mh.ResolveString(dec_insn.vB);
644 shadow_frame.SetReferenceAndVReg(dec_insn.vA, s);
645 break;
646 }
647 case Instruction::CONST_CLASS:
648 shadow_frame.SetReference(dec_insn.vA, mh.ResolveClass(dec_insn.vB));
649 break;
650 case Instruction::MONITOR_ENTER:
651 DoMonitorEnter(self, shadow_frame.GetReference(dec_insn.vA));
652 break;
653 case Instruction::MONITOR_EXIT:
654 DoMonitorExit(self, shadow_frame.GetReference(dec_insn.vA));
655 break;
656 case Instruction::CHECK_CAST: {
657 Class* c = mh.ResolveClass(dec_insn.vB);
658 Object* obj = shadow_frame.GetReference(dec_insn.vA);
659 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
660 self->ThrowNewExceptionF("Ljava/lang/ClassCastException;",
661 "%s cannot be cast to %s",
662 PrettyDescriptor(obj->GetClass()).c_str(),
663 PrettyDescriptor(c).c_str());
664 }
665 break;
666 }
667 case Instruction::INSTANCE_OF: {
668 Class* c = mh.ResolveClass(dec_insn.vC);
669 Object* obj = shadow_frame.GetReference(dec_insn.vB);
670 shadow_frame.SetVReg(dec_insn.vA, (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
671 break;
672 }
673 case Instruction::ARRAY_LENGTH: {
Ian Rogers64b6d142012-10-29 16:34:15 -0700674 Object* array = shadow_frame.GetReference(dec_insn.vB);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700675 if (UNLIKELY(array == NULL)) {
676 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
677 break;
678 }
Ian Rogers64b6d142012-10-29 16:34:15 -0700679 shadow_frame.SetVReg(dec_insn.vA, array->AsArray()->GetLength());
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700680 break;
681 }
682 case Instruction::NEW_INSTANCE: {
683 Object* obj = AllocObjectFromCode(dec_insn.vB, shadow_frame.GetMethod(), self, true);
684 shadow_frame.SetReferenceAndVReg(dec_insn.vA, obj);
685 break;
686 }
687 case Instruction::NEW_ARRAY: {
688 int32_t length = shadow_frame.GetVReg(dec_insn.vB);
689 Object* obj = AllocArrayFromCode(dec_insn.vC, shadow_frame.GetMethod(), length, self, true);
690 shadow_frame.SetReferenceAndVReg(dec_insn.vA, obj);
691 break;
692 }
693 case Instruction::FILLED_NEW_ARRAY:
Ian Rogers64b6d142012-10-29 16:34:15 -0700694 case Instruction::FILLED_NEW_ARRAY_RANGE: {
695 bool is_range = (dec_insn.opcode == Instruction::FILLED_NEW_ARRAY_RANGE);
696 int32_t length = dec_insn.vA;
697 CHECK(is_range || length <= 5);
698 Class* arrayClass = mh.ResolveClass(dec_insn.vB);
699 CHECK(arrayClass->IsArrayClass());
700 if (arrayClass->GetComponentType()->IsPrimitiveInt()) {
701 IntArray* newArray = IntArray::Alloc(self, length);
702 if (newArray != NULL) {
703 for (int32_t i = 0; i < length; ++i) {
704 if (is_range) {
705 newArray->Set(i, shadow_frame.GetVReg(dec_insn.vC + i));
706 } else {
707 newArray->Set(i, shadow_frame.GetVReg(dec_insn.arg[i]));
708 }
709 }
710 }
711 result_register.SetL(newArray);
712 } else {
713 UNIMPLEMENTED(FATAL) << inst->DumpString(&mh.GetDexFile())
714 << " for array type: " << PrettyDescriptor(arrayClass);
715 }
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700716 break;
Ian Rogers64b6d142012-10-29 16:34:15 -0700717 }
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700718 case Instruction::CMPL_FLOAT: {
719 float val1 = shadow_frame.GetVRegFloat(dec_insn.vB);
720 float val2 = shadow_frame.GetVRegFloat(dec_insn.vC);
721 int32_t result;
722 if (val1 == val2) {
723 result = 0;
724 } else if (val1 > val2) {
725 result = 1;
726 } else {
727 result = -1;
728 }
729 shadow_frame.SetVReg(dec_insn.vA, result);
730 break;
731 }
732 case Instruction::CMPG_FLOAT: {
733 float val1 = shadow_frame.GetVRegFloat(dec_insn.vB);
734 float val2 = shadow_frame.GetVRegFloat(dec_insn.vC);
735 int32_t result;
736 if (val1 == val2) {
737 result = 0;
738 } else if (val1 < val2) {
739 result = -1;
740 } else {
741 result = 1;
742 }
743 shadow_frame.SetVReg(dec_insn.vA, result);
744 break;
745 }
746 case Instruction::CMPL_DOUBLE: {
747 double val1 = shadow_frame.GetVRegDouble(dec_insn.vB);
748 double val2 = shadow_frame.GetVRegDouble(dec_insn.vC);
749 int32_t result;
750 if (val1 == val2) {
751 result = 0;
Ian Rogers64b6d142012-10-29 16:34:15 -0700752 } else if (val1 < val2) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700753 result = 1;
754 } else {
755 result = -1;
756 }
757 shadow_frame.SetVReg(dec_insn.vA, result);
758 break;
759 }
760
761 case Instruction::CMPG_DOUBLE: {
762 double val1 = shadow_frame.GetVRegDouble(dec_insn.vB);
763 double val2 = shadow_frame.GetVRegDouble(dec_insn.vC);
764 int32_t result;
765 if (val1 == val2) {
766 result = 0;
Ian Rogers64b6d142012-10-29 16:34:15 -0700767 } else if (val1 > val2) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700768 result = -1;
769 } else {
770 result = 1;
771 }
772 shadow_frame.SetVReg(dec_insn.vA, result);
773 break;
774 }
775 case Instruction::CMP_LONG: {
776 int64_t val1 = shadow_frame.GetVRegLong(dec_insn.vB);
777 int64_t val2 = shadow_frame.GetVRegLong(dec_insn.vC);
778 int32_t result;
779 if (val1 < val2) {
Ian Rogers64b6d142012-10-29 16:34:15 -0700780 result = 1;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700781 } else if (val1 == val2) {
782 result = 0;
783 } else {
Ian Rogers64b6d142012-10-29 16:34:15 -0700784 result = -1;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700785 }
786 shadow_frame.SetVReg(dec_insn.vA, result);
787 break;
788 }
789 case Instruction::THROW: {
790 Throwable* t = shadow_frame.GetReference(dec_insn.vA)->AsThrowable();
791 self->SetException(t);
792 break;
793 }
794 case Instruction::GOTO:
795 case Instruction::GOTO_16:
796 case Instruction::GOTO_32: {
797 uint32_t dex_pc = inst->GetDexPc(insns);
798 next_inst = Instruction::At(insns + dex_pc + dec_insn.vA);
799 break;
800 }
Ian Rogers556d6372012-11-20 12:19:36 -0800801 case Instruction::PACKED_SWITCH: {
802 uint32_t dex_pc = inst->GetDexPc(insns);
803 const uint16_t* switch_data = insns + dex_pc + dec_insn.vB;
804 int32_t test_val = shadow_frame.GetVReg(dec_insn.vA);
805 CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature));
806 uint16_t size = switch_data[1];
807 CHECK_GT(size, 0);
808 const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]);
809 CHECK(IsAligned<4>(keys));
810 int32_t first_key = keys[0];
811 const int32_t* targets = reinterpret_cast<const int32_t*>(&switch_data[4]);
812 CHECK(IsAligned<4>(targets));
813 int32_t index = test_val - first_key;
814 if (index >= 0 && index < size) {
815 next_inst = Instruction::At(insns + dex_pc + targets[index]);
816 }
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700817 break;
Ian Rogers556d6372012-11-20 12:19:36 -0800818 }
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700819 case Instruction::SPARSE_SWITCH: {
820 uint32_t dex_pc = inst->GetDexPc(insns);
Ian Rogers556d6372012-11-20 12:19:36 -0800821 const uint16_t* switch_data = insns + dex_pc + dec_insn.vB;
822 int32_t test_val = shadow_frame.GetVReg(dec_insn.vA);
823 CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature));
824 uint16_t size = switch_data[1];
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700825 CHECK_GT(size, 0);
Ian Rogers556d6372012-11-20 12:19:36 -0800826 const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700827 CHECK(IsAligned<4>(keys));
828 const int32_t* entries = keys + size;
829 CHECK(IsAligned<4>(entries));
830 int lo = 0;
831 int hi = size - 1;
832 while (lo <= hi) {
833 int mid = (lo + hi) / 2;
834 int32_t foundVal = keys[mid];
Ian Rogers556d6372012-11-20 12:19:36 -0800835 if (test_val < foundVal) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700836 hi = mid - 1;
Ian Rogers556d6372012-11-20 12:19:36 -0800837 } else if (test_val > foundVal) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700838 lo = mid + 1;
839 } else {
840 next_inst = Instruction::At(insns + dex_pc + entries[mid]);
841 break;
842 }
843 }
844 break;
845 }
846 case Instruction::FILL_ARRAY_DATA: {
847 Array* array = shadow_frame.GetReference(dec_insn.vA)->AsArray();
848 if (UNLIKELY(array == NULL)) {
849 Thread::Current()->ThrowNewExceptionF("Ljava/lang/NullPointerException;",
850 "null array in FILL_ARRAY_DATA");
851 break;
852 }
853 DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
854 uint32_t dex_pc = inst->GetDexPc(insns);
855 const Instruction::ArrayDataPayload* payload =
856 reinterpret_cast<const Instruction::ArrayDataPayload*>(insns + dex_pc + dec_insn.vB);
857 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
858 Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
859 "failed FILL_ARRAY_DATA; length=%d, index=%d",
860 array->GetLength(), payload->element_count);
861 break;
862 }
863 uint32_t size_in_bytes = payload->element_count * payload->element_width;
864 memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes);
865 break;
866 }
867 case Instruction::IF_EQ: {
868 if (shadow_frame.GetVReg(dec_insn.vA) == shadow_frame.GetVReg(dec_insn.vB)) {
869 uint32_t dex_pc = inst->GetDexPc(insns);
870 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
871 }
872 break;
873 }
874 case Instruction::IF_NE: {
875 if (shadow_frame.GetVReg(dec_insn.vA) != shadow_frame.GetVReg(dec_insn.vB)) {
876 uint32_t dex_pc = inst->GetDexPc(insns);
877 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
878 }
879 break;
880 }
881 case Instruction::IF_LT: {
882 if (shadow_frame.GetVReg(dec_insn.vA) < shadow_frame.GetVReg(dec_insn.vB)) {
883 uint32_t dex_pc = inst->GetDexPc(insns);
884 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
885 }
886 break;
887 }
888 case Instruction::IF_GE: {
889 if (shadow_frame.GetVReg(dec_insn.vA) >= shadow_frame.GetVReg(dec_insn.vB)) {
890 uint32_t dex_pc = inst->GetDexPc(insns);
891 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
892 }
893 break;
894 }
895 case Instruction::IF_GT: {
896 if (shadow_frame.GetVReg(dec_insn.vA) > shadow_frame.GetVReg(dec_insn.vB)) {
897 uint32_t dex_pc = inst->GetDexPc(insns);
898 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
899 }
900 break;
901 }
902 case Instruction::IF_LE: {
903 if (shadow_frame.GetVReg(dec_insn.vA) <= shadow_frame.GetVReg(dec_insn.vB)) {
904 uint32_t dex_pc = inst->GetDexPc(insns);
905 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
906 }
907 break;
908 }
909 case Instruction::IF_EQZ: {
910 if (shadow_frame.GetVReg(dec_insn.vA) == 0) {
911 uint32_t dex_pc = inst->GetDexPc(insns);
912 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
913 }
914 break;
915 }
916 case Instruction::IF_NEZ: {
917 if (shadow_frame.GetVReg(dec_insn.vA) != 0) {
918 uint32_t dex_pc = inst->GetDexPc(insns);
919 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
920 }
921 break;
922 }
923 case Instruction::IF_LTZ: {
924 if (shadow_frame.GetVReg(dec_insn.vA) < 0) {
925 uint32_t dex_pc = inst->GetDexPc(insns);
926 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
927 }
928 break;
929 }
930 case Instruction::IF_GEZ: {
931 if (shadow_frame.GetVReg(dec_insn.vA) >= 0) {
932 uint32_t dex_pc = inst->GetDexPc(insns);
933 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
934 }
935 break;
936 }
937 case Instruction::IF_GTZ: {
938 if (shadow_frame.GetVReg(dec_insn.vA) > 0) {
939 uint32_t dex_pc = inst->GetDexPc(insns);
940 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
941 }
942 break;
943 }
944 case Instruction::IF_LEZ: {
945 if (shadow_frame.GetVReg(dec_insn.vA) <= 0) {
946 uint32_t dex_pc = inst->GetDexPc(insns);
947 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
948 }
949 break;
950 }
951 case Instruction::AGET_BOOLEAN: {
952 BooleanArray* a = shadow_frame.GetReference(dec_insn.vB)->AsBooleanArray();
953 if (UNLIKELY(a == NULL)) {
954 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
955 break;
956 }
957 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
958 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
959 break;
960 }
961 case Instruction::AGET_BYTE: {
962 ByteArray* a = shadow_frame.GetReference(dec_insn.vB)->AsByteArray();
963 if (UNLIKELY(a == NULL)) {
964 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
965 break;
966 }
967 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
968 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
969 break;
970 }
971 case Instruction::AGET_CHAR: {
972 CharArray* a = shadow_frame.GetReference(dec_insn.vB)->AsCharArray();
973 if (UNLIKELY(a == NULL)) {
974 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
975 break;
976 }
977 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
978 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
979 break;
980 }
981 case Instruction::AGET_SHORT: {
982 ShortArray* a = shadow_frame.GetReference(dec_insn.vB)->AsShortArray();
983 if (UNLIKELY(a == NULL)) {
984 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
985 break;
986 }
987 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
988 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
989 break;
990 }
991 case Instruction::AGET: {
992 IntArray* a = shadow_frame.GetReference(dec_insn.vB)->AsIntArray();
993 if (UNLIKELY(a == NULL)) {
994 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
995 break;
996 }
997 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
998 shadow_frame.SetVReg(dec_insn.vA, a->Get(index));
999 break;
1000 }
1001 case Instruction::AGET_WIDE: {
1002 LongArray* a = shadow_frame.GetReference(dec_insn.vB)->AsLongArray();
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 shadow_frame.SetVRegLong(dec_insn.vA, a->Get(index));
1009 break;
1010 }
1011 case Instruction::AGET_OBJECT: {
1012 ObjectArray<Object>* a = shadow_frame.GetReference(dec_insn.vB)->AsObjectArray<Object>();
1013 if (UNLIKELY(a == NULL)) {
1014 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
1015 break;
1016 }
1017 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
1018 Object* o = a->Get(index);
1019 shadow_frame.SetReferenceAndVReg(dec_insn.vA, o);
1020 break;
1021 }
1022 case Instruction::APUT_BOOLEAN: {
1023 uint8_t val = shadow_frame.GetVReg(dec_insn.vA);
1024 BooleanArray* a = shadow_frame.GetReference(dec_insn.vB)->AsBooleanArray();
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_BYTE: {
1034 int8_t val = shadow_frame.GetVReg(dec_insn.vA);
1035 ByteArray* a = shadow_frame.GetReference(dec_insn.vB)->AsByteArray();
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_CHAR: {
1045 uint16_t val = shadow_frame.GetVReg(dec_insn.vA);
1046 CharArray* a = shadow_frame.GetReference(dec_insn.vB)->AsCharArray();
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_SHORT: {
1056 int16_t val = shadow_frame.GetVReg(dec_insn.vA);
1057 ShortArray* a = shadow_frame.GetReference(dec_insn.vB)->AsShortArray();
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::APUT: {
1067 int32_t val = shadow_frame.GetVReg(dec_insn.vA);
1068 IntArray* a = shadow_frame.GetReference(dec_insn.vB)->AsIntArray();
1069 if (UNLIKELY(a == NULL)) {
1070 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
1071 break;
1072 }
1073 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
1074 a->Set(index, val);
1075 break;
1076 }
1077 case Instruction::APUT_WIDE: {
1078 int64_t val = shadow_frame.GetVRegLong(dec_insn.vA);
1079 LongArray* a = shadow_frame.GetReference(dec_insn.vB)->AsLongArray();
1080 if (UNLIKELY(a == NULL)) {
1081 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
1082 break;
1083 }
1084 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
1085 a->Set(index, val);
1086 break;
1087 }
1088 case Instruction::APUT_OBJECT: {
1089 Object* val = shadow_frame.GetReference(dec_insn.vA);
1090 ObjectArray<Object>* a = shadow_frame.GetReference(dec_insn.vB)->AsObjectArray<Object>();
1091 if (UNLIKELY(a == NULL)) {
1092 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetMethod(), inst->GetDexPc(insns));
1093 break;
1094 }
1095 int32_t index = shadow_frame.GetVReg(dec_insn.vC);
1096 a->Set(index, val);
1097 break;
1098 }
1099 case Instruction::IGET_BOOLEAN:
1100 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimBoolean);
1101 break;
1102 case Instruction::IGET_BYTE:
1103 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimByte);
1104 break;
1105 case Instruction::IGET_CHAR:
1106 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimChar);
1107 break;
1108 case Instruction::IGET_SHORT:
1109 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimShort);
1110 break;
1111 case Instruction::IGET:
1112 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimInt);
1113 break;
1114 case Instruction::IGET_WIDE:
1115 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimLong);
1116 break;
1117 case Instruction::IGET_OBJECT:
1118 DoFieldGet(self, shadow_frame, dec_insn, InstanceObjectRead, Primitive::kPrimNot);
1119 break;
1120 case Instruction::SGET_BOOLEAN:
1121 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimBoolean);
1122 break;
1123 case Instruction::SGET_BYTE:
1124 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimByte);
1125 break;
1126 case Instruction::SGET_CHAR:
1127 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimChar);
1128 break;
1129 case Instruction::SGET_SHORT:
1130 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimShort);
1131 break;
1132 case Instruction::SGET:
1133 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimInt);
1134 break;
1135 case Instruction::SGET_WIDE:
1136 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimLong);
1137 break;
1138 case Instruction::SGET_OBJECT:
1139 DoFieldGet(self, shadow_frame, dec_insn, StaticObjectRead, Primitive::kPrimNot);
1140 break;
1141 case Instruction::IPUT_BOOLEAN:
1142 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimBoolean);
1143 break;
1144 case Instruction::IPUT_BYTE:
1145 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimByte);
1146 break;
1147 case Instruction::IPUT_CHAR:
1148 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimChar);
1149 break;
1150 case Instruction::IPUT_SHORT:
1151 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimShort);
1152 break;
1153 case Instruction::IPUT:
1154 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimInt);
1155 break;
1156 case Instruction::IPUT_WIDE:
1157 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimLong);
1158 break;
1159 case Instruction::IPUT_OBJECT:
1160 DoFieldPut(self, shadow_frame, dec_insn, InstanceObjectWrite, Primitive::kPrimNot);
1161 break;
1162 case Instruction::SPUT_BOOLEAN:
1163 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimBoolean);
1164 break;
1165 case Instruction::SPUT_BYTE:
1166 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimByte);
1167 break;
1168 case Instruction::SPUT_CHAR:
1169 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimChar);
1170 break;
1171 case Instruction::SPUT_SHORT:
1172 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimShort);
1173 break;
1174 case Instruction::SPUT:
1175 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimInt);
1176 break;
1177 case Instruction::SPUT_WIDE:
1178 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimLong);
1179 break;
1180 case Instruction::SPUT_OBJECT:
1181 DoFieldPut(self, shadow_frame, dec_insn, StaticObjectWrite, Primitive::kPrimNot);
1182 break;
1183 case Instruction::INVOKE_VIRTUAL:
1184 DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, false, &result_register);
1185 break;
1186 case Instruction::INVOKE_VIRTUAL_RANGE:
1187 DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, true, &result_register);
1188 break;
1189 case Instruction::INVOKE_SUPER:
1190 DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, false, &result_register);
1191 break;
1192 case Instruction::INVOKE_SUPER_RANGE:
1193 DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, true, &result_register);
1194 break;
1195 case Instruction::INVOKE_DIRECT:
1196 DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, false, &result_register);
1197 break;
1198 case Instruction::INVOKE_DIRECT_RANGE:
1199 DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, true, &result_register);
1200 break;
1201 case Instruction::INVOKE_INTERFACE:
1202 DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, false, &result_register);
1203 break;
1204 case Instruction::INVOKE_INTERFACE_RANGE:
1205 DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, true, &result_register);
1206 break;
1207 case Instruction::INVOKE_STATIC:
1208 DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, false, &result_register);
1209 break;
1210 case Instruction::INVOKE_STATIC_RANGE:
1211 DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, true, &result_register);
1212 break;
1213 case Instruction::NEG_INT:
1214 shadow_frame.SetVReg(dec_insn.vA, -shadow_frame.GetVReg(dec_insn.vB));
1215 break;
1216 case Instruction::NOT_INT:
1217 shadow_frame.SetVReg(dec_insn.vA, 0 ^ shadow_frame.GetVReg(dec_insn.vB));
1218 break;
1219 case Instruction::NEG_LONG:
1220 shadow_frame.SetVRegLong(dec_insn.vA, -shadow_frame.GetVRegLong(dec_insn.vB));
1221 break;
1222 case Instruction::NOT_LONG:
1223 shadow_frame.SetVRegLong(dec_insn.vA, 0 ^ shadow_frame.GetVRegLong(dec_insn.vB));
1224 break;
1225 case Instruction::NEG_FLOAT:
1226 shadow_frame.SetVRegFloat(dec_insn.vA, -shadow_frame.GetVRegFloat(dec_insn.vB));
1227 break;
1228 case Instruction::NEG_DOUBLE:
1229 shadow_frame.SetVRegDouble(dec_insn.vA, -shadow_frame.GetVRegDouble(dec_insn.vB));
1230 break;
1231 case Instruction::INT_TO_LONG:
1232 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
1233 break;
1234 case Instruction::INT_TO_FLOAT:
1235 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
1236 break;
1237 case Instruction::INT_TO_DOUBLE:
1238 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
1239 break;
1240 case Instruction::LONG_TO_INT:
1241 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
1242 break;
1243 case Instruction::LONG_TO_FLOAT:
1244 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
1245 break;
1246 case Instruction::LONG_TO_DOUBLE:
1247 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
1248 break;
1249 case Instruction::FLOAT_TO_INT:
1250 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB));
1251 break;
1252 case Instruction::FLOAT_TO_LONG:
1253 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB));
1254 break;
1255 case Instruction::FLOAT_TO_DOUBLE:
1256 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB));
1257 break;
1258 case Instruction::DOUBLE_TO_INT:
1259 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB));
1260 break;
1261 case Instruction::DOUBLE_TO_LONG:
1262 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB));
1263 break;
1264 case Instruction::DOUBLE_TO_FLOAT:
1265 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB));
1266 break;
1267 case Instruction::INT_TO_BYTE:
1268 shadow_frame.SetVReg(dec_insn.vA, static_cast<int8_t>(shadow_frame.GetVReg(dec_insn.vB)));
1269 break;
1270 case Instruction::INT_TO_CHAR:
1271 shadow_frame.SetVReg(dec_insn.vA, static_cast<uint16_t>(shadow_frame.GetVReg(dec_insn.vB)));
1272 break;
1273 case Instruction::INT_TO_SHORT:
1274 shadow_frame.SetVReg(dec_insn.vA, static_cast<int16_t>(shadow_frame.GetVReg(dec_insn.vB)));
1275 break;
1276 case Instruction::ADD_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::SUB_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::MUL_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::REM_INT:
1289 shadow_frame.SetVReg(dec_insn.vA,
1290 shadow_frame.GetVReg(dec_insn.vB) % shadow_frame.GetVReg(dec_insn.vC));
1291 break;
1292 case Instruction::DIV_INT:
1293 shadow_frame.SetVReg(dec_insn.vA,
1294 shadow_frame.GetVReg(dec_insn.vB) / shadow_frame.GetVReg(dec_insn.vC));
1295 break;
1296 case Instruction::SHL_INT:
1297 shadow_frame.SetVReg(dec_insn.vA,
1298 shadow_frame.GetVReg(dec_insn.vB) << shadow_frame.GetVReg(dec_insn.vC));
1299 break;
1300 case Instruction::SHR_INT:
1301 shadow_frame.SetVReg(dec_insn.vA,
1302 shadow_frame.GetVReg(dec_insn.vB) >> shadow_frame.GetVReg(dec_insn.vC));
1303 break;
1304 case Instruction::USHR_INT:
1305 shadow_frame.SetVReg(dec_insn.vA,
1306 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >>
1307 shadow_frame.GetVReg(dec_insn.vC));
1308 break;
1309 case Instruction::AND_INT:
1310 shadow_frame.SetVReg(dec_insn.vA,
1311 shadow_frame.GetVReg(dec_insn.vB) & shadow_frame.GetVReg(dec_insn.vC));
1312 break;
1313 case Instruction::OR_INT:
1314 shadow_frame.SetVReg(dec_insn.vA,
1315 shadow_frame.GetVReg(dec_insn.vB) | shadow_frame.GetVReg(dec_insn.vC));
1316 break;
1317 case Instruction::XOR_INT:
1318 shadow_frame.SetVReg(dec_insn.vA,
1319 shadow_frame.GetVReg(dec_insn.vB) ^ shadow_frame.GetVReg(dec_insn.vC));
1320 break;
1321 case Instruction::ADD_LONG:
1322 shadow_frame.SetVRegLong(dec_insn.vA,
1323 shadow_frame.GetVRegLong(dec_insn.vB) +
1324 shadow_frame.GetVRegLong(dec_insn.vC));
1325 break;
1326 case Instruction::SUB_LONG:
1327 shadow_frame.SetVRegLong(dec_insn.vA,
1328 shadow_frame.GetVRegLong(dec_insn.vB) -
1329 shadow_frame.GetVRegLong(dec_insn.vC));
1330 break;
1331 case Instruction::MUL_LONG:
1332 shadow_frame.SetVRegLong(dec_insn.vA,
1333 shadow_frame.GetVRegLong(dec_insn.vB) *
1334 shadow_frame.GetVRegLong(dec_insn.vC));
1335 break;
1336 case Instruction::DIV_LONG:
1337 shadow_frame.SetVRegLong(dec_insn.vA,
1338 shadow_frame.GetVRegLong(dec_insn.vB) /
1339 shadow_frame.GetVRegLong(dec_insn.vC));
1340 break;
1341 case Instruction::REM_LONG:
1342 shadow_frame.SetVRegLong(dec_insn.vA,
1343 shadow_frame.GetVRegLong(dec_insn.vB) %
1344 shadow_frame.GetVRegLong(dec_insn.vC));
1345 break;
1346 case Instruction::AND_LONG:
1347 shadow_frame.SetVRegLong(dec_insn.vA,
1348 shadow_frame.GetVRegLong(dec_insn.vB) &
1349 shadow_frame.GetVRegLong(dec_insn.vC));
1350 break;
1351 case Instruction::OR_LONG:
1352 shadow_frame.SetVRegLong(dec_insn.vA,
1353 shadow_frame.GetVRegLong(dec_insn.vB) |
1354 shadow_frame.GetVRegLong(dec_insn.vC));
1355 break;
1356 case Instruction::XOR_LONG:
1357 shadow_frame.SetVRegLong(dec_insn.vA,
1358 shadow_frame.GetVRegLong(dec_insn.vB) ^
1359 shadow_frame.GetVRegLong(dec_insn.vC));
1360 break;
1361 case Instruction::SHL_LONG:
1362 shadow_frame.SetVRegLong(dec_insn.vA,
1363 shadow_frame.GetVRegLong(dec_insn.vB) <<
1364 shadow_frame.GetVReg(dec_insn.vC));
1365 break;
1366 case Instruction::SHR_LONG:
1367 shadow_frame.SetVRegLong(dec_insn.vA,
1368 shadow_frame.GetVRegLong(dec_insn.vB) >>
1369 shadow_frame.GetVReg(dec_insn.vC));
1370 break;
1371 case Instruction::USHR_LONG:
1372 shadow_frame.SetVRegLong(dec_insn.vA,
1373 static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vB)) >>
1374 shadow_frame.GetVReg(dec_insn.vC));
1375 break;
1376 case Instruction::ADD_FLOAT:
1377 shadow_frame.SetVRegFloat(dec_insn.vA,
1378 shadow_frame.GetVRegFloat(dec_insn.vB) +
1379 shadow_frame.GetVRegFloat(dec_insn.vC));
1380 break;
1381 case Instruction::SUB_FLOAT:
1382 shadow_frame.SetVRegFloat(dec_insn.vA,
1383 shadow_frame.GetVRegFloat(dec_insn.vB) -
1384 shadow_frame.GetVRegFloat(dec_insn.vC));
1385 break;
1386 case Instruction::MUL_FLOAT:
1387 shadow_frame.SetVRegFloat(dec_insn.vA,
1388 shadow_frame.GetVRegFloat(dec_insn.vB) *
1389 shadow_frame.GetVRegFloat(dec_insn.vC));
1390 break;
1391 case Instruction::DIV_FLOAT:
1392 shadow_frame.SetVRegFloat(dec_insn.vA,
1393 shadow_frame.GetVRegFloat(dec_insn.vB) /
1394 shadow_frame.GetVRegFloat(dec_insn.vC));
1395 break;
1396 case Instruction::REM_FLOAT:
1397 shadow_frame.SetVRegFloat(dec_insn.vA,
1398 fmodf(shadow_frame.GetVRegFloat(dec_insn.vB),
1399 shadow_frame.GetVRegFloat(dec_insn.vC)));
1400 break;
1401 case Instruction::ADD_DOUBLE:
1402 shadow_frame.SetVRegDouble(dec_insn.vA,
1403 shadow_frame.GetVRegDouble(dec_insn.vB) +
1404 shadow_frame.GetVRegDouble(dec_insn.vC));
1405 break;
1406 case Instruction::SUB_DOUBLE:
1407 shadow_frame.SetVRegDouble(dec_insn.vA,
1408 shadow_frame.GetVRegDouble(dec_insn.vB) -
1409 shadow_frame.GetVRegDouble(dec_insn.vC));
1410 break;
1411 case Instruction::MUL_DOUBLE:
1412 shadow_frame.SetVRegDouble(dec_insn.vA,
1413 shadow_frame.GetVRegDouble(dec_insn.vB) *
1414 shadow_frame.GetVRegDouble(dec_insn.vC));
1415 break;
1416 case Instruction::DIV_DOUBLE:
1417 shadow_frame.SetVRegDouble(dec_insn.vA,
1418 shadow_frame.GetVRegDouble(dec_insn.vB) /
1419 shadow_frame.GetVRegDouble(dec_insn.vC));
1420 break;
1421 case Instruction::REM_DOUBLE:
1422 shadow_frame.SetVRegDouble(dec_insn.vA,
1423 fmod(shadow_frame.GetVRegDouble(dec_insn.vB),
1424 shadow_frame.GetVRegDouble(dec_insn.vC)));
1425 break;
1426 case Instruction::ADD_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::SUB_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::MUL_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::REM_INT_2ADDR:
1439 shadow_frame.SetVReg(dec_insn.vA,
1440 shadow_frame.GetVReg(dec_insn.vA) % shadow_frame.GetVReg(dec_insn.vB));
1441 break;
1442 case Instruction::SHL_INT_2ADDR:
1443 shadow_frame.SetVReg(dec_insn.vA,
1444 shadow_frame.GetVReg(dec_insn.vA) << shadow_frame.GetVReg(dec_insn.vB));
1445 break;
1446 case Instruction::SHR_INT_2ADDR:
1447 shadow_frame.SetVReg(dec_insn.vA,
1448 shadow_frame.GetVReg(dec_insn.vA) >> shadow_frame.GetVReg(dec_insn.vB));
1449 break;
1450 case Instruction::USHR_INT_2ADDR:
1451 shadow_frame.SetVReg(dec_insn.vA,
1452 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vA)) >>
1453 shadow_frame.GetVReg(dec_insn.vB));
1454 break;
1455 case Instruction::AND_INT_2ADDR:
1456 shadow_frame.SetVReg(dec_insn.vA,
1457 shadow_frame.GetVReg(dec_insn.vA) & shadow_frame.GetVReg(dec_insn.vB));
1458 break;
1459 case Instruction::OR_INT_2ADDR:
1460 shadow_frame.SetVReg(dec_insn.vA,
1461 shadow_frame.GetVReg(dec_insn.vA) | shadow_frame.GetVReg(dec_insn.vB));
1462 break;
1463 case Instruction::XOR_INT_2ADDR:
1464 shadow_frame.SetVReg(dec_insn.vA,
1465 shadow_frame.GetVReg(dec_insn.vA) ^ shadow_frame.GetVReg(dec_insn.vB));
1466 break;
1467 case Instruction::DIV_INT_2ADDR:
1468 shadow_frame.SetVReg(dec_insn.vA,
1469 shadow_frame.GetVReg(dec_insn.vA) / shadow_frame.GetVReg(dec_insn.vB));
1470 break;
1471 case Instruction::ADD_LONG_2ADDR:
1472 shadow_frame.SetVRegLong(dec_insn.vA,
1473 shadow_frame.GetVRegLong(dec_insn.vA) +
1474 shadow_frame.GetVRegLong(dec_insn.vB));
1475 break;
1476 case Instruction::SUB_LONG_2ADDR:
1477 shadow_frame.SetVRegLong(dec_insn.vA,
1478 shadow_frame.GetVRegLong(dec_insn.vA) -
1479 shadow_frame.GetVRegLong(dec_insn.vB));
1480 break;
1481 case Instruction::MUL_LONG_2ADDR:
1482 shadow_frame.SetVRegLong(dec_insn.vA,
Ian Rogers64b6d142012-10-29 16:34:15 -07001483 shadow_frame.GetVRegLong(dec_insn.vA) *
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001484 shadow_frame.GetVRegLong(dec_insn.vB));
1485 break;
1486 case Instruction::DIV_LONG_2ADDR:
1487 shadow_frame.SetVRegLong(dec_insn.vA,
1488 shadow_frame.GetVRegLong(dec_insn.vA) /
1489 shadow_frame.GetVRegLong(dec_insn.vB));
1490 break;
1491 case Instruction::REM_LONG_2ADDR:
1492 shadow_frame.SetVRegLong(dec_insn.vA,
1493 shadow_frame.GetVRegLong(dec_insn.vA) %
1494 shadow_frame.GetVRegLong(dec_insn.vB));
1495 break;
1496 case Instruction::AND_LONG_2ADDR:
1497 shadow_frame.SetVRegLong(dec_insn.vA,
1498 shadow_frame.GetVRegLong(dec_insn.vA) &
1499 shadow_frame.GetVRegLong(dec_insn.vB));
1500 break;
1501 case Instruction::OR_LONG_2ADDR:
1502 shadow_frame.SetVRegLong(dec_insn.vA,
1503 shadow_frame.GetVRegLong(dec_insn.vA) |
1504 shadow_frame.GetVRegLong(dec_insn.vB));
1505 break;
1506 case Instruction::XOR_LONG_2ADDR:
1507 shadow_frame.SetVRegLong(dec_insn.vA,
1508 shadow_frame.GetVRegLong(dec_insn.vA) ^
1509 shadow_frame.GetVRegLong(dec_insn.vB));
1510 break;
1511 case Instruction::SHL_LONG_2ADDR:
1512 shadow_frame.SetVRegLong(dec_insn.vA,
1513 shadow_frame.GetVRegLong(dec_insn.vA) <<
1514 shadow_frame.GetVReg(dec_insn.vB));
1515 break;
1516 case Instruction::SHR_LONG_2ADDR:
1517 shadow_frame.SetVRegLong(dec_insn.vA,
1518 shadow_frame.GetVRegLong(dec_insn.vA) >>
1519 shadow_frame.GetVReg(dec_insn.vB));
1520 break;
1521 case Instruction::USHR_LONG_2ADDR:
1522 shadow_frame.SetVRegLong(dec_insn.vA,
1523 static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vA)) >>
1524 shadow_frame.GetVReg(dec_insn.vB));
1525 break;
1526 case Instruction::ADD_FLOAT_2ADDR:
1527 shadow_frame.SetVRegFloat(dec_insn.vA,
1528 shadow_frame.GetVRegFloat(dec_insn.vA) +
1529 shadow_frame.GetVRegFloat(dec_insn.vB));
1530 break;
1531 case Instruction::SUB_FLOAT_2ADDR:
1532 shadow_frame.SetVRegFloat(dec_insn.vA,
1533 shadow_frame.GetVRegFloat(dec_insn.vA) -
1534 shadow_frame.GetVRegFloat(dec_insn.vB));
1535 break;
1536 case Instruction::MUL_FLOAT_2ADDR:
1537 shadow_frame.SetVRegFloat(dec_insn.vA,
1538 shadow_frame.GetVRegFloat(dec_insn.vA) *
1539 shadow_frame.GetVRegFloat(dec_insn.vB));
1540 break;
1541 case Instruction::DIV_FLOAT_2ADDR:
1542 shadow_frame.SetVRegFloat(dec_insn.vA,
1543 shadow_frame.GetVRegFloat(dec_insn.vA) /
1544 shadow_frame.GetVRegFloat(dec_insn.vB));
1545 break;
1546 case Instruction::REM_FLOAT_2ADDR:
1547 shadow_frame.SetVRegFloat(dec_insn.vA,
1548 fmodf(shadow_frame.GetVRegFloat(dec_insn.vA),
1549 shadow_frame.GetVRegFloat(dec_insn.vB)));
1550 break;
1551 case Instruction::ADD_DOUBLE_2ADDR:
1552 shadow_frame.SetVRegDouble(dec_insn.vA,
1553 shadow_frame.GetVRegDouble(dec_insn.vA) +
1554 shadow_frame.GetVRegDouble(dec_insn.vB));
1555 break;
1556 case Instruction::SUB_DOUBLE_2ADDR:
1557 shadow_frame.SetVRegDouble(dec_insn.vA,
1558 shadow_frame.GetVRegDouble(dec_insn.vA) -
1559 shadow_frame.GetVRegDouble(dec_insn.vB));
1560 break;
1561 case Instruction::MUL_DOUBLE_2ADDR:
1562 shadow_frame.SetVRegDouble(dec_insn.vA,
1563 shadow_frame.GetVRegDouble(dec_insn.vA) *
1564 shadow_frame.GetVRegDouble(dec_insn.vB));
1565 break;
1566 case Instruction::DIV_DOUBLE_2ADDR:
1567 shadow_frame.SetVRegDouble(dec_insn.vA,
1568 shadow_frame.GetVRegDouble(dec_insn.vA) /
1569 shadow_frame.GetVRegDouble(dec_insn.vB));
1570 break;
1571 case Instruction::REM_DOUBLE_2ADDR:
1572 shadow_frame.SetVRegDouble(dec_insn.vA,
1573 fmod(shadow_frame.GetVRegDouble(dec_insn.vA),
1574 shadow_frame.GetVRegDouble(dec_insn.vB)));
1575 break;
1576 case Instruction::ADD_INT_LIT16:
1577 case Instruction::ADD_INT_LIT8:
1578 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) + dec_insn.vC);
1579 break;
1580 case Instruction::RSUB_INT:
1581 case Instruction::RSUB_INT_LIT8:
1582 shadow_frame.SetVReg(dec_insn.vA, dec_insn.vC - shadow_frame.GetVReg(dec_insn.vB));
1583 break;
1584 case Instruction::MUL_INT_LIT16:
1585 case Instruction::MUL_INT_LIT8:
1586 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) * dec_insn.vC);
1587 break;
1588 case Instruction::DIV_INT_LIT16:
1589 case Instruction::DIV_INT_LIT8:
1590 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) / dec_insn.vC);
1591 break;
1592 case Instruction::REM_INT_LIT16:
1593 case Instruction::REM_INT_LIT8:
1594 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) % dec_insn.vC);
1595 break;
1596 case Instruction::AND_INT_LIT16:
1597 case Instruction::AND_INT_LIT8:
1598 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) & dec_insn.vC);
1599 break;
1600 case Instruction::OR_INT_LIT16:
1601 case Instruction::OR_INT_LIT8:
1602 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) | dec_insn.vC);
1603 break;
1604 case Instruction::XOR_INT_LIT16:
1605 case Instruction::XOR_INT_LIT8:
1606 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) ^ dec_insn.vC);
1607 break;
1608 case Instruction::SHL_INT_LIT8:
1609 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) << dec_insn.vC);
1610 break;
1611 case Instruction::SHR_INT_LIT8:
1612 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) >> dec_insn.vC);
1613 break;
1614 case Instruction::USHR_INT_LIT8:
1615 shadow_frame.SetVReg(dec_insn.vA,
1616 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >>
1617 dec_insn.vC);
1618 break;
1619 default:
1620 LOG(FATAL) << "Unexpected instruction: " << inst->DumpString(&mh.GetDexFile());
1621 break;
1622 }
1623 if (UNLIKELY(self->IsExceptionPending())) {
1624 uint32_t found_dex_pc =
1625 shadow_frame.GetMethod()->FindCatchBlock(self->GetException()->GetClass(),
1626 inst->GetDexPc(insns));
1627 if (found_dex_pc == DexFile::kDexNoIndex) {
1628 JValue result;
1629 result.SetJ(0);
1630 return result; // Handler in caller.
1631 } else {
1632 next_inst = Instruction::At(insns + found_dex_pc);
1633 }
1634 }
1635 inst = next_inst;
1636 }
1637}
1638
1639void EnterInterpreterFromInvoke(Thread* self, AbstractMethod* method, Object* receiver,
1640 JValue* args, JValue* result) {
Ian Rogers64b6d142012-10-29 16:34:15 -07001641 DCHECK_EQ(self, Thread::Current());
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001642 MethodHelper mh(method);
1643 const DexFile::CodeItem* code_item = mh.GetCodeItem();
1644 uint16_t num_regs;
1645 uint16_t num_ins;
1646 if (code_item != NULL) {
1647 num_regs = code_item->registers_size_;
1648 num_ins = code_item->ins_size_;
1649 } else {
1650 DCHECK(method->IsNative());
1651 num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty());
1652 if (!method->IsStatic()) {
1653 num_regs++;
1654 num_ins++;
1655 }
1656 }
1657 // Set up shadow frame with matching number of reference slots to vregs.
1658 ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame();
1659 UniquePtr<ShadowFrame> shadow_frame(ShadowFrame::Create(num_regs, num_regs,
1660 (last_shadow_frame == NULL) ? NULL : last_shadow_frame->GetLink(),
1661 method, 0));
1662 self->PushShadowFrame(shadow_frame.get());
1663 size_t cur_reg = num_regs - num_ins;
1664 if (!method->IsStatic()) {
1665 CHECK(receiver != NULL);
1666 shadow_frame->SetReferenceAndVReg(cur_reg, receiver);
1667 ++cur_reg;
1668 } else if (!method->GetDeclaringClass()->IsInitializing()) {
1669 Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(),
1670 true, true);
1671 CHECK(method->GetDeclaringClass()->IsInitializing());
1672 }
Ian Rogers64b6d142012-10-29 16:34:15 -07001673 const char* shorty = mh.GetShorty();
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001674 size_t arg_pos = 0;
1675 for (; cur_reg < num_regs; ++cur_reg, ++arg_pos) {
1676 DCHECK_LT(arg_pos + 1, mh.GetShortyLength());
1677 switch (shorty[arg_pos + 1]) {
1678 case 'L': {
1679 Object* o = args[arg_pos].GetL();
1680 shadow_frame->SetReferenceAndVReg(cur_reg, o);
1681 break;
1682 }
1683 case 'J': case 'D':
1684 shadow_frame->SetVRegLong(cur_reg, args[arg_pos].GetJ());
1685 cur_reg++;
1686 break;
1687 default:
1688 shadow_frame->SetVReg(cur_reg, args[arg_pos].GetI());
1689 break;
1690 }
1691 }
Ian Rogers64b6d142012-10-29 16:34:15 -07001692 if (LIKELY(!method->IsNative())) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001693 JValue r = Execute(self, mh, code_item, *shadow_frame.get());
1694 if (result != NULL) {
1695 *result = r;
1696 }
1697 } else {
Ian Rogers64b6d142012-10-29 16:34:15 -07001698 // We don't expect to be asked to interpret native code (which is entered via a JNI compiler
1699 // generated stub) except during testing and image writing.
1700 if (!Runtime::Current()->IsStarted()) {
1701 UnstartedRuntimeJni(self, method, receiver, args, result);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001702 } else {
Ian Rogers64b6d142012-10-29 16:34:15 -07001703 InterpreterJni(self, method, shorty, receiver, args, result);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001704 }
1705 }
1706 self->PopShadowFrame();
1707}
1708
1709} // namespace interpreter
1710} // namespace art