blob: 13f9c07223e80894400711d1e1a2e300d7fdcfd7 [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
Shih-wei Liaoc486c112011-09-13 16:43:52 -070012typedef void (*ThrowAme)(Method*, Thread*);
13
Ian Rogersbdb03912011-09-14 00:55:44 -070014ByteArray* CreateAbstractMethodErrorStub() {
Shih-wei Liaoc486c112011-09-13 16:43:52 -070015 UniquePtr<X86Assembler> assembler( static_cast<X86Assembler*>(Assembler::Create(kX86)) );
16
17 // Pad stack to ensure 16-byte alignment
18 __ pushl(Immediate(0));
Shih-wei Liaoc486c112011-09-13 16:43:52 -070019 __ fs()->pushl(Address::Absolute(Thread::SelfOffset())); // Thread*
Ian Rogers67375ac2011-09-14 00:55:44 -070020 __ pushl(EAX); // Method*
Shih-wei Liaoc486c112011-09-13 16:43:52 -070021
Ian Rogersbdb03912011-09-14 00:55:44 -070022 // Call to throw AbstractMethodError
23 __ Call(ThreadOffset(OFFSETOF_MEMBER(Thread, pThrowAbstractMethodErrorFromCode)),
24 X86ManagedRegister::FromCpuRegister(ECX));
Shih-wei Liaoc486c112011-09-13 16:43:52 -070025
26 // Because the call above never returns, we do not need to do ESP+=16 here.
27
28 __ int3();
29
30 assembler->EmitSlowPaths();
31
32 size_t cs = assembler->CodeSize();
33 ByteArray* abstract_stub = ByteArray::Alloc(cs);
34 CHECK(abstract_stub != NULL);
35 MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
36 assembler->FinalizeInstructions(code);
37
38 return abstract_stub;
39}
40
Shih-wei Liao31384c52011-09-06 15:27:45 -070041ByteArray* CreateJniStub() {
42 UniquePtr<X86Assembler> assembler( static_cast<X86Assembler*>(Assembler::Create(kX86)) );
43
44 // Pad stack to ensure 16-byte alignment
45 __ pushl(Immediate(0));
46 __ pushl(Immediate(0));
Ian Rogers67375ac2011-09-14 00:55:44 -070047 __ fs()->pushl(Address::Absolute(Thread::SelfOffset())); // Thread*
Shih-wei Liao31384c52011-09-06 15:27:45 -070048
Ian Rogersbdb03912011-09-14 00:55:44 -070049 __ Call(ThreadOffset(OFFSETOF_MEMBER(Thread, pFindNativeMethod)),
50 X86ManagedRegister::FromCpuRegister(ECX));
Shih-wei Liao31384c52011-09-06 15:27:45 -070051
Ian Rogers67375ac2011-09-14 00:55:44 -070052 __ addl(ESP, Immediate(12));
Shih-wei Liao31384c52011-09-06 15:27:45 -070053
54 Label no_native_code_found; // forward declaration
55 __ cmpl(EAX, Immediate(0));
56 __ j(kEqual, &no_native_code_found);
57
58 __ jmp(EAX); // Tail call into native code
59
60 __ Bind(&no_native_code_found);
61 __ ret(); // return to caller to handle exception
62
63 assembler->EmitSlowPaths();
64
65 size_t cs = assembler->CodeSize();
66 ByteArray* jni_stub = ByteArray::Alloc(cs);
67 CHECK(jni_stub != NULL);
68 MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength());
69 assembler->FinalizeInstructions(code);
70
71 return jni_stub;
72}
73
74} // namespace x86
75} // namespace art