blob: d5820bf1198d34d0851a5fef7a4e677e88e0b5d1 [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"
18#include "dex_verifier.h"
19#include "object.h"
20#include "object_utils.h"
21#include "runtime_support.h"
22#include "thread.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, Method** sp) {
28 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
29 thread->DeliverException();
30}
31
32// Called by generated call to throw an exception.
33extern "C" void artDeliverExceptionFromCode(Throwable* exception, Thread* thread, Method** sp) {
34 /*
35 * exception may be NULL, in which case this routine should
36 * throw NPE. NOTE: this is a convenience for generated code,
37 * which previously did the null check inline and constructed
38 * and threw a NPE if NULL. This routine responsible for setting
39 * exception_ in thread and delivering the exception.
40 */
41 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
42 if (exception == NULL) {
43 thread->ThrowNewException("Ljava/lang/NullPointerException;", "throw with null exception");
44 } else {
45 thread->SetException(exception);
46 }
47 thread->DeliverException();
48}
49
50// Called by generated call to throw a NPE exception.
51extern "C" void artThrowNullPointerExceptionFromCode(Thread* self, Method** sp) {
52 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
Elliott Hughes6a144332012-04-03 13:07:11 -070053 Frame frame = self->GetTopOfStack();
54 uintptr_t throw_native_pc = frame.GetReturnPC();
55 frame.Next();
56 Method* throw_method = frame.GetMethod();
Ian Rogers57b86d42012-03-27 16:05:41 -070057 uint32_t dex_pc = throw_method->ToDexPC(throw_native_pc - 2);
TDYa1273f9137d2012-04-08 15:59:19 -070058 ThrowNullPointerExceptionFromDexPC(self, throw_method, dex_pc);
Ian Rogers57b86d42012-03-27 16:05:41 -070059 self->DeliverException();
60}
61
62// Called by generated call to throw an arithmetic divide by zero exception.
63extern "C" void artThrowDivZeroFromCode(Thread* thread, Method** sp) {
64 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.
70extern "C" void artThrowArrayBoundsFromCode(int index, int limit, Thread* thread, Method** sp) {
71 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
72 thread->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
73 "length=%d; index=%d", limit, index);
74 thread->DeliverException();
75}
76
77extern "C" void artThrowStackOverflowFromCode(Thread* thread, Method** sp) {
78 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
79 // Remove extra entry pushed onto second stack during method tracing
80 if (Runtime::Current()->IsMethodTracingActive()) {
81 TraceMethodUnwindFromCode(thread);
82 }
83 thread->SetStackEndForStackOverflow(); // Allow space on the stack for constructor to execute
84 thread->ThrowNewExceptionF("Ljava/lang/StackOverflowError;",
85 "stack size %zdkb; default stack size: %zdkb",
86 thread->GetStackSize() / KB, Runtime::Current()->GetDefaultStackSize() / KB);
87 thread->ResetDefaultStackEnd(); // Return to default stack size
88 thread->DeliverException();
89}
90
91extern "C" void artThrowNoSuchMethodFromCode(int32_t method_idx, Thread* self, Method** sp) {
92 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
93 Frame frame = self->GetTopOfStack(); // We need the calling method as context for the method_idx
94 frame.Next();
95 Method* method = frame.GetMethod();
96 self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
97 MethodNameFromIndex(method, method_idx, verifier::VERIFY_ERROR_REF_METHOD, false).c_str());
98 self->DeliverException();
99}
100
Ian Rogers57b86d42012-03-27 16:05:41 -0700101extern "C" void artThrowVerificationErrorFromCode(int32_t kind, int32_t ref, Thread* self, Method** sp) {
102 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
103 Frame frame = self->GetTopOfStack(); // We need the calling method as context to interpret 'ref'
104 frame.Next();
105 Method* method = frame.GetMethod();
Logan Chien9e5f5c12012-04-10 13:51:45 +0800106 ThrowVerificationError(self, method, kind, ref);
Ian Rogers57b86d42012-03-27 16:05:41 -0700107 self->DeliverException();
108}
109
110} // namespace art