quick_throw_entrypoints.cc revision ab9a0dbf3b63d517da5278b8298e6cd316e09f68
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "callee_save_frame.h"
18#include "common_throws.h"
19#include "entrypoints/entrypoint_utils-inl.h"
20#include "mirror/object-inl.h"
21#include "thread.h"
22#include "well_known_classes.h"
23
24namespace art {
25
26// Deliver an exception that's pending on thread helping set up a callee save frame on the way.
27extern "C" void artDeliverPendingExceptionFromCode(Thread* thread,
28                                                   StackReference<mirror::ArtMethod>* sp)
29    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
30  FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
31  thread->QuickDeliverException();
32}
33
34// Called by generated call to throw an exception.
35extern "C" void artDeliverExceptionFromCode(mirror::Throwable* exception, Thread* self,
36                                            StackReference<mirror::ArtMethod>* sp)
37    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
38  /*
39   * exception may be NULL, in which case this routine should
40   * throw NPE.  NOTE: this is a convenience for generated code,
41   * which previously did the null check inline and constructed
42   * and threw a NPE if NULL.  This routine responsible for setting
43   * exception_ in thread and delivering the exception.
44   */
45  FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
46  ThrowLocation throw_location = self->GetCurrentLocationForThrow();
47  if (exception == NULL) {
48    self->ThrowNewException(throw_location, "Ljava/lang/NullPointerException;",
49                            "throw with null exception");
50  } else {
51    self->SetException(throw_location, exception);
52  }
53  self->QuickDeliverException();
54}
55
56// Called by generated call to throw a NPE exception.
57extern "C" void artThrowNullPointerExceptionFromCode(Thread* self,
58                                                     StackReference<mirror::ArtMethod>* sp)
59    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
60  FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
61  ThrowLocation throw_location = self->GetCurrentLocationForThrow();
62  ThrowNullPointerExceptionFromDexPC(throw_location);
63  self->QuickDeliverException();
64}
65
66// Called by generated call to throw an arithmetic divide by zero exception.
67extern "C" void artThrowDivZeroFromCode(Thread* self, StackReference<mirror::ArtMethod>* sp)
68    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
69  FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
70  ThrowArithmeticExceptionDivideByZero();
71  self->QuickDeliverException();
72}
73
74// Called by generated call to throw an array index out of bounds exception.
75extern "C" void artThrowArrayBoundsFromCode(int index, int length, Thread* self,
76                                            StackReference<mirror::ArtMethod>*sp)
77    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
78  FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
79  ThrowArrayIndexOutOfBoundsException(index, length);
80  self->QuickDeliverException();
81}
82
83extern "C" void artThrowStackOverflowFromCode(Thread* self, StackReference<mirror::ArtMethod>* sp)
84    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
85  FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
86  ThrowStackOverflowError(self);
87  self->QuickDeliverException();
88}
89
90extern "C" void artThrowNoSuchMethodFromCode(int32_t method_idx, Thread* self,
91                                             StackReference<mirror::ArtMethod>* sp)
92    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
93  FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
94  ThrowNoSuchMethodError(method_idx);
95  self->QuickDeliverException();
96}
97
98extern "C" void artThrowClassCastException(mirror::Class* dest_type, mirror::Class* src_type,
99                                           Thread* self, StackReference<mirror::ArtMethod>* sp)
100    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
101  FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
102  CHECK(!dest_type->IsAssignableFrom(src_type));
103  ThrowClassCastException(dest_type, src_type);
104  self->QuickDeliverException();
105}
106
107extern "C" void artThrowArrayStoreException(mirror::Object* array, mirror::Object* value,
108                                            Thread* self, StackReference<mirror::ArtMethod>* sp)
109    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
110  FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
111  ThrowArrayStoreException(value->GetClass(), array->GetClass());
112  self->QuickDeliverException();
113}
114
115}  // namespace art
116