blob: 6e1e1010ce6eced6afab7de82847911ba578adcf [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.
Ian Rogers00f7d0e2012-07-19 15:28:27 -070026extern "C" void artDeliverPendingExceptionFromCode(Thread* thread, Method** 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.
Ian Rogers00f7d0e2012-07-19 15:28:27 -070033extern "C" void artDeliverExceptionFromCode(Throwable* exception, Thread* thread, Method** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070034 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070035 /*
36 * exception may be NULL, in which case this routine should
37 * throw NPE. NOTE: this is a convenience for generated code,
38 * which previously did the null check inline and constructed
39 * and threw a NPE if NULL. This routine responsible for setting
40 * exception_ in thread and delivering the exception.
41 */
42 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
43 if (exception == NULL) {
44 thread->ThrowNewException("Ljava/lang/NullPointerException;", "throw with null exception");
45 } else {
46 thread->SetException(exception);
47 }
48 thread->DeliverException();
49}
50
51// Called by generated call to throw a NPE exception.
Ian Rogers00f7d0e2012-07-19 15:28:27 -070052extern "C" void artThrowNullPointerExceptionFromCode(Thread* self, Method** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070053 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070054 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
Ian Rogers0399dde2012-06-06 17:09:28 -070055 uint32_t dex_pc;
56 Method* throw_method = self->GetCurrentMethod(&dex_pc);
Ian Rogers87e552d2012-08-31 15:54:48 -070057 ThrowNullPointerExceptionFromDexPC(throw_method, dex_pc);
Ian Rogers57b86d42012-03-27 16:05:41 -070058 self->DeliverException();
59}
60
61// Called by generated call to throw an arithmetic divide by zero exception.
Ian Rogers00f7d0e2012-07-19 15:28:27 -070062extern "C" void artThrowDivZeroFromCode(Thread* thread, Method** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070063 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070064 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
65 thread->ThrowNewException("Ljava/lang/ArithmeticException;", "divide by zero");
66 thread->DeliverException();
67}
68
69// Called by generated call to throw an array index out of bounds exception.
Ian Rogers00f7d0e2012-07-19 15:28:27 -070070extern "C" void artThrowArrayBoundsFromCode(int index, int limit, Thread* thread, Method** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070071 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070072 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
73 thread->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
74 "length=%d; index=%d", limit, index);
75 thread->DeliverException();
76}
77
Ian Rogers00f7d0e2012-07-19 15:28:27 -070078extern "C" void artThrowStackOverflowFromCode(Thread* thread, Method** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070079 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070080 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
Elliott Hughes6cf23882012-06-15 15:42:07 -070081 // Remove extra entry pushed onto second stack during method tracing.
Ian Rogers57b86d42012-03-27 16:05:41 -070082 if (Runtime::Current()->IsMethodTracingActive()) {
83 TraceMethodUnwindFromCode(thread);
84 }
Elliott Hughes6cf23882012-06-15 15:42:07 -070085 thread->SetStackEndForStackOverflow(); // Allow space on the stack for constructor to execute.
86 thread->ThrowNewExceptionF("Ljava/lang/StackOverflowError;", "stack size %s",
87 PrettySize(thread->GetStackSize()).c_str());
88 thread->ResetDefaultStackEnd(); // Return to default stack size.
Ian Rogers57b86d42012-03-27 16:05:41 -070089 thread->DeliverException();
90}
91
Ian Rogers00f7d0e2012-07-19 15:28:27 -070092extern "C" void artThrowNoSuchMethodFromCode(int32_t method_idx, Thread* self, Method** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070093 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -070094 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
Ian Rogers0399dde2012-06-06 17:09:28 -070095 Method* method = self->GetCurrentMethod();
Ian Rogers87e552d2012-08-31 15:54:48 -070096 ThrowNoSuchMethodError(method_idx, method);
Ian Rogers57b86d42012-03-27 16:05:41 -070097 self->DeliverException();
98}
99
Ian Rogers57b86d42012-03-27 16:05:41 -0700100} // namespace art