blob: 5df7da30bbc9da58f21311cefb2fffb9dc6be071 [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
TDYa12705fe3b62012-04-21 00:28:54 -070017#if !defined(ART_USE_LLVM_COMPILER)
Ian Rogers57b86d42012-03-27 16:05:41 -070018#include "callee_save_frame.h"
TDYa12705fe3b62012-04-21 00:28:54 -070019#endif
Ian Rogers57b86d42012-03-27 16:05:41 -070020#include "dex_instruction.h"
21#include "object.h"
22#include "object_utils.h"
TDYa12705fe3b62012-04-21 00:28:54 -070023#if defined(ART_USE_LLVM_COMPILER)
24#include "nth_caller_visitor.h"
25#endif
Ian Rogers00f7d0e2012-07-19 15:28:27 -070026#include "scoped_thread_state_change.h"
Ian Rogers57b86d42012-03-27 16:05:41 -070027
28// Architecture specific assembler helper to deliver exception.
29extern "C" void art_deliver_exception_from_code(void*);
30
31namespace art {
32
TDYa12705fe3b62012-04-21 00:28:54 -070033#if !defined(ART_USE_LLVM_COMPILER)
Ian Rogers57b86d42012-03-27 16:05:41 -070034// Lazily resolve a method. Called by stub code.
35const void* UnresolvedDirectMethodTrampolineFromCode(Method* called, Method** sp, Thread* thread,
Ian Rogers00f7d0e2012-07-19 15:28:27 -070036 Runtime::TrampolineType type)
Ian Rogersb726dcb2012-09-05 08:57:23 -070037 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers7caad772012-03-30 01:07:54 -070038#if defined(__arm__)
Ian Rogers57b86d42012-03-27 16:05:41 -070039 // On entry the stack pointed by sp is:
40 // | argN | |
41 // | ... | |
42 // | arg4 | |
43 // | arg3 spill | | Caller's frame
44 // | arg2 spill | |
45 // | arg1 spill | |
46 // | Method* | ---
47 // | LR |
48 // | ... | callee saves
49 // | R3 | arg3
50 // | R2 | arg2
51 // | R1 | arg1
52 // | R0 |
53 // | Method* | <- sp
Ian Rogers57b86d42012-03-27 16:05:41 -070054 DCHECK_EQ(48U, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes());
55 Method** caller_sp = reinterpret_cast<Method**>(reinterpret_cast<byte*>(sp) + 48);
Ian Rogers7caad772012-03-30 01:07:54 -070056 uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp) + kPointerSize);
Ian Rogers57b86d42012-03-27 16:05:41 -070057 uintptr_t caller_pc = regs[10];
Ian Rogers7caad772012-03-30 01:07:54 -070058#elif defined(__i386__)
59 // On entry the stack pointed by sp is:
60 // | argN | |
61 // | ... | |
62 // | arg4 | |
63 // | arg3 spill | | Caller's frame
64 // | arg2 spill | |
65 // | arg1 spill | |
66 // | Method* | ---
67 // | Return |
68 // | EBP,ESI,EDI | callee saves
69 // | EBX | arg3
70 // | EDX | arg2
71 // | ECX | arg1
72 // | EAX/Method* | <- sp
73 DCHECK_EQ(32U, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes());
74 Method** caller_sp = reinterpret_cast<Method**>(reinterpret_cast<byte*>(sp) + 32);
75 uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp));
76 uintptr_t caller_pc = regs[7];
77#else
78 UNIMPLEMENTED(FATAL);
79 Method** caller_sp = NULL;
80 uintptr_t* regs = NULL;
81 uintptr_t caller_pc = 0;
82#endif
Ian Rogers57b86d42012-03-27 16:05:41 -070083 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kRefsAndArgs);
84 // Start new JNI local reference state
85 JNIEnvExt* env = thread->GetJniEnv();
Ian Rogers00f7d0e2012-07-19 15:28:27 -070086 ScopedObjectAccessUnchecked soa(env);
Ian Rogers57b86d42012-03-27 16:05:41 -070087 ScopedJniEnvLocalRefState env_state(env);
88
89 // Compute details about the called method (avoid GCs)
90 ClassLinker* linker = Runtime::Current()->GetClassLinker();
91 Method* caller = *caller_sp;
Ian Rogers08f753d2012-08-24 14:35:25 -070092 InvokeType invoke_type;
Ian Rogers57b86d42012-03-27 16:05:41 -070093 uint32_t dex_method_idx;
Brian Carlstromfd2ec542012-05-02 15:08:57 -070094#if !defined(__i386__)
Ian Rogers57b86d42012-03-27 16:05:41 -070095 const char* shorty;
96 uint32_t shorty_len;
Brian Carlstromfd2ec542012-05-02 15:08:57 -070097#endif
Ian Rogers57b86d42012-03-27 16:05:41 -070098 if (type == Runtime::kUnknownMethod) {
99 DCHECK(called->IsRuntimeMethod());
Ian Rogers0c7abda2012-09-19 13:33:42 -0700100 uint32_t dex_pc = caller->ToDexPc(caller_pc);
Ian Rogers57b86d42012-03-27 16:05:41 -0700101 const DexFile::CodeItem* code = MethodHelper(caller).GetCodeItem();
102 CHECK_LT(dex_pc, code->insns_size_in_code_units_);
103 const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
104 Instruction::Code instr_code = instr->Opcode();
Ian Rogers08f753d2012-08-24 14:35:25 -0700105 switch (instr_code) {
106 case Instruction::INVOKE_DIRECT: // Fall-through.
107 case Instruction::INVOKE_DIRECT_RANGE:
108 invoke_type = kDirect;
109 break;
110 case Instruction::INVOKE_STATIC: // Fall-through.
111 case Instruction::INVOKE_STATIC_RANGE:
112 invoke_type = kStatic;
113 break;
114 case Instruction::INVOKE_SUPER: // Fall-through.
115 case Instruction::INVOKE_SUPER_RANGE:
116 invoke_type = kSuper;
117 break;
118 case Instruction::INVOKE_VIRTUAL: // Fall-through.
119 case Instruction::INVOKE_VIRTUAL_RANGE:
120 invoke_type = kVirtual;
121 break;
122 default:
123 LOG(FATAL) << "Unexpected call into trampoline: " << instr->DumpString(NULL);
124 invoke_type = kDirect; // Avoid used uninitialized warnings.
125 }
Ian Rogers57b86d42012-03-27 16:05:41 -0700126 DecodedInstruction dec_insn(instr);
127 dex_method_idx = dec_insn.vB;
Brian Carlstromfd2ec542012-05-02 15:08:57 -0700128#if !defined(__i386__)
Ian Rogers57b86d42012-03-27 16:05:41 -0700129 shorty = linker->MethodShorty(dex_method_idx, caller, &shorty_len);
Brian Carlstromfd2ec542012-05-02 15:08:57 -0700130#endif
Ian Rogers57b86d42012-03-27 16:05:41 -0700131 } else {
132 DCHECK(!called->IsRuntimeMethod());
Ian Rogers08f753d2012-08-24 14:35:25 -0700133 invoke_type = (type == Runtime::kStaticMethod) ? kStatic : kDirect;
Ian Rogers57b86d42012-03-27 16:05:41 -0700134 dex_method_idx = called->GetDexMethodIndex();
Brian Carlstromfd2ec542012-05-02 15:08:57 -0700135#if !defined(__i386__)
Ian Rogers57b86d42012-03-27 16:05:41 -0700136 MethodHelper mh(called);
137 shorty = mh.GetShorty();
138 shorty_len = mh.GetShortyLength();
Brian Carlstromfd2ec542012-05-02 15:08:57 -0700139#endif
Ian Rogers57b86d42012-03-27 16:05:41 -0700140 }
Ian Rogers7caad772012-03-30 01:07:54 -0700141#if !defined(__i386__)
Ian Rogers57b86d42012-03-27 16:05:41 -0700142 // Discover shorty (avoid GCs)
143 size_t args_in_regs = 0;
144 for (size_t i = 1; i < shorty_len; i++) {
145 char c = shorty[i];
146 args_in_regs = args_in_regs + (c == 'J' || c == 'D' ? 2 : 1);
147 if (args_in_regs > 3) {
148 args_in_regs = 3;
149 break;
150 }
151 }
152 // Place into local references incoming arguments from the caller's register arguments
153 size_t cur_arg = 1; // skip method_idx in R0, first arg is in R1
Ian Rogers08f753d2012-08-24 14:35:25 -0700154 if (invoke_type != kStatic) {
Ian Rogers57b86d42012-03-27 16:05:41 -0700155 Object* obj = reinterpret_cast<Object*>(regs[cur_arg]);
156 cur_arg++;
157 if (args_in_regs < 3) {
158 // If we thought we had fewer than 3 arguments in registers, account for the receiver
159 args_in_regs++;
160 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700161 soa.AddLocalReference<jobject>(obj);
Ian Rogers57b86d42012-03-27 16:05:41 -0700162 }
163 size_t shorty_index = 1; // skip return value
164 // Iterate while arguments and arguments in registers (less 1 from cur_arg which is offset to skip
165 // R0)
166 while ((cur_arg - 1) < args_in_regs && shorty_index < shorty_len) {
167 char c = shorty[shorty_index];
168 shorty_index++;
169 if (c == 'L') {
170 Object* obj = reinterpret_cast<Object*>(regs[cur_arg]);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700171 soa.AddLocalReference<jobject>(obj);
Ian Rogers57b86d42012-03-27 16:05:41 -0700172 }
173 cur_arg = cur_arg + (c == 'J' || c == 'D' ? 2 : 1);
174 }
175 // Place into local references incoming arguments from the caller's stack arguments
176 cur_arg += 11; // skip LR, Method* and spills for R1 to R3 and callee saves
177 while (shorty_index < shorty_len) {
178 char c = shorty[shorty_index];
179 shorty_index++;
180 if (c == 'L') {
181 Object* obj = reinterpret_cast<Object*>(regs[cur_arg]);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700182 soa.AddLocalReference<jobject>(obj);
Ian Rogers57b86d42012-03-27 16:05:41 -0700183 }
184 cur_arg = cur_arg + (c == 'J' || c == 'D' ? 2 : 1);
185 }
Ian Rogers7caad772012-03-30 01:07:54 -0700186#endif
Ian Rogers57b86d42012-03-27 16:05:41 -0700187 // Resolve method filling in dex cache
188 if (type == Runtime::kUnknownMethod) {
Ian Rogers08f753d2012-08-24 14:35:25 -0700189 called = linker->ResolveMethod(dex_method_idx, caller, invoke_type);
Ian Rogers57b86d42012-03-27 16:05:41 -0700190 }
191 const void* code = NULL;
192 if (LIKELY(!thread->IsExceptionPending())) {
Ian Rogers08f753d2012-08-24 14:35:25 -0700193 // Incompatible class change should have been handled in resolve method.
194 CHECK(!called->CheckIncompatibleClassChange(invoke_type));
195 // Ensure that the called method's class is initialized.
196 Class* called_class = called->GetDeclaringClass();
197 linker->EnsureInitialized(called_class, true, true);
198 if (LIKELY(called_class->IsInitialized())) {
199 code = called->GetCode();
200 } else if (called_class->IsInitializing()) {
201 if (invoke_type == kStatic) {
202 // Class is still initializing, go to oat and grab code (trampoline must be left in place
203 // until class is initialized to stop races between threads).
204 code = linker->GetOatCodeFor(called);
Ian Rogers57b86d42012-03-27 16:05:41 -0700205 } else {
Ian Rogers08f753d2012-08-24 14:35:25 -0700206 // No trampoline for non-static methods.
207 code = called->GetCode();
Ian Rogers57b86d42012-03-27 16:05:41 -0700208 }
209 } else {
Ian Rogers08f753d2012-08-24 14:35:25 -0700210 DCHECK(called_class->IsErroneous());
Ian Rogers57b86d42012-03-27 16:05:41 -0700211 }
212 }
213 if (UNLIKELY(code == NULL)) {
214 // Something went wrong in ResolveMethod or EnsureInitialized,
215 // go into deliver exception with the pending exception in r0
216 code = reinterpret_cast<void*>(art_deliver_exception_from_code);
217 regs[0] = reinterpret_cast<uintptr_t>(thread->GetException());
218 thread->ClearException();
219 } else {
220 // Expect class to at least be initializing.
221 DCHECK(called->GetDeclaringClass()->IsInitializing());
222 // Don't want infinite recursion.
223 DCHECK(code != Runtime::Current()->GetResolutionStubArray(Runtime::kUnknownMethod)->GetData());
224 // Set up entry into main method
225 regs[0] = reinterpret_cast<uintptr_t>(called);
226 }
227 return code;
228}
TDYa12705fe3b62012-04-21 00:28:54 -0700229#else // ART_USE_LLVM_COMPILER
230const void* UnresolvedDirectMethodTrampolineFromCode(Method* called, Method** called_addr,
Shih-wei Liaocd05a622012-08-15 00:02:05 -0700231 Thread* thread, Runtime::TrampolineType type)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700232 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers0399dde2012-06-06 17:09:28 -0700233 uint32_t dex_pc;
234 Method* caller = thread->GetCurrentMethod(&dex_pc);
Ian Rogers57b86d42012-03-27 16:05:41 -0700235
TDYa12705fe3b62012-04-21 00:28:54 -0700236 ClassLinker* linker = Runtime::Current()->GetClassLinker();
Ian Rogers08f753d2012-08-24 14:35:25 -0700237 InvokeType invoke_type;
TDYa12705fe3b62012-04-21 00:28:54 -0700238 uint32_t dex_method_idx;
239 if (type == Runtime::kUnknownMethod) {
240 DCHECK(called->IsRuntimeMethod());
TDYa12705fe3b62012-04-21 00:28:54 -0700241 const DexFile::CodeItem* code = MethodHelper(caller).GetCodeItem();
242 CHECK_LT(dex_pc, code->insns_size_in_code_units_);
243 const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
244 Instruction::Code instr_code = instr->Opcode();
Ian Rogers08f753d2012-08-24 14:35:25 -0700245 switch (instr_code) {
246 case Instruction::INVOKE_DIRECT: // Fall-through.
247 case Instruction::INVOKE_DIRECT_RANGE:
248 invoke_type = kDirect;
249 break;
250 case Instruction::INVOKE_STATIC: // Fall-through.
251 case Instruction::INVOKE_STATIC_RANGE:
252 invoke_type = kStatic;
253 break;
254 case Instruction::INVOKE_SUPER: // Fall-through.
255 case Instruction::INVOKE_SUPER_RANGE:
256 invoke_type = kSuper;
257 break;
258 case Instruction::INVOKE_VIRTUAL: // Fall-through.
259 case Instruction::INVOKE_VIRTUAL_RANGE:
260 invoke_type = kVirtual;
261 break;
262 default:
263 LOG(FATAL) << "Unexpected call into trampoline: " << instr->DumpString(NULL);
264 invoke_type = kDirect; // Avoid used uninitialized warnings.
265 }
TDYa12705fe3b62012-04-21 00:28:54 -0700266 DecodedInstruction dec_insn(instr);
267 dex_method_idx = dec_insn.vB;
268 } else {
269 DCHECK(!called->IsRuntimeMethod());
Ian Rogers08f753d2012-08-24 14:35:25 -0700270 invoke_type = (type == Runtime::kStaticMethod) ? kStatic : kDirect;
TDYa12705fe3b62012-04-21 00:28:54 -0700271 dex_method_idx = called->GetDexMethodIndex();
272 }
273 if (type == Runtime::kUnknownMethod) {
Ian Rogers08f753d2012-08-24 14:35:25 -0700274 called = linker->ResolveMethod(dex_method_idx, caller, invoke_type);
TDYa12705fe3b62012-04-21 00:28:54 -0700275 }
276 const void* code = NULL;
277 if (LIKELY(!thread->IsExceptionPending())) {
Ian Rogers08f753d2012-08-24 14:35:25 -0700278 // Incompatible class change should have been handled in resolve method.
279 CHECK(!called->CheckIncompatibleClassChange(invoke_type));
280 // Ensure that the called method's class is initialized.
281 Class* called_class = called->GetDeclaringClass();
282 linker->EnsureInitialized(called_class, true, true);
283 if (LIKELY(called_class->IsInitialized())) {
284 code = called->GetCode();
285 // TODO: remove this after we solve the link issue.
286 { // for lazy link.
287 if (code == NULL) {
288 code = linker->GetOatCodeFor(called);
289 }
290 }
291 } else if (called_class->IsInitializing()) {
292 if (invoke_type == kStatic) {
293 // Class is still initializing, go to oat and grab code (trampoline must be left in place
294 // until class is initialized to stop races between threads).
295 code = linker->GetOatCodeFor(called);
296 } else {
297 // No trampoline for non-static methods.
TDYa12705fe3b62012-04-21 00:28:54 -0700298 code = called->GetCode();
299 // TODO: remove this after we solve the link issue.
300 { // for lazy link.
301 if (code == NULL) {
302 code = linker->GetOatCodeFor(called);
303 }
304 }
TDYa12705fe3b62012-04-21 00:28:54 -0700305 }
306 } else {
Ian Rogers08f753d2012-08-24 14:35:25 -0700307 DCHECK(called_class->IsErroneous());
TDYa12705fe3b62012-04-21 00:28:54 -0700308 }
309 }
310 if (LIKELY(code != NULL)) {
311 // Expect class to at least be initializing.
312 DCHECK(called->GetDeclaringClass()->IsInitializing());
313 // Don't want infinite recursion.
314 DCHECK(code != Runtime::Current()->GetResolutionStubArray(Runtime::kUnknownMethod)->GetData());
315 // Set up entry into main method
316 *called_addr = called;
317 }
318 return code;
319}
320#endif // ART_USE_LLVM_COMPILER
321
322#if !defined(ART_USE_LLVM_COMPILER)
Ian Rogers57b86d42012-03-27 16:05:41 -0700323// Called by the AbstractMethodError. Called by stub code.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700324extern void ThrowAbstractMethodErrorFromCode(Method* method, Thread* thread, Method** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700325 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers57b86d42012-03-27 16:05:41 -0700326 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
327 thread->ThrowNewExceptionF("Ljava/lang/AbstractMethodError;",
328 "abstract method \"%s\"", PrettyMethod(method).c_str());
329 thread->DeliverException();
330}
TDYa12705fe3b62012-04-21 00:28:54 -0700331#else // ART_USE_LLVM_COMPILER
Shih-wei Liaocd05a622012-08-15 00:02:05 -0700332extern void ThrowAbstractMethodErrorFromCode(Method* method, Thread* thread, Method**)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700333 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
TDYa12705fe3b62012-04-21 00:28:54 -0700334 thread->ThrowNewExceptionF("Ljava/lang/AbstractMethodError;",
335 "abstract method \"%s\"", PrettyMethod(method).c_str());
336}
337#endif // ART_USE_LLVM_COMPILER
Ian Rogers57b86d42012-03-27 16:05:41 -0700338
339} // namespace art