Line data Source code
1 : // Copyright 2018 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_COMPILER_SERIALIZER_FOR_BACKGROUND_COMPILATION_H_
6 : #define V8_COMPILER_SERIALIZER_FOR_BACKGROUND_COMPILATION_H_
7 :
8 : #include "src/base/optional.h"
9 : #include "src/compiler/access-info.h"
10 : #include "src/handles.h"
11 : #include "src/maybe-handles.h"
12 : #include "src/utils.h"
13 : #include "src/zone/zone-containers.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 : namespace interpreter {
19 : class BytecodeArrayIterator;
20 : } // namespace interpreter
21 :
22 : class BytecodeArray;
23 : class FeedbackVector;
24 : class LookupIterator;
25 : class NativeContext;
26 : class ScriptContextTable;
27 : class SharedFunctionInfo;
28 : class SourcePositionTableIterator;
29 : class Zone;
30 :
31 : namespace compiler {
32 :
33 : #define CLEAR_ENVIRONMENT_LIST(V) \
34 : V(Abort) \
35 : V(CallRuntime) \
36 : V(CallRuntimeForPair) \
37 : V(CreateBlockContext) \
38 : V(CreateEvalContext) \
39 : V(CreateFunctionContext) \
40 : V(Debugger) \
41 : V(PopContext) \
42 : V(PushContext) \
43 : V(ResumeGenerator) \
44 : V(ReThrow) \
45 : V(StaContextSlot) \
46 : V(StaCurrentContextSlot) \
47 : V(SuspendGenerator) \
48 : V(SwitchOnGeneratorState) \
49 : V(Throw)
50 :
51 : #define CLEAR_ACCUMULATOR_LIST(V) \
52 : V(Add) \
53 : V(AddSmi) \
54 : V(BitwiseAnd) \
55 : V(BitwiseAndSmi) \
56 : V(BitwiseNot) \
57 : V(BitwiseOr) \
58 : V(BitwiseOrSmi) \
59 : V(BitwiseXor) \
60 : V(BitwiseXorSmi) \
61 : V(CloneObject) \
62 : V(CreateArrayFromIterable) \
63 : V(CreateArrayLiteral) \
64 : V(CreateEmptyArrayLiteral) \
65 : V(CreateEmptyObjectLiteral) \
66 : V(CreateMappedArguments) \
67 : V(CreateObjectLiteral) \
68 : V(CreateRestParameter) \
69 : V(CreateUnmappedArguments) \
70 : V(Dec) \
71 : V(DeletePropertySloppy) \
72 : V(DeletePropertyStrict) \
73 : V(Div) \
74 : V(DivSmi) \
75 : V(Exp) \
76 : V(ExpSmi) \
77 : V(ForInContinue) \
78 : V(ForInEnumerate) \
79 : V(ForInNext) \
80 : V(ForInStep) \
81 : V(GetTemplateObject) \
82 : V(Inc) \
83 : V(LdaContextSlot) \
84 : V(LdaCurrentContextSlot) \
85 : V(LdaImmutableContextSlot) \
86 : V(LdaImmutableCurrentContextSlot) \
87 : V(LogicalNot) \
88 : V(Mod) \
89 : V(ModSmi) \
90 : V(Mul) \
91 : V(MulSmi) \
92 : V(Negate) \
93 : V(SetPendingMessage) \
94 : V(ShiftLeft) \
95 : V(ShiftLeftSmi) \
96 : V(ShiftRight) \
97 : V(ShiftRightLogical) \
98 : V(ShiftRightLogicalSmi) \
99 : V(ShiftRightSmi) \
100 : V(Sub) \
101 : V(SubSmi) \
102 : V(TestEqual) \
103 : V(TestEqualStrict) \
104 : V(TestGreaterThan) \
105 : V(TestGreaterThanOrEqual) \
106 : V(TestInstanceOf) \
107 : V(TestLessThan) \
108 : V(TestLessThanOrEqual) \
109 : V(TestNull) \
110 : V(TestReferenceEqual) \
111 : V(TestTypeOf) \
112 : V(TestUndefined) \
113 : V(TestUndetectable) \
114 : V(ToBooleanLogicalNot) \
115 : V(ToName) \
116 : V(ToNumber) \
117 : V(ToNumeric) \
118 : V(ToString) \
119 : V(TypeOf)
120 :
121 : #define UNCONDITIONAL_JUMPS_LIST(V) \
122 : V(Jump) \
123 : V(JumpConstant) \
124 : V(JumpLoop)
125 :
126 : #define CONDITIONAL_JUMPS_LIST(V) \
127 : V(JumpIfFalse) \
128 : V(JumpIfFalseConstant) \
129 : V(JumpIfJSReceiver) \
130 : V(JumpIfJSReceiverConstant) \
131 : V(JumpIfNotNull) \
132 : V(JumpIfNotNullConstant) \
133 : V(JumpIfNotUndefined) \
134 : V(JumpIfNotUndefinedConstant) \
135 : V(JumpIfNull) \
136 : V(JumpIfNullConstant) \
137 : V(JumpIfToBooleanFalse) \
138 : V(JumpIfToBooleanFalseConstant) \
139 : V(JumpIfToBooleanTrue) \
140 : V(JumpIfToBooleanTrueConstant) \
141 : V(JumpIfTrue) \
142 : V(JumpIfTrueConstant) \
143 : V(JumpIfUndefined) \
144 : V(JumpIfUndefinedConstant)
145 :
146 : #define IGNORED_BYTECODE_LIST(V) \
147 : V(CallNoFeedback) \
148 : V(LdaNamedPropertyNoFeedback) \
149 : V(StackCheck) \
150 : V(StaNamedPropertyNoFeedback) \
151 : V(ThrowReferenceErrorIfHole) \
152 : V(ThrowSuperAlreadyCalledIfNotHole) \
153 : V(ThrowSuperNotCalledIfHole)
154 :
155 : #define SUPPORTED_BYTECODE_LIST(V) \
156 : V(CallAnyReceiver) \
157 : V(CallProperty) \
158 : V(CallProperty0) \
159 : V(CallProperty1) \
160 : V(CallProperty2) \
161 : V(CallUndefinedReceiver) \
162 : V(CallUndefinedReceiver0) \
163 : V(CallUndefinedReceiver1) \
164 : V(CallUndefinedReceiver2) \
165 : V(CallWithSpread) \
166 : V(Construct) \
167 : V(ConstructWithSpread) \
168 : V(CreateClosure) \
169 : V(ExtraWide) \
170 : V(GetSuperConstructor) \
171 : V(Illegal) \
172 : V(LdaConstant) \
173 : V(LdaFalse) \
174 : V(LdaGlobal) \
175 : V(LdaGlobalInsideTypeof) \
176 : V(LdaKeyedProperty) \
177 : V(LdaLookupGlobalSlot) \
178 : V(LdaLookupGlobalSlotInsideTypeof) \
179 : V(LdaNamedProperty) \
180 : V(LdaNull) \
181 : V(Ldar) \
182 : V(LdaSmi) \
183 : V(LdaTheHole) \
184 : V(LdaTrue) \
185 : V(LdaUndefined) \
186 : V(LdaZero) \
187 : V(Mov) \
188 : V(Return) \
189 : V(StaGlobal) \
190 : V(StaInArrayLiteral) \
191 : V(StaKeyedProperty) \
192 : V(StaNamedProperty) \
193 : V(Star) \
194 : V(TestIn) \
195 : V(Wide) \
196 : CLEAR_ENVIRONMENT_LIST(V) \
197 : CLEAR_ACCUMULATOR_LIST(V) \
198 : CONDITIONAL_JUMPS_LIST(V) \
199 : UNCONDITIONAL_JUMPS_LIST(V) \
200 : IGNORED_BYTECODE_LIST(V)
201 :
202 : class JSHeapBroker;
203 :
204 : template <typename T>
205 : struct HandleComparator {
206 : bool operator()(const Handle<T>& lhs, const Handle<T>& rhs) const {
207 36 : return lhs.address() < rhs.address();
208 : }
209 : };
210 :
211 : struct FunctionBlueprint {
212 : Handle<SharedFunctionInfo> shared;
213 : Handle<FeedbackVector> feedback_vector;
214 :
215 : bool operator<(const FunctionBlueprint& other) const {
216 : // A feedback vector is never used for more than one SFI, so it can
217 : // be used for strict ordering of blueprints.
218 : DCHECK_IMPLIES(feedback_vector.equals(other.feedback_vector),
219 : shared.equals(other.shared));
220 : return HandleComparator<FeedbackVector>()(feedback_vector,
221 : other.feedback_vector);
222 : }
223 : };
224 :
225 : class CompilationSubject {
226 : public:
227 : explicit CompilationSubject(FunctionBlueprint blueprint)
228 18 : : blueprint_(blueprint) {}
229 : CompilationSubject(Handle<JSFunction> closure, Isolate* isolate);
230 :
231 : FunctionBlueprint blueprint() const { return blueprint_; }
232 : MaybeHandle<JSFunction> closure() const { return closure_; }
233 :
234 : private:
235 : FunctionBlueprint blueprint_;
236 : MaybeHandle<JSFunction> closure_;
237 : };
238 :
239 : using ConstantsSet = ZoneSet<Handle<Object>, HandleComparator<Object>>;
240 : using MapsSet = ZoneSet<Handle<Map>, HandleComparator<Map>>;
241 : using BlueprintsSet = ZoneSet<FunctionBlueprint>;
242 :
243 6100 : class Hints {
244 : public:
245 : explicit Hints(Zone* zone);
246 :
247 : const ConstantsSet& constants() const;
248 : const MapsSet& maps() const;
249 : const BlueprintsSet& function_blueprints() const;
250 :
251 : void AddConstant(Handle<Object> constant);
252 : void AddMap(Handle<Map> map);
253 : void AddFunctionBlueprint(FunctionBlueprint function_blueprint);
254 :
255 : void Add(const Hints& other);
256 :
257 : void Clear();
258 : bool IsEmpty() const;
259 :
260 : private:
261 : ConstantsSet constants_;
262 : MapsSet maps_;
263 : BlueprintsSet function_blueprints_;
264 : };
265 :
266 : using HintsVector = ZoneVector<Hints>;
267 :
268 : // The SerializerForBackgroundCompilation makes sure that the relevant function
269 : // data such as bytecode, SharedFunctionInfo and FeedbackVector, used by later
270 : // optimizations in the compiler, is copied to the heap broker.
271 171 : class SerializerForBackgroundCompilation {
272 : public:
273 : SerializerForBackgroundCompilation(JSHeapBroker* broker, Zone* zone,
274 : Handle<JSFunction> closure);
275 : Hints Run(); // NOTE: Returns empty for an already-serialized function.
276 :
277 : class Environment;
278 :
279 : private:
280 : SerializerForBackgroundCompilation(JSHeapBroker* broker, Zone* zone,
281 : CompilationSubject function,
282 : base::Optional<Hints> new_target,
283 : const HintsVector& arguments);
284 :
285 : void TraverseBytecode();
286 :
287 : #define DECLARE_VISIT_BYTECODE(name, ...) \
288 : void Visit##name(interpreter::BytecodeArrayIterator* iterator);
289 : SUPPORTED_BYTECODE_LIST(DECLARE_VISIT_BYTECODE)
290 : #undef DECLARE_VISIT_BYTECODE
291 :
292 : void ProcessCallOrConstruct(Hints callee, base::Optional<Hints> new_target,
293 : const HintsVector& arguments, FeedbackSlot slot,
294 : bool with_spread = false);
295 : void ProcessCallVarArgs(interpreter::BytecodeArrayIterator* iterator,
296 : ConvertReceiverMode receiver_mode,
297 : bool with_spread = false);
298 :
299 : void ProcessJump(interpreter::BytecodeArrayIterator* iterator);
300 : void MergeAfterJump(interpreter::BytecodeArrayIterator* iterator);
301 :
302 : void ProcessKeyedPropertyAccess(Hints const& receiver, Hints const& key,
303 : FeedbackSlot slot, AccessMode mode);
304 : void ProcessNamedPropertyAccess(interpreter::BytecodeArrayIterator* iterator,
305 : AccessMode mode);
306 : void ProcessNamedPropertyAccess(Hints const& receiver, NameRef const& name,
307 : FeedbackSlot slot, AccessMode mode);
308 :
309 : GlobalAccessFeedback const* ProcessFeedbackForGlobalAccess(FeedbackSlot slot);
310 : void ProcessFeedbackForKeyedPropertyAccess(FeedbackSlot slot,
311 : AccessMode mode);
312 : void ProcessFeedbackForNamedPropertyAccess(FeedbackSlot slot,
313 : NameRef const& name);
314 : void ProcessMapForNamedPropertyAccess(MapRef const& map, NameRef const& name);
315 :
316 : Hints RunChildSerializer(CompilationSubject function,
317 : base::Optional<Hints> new_target,
318 : const HintsVector& arguments, bool with_spread);
319 :
320 : JSHeapBroker* broker() const { return broker_; }
321 : Zone* zone() const { return zone_; }
322 : Environment* environment() const { return environment_; }
323 :
324 : JSHeapBroker* const broker_;
325 : Zone* const zone_;
326 : Environment* const environment_;
327 : ZoneUnorderedMap<int, Environment*> stashed_environments_;
328 : };
329 :
330 : } // namespace compiler
331 : } // namespace internal
332 : } // namespace v8
333 :
334 : #endif // V8_COMPILER_SERIALIZER_FOR_BACKGROUND_COMPILATION_H_
|