blob: 9a6797a2fbc49ff8bac343dbe48c30d3d9b4b7d6 [file] [log] [blame]
Shih-wei Liao31384c52011-09-06 15:27:45 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#include "assembler_x86.h"
4#include "jni_internal.h"
5#include "object.h"
6
7#define __ assembler->
8
9namespace art {
10namespace x86 {
11
Ian Rogers1cb0a1d2011-10-06 15:24:35 -070012ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType) {
Ian Rogersad25ac52011-10-04 19:13:33 -070013 UniquePtr<X86Assembler> assembler( static_cast<X86Assembler*>(Assembler::Create(kX86)) );
14
15 // TODO: unimplemented
16 __ int3();
17
18 assembler->EmitSlowPaths();
19 size_t cs = assembler->CodeSize();
20 ByteArray* resolution_trampoline = ByteArray::Alloc(cs);
21 CHECK(resolution_trampoline != NULL);
22 MemoryRegion code(resolution_trampoline->GetData(), resolution_trampoline->GetLength());
23 assembler->FinalizeInstructions(code);
24
25 return resolution_trampoline;
26}
27
Shih-wei Liaoc486c112011-09-13 16:43:52 -070028typedef void (*ThrowAme)(Method*, Thread*);
29
Ian Rogersbdb03912011-09-14 00:55:44 -070030ByteArray* CreateAbstractMethodErrorStub() {
Shih-wei Liaoc486c112011-09-13 16:43:52 -070031 UniquePtr<X86Assembler> assembler( static_cast<X86Assembler*>(Assembler::Create(kX86)) );
32
33 // Pad stack to ensure 16-byte alignment
34 __ pushl(Immediate(0));
Shih-wei Liaoc486c112011-09-13 16:43:52 -070035 __ fs()->pushl(Address::Absolute(Thread::SelfOffset())); // Thread*
Ian Rogers67375ac2011-09-14 00:55:44 -070036 __ pushl(EAX); // Method*
Shih-wei Liaoc486c112011-09-13 16:43:52 -070037
Ian Rogersbdb03912011-09-14 00:55:44 -070038 // Call to throw AbstractMethodError
39 __ Call(ThreadOffset(OFFSETOF_MEMBER(Thread, pThrowAbstractMethodErrorFromCode)),
40 X86ManagedRegister::FromCpuRegister(ECX));
Shih-wei Liaoc486c112011-09-13 16:43:52 -070041
42 // Because the call above never returns, we do not need to do ESP+=16 here.
43
44 __ int3();
45
46 assembler->EmitSlowPaths();
47
48 size_t cs = assembler->CodeSize();
49 ByteArray* abstract_stub = ByteArray::Alloc(cs);
50 CHECK(abstract_stub != NULL);
51 MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
52 assembler->FinalizeInstructions(code);
53
54 return abstract_stub;
55}
56
Shih-wei Liao31384c52011-09-06 15:27:45 -070057ByteArray* CreateJniStub() {
58 UniquePtr<X86Assembler> assembler( static_cast<X86Assembler*>(Assembler::Create(kX86)) );
59
60 // Pad stack to ensure 16-byte alignment
61 __ pushl(Immediate(0));
62 __ pushl(Immediate(0));
Ian Rogers67375ac2011-09-14 00:55:44 -070063 __ fs()->pushl(Address::Absolute(Thread::SelfOffset())); // Thread*
Shih-wei Liao31384c52011-09-06 15:27:45 -070064
Ian Rogersbdb03912011-09-14 00:55:44 -070065 __ Call(ThreadOffset(OFFSETOF_MEMBER(Thread, pFindNativeMethod)),
66 X86ManagedRegister::FromCpuRegister(ECX));
Shih-wei Liao31384c52011-09-06 15:27:45 -070067
Ian Rogers67375ac2011-09-14 00:55:44 -070068 __ addl(ESP, Immediate(12));
Shih-wei Liao31384c52011-09-06 15:27:45 -070069
70 Label no_native_code_found; // forward declaration
71 __ cmpl(EAX, Immediate(0));
72 __ j(kEqual, &no_native_code_found);
73
74 __ jmp(EAX); // Tail call into native code
75
76 __ Bind(&no_native_code_found);
77 __ ret(); // return to caller to handle exception
78
79 assembler->EmitSlowPaths();
80
81 size_t cs = assembler->CodeSize();
82 ByteArray* jni_stub = ByteArray::Alloc(cs);
83 CHECK(jni_stub != NULL);
84 MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength());
85 assembler->FinalizeInstructions(code);
86
87 return jni_stub;
88}
89
90} // namespace x86
91} // namespace art