2 * Copyright (C) 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef SpecializedThunkJIT_h
27 #define SpecializedThunkJIT_h
31 #include "Executable.h"
32 #include "JSInterfaceJIT.h"
33 #include "LinkBuffer.h"
37 class SpecializedThunkJIT
: public JSInterfaceJIT
{
39 static const int ThisArgument
= -1;
40 SpecializedThunkJIT(int expectedArgCount
, JSGlobalData
* globalData
, ExecutablePool
* pool
)
41 : m_expectedArgCount(expectedArgCount
)
42 , m_globalData(globalData
)
45 // Check that we have the expected number of arguments
46 m_failures
.append(branch32(NotEqual
, Address(callFrameRegister
, RegisterFile::ArgumentCount
* (int)sizeof(Register
)), TrustedImm32(expectedArgCount
+ 1)));
49 void loadDoubleArgument(int argument
, FPRegisterID dst
, RegisterID scratch
)
51 unsigned src
= argumentToVirtualRegister(argument
);
52 m_failures
.append(emitLoadDouble(src
, dst
, scratch
));
55 void loadCellArgument(int argument
, RegisterID dst
)
57 unsigned src
= argumentToVirtualRegister(argument
);
58 m_failures
.append(emitLoadJSCell(src
, dst
));
61 void loadJSStringArgument(int argument
, RegisterID dst
)
63 loadCellArgument(argument
, dst
);
64 m_failures
.append(branchPtr(NotEqual
, Address(dst
, 0), TrustedImmPtr(m_globalData
->jsStringVPtr
)));
65 m_failures
.append(branchTest32(NonZero
, Address(dst
, OBJECT_OFFSETOF(JSString
, m_fiberCount
))));
68 void loadInt32Argument(int argument
, RegisterID dst
, Jump
& failTarget
)
70 unsigned src
= argumentToVirtualRegister(argument
);
71 failTarget
= emitLoadInt32(src
, dst
);
74 void loadInt32Argument(int argument
, RegisterID dst
)
76 Jump conversionFailed
;
77 loadInt32Argument(argument
, dst
, conversionFailed
);
78 m_failures
.append(conversionFailed
);
81 void appendFailure(const Jump
& failure
)
83 m_failures
.append(failure
);
86 void returnJSValue(RegisterID src
)
90 loadPtr(payloadFor(RegisterFile::CallerFrame
, callFrameRegister
), callFrameRegister
);
94 void returnDouble(FPRegisterID src
)
97 moveDoubleToPtr(src
, regT0
);
98 subPtr(tagTypeNumberRegister
, regT0
);
100 storeDouble(src
, Address(stackPointerRegister
, -(int)sizeof(double)));
101 loadPtr(Address(stackPointerRegister
, OBJECT_OFFSETOF(JSValue
, u
.asBits
.tag
) - sizeof(double)), regT1
);
102 loadPtr(Address(stackPointerRegister
, OBJECT_OFFSETOF(JSValue
, u
.asBits
.payload
) - sizeof(double)), regT0
);
104 loadPtr(payloadFor(RegisterFile::CallerFrame
, callFrameRegister
), callFrameRegister
);
108 void returnInt32(RegisterID src
)
113 loadPtr(payloadFor(RegisterFile::CallerFrame
, callFrameRegister
), callFrameRegister
);
117 void returnJSCell(RegisterID src
)
122 loadPtr(payloadFor(RegisterFile::CallerFrame
, callFrameRegister
), callFrameRegister
);
126 MacroAssemblerCodePtr
finalize(JSGlobalData
& globalData
, MacroAssemblerCodePtr fallback
)
128 LinkBuffer
patchBuffer(globalData
, this, m_pool
.get());
129 patchBuffer
.link(m_failures
, CodeLocationLabel(fallback
));
130 return patchBuffer
.finalizeCode().m_code
;
134 int argumentToVirtualRegister(unsigned argument
)
136 return -static_cast<int>(RegisterFile::CallFrameHeaderSize
+ (m_expectedArgCount
- argument
));
139 void tagReturnAsInt32()
142 orPtr(tagTypeNumberRegister
, regT0
);
144 move(TrustedImm32(JSValue::Int32Tag
), regT1
);
148 void tagReturnAsJSCell()
150 #if USE(JSVALUE32_64)
151 move(TrustedImm32(JSValue::CellTag
), regT1
);
155 int m_expectedArgCount
;
156 JSGlobalData
* m_globalData
;
157 RefPtr
<ExecutablePool
> m_pool
;
158 MacroAssembler::JumpList m_failures
;
163 #endif // ENABLE(JIT)
165 #endif // SpecializedThunkJIT_h