blob: 230421a7d689dd0caf27be1bc3dd44a83b99e6e2 [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
Ian Rogersc928de92013-02-27 14:30:44 -080017#if !defined(ART_USE_PORTABLE_COMPILER)
Ian Rogers57b86d42012-03-27 16:05:41 -070018#include "callee_save_frame.h"
TDYa12705fe3b62012-04-21 00:28:54 -070019#endif
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080020#include "class_linker-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070021#include "dex_file-inl.h"
Ian Rogers57b86d42012-03-27 16:05:41 -070022#include "dex_instruction.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080023#include "mirror/class-inl.h"
24#include "mirror/abstract_method-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080025#include "mirror/object_array-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070026#include "mirror/object-inl.h"
Ian Rogers57b86d42012-03-27 16:05:41 -070027#include "object_utils.h"
Ian Rogersc928de92013-02-27 14:30:44 -080028#if defined(ART_USE_PORTABLE_COMPILER)
TDYa12705fe3b62012-04-21 00:28:54 -070029#include "nth_caller_visitor.h"
30#endif
Ian Rogers00f7d0e2012-07-19 15:28:27 -070031#include "scoped_thread_state_change.h"
Ian Rogers57b86d42012-03-27 16:05:41 -070032
33// Architecture specific assembler helper to deliver exception.
Logan Chien8dbb7082013-01-25 20:31:17 +080034extern "C" void art_quick_deliver_exception_from_code(void*);
Ian Rogers57b86d42012-03-27 16:05:41 -070035
36namespace art {
37
Jeff Hao58df3272013-04-22 15:28:53 -070038// Lazily resolve a method for portable. Called by stub code.
39extern "C" const void* artPortableResolutionTrampoline(mirror::AbstractMethod* called,
40 mirror::AbstractMethod** called_addr,
41 Thread* thread)
42 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
43 uint32_t dex_pc;
44 mirror::AbstractMethod* caller = thread->GetCurrentMethod(&dex_pc);
45
46 ClassLinker* linker = Runtime::Current()->GetClassLinker();
47 InvokeType invoke_type;
48 uint32_t dex_method_idx;
49 DCHECK(called->IsRuntimeMethod());
50 const DexFile::CodeItem* code_item = MethodHelper(caller).GetCodeItem();
51 CHECK_LT(dex_pc, code_item->insns_size_in_code_units_);
52 const Instruction* instr = Instruction::At(&code_item->insns_[dex_pc]);
53 Instruction::Code instr_code = instr->Opcode();
54 switch (instr_code) {
55 case Instruction::INVOKE_DIRECT: // Fall-through.
56 case Instruction::INVOKE_DIRECT_RANGE:
57 invoke_type = kDirect;
58 break;
59 case Instruction::INVOKE_STATIC: // Fall-through.
60 case Instruction::INVOKE_STATIC_RANGE:
61 invoke_type = kStatic;
62 break;
63 case Instruction::INVOKE_SUPER: // Fall-through.
64 case Instruction::INVOKE_SUPER_RANGE:
65 invoke_type = kSuper;
66 break;
67 case Instruction::INVOKE_VIRTUAL: // Fall-through.
68 case Instruction::INVOKE_VIRTUAL_RANGE:
69 invoke_type = kVirtual;
70 break;
71 default:
72 LOG(FATAL) << "Unexpected call into trampoline: " << instr->DumpString(NULL);
73 invoke_type = kDirect; // Avoid used uninitialized warnings.
74 }
75 DecodedInstruction dec_insn(instr);
76 dex_method_idx = dec_insn.vB;
77 called = linker->ResolveMethod(dex_method_idx, caller, invoke_type);
78 const void* code = NULL;
79 if (LIKELY(!thread->IsExceptionPending())) {
80 // Incompatible class change should have been handled in resolve method.
81 CHECK(!called->CheckIncompatibleClassChange(invoke_type));
82 // Ensure that the called method's class is initialized.
83 mirror::Class* called_class = called->GetDeclaringClass();
84 linker->EnsureInitialized(called_class, true, true);
85 if (LIKELY(called_class->IsInitialized())) {
86 code = called->GetCode();
87 // TODO: remove this after we solve the link issue.
88 { // for lazy link.
89 if (code == NULL) {
90 code = linker->GetOatCodeFor(called);
91 }
92 }
93 } else if (called_class->IsInitializing()) {
94 if (invoke_type == kStatic) {
95 // Class is still initializing, go to oat and grab code (trampoline must be left in place
96 // until class is initialized to stop races between threads).
97 code = linker->GetOatCodeFor(called);
98 } else {
99 // No trampoline for non-static methods.
100 code = called->GetCode();
101 // TODO: remove this after we solve the link issue.
102 { // for lazy link.
103 if (code == NULL) {
104 code = linker->GetOatCodeFor(called);
105 }
106 }
107 }
108 } else {
109 DCHECK(called_class->IsErroneous());
110 }
111 }
112 if (LIKELY(code != NULL)) {
113 // Expect class to at least be initializing.
114 DCHECK(called->GetDeclaringClass()->IsInitializing());
115 // Don't want infinite recursion.
116 DCHECK(code != GetResolutionTrampoline());
117 // Set up entry into main method
118 *called_addr = called;
119 }
120 return code;
121}
122
123// Lazily resolve a method for quick. Called by stub code.
124extern "C" const void* artQuickResolutionTrampoline(mirror::AbstractMethod* called,
125 mirror::AbstractMethod** sp, Thread* thread)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700126 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers7caad772012-03-30 01:07:54 -0700127#if defined(__arm__)
Ian Rogers57b86d42012-03-27 16:05:41 -0700128 // On entry the stack pointed by sp is:
129 // | argN | |
130 // | ... | |
131 // | arg4 | |
132 // | arg3 spill | | Caller's frame
133 // | arg2 spill | |
134 // | arg1 spill | |
135 // | Method* | ---
136 // | LR |
137 // | ... | callee saves
138 // | R3 | arg3
139 // | R2 | arg2
140 // | R1 | arg1
141 // | R0 |
142 // | Method* | <- sp
Ian Rogers57b86d42012-03-27 16:05:41 -0700143 DCHECK_EQ(48U, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800144 mirror::AbstractMethod** caller_sp = reinterpret_cast<mirror::AbstractMethod**>(reinterpret_cast<byte*>(sp) + 48);
Ian Rogers7caad772012-03-30 01:07:54 -0700145 uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp) + kPointerSize);
jeffhaofa147e22012-10-12 17:03:32 -0700146 uint32_t pc_offset = 10;
147 uintptr_t caller_pc = regs[pc_offset];
Ian Rogers7caad772012-03-30 01:07:54 -0700148#elif defined(__i386__)
149 // On entry the stack pointed by sp is:
150 // | argN | |
151 // | ... | |
152 // | arg4 | |
153 // | arg3 spill | | Caller's frame
154 // | arg2 spill | |
155 // | arg1 spill | |
156 // | Method* | ---
157 // | Return |
158 // | EBP,ESI,EDI | callee saves
159 // | EBX | arg3
160 // | EDX | arg2
161 // | ECX | arg1
162 // | EAX/Method* | <- sp
163 DCHECK_EQ(32U, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800164 mirror::AbstractMethod** caller_sp = reinterpret_cast<mirror::AbstractMethod**>(reinterpret_cast<byte*>(sp) + 32);
Ian Rogers7caad772012-03-30 01:07:54 -0700165 uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp));
166 uintptr_t caller_pc = regs[7];
jeffhaofa147e22012-10-12 17:03:32 -0700167#elif defined(__mips__)
168 // On entry the stack pointed by sp is:
169 // | argN | |
170 // | ... | |
171 // | arg4 | |
172 // | arg3 spill | | Caller's frame
173 // | arg2 spill | |
174 // | arg1 spill | |
175 // | Method* | ---
176 // | RA |
177 // | ... | callee saves
178 // | A3 | arg3
179 // | A2 | arg2
180 // | A1 | arg1
181 // | A0/Method* | <- sp
182 DCHECK_EQ(48U, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800183 mirror::AbstractMethod** caller_sp = reinterpret_cast<mirror::AbstractMethod**>(reinterpret_cast<byte*>(sp) + 48);
jeffhaofa147e22012-10-12 17:03:32 -0700184 uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp));
185 uint32_t pc_offset = 11;
186 uintptr_t caller_pc = regs[pc_offset];
Ian Rogers7caad772012-03-30 01:07:54 -0700187#else
188 UNIMPLEMENTED(FATAL);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800189 mirror::AbstractMethod** caller_sp = NULL;
Ian Rogers7caad772012-03-30 01:07:54 -0700190 uintptr_t* regs = NULL;
191 uintptr_t caller_pc = 0;
192#endif
Ian Rogers57b86d42012-03-27 16:05:41 -0700193 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kRefsAndArgs);
194 // Start new JNI local reference state
195 JNIEnvExt* env = thread->GetJniEnv();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700196 ScopedObjectAccessUnchecked soa(env);
Ian Rogers57b86d42012-03-27 16:05:41 -0700197 ScopedJniEnvLocalRefState env_state(env);
198
199 // Compute details about the called method (avoid GCs)
200 ClassLinker* linker = Runtime::Current()->GetClassLinker();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800201 mirror::AbstractMethod* caller = *caller_sp;
Ian Rogers08f753d2012-08-24 14:35:25 -0700202 InvokeType invoke_type;
Ian Rogers57b86d42012-03-27 16:05:41 -0700203 uint32_t dex_method_idx;
Brian Carlstromfd2ec542012-05-02 15:08:57 -0700204#if !defined(__i386__)
Ian Rogers57b86d42012-03-27 16:05:41 -0700205 const char* shorty;
206 uint32_t shorty_len;
Brian Carlstromfd2ec542012-05-02 15:08:57 -0700207#endif
Jeff Hao58df3272013-04-22 15:28:53 -0700208 if (called->IsRuntimeMethod()) {
Ian Rogers0c7abda2012-09-19 13:33:42 -0700209 uint32_t dex_pc = caller->ToDexPc(caller_pc);
Ian Rogers57b86d42012-03-27 16:05:41 -0700210 const DexFile::CodeItem* code = MethodHelper(caller).GetCodeItem();
211 CHECK_LT(dex_pc, code->insns_size_in_code_units_);
212 const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
213 Instruction::Code instr_code = instr->Opcode();
Ian Rogers08f753d2012-08-24 14:35:25 -0700214 switch (instr_code) {
215 case Instruction::INVOKE_DIRECT: // Fall-through.
216 case Instruction::INVOKE_DIRECT_RANGE:
217 invoke_type = kDirect;
218 break;
219 case Instruction::INVOKE_STATIC: // Fall-through.
220 case Instruction::INVOKE_STATIC_RANGE:
221 invoke_type = kStatic;
222 break;
223 case Instruction::INVOKE_SUPER: // Fall-through.
224 case Instruction::INVOKE_SUPER_RANGE:
225 invoke_type = kSuper;
226 break;
227 case Instruction::INVOKE_VIRTUAL: // Fall-through.
228 case Instruction::INVOKE_VIRTUAL_RANGE:
229 invoke_type = kVirtual;
230 break;
231 default:
232 LOG(FATAL) << "Unexpected call into trampoline: " << instr->DumpString(NULL);
233 invoke_type = kDirect; // Avoid used uninitialized warnings.
234 }
Ian Rogers57b86d42012-03-27 16:05:41 -0700235 DecodedInstruction dec_insn(instr);
236 dex_method_idx = dec_insn.vB;
Brian Carlstromfd2ec542012-05-02 15:08:57 -0700237#if !defined(__i386__)
Ian Rogers57b86d42012-03-27 16:05:41 -0700238 shorty = linker->MethodShorty(dex_method_idx, caller, &shorty_len);
Brian Carlstromfd2ec542012-05-02 15:08:57 -0700239#endif
Ian Rogers57b86d42012-03-27 16:05:41 -0700240 } else {
Jeff Hao58df3272013-04-22 15:28:53 -0700241 invoke_type = kStatic;
Ian Rogers57b86d42012-03-27 16:05:41 -0700242 dex_method_idx = called->GetDexMethodIndex();
Brian Carlstromfd2ec542012-05-02 15:08:57 -0700243#if !defined(__i386__)
Ian Rogers57b86d42012-03-27 16:05:41 -0700244 MethodHelper mh(called);
245 shorty = mh.GetShorty();
246 shorty_len = mh.GetShortyLength();
Brian Carlstromfd2ec542012-05-02 15:08:57 -0700247#endif
Ian Rogers57b86d42012-03-27 16:05:41 -0700248 }
Ian Rogers7caad772012-03-30 01:07:54 -0700249#if !defined(__i386__)
Ian Rogers57b86d42012-03-27 16:05:41 -0700250 // Discover shorty (avoid GCs)
251 size_t args_in_regs = 0;
252 for (size_t i = 1; i < shorty_len; i++) {
253 char c = shorty[i];
254 args_in_regs = args_in_regs + (c == 'J' || c == 'D' ? 2 : 1);
255 if (args_in_regs > 3) {
256 args_in_regs = 3;
257 break;
258 }
259 }
260 // Place into local references incoming arguments from the caller's register arguments
261 size_t cur_arg = 1; // skip method_idx in R0, first arg is in R1
Ian Rogers08f753d2012-08-24 14:35:25 -0700262 if (invoke_type != kStatic) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800263 mirror::Object* obj = reinterpret_cast<mirror::Object*>(regs[cur_arg]);
Ian Rogers57b86d42012-03-27 16:05:41 -0700264 cur_arg++;
265 if (args_in_regs < 3) {
266 // If we thought we had fewer than 3 arguments in registers, account for the receiver
267 args_in_regs++;
268 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700269 soa.AddLocalReference<jobject>(obj);
Ian Rogers57b86d42012-03-27 16:05:41 -0700270 }
271 size_t shorty_index = 1; // skip return value
272 // Iterate while arguments and arguments in registers (less 1 from cur_arg which is offset to skip
273 // R0)
274 while ((cur_arg - 1) < args_in_regs && shorty_index < shorty_len) {
275 char c = shorty[shorty_index];
276 shorty_index++;
277 if (c == 'L') {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800278 mirror::Object* obj = reinterpret_cast<mirror::Object*>(regs[cur_arg]);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700279 soa.AddLocalReference<jobject>(obj);
Ian Rogers57b86d42012-03-27 16:05:41 -0700280 }
281 cur_arg = cur_arg + (c == 'J' || c == 'D' ? 2 : 1);
282 }
283 // Place into local references incoming arguments from the caller's stack arguments
jeffhaofa147e22012-10-12 17:03:32 -0700284 cur_arg += pc_offset + 1; // skip LR/RA, Method* and spills for R1-R3/A1-A3 and callee saves
Ian Rogers57b86d42012-03-27 16:05:41 -0700285 while (shorty_index < shorty_len) {
286 char c = shorty[shorty_index];
287 shorty_index++;
288 if (c == 'L') {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800289 mirror::Object* obj = reinterpret_cast<mirror::Object*>(regs[cur_arg]);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700290 soa.AddLocalReference<jobject>(obj);
Ian Rogers57b86d42012-03-27 16:05:41 -0700291 }
292 cur_arg = cur_arg + (c == 'J' || c == 'D' ? 2 : 1);
293 }
Ian Rogers7caad772012-03-30 01:07:54 -0700294#endif
Ian Rogers57b86d42012-03-27 16:05:41 -0700295 // Resolve method filling in dex cache
Jeff Hao58df3272013-04-22 15:28:53 -0700296 if (called->IsRuntimeMethod()) {
Ian Rogers08f753d2012-08-24 14:35:25 -0700297 called = linker->ResolveMethod(dex_method_idx, caller, invoke_type);
Ian Rogers57b86d42012-03-27 16:05:41 -0700298 }
299 const void* code = NULL;
300 if (LIKELY(!thread->IsExceptionPending())) {
Ian Rogers08f753d2012-08-24 14:35:25 -0700301 // Incompatible class change should have been handled in resolve method.
302 CHECK(!called->CheckIncompatibleClassChange(invoke_type));
303 // Ensure that the called method's class is initialized.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800304 mirror::Class* called_class = called->GetDeclaringClass();
Ian Rogers08f753d2012-08-24 14:35:25 -0700305 linker->EnsureInitialized(called_class, true, true);
306 if (LIKELY(called_class->IsInitialized())) {
307 code = called->GetCode();
308 } else if (called_class->IsInitializing()) {
309 if (invoke_type == kStatic) {
310 // Class is still initializing, go to oat and grab code (trampoline must be left in place
311 // until class is initialized to stop races between threads).
312 code = linker->GetOatCodeFor(called);
Ian Rogers57b86d42012-03-27 16:05:41 -0700313 } else {
Ian Rogers08f753d2012-08-24 14:35:25 -0700314 // No trampoline for non-static methods.
315 code = called->GetCode();
Ian Rogers57b86d42012-03-27 16:05:41 -0700316 }
317 } else {
Ian Rogers08f753d2012-08-24 14:35:25 -0700318 DCHECK(called_class->IsErroneous());
Ian Rogers57b86d42012-03-27 16:05:41 -0700319 }
320 }
321 if (UNLIKELY(code == NULL)) {
322 // Something went wrong in ResolveMethod or EnsureInitialized,
323 // go into deliver exception with the pending exception in r0
Ian Rogersf3e98552013-03-20 15:49:49 -0700324 CHECK(thread->IsExceptionPending());
Logan Chien8dbb7082013-01-25 20:31:17 +0800325 code = reinterpret_cast<void*>(art_quick_deliver_exception_from_code);
Ian Rogers62d6c772013-02-27 08:32:07 -0800326 regs[0] = reinterpret_cast<uintptr_t>(thread->GetException(NULL));
Ian Rogers57b86d42012-03-27 16:05:41 -0700327 thread->ClearException();
328 } else {
329 // Expect class to at least be initializing.
330 DCHECK(called->GetDeclaringClass()->IsInitializing());
331 // Don't want infinite recursion.
Jeff Hao58df3272013-04-22 15:28:53 -0700332 DCHECK(code != GetResolutionTrampoline());
Ian Rogers57b86d42012-03-27 16:05:41 -0700333 // Set up entry into main method
334 regs[0] = reinterpret_cast<uintptr_t>(called);
335 }
336 return code;
337}
TDYa12705fe3b62012-04-21 00:28:54 -0700338
Ian Rogers57b86d42012-03-27 16:05:41 -0700339// Called by the AbstractMethodError. Called by stub code.
Ian Rogers62d6c772013-02-27 08:32:07 -0800340extern void ThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thread* self,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800341 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700342 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers1c42ff92013-04-09 10:03:34 -0700343#if !defined(ART_USE_PORTABLE_COMPILER)
Ian Rogers62d6c772013-02-27 08:32:07 -0800344 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
Ian Rogers1c42ff92013-04-09 10:03:34 -0700345#else
346 UNUSED(sp);
347#endif
Ian Rogers62d6c772013-02-27 08:32:07 -0800348 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
349 self->ThrowNewExceptionF(throw_location, "Ljava/lang/AbstractMethodError;",
350 "abstract method \"%s\"", PrettyMethod(method).c_str());
351 self->QuickDeliverException();
Ian Rogers57b86d42012-03-27 16:05:41 -0700352}
Ian Rogers57b86d42012-03-27 16:05:41 -0700353
354} // namespace art