1/*
2 * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#if ENABLE(JIT)
29
30#include "CodeOrigin.h"
31#include "JITOperations.h"
32#include "JSCJSValue.h"
33#include "PutKind.h"
34#include "RegisterSet.h"
35
36namespace JSC {
37
38class CallSiteIndex;
39class CodeBlock;
40class StructureStubInfo;
41
42enum class AccessType : int8_t;
43
44class JITInlineCacheGenerator {
45protected:
46 JITInlineCacheGenerator() { }
47 JITInlineCacheGenerator(
48 CodeBlock*, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters);
49
50public:
51 StructureStubInfo* stubInfo() const { return m_stubInfo; }
52
53 void reportSlowPathCall(MacroAssembler::Label slowPathBegin, MacroAssembler::Call call)
54 {
55 m_slowPathBegin = slowPathBegin;
56 m_slowPathCall = call;
57 }
58
59 MacroAssembler::Label slowPathBegin() const { return m_slowPathBegin; }
60
61 void finalize(
62 LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer,
63 CodeLocationLabel<JITStubRoutinePtrTag> start);
64
65protected:
66 CodeBlock* m_codeBlock;
67 StructureStubInfo* m_stubInfo;
68
69 MacroAssembler::Label m_done;
70 MacroAssembler::Label m_slowPathBegin;
71 MacroAssembler::Call m_slowPathCall;
72};
73
74class JITByIdGenerator : public JITInlineCacheGenerator {
75protected:
76 JITByIdGenerator() { }
77
78 JITByIdGenerator(
79 CodeBlock*, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters,
80 JSValueRegs base, JSValueRegs value);
81
82public:
83 MacroAssembler::Jump slowPathJump() const
84 {
85 ASSERT(m_slowPathJump.isSet());
86 return m_slowPathJump;
87 }
88
89 void finalize(
90 LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer);
91
92protected:
93
94 void generateFastCommon(MacroAssembler&, size_t size);
95
96 JSValueRegs m_base;
97 JSValueRegs m_value;
98
99 MacroAssembler::Label m_start;
100 MacroAssembler::Jump m_slowPathJump;
101};
102
103class JITGetByIdGenerator : public JITByIdGenerator {
104public:
105 JITGetByIdGenerator() { }
106
107 JITGetByIdGenerator(
108 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, UniquedStringImpl* propertyName,
109 JSValueRegs base, JSValueRegs value, AccessType);
110
111 void generateFastPath(MacroAssembler&);
112
113private:
114 bool m_isLengthAccess;
115};
116
117class JITGetByIdWithThisGenerator : public JITByIdGenerator {
118public:
119 JITGetByIdWithThisGenerator() { }
120
121 JITGetByIdWithThisGenerator(
122 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, UniquedStringImpl* propertyName,
123 JSValueRegs value, JSValueRegs base, JSValueRegs thisRegs);
124
125 void generateFastPath(MacroAssembler&);
126};
127
128class JITPutByIdGenerator : public JITByIdGenerator {
129public:
130 JITPutByIdGenerator() { }
131
132 JITPutByIdGenerator(
133 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, JSValueRegs base,
134 JSValueRegs value, GPRReg scratch, ECMAMode, PutKind);
135
136 void generateFastPath(MacroAssembler&);
137
138 V_JITOperation_GSsiJJI slowPathFunction();
139
140private:
141 ECMAMode m_ecmaMode;
142 PutKind m_putKind;
143};
144
145class JITInByIdGenerator : public JITByIdGenerator {
146public:
147 JITInByIdGenerator() { }
148
149 JITInByIdGenerator(
150 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, UniquedStringImpl* propertyName,
151 JSValueRegs base, JSValueRegs value);
152
153 void generateFastPath(MacroAssembler&);
154};
155
156class JITInstanceOfGenerator : public JITInlineCacheGenerator {
157public:
158 JITInstanceOfGenerator() { }
159
160 JITInstanceOfGenerator(
161 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, GPRReg result,
162 GPRReg value, GPRReg prototype, GPRReg scratch1, GPRReg scratch2,
163 bool prototypeIsKnownObject = false);
164
165 void generateFastPath(MacroAssembler&);
166
167 void finalize(LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer);
168
169private:
170 MacroAssembler::PatchableJump m_jump;
171};
172
173class JITGetByValGenerator : public JITInlineCacheGenerator {
174 using Base = JITInlineCacheGenerator;
175public:
176 JITGetByValGenerator() { }
177
178 JITGetByValGenerator(
179 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters,
180 JSValueRegs base, JSValueRegs property, JSValueRegs result);
181
182 MacroAssembler::Jump slowPathJump() const
183 {
184 ASSERT(m_slowPathJump.m_jump.isSet());
185 return m_slowPathJump.m_jump;
186 }
187
188 void finalize(
189 LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer);
190
191 void generateFastPath(MacroAssembler&);
192
193private:
194 JSValueRegs m_base;
195 JSValueRegs m_result;
196 JSValueRegs m_;
197
198 MacroAssembler::Label m_start;
199 MacroAssembler::PatchableJump m_slowPathJump;
200};
201
202template<typename VectorType>
203void finalizeInlineCaches(VectorType& vector, LinkBuffer& fastPath, LinkBuffer& slowPath)
204{
205 for (auto& entry : vector)
206 entry.finalize(fastPath, slowPath);
207}
208
209template<typename VectorType>
210void finalizeInlineCaches(VectorType& vector, LinkBuffer& linkBuffer)
211{
212 finalizeInlineCaches(vector, linkBuffer, linkBuffer);
213}
214
215} // namespace JSC
216
217#endif // ENABLE(JIT)
218