12d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao/*
20f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Copyright (C) 2012 The Android Open Source Project
32d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao *
42d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
52d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * you may not use this file except in compliance with the License.
62d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * You may obtain a copy of the License at
72d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao *
82d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao *      http://www.apache.org/licenses/LICENSE-2.0
92d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao *
102d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * Unless required by applicable law or agreed to in writing, software
112d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
122d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * See the License for the specific language governing permissions and
142d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao * limitations under the License.
152d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao */
162d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao
177655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "entrypoints/entrypoint_utils.h"
182d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao
1998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang#include "base/mutex.h"
202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class_linker-inl.h"
214f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h"
221d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/accounting/card_table-inl.h"
23e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers#include "method_helper-inl.h"
24ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_field-inl.h"
25ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method-inl.h"
262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h"
272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h"
282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h"
29af6e67a4816d2593586115b89faa659225363246Ian Rogers#include "reflection.h"
30af6e67a4816d2593586115b89faa659225363246Ian Rogers#include "scoped_thread_state_change.h"
315bb8601175bbb9cd761c715f4ba04f84d65e913bTDYa#include "ScopedLocalRef.h"
32eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "well_known_classes.h"
335bb8601175bbb9cd761c715f4ba04f84d65e913bTDYa
3441005ddb5576b8630a1084fbb3979ffa602c0599jeffhaonamespace art {
3541005ddb5576b8630a1084fbb3979ffa602c0599jeffhao
36bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstromstatic inline mirror::Class* CheckFilledNewArrayAlloc(uint32_t type_idx,
37bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom                                                      mirror::ArtMethod* referrer,
38bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom                                                      int32_t component_count,
39bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom                                                      Thread* self,
40cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier                                                      bool access_check)
413b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
4257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  if (UNLIKELY(component_count < 0)) {
4362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    ThrowNegativeArraySizeException(component_count);
44cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier    return nullptr;  // Failure
45ea2a11d5f20814f17985ae3d4defc8dd843f19b9Ian Rogers  }
464ef12f5b0e26c6016c87866f6a33da5ed8e98d74Andreas Gampe  mirror::Class* klass = referrer->GetDexCacheResolvedType<false>(type_idx);
4757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  if (UNLIKELY(klass == NULL)) {  // Not in dex cache so try to resolve
4862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, referrer);
4957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    if (klass == NULL) {  // Error
5050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers      DCHECK(self->IsExceptionPending());
51cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier      return nullptr;  // Failure
52ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers    }
53ea2a11d5f20814f17985ae3d4defc8dd843f19b9Ian Rogers  }
5457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  if (UNLIKELY(klass->IsPrimitive() && !klass->IsPrimitiveInt())) {
5557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    if (klass->IsPrimitiveLong() || klass->IsPrimitiveDouble()) {
5662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      ThrowRuntimeException("Bad filled array request for type %s",
5762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                            PrettyDescriptor(klass).c_str());
58573db4a2077380d81fa74ee2309162530db87a98Ian Rogers    } else {
5962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      ThrowLocation throw_location = self->GetCurrentLocationForThrow();
6062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      DCHECK(throw_location.GetMethod() == referrer);
61bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom      self->ThrowNewExceptionF(
62bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom          throw_location, "Ljava/lang/InternalError;",
63bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom          "Found type %s; filled-new-array not implemented for anything but 'int'",
64bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom          PrettyDescriptor(klass).c_str());
65573db4a2077380d81fa74ee2309162530db87a98Ian Rogers    }
66cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier    return nullptr;  // Failure
673b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  }
683b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  if (access_check) {
693b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi    mirror::Class* referrer_klass = referrer->GetDeclaringClass();
703b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi    if (UNLIKELY(!referrer_klass->CanAccess(klass))) {
713b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi      ThrowIllegalAccessErrorClass(referrer_klass, klass);
72cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier      return nullptr;  // Failure
7357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers    }
74ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers  }
753b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  DCHECK(klass->IsArrayClass()) << PrettyClass(klass);
76cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier  return klass;
773b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi}
783b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi
793b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi// Helper function to allocate array for FILLED_NEW_ARRAY.
803b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchimirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, mirror::ArtMethod* referrer,
813b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi                                          int32_t component_count, Thread* self,
82cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier                                          bool access_check,
83e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier                                          gc::AllocatorType /* allocator_type */) {
84cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier  mirror::Class* klass = CheckFilledNewArrayAlloc(type_idx, referrer, component_count, self,
85cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier                                                  access_check);
86cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier  if (UNLIKELY(klass == nullptr)) {
87cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier    return nullptr;
883b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  }
89e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier  // Always go slow path for now, filled new array is not common.
90e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier  gc::Heap* heap = Runtime::Current()->GetHeap();
91e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier  // Use the current allocator type in case CheckFilledNewArrayAlloc caused us to suspend and then
92e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier  // the heap switched the allocator type while we were suspended.
936fac447555dc94a935b78198479cce645c837b89Ian Rogers  return mirror::Array::Alloc<false>(self, klass, component_count, klass->GetComponentSize(),
946fac447555dc94a935b78198479cce645c837b89Ian Rogers                                     heap->GetCurrentAllocator());
953b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi}
963b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi
973b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi// Helper function to allocate array for FILLED_NEW_ARRAY.
98bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrommirror::Array* CheckAndAllocArrayFromCodeInstrumented(uint32_t type_idx,
99bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom                                                      mirror::ArtMethod* referrer,
100bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom                                                      int32_t component_count,
101bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom                                                      Thread* self,
102cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier                                                      bool access_check,
103e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier                                                      gc::AllocatorType /* allocator_type */) {
104cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier  mirror::Class* klass = CheckFilledNewArrayAlloc(type_idx, referrer, component_count, self,
105cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier                                                  access_check);
106cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier  if (UNLIKELY(klass == nullptr)) {
107cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier    return nullptr;
1083b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  }
109e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier  gc::Heap* heap = Runtime::Current()->GetHeap();
110e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier  // Use the current allocator type in case CheckFilledNewArrayAlloc caused us to suspend and then
111e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier  // the heap switched the allocator type while we were suspended.
1126fac447555dc94a935b78198479cce645c837b89Ian Rogers  return mirror::Array::Alloc<true>(self, klass, component_count, klass->GetComponentSize(),
1136fac447555dc94a935b78198479cce645c837b89Ian Rogers                                    heap->GetCurrentAllocator());
114ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers}
115ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers
116d752132c73072084a3def9257cca4fcee76047b6jeffhaovoid ThrowStackOverflowError(Thread* self) {
1177571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom  if (self->IsHandlingStackOverflow()) {
1187ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    LOG(ERROR) << "Recursive stack overflow.";
1197ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    // We don't fail here because SetStackEndForStackOverflow will print better diagnostics.
1207571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom  }
12162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
122d752132c73072084a3def9257cca4fcee76047b6jeffhao  self->SetStackEndForStackOverflow();  // Allow space on the stack for constructor to execute.
123d752132c73072084a3def9257cca4fcee76047b6jeffhao  JNIEnvExt* env = self->GetJniEnv();
124d752132c73072084a3def9257cca4fcee76047b6jeffhao  std::string msg("stack size ");
125d752132c73072084a3def9257cca4fcee76047b6jeffhao  msg += PrettySize(self->GetStackSize());
1267ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe
1277ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe  // Avoid running Java code for exception initialization.
1287ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe  // TODO: Checks to make this a bit less brittle.
1297ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe
1307ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe  std::string error_msg;
1317ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe
1327ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe  // Allocate an uninitialized object.
1337ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe  ScopedLocalRef<jobject> exc(env,
1347ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe                              env->AllocObject(WellKnownClasses::java_lang_StackOverflowError));
1357ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe  if (exc.get() != nullptr) {
1367ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    // "Initialize".
1377ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    // StackOverflowError -> VirtualMachineError -> Error -> Throwable -> Object.
1387ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    // Only Throwable has "custom" fields:
1397ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    //   String detailMessage.
1407ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    //   Throwable cause (= this).
1417ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    //   List<Throwable> suppressedExceptions (= Collections.emptyList()).
1427ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    //   Object stackState;
1437ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    //   StackTraceElement[] stackTrace;
1447ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    // Only Throwable has a non-empty constructor:
1457ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    //   this.stackTrace = EmptyArray.STACK_TRACE_ELEMENT;
1467ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    //   fillInStackTrace();
1477ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe
1487ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    // detailMessage.
1497ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    // TODO: Use String::FromModifiedUTF...?
1507ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg.c_str()));
1517ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    if (s.get() != nullptr) {
152bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom      env->SetObjectField(exc.get(), WellKnownClasses::java_lang_Throwable_detailMessage, s.get());
1537ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe
1547ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      // cause.
155bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom      env->SetObjectField(exc.get(), WellKnownClasses::java_lang_Throwable_cause, exc.get());
1567ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe
1577ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      // suppressedExceptions.
1587ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      ScopedLocalRef<jobject> emptylist(env, env->GetStaticObjectField(
159bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom          WellKnownClasses::java_util_Collections,
160bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom          WellKnownClasses::java_util_Collections_EMPTY_LIST));
1617ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      CHECK(emptylist.get() != nullptr);
162bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom      env->SetObjectField(exc.get(),
163bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom                          WellKnownClasses::java_lang_Throwable_suppressedExceptions,
164bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom                          emptylist.get());
1657ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe
1667ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      // stackState is set as result of fillInStackTrace. fillInStackTrace calls
1677ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      // nativeFillInStackTrace.
1687ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      ScopedLocalRef<jobject> stack_state_val(env, nullptr);
1697ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      {
1707ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe        ScopedObjectAccessUnchecked soa(env);
1717ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe        stack_state_val.reset(soa.Self()->CreateInternalStackTrace<false>(soa));
1727ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      }
1737ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      if (stack_state_val.get() != nullptr) {
174bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom        env->SetObjectField(exc.get(),
175bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom                            WellKnownClasses::java_lang_Throwable_stackState,
176bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom                            stack_state_val.get());
1777ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe
1787ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe        // stackTrace.
1797ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe        ScopedLocalRef<jobject> stack_trace_elem(env, env->GetStaticObjectField(
180bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom            WellKnownClasses::libcore_util_EmptyArray,
181bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom            WellKnownClasses::libcore_util_EmptyArray_STACK_TRACE_ELEMENT));
182bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom        env->SetObjectField(exc.get(),
183bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom                            WellKnownClasses::java_lang_Throwable_stackTrace,
184bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom                            stack_trace_elem.get());
1857ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe
1867ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe        // Throw the exception.
1877ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe        ThrowLocation throw_location = self->GetCurrentLocationForThrow();
1887ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe        self->SetException(throw_location,
1897ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe            reinterpret_cast<mirror::Throwable*>(self->DecodeJObject(exc.get())));
1907ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      } else {
1917ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe        error_msg = "Could not create stack trace.";
1927ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      }
1937ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    } else {
1947ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      // Could not allocate a string object.
1957ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe      error_msg = "Couldn't throw new StackOverflowError because JNI NewStringUTF failed.";
1967ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    }
1977ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe  } else {
1987ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    error_msg = "Could not allocate StackOverflowError object.";
1997ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe  }
2007ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe
2017ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe  if (!error_msg.empty()) {
2027ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe    LOG(ERROR) << error_msg;
203d752132c73072084a3def9257cca4fcee76047b6jeffhao    CHECK(self->IsExceptionPending());
204d752132c73072084a3def9257cca4fcee76047b6jeffhao  }
205f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison
206f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison  bool explicit_overflow_check = Runtime::Current()->ExplicitStackOverflowChecks();
20703c9785a8a6d712775cf406c4371d0227c44148fDave Allison  self->ResetDefaultStackEnd();  // Return to default stack size.
20803c9785a8a6d712775cf406c4371d0227c44148fDave Allison
20903c9785a8a6d712775cf406c4371d0227c44148fDave Allison  // And restore protection if implicit checks are on.
21003c9785a8a6d712775cf406c4371d0227c44148fDave Allison  if (!explicit_overflow_check) {
21103c9785a8a6d712775cf406c4371d0227c44148fDave Allison    self->ProtectStack();
21203c9785a8a6d712775cf406c4371d0227c44148fDave Allison  }
213d752132c73072084a3def9257cca4fcee76047b6jeffhao}
214d752132c73072084a3def9257cca4fcee76047b6jeffhao
215e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogersvoid CheckReferenceResult(mirror::Object* o, Thread* self) {
216e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers  if (o == NULL) {
217e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers    return;
218e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers  }
219e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers  mirror::ArtMethod* m = self->GetCurrentMethod(NULL);
220e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers  if (o == kInvalidIndirectRefObject) {
221e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers    JniAbortF(NULL, "invalid reference returned from %s", PrettyMethod(m).c_str());
222e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers  }
223e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers  // Make sure that the result is an instance of the type this method was expected to return.
224e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers  StackHandleScope<1> hs(self);
225e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers  Handle<mirror::ArtMethod> h_m(hs.NewHandle(m));
226e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers  mirror::Class* return_type = MethodHelper(h_m).GetReturnType();
227e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers
228e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers  if (!o->InstanceOf(return_type)) {
229e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers    JniAbortF(NULL, "attempt to return an instance of %s from %s", PrettyTypeOf(o).c_str(),
230e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers              PrettyMethod(h_m.Get()).c_str());
231e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers  }
232e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers}
233e5877a12c30afe10a5c6a1afaff7a47ef44a2a5fIan Rogers
2342b7c4d196c8abe32f4ca633534917da9de53c359Mathieu ChartierJValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, const char* shorty,
235af6e67a4816d2593586115b89faa659225363246Ian Rogers                                    jobject rcvr_jobj, jobject interface_method_jobj,
236af6e67a4816d2593586115b89faa659225363246Ian Rogers                                    std::vector<jvalue>& args) {
237af6e67a4816d2593586115b89faa659225363246Ian Rogers  DCHECK(soa.Env()->IsInstanceOf(rcvr_jobj, WellKnownClasses::java_lang_reflect_Proxy));
238af6e67a4816d2593586115b89faa659225363246Ian Rogers
239af6e67a4816d2593586115b89faa659225363246Ian Rogers  // Build argument array possibly triggering GC.
240af6e67a4816d2593586115b89faa659225363246Ian Rogers  soa.Self()->AssertThreadSuspensionIsAllowable();
241af6e67a4816d2593586115b89faa659225363246Ian Rogers  jobjectArray args_jobj = NULL;
242af6e67a4816d2593586115b89faa659225363246Ian Rogers  const JValue zero;
243f00571c4e1ae202b3b4acb6b47cbe23a65178f7fJeff Hao  int32_t target_sdk_version = Runtime::Current()->GetTargetSdkVersion();
244f00571c4e1ae202b3b4acb6b47cbe23a65178f7fJeff Hao  // Do not create empty arrays unless needed to maintain Dalvik bug compatibility.
245f00571c4e1ae202b3b4acb6b47cbe23a65178f7fJeff Hao  if (args.size() > 0 || (target_sdk_version > 0 && target_sdk_version <= 21)) {
246af6e67a4816d2593586115b89faa659225363246Ian Rogers    args_jobj = soa.Env()->NewObjectArray(args.size(), WellKnownClasses::java_lang_Object, NULL);
247af6e67a4816d2593586115b89faa659225363246Ian Rogers    if (args_jobj == NULL) {
248af6e67a4816d2593586115b89faa659225363246Ian Rogers      CHECK(soa.Self()->IsExceptionPending());
249af6e67a4816d2593586115b89faa659225363246Ian Rogers      return zero;
250af6e67a4816d2593586115b89faa659225363246Ian Rogers    }
251af6e67a4816d2593586115b89faa659225363246Ian Rogers    for (size_t i = 0; i < args.size(); ++i) {
252af6e67a4816d2593586115b89faa659225363246Ian Rogers      if (shorty[i + 1] == 'L') {
253af6e67a4816d2593586115b89faa659225363246Ian Rogers        jobject val = args.at(i).l;
254af6e67a4816d2593586115b89faa659225363246Ian Rogers        soa.Env()->SetObjectArrayElement(args_jobj, i, val);
255af6e67a4816d2593586115b89faa659225363246Ian Rogers      } else {
256af6e67a4816d2593586115b89faa659225363246Ian Rogers        JValue jv;
257af6e67a4816d2593586115b89faa659225363246Ian Rogers        jv.SetJ(args.at(i).j);
2582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        mirror::Object* val = BoxPrimitive(Primitive::GetType(shorty[i + 1]), jv);
259af6e67a4816d2593586115b89faa659225363246Ian Rogers        if (val == NULL) {
260af6e67a4816d2593586115b89faa659225363246Ian Rogers          CHECK(soa.Self()->IsExceptionPending());
261af6e67a4816d2593586115b89faa659225363246Ian Rogers          return zero;
262af6e67a4816d2593586115b89faa659225363246Ian Rogers        }
263d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz        soa.Decode<mirror::ObjectArray<mirror::Object>* >(args_jobj)->Set<false>(i, val);
264af6e67a4816d2593586115b89faa659225363246Ian Rogers      }
265af6e67a4816d2593586115b89faa659225363246Ian Rogers    }
266af6e67a4816d2593586115b89faa659225363246Ian Rogers  }
267af6e67a4816d2593586115b89faa659225363246Ian Rogers
268ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Call Proxy.invoke(Proxy proxy, ArtMethod method, Object[] args).
269af6e67a4816d2593586115b89faa659225363246Ian Rogers  jvalue invocation_args[3];
270af6e67a4816d2593586115b89faa659225363246Ian Rogers  invocation_args[0].l = rcvr_jobj;
271af6e67a4816d2593586115b89faa659225363246Ian Rogers  invocation_args[1].l = interface_method_jobj;
272af6e67a4816d2593586115b89faa659225363246Ian Rogers  invocation_args[2].l = args_jobj;
273af6e67a4816d2593586115b89faa659225363246Ian Rogers  jobject result =
274ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom      soa.Env()->CallStaticObjectMethodA(WellKnownClasses::java_lang_reflect_Proxy,
275ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                         WellKnownClasses::java_lang_reflect_Proxy_invoke,
276ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                         invocation_args);
277af6e67a4816d2593586115b89faa659225363246Ian Rogers
278af6e67a4816d2593586115b89faa659225363246Ian Rogers  // Unbox result and handle error conditions.
27962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  if (LIKELY(!soa.Self()->IsExceptionPending())) {
28062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    if (shorty[0] == 'V' || (shorty[0] == 'L' && result == NULL)) {
281af6e67a4816d2593586115b89faa659225363246Ian Rogers      // Do nothing.
282af6e67a4816d2593586115b89faa659225363246Ian Rogers      return zero;
283af6e67a4816d2593586115b89faa659225363246Ian Rogers    } else {
284bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier      StackHandleScope<1> hs(soa.Self());
285bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier      MethodHelper mh_interface_method(
286bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier          hs.NewHandle(soa.Decode<mirror::ArtMethod*>(interface_method_jobj)));
287bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier      // This can cause thread suspension.
288bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier      mirror::Class* result_type = mh_interface_method.GetReturnType();
2892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      mirror::Object* result_ref = soa.Decode<mirror::Object*>(result);
29062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      mirror::Object* rcvr = soa.Decode<mirror::Object*>(rcvr_jobj);
291ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom      mirror::ArtMethod* proxy_method;
292bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier      if (mh_interface_method.GetMethod()->GetDeclaringClass()->IsInterface()) {
293bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier        proxy_method = rcvr->GetClass()->FindVirtualMethodForInterface(
294bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier            mh_interface_method.GetMethod());
29562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      } else {
29662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        // Proxy dispatch to a method defined in Object.
297bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier        DCHECK(mh_interface_method.GetMethod()->GetDeclaringClass()->IsObjectClass());
298bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier        proxy_method = mh_interface_method.GetMethod();
29962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      }
30062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      ThrowLocation throw_location(rcvr, proxy_method, -1);
30162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      JValue result_unboxed;
30284956ff6c0ff150d86a08157216ded79217d860aIan Rogers      if (!UnboxPrimitiveForResult(throw_location, result_ref, result_type, &result_unboxed)) {
303530f71c040cb1a7b946d5566d5a746f08f2d082cIan Rogers        DCHECK(soa.Self()->IsExceptionPending());
30462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        return zero;
305af6e67a4816d2593586115b89faa659225363246Ian Rogers      }
306af6e67a4816d2593586115b89faa659225363246Ian Rogers      return result_unboxed;
307af6e67a4816d2593586115b89faa659225363246Ian Rogers    }
308af6e67a4816d2593586115b89faa659225363246Ian Rogers  } else {
309af6e67a4816d2593586115b89faa659225363246Ian Rogers    // In the case of checked exceptions that aren't declared, the exception must be wrapped by
310af6e67a4816d2593586115b89faa659225363246Ian Rogers    // a UndeclaredThrowableException.
31162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    mirror::Throwable* exception = soa.Self()->GetException(NULL);
312af6e67a4816d2593586115b89faa659225363246Ian Rogers    if (exception->IsCheckedException()) {
3132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      mirror::Object* rcvr = soa.Decode<mirror::Object*>(rcvr_jobj);
31498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang      mirror::Class* proxy_class = rcvr->GetClass();
315ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom      mirror::ArtMethod* interface_method =
316ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom          soa.Decode<mirror::ArtMethod*>(interface_method_jobj);
317ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom      mirror::ArtMethod* proxy_method =
318af6e67a4816d2593586115b89faa659225363246Ian Rogers          rcvr->GetClass()->FindVirtualMethodForInterface(interface_method);
319af6e67a4816d2593586115b89faa659225363246Ian Rogers      int throws_index = -1;
320af6e67a4816d2593586115b89faa659225363246Ian Rogers      size_t num_virt_methods = proxy_class->NumVirtualMethods();
321af6e67a4816d2593586115b89faa659225363246Ian Rogers      for (size_t i = 0; i < num_virt_methods; i++) {
322af6e67a4816d2593586115b89faa659225363246Ian Rogers        if (proxy_class->GetVirtualMethod(i) == proxy_method) {
323af6e67a4816d2593586115b89faa659225363246Ian Rogers          throws_index = i;
324af6e67a4816d2593586115b89faa659225363246Ian Rogers          break;
325af6e67a4816d2593586115b89faa659225363246Ian Rogers        }
326af6e67a4816d2593586115b89faa659225363246Ian Rogers      }
327af6e67a4816d2593586115b89faa659225363246Ian Rogers      CHECK_NE(throws_index, -1);
328bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom      mirror::ObjectArray<mirror::Class>* declared_exceptions =
329bfc2b98a3cf7a9d580f2477e54aabded5004fd26Brian Carlstrom          proxy_class->GetThrows()->Get(throws_index);
3302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      mirror::Class* exception_class = exception->GetClass();
331af6e67a4816d2593586115b89faa659225363246Ian Rogers      bool declares_exception = false;
332af6e67a4816d2593586115b89faa659225363246Ian Rogers      for (int i = 0; i < declared_exceptions->GetLength() && !declares_exception; i++) {
3332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        mirror::Class* declared_exception = declared_exceptions->Get(i);
334af6e67a4816d2593586115b89faa659225363246Ian Rogers        declares_exception = declared_exception->IsAssignableFrom(exception_class);
335af6e67a4816d2593586115b89faa659225363246Ian Rogers      }
336af6e67a4816d2593586115b89faa659225363246Ian Rogers      if (!declares_exception) {
33762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        ThrowLocation throw_location(rcvr, proxy_method, -1);
33862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        soa.Self()->ThrowNewWrappedException(throw_location,
33962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                             "Ljava/lang/reflect/UndeclaredThrowableException;",
340af6e67a4816d2593586115b89faa659225363246Ian Rogers                                             NULL);
341af6e67a4816d2593586115b89faa659225363246Ian Rogers      }
342af6e67a4816d2593586115b89faa659225363246Ian Rogers    }
343af6e67a4816d2593586115b89faa659225363246Ian Rogers    return zero;
344af6e67a4816d2593586115b89faa659225363246Ian Rogers  }
345af6e67a4816d2593586115b89faa659225363246Ian Rogers}
3462d831014d88e38c0c499ce8597dcdb17b9d4c4b9Shih-wei Liao}  // namespace art
347