blob: 12295b142c27aee43f048a3f63924341d2d725f2 [file] [log] [blame]
Ian Rogers57b86d42012-03-27 16:05:41 -07001/*
Elliott Hughes0f3c5532012-03-30 14:51:51 -07002 * Copyright (C) 2012 The Android Open Source Project
Ian Rogers57b86d42012-03-27 16:05:41 -07003 *
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"
Ian Rogers57b86d42012-03-27 16:05:41 -070018#include "object.h"
19#include "object_utils.h"
20#include "runtime_support.h"
21#include "thread.h"
22
23namespace art {
24
25// Deliver an exception that's pending on thread helping set up a callee save frame on the way.
Mathieu Chartier66f19252012-09-18 08:57:04 -070026extern "C" void artDeliverPendingExceptionFromCode(Thread* thread, AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070027 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070028 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
29 thread->DeliverException();
30}
31
32// Called by generated call to throw an exception.
Mathieu Chartier66f19252012-09-18 08:57:04 -070033extern "C" void artDeliverExceptionFromCode(Throwable* exception, Thread* thread,
34 AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070035 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070036 /*
37 * exception may be NULL, in which case this routine should
38 * throw NPE. NOTE: this is a convenience for generated code,
39 * which previously did the null check inline and constructed
40 * and threw a NPE if NULL. This routine responsible for setting
41 * exception_ in thread and delivering the exception.
42 */
43 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
44 if (exception == NULL) {
45 thread->ThrowNewException("Ljava/lang/NullPointerException;", "throw with null exception");
46 } else {
47 thread->SetException(exception);
48 }
49 thread->DeliverException();
50}
51
52// Called by generated call to throw a NPE exception.
Mathieu Chartier66f19252012-09-18 08:57:04 -070053extern "C" void artThrowNullPointerExceptionFromCode(Thread* self,
54 AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070055 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070056 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
Ian Rogers0399dde2012-06-06 17:09:28 -070057 uint32_t dex_pc;
Mathieu Chartier66f19252012-09-18 08:57:04 -070058 AbstractMethod* throw_method = self->GetCurrentMethod(&dex_pc);
Ian Rogers87e552d2012-08-31 15:54:48 -070059 ThrowNullPointerExceptionFromDexPC(throw_method, dex_pc);
Ian Rogers57b86d42012-03-27 16:05:41 -070060 self->DeliverException();
61}
62
63// Called by generated call to throw an arithmetic divide by zero exception.
Mathieu Chartier66f19252012-09-18 08:57:04 -070064extern "C" void artThrowDivZeroFromCode(Thread* thread,
65 AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070066 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070067 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
68 thread->ThrowNewException("Ljava/lang/ArithmeticException;", "divide by zero");
69 thread->DeliverException();
70}
71
72// Called by generated call to throw an array index out of bounds exception.
Mathieu Chartier66f19252012-09-18 08:57:04 -070073extern "C" void artThrowArrayBoundsFromCode(int index, int limit, Thread* thread,
74 AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070075 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070076 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
77 thread->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
78 "length=%d; index=%d", limit, index);
79 thread->DeliverException();
80}
81
Mathieu Chartier66f19252012-09-18 08:57:04 -070082extern "C" void artThrowStackOverflowFromCode(Thread* thread, AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070083 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070084 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
Elliott Hughes6cf23882012-06-15 15:42:07 -070085 // Remove extra entry pushed onto second stack during method tracing.
Ian Rogers57b86d42012-03-27 16:05:41 -070086 if (Runtime::Current()->IsMethodTracingActive()) {
87 TraceMethodUnwindFromCode(thread);
88 }
Elliott Hughes6cf23882012-06-15 15:42:07 -070089 thread->SetStackEndForStackOverflow(); // Allow space on the stack for constructor to execute.
90 thread->ThrowNewExceptionF("Ljava/lang/StackOverflowError;", "stack size %s",
91 PrettySize(thread->GetStackSize()).c_str());
92 thread->ResetDefaultStackEnd(); // Return to default stack size.
Ian Rogers57b86d42012-03-27 16:05:41 -070093 thread->DeliverException();
94}
95
Mathieu Chartier66f19252012-09-18 08:57:04 -070096extern "C" void artThrowNoSuchMethodFromCode(int32_t method_idx, Thread* self,
97 AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070098 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070099 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
Mathieu Chartier66f19252012-09-18 08:57:04 -0700100 AbstractMethod* method = self->GetCurrentMethod();
Ian Rogers87e552d2012-08-31 15:54:48 -0700101 ThrowNoSuchMethodError(method_idx, method);
Ian Rogers57b86d42012-03-27 16:05:41 -0700102 self->DeliverException();
103}
104
Ian Rogers57b86d42012-03-27 16:05:41 -0700105} // namespace art