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/handles.h"
10 : #include "src/maybe-handles.h"
11 : #include "src/zone/zone-containers.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 : namespace interpreter {
17 : class BytecodeArrayIterator;
18 : } // namespace interpreter
19 :
20 : class BytecodeArray;
21 : class FeedbackVector;
22 : class LookupIterator;
23 : class NativeContext;
24 : class ScriptContextTable;
25 : class SharedFunctionInfo;
26 : class SourcePositionTableIterator;
27 : class Zone;
28 :
29 : namespace compiler {
30 :
31 : #define CLEAR_ENVIRONMENT_LIST(V) \
32 : V(Abort) \
33 : V(CallRuntime) \
34 : V(CallRuntimeForPair) \
35 : V(CreateBlockContext) \
36 : V(CreateFunctionContext) \
37 : V(CreateEvalContext) \
38 : V(Debugger) \
39 : V(PushContext) \
40 : V(PopContext) \
41 : V(ResumeGenerator) \
42 : V(ReThrow) \
43 : V(StaContextSlot) \
44 : V(StaCurrentContextSlot) \
45 : V(SuspendGenerator) \
46 : V(SwitchOnGeneratorState) \
47 : V(Throw)
48 :
49 : #define CLEAR_ACCUMULATOR_LIST(V) \
50 : V(CreateEmptyObjectLiteral) \
51 : V(CreateMappedArguments) \
52 : V(CreateRestParameter) \
53 : V(CreateUnmappedArguments) \
54 : V(LdaContextSlot) \
55 : V(LdaCurrentContextSlot) \
56 : V(LdaGlobal) \
57 : V(LdaGlobalInsideTypeof) \
58 : V(LdaImmutableContextSlot) \
59 : V(LdaImmutableCurrentContextSlot) \
60 : V(LdaKeyedProperty) \
61 : V(LdaNamedProperty) \
62 : V(LdaNamedPropertyNoFeedback)
63 :
64 : #define UNCONDITIONAL_JUMPS_LIST(V) \
65 : V(Jump) \
66 : V(JumpConstant) \
67 : V(JumpLoop)
68 :
69 : #define CONDITIONAL_JUMPS_LIST(V) \
70 : V(JumpIfFalse) \
71 : V(JumpIfFalseConstant) \
72 : V(JumpIfJSReceiver) \
73 : V(JumpIfJSReceiverConstant) \
74 : V(JumpIfNotNull) \
75 : V(JumpIfNotNullConstant) \
76 : V(JumpIfNotUndefined) \
77 : V(JumpIfNotUndefinedConstant) \
78 : V(JumpIfNull) \
79 : V(JumpIfNullConstant) \
80 : V(JumpIfToBooleanTrueConstant) \
81 : V(JumpIfToBooleanFalseConstant) \
82 : V(JumpIfToBooleanTrue) \
83 : V(JumpIfToBooleanFalse) \
84 : V(JumpIfTrue) \
85 : V(JumpIfTrueConstant) \
86 : V(JumpIfUndefined) \
87 : V(JumpIfUndefinedConstant)
88 :
89 : #define INGORED_BYTECODE_LIST(V) \
90 : V(TestEqual) \
91 : V(TestEqualStrict) \
92 : V(TestLessThan) \
93 : V(TestGreaterThan) \
94 : V(TestLessThanOrEqual) \
95 : V(TestGreaterThanOrEqual) \
96 : V(TestReferenceEqual) \
97 : V(TestInstanceOf) \
98 : V(TestIn) \
99 : V(TestUndetectable) \
100 : V(TestNull) \
101 : V(TestUndefined) \
102 : V(TestTypeOf) \
103 : V(ThrowReferenceErrorIfHole) \
104 : V(ThrowSuperNotCalledIfHole) \
105 : V(ThrowSuperAlreadyCalledIfNotHole)
106 :
107 : #define SUPPORTED_BYTECODE_LIST(V) \
108 : V(CallAnyReceiver) \
109 : V(CallNoFeedback) \
110 : V(CallProperty) \
111 : V(CallProperty0) \
112 : V(CallProperty1) \
113 : V(CallProperty2) \
114 : V(CallUndefinedReceiver) \
115 : V(CallUndefinedReceiver0) \
116 : V(CallUndefinedReceiver1) \
117 : V(CallUndefinedReceiver2) \
118 : V(CallWithSpread) \
119 : V(Construct) \
120 : V(ConstructWithSpread) \
121 : V(CreateClosure) \
122 : V(ExtraWide) \
123 : V(Illegal) \
124 : V(LdaConstant) \
125 : V(LdaNull) \
126 : V(Ldar) \
127 : V(LdaSmi) \
128 : V(LdaUndefined) \
129 : V(LdaZero) \
130 : V(Mov) \
131 : V(Return) \
132 : V(StackCheck) \
133 : V(Star) \
134 : V(Wide) \
135 : CLEAR_ENVIRONMENT_LIST(V) \
136 : CLEAR_ACCUMULATOR_LIST(V) \
137 : CONDITIONAL_JUMPS_LIST(V) \
138 : UNCONDITIONAL_JUMPS_LIST(V) \
139 : INGORED_BYTECODE_LIST(V)
140 :
141 : class JSHeapBroker;
142 :
143 : template <typename T>
144 : struct HandleComparator {
145 50 : bool operator()(const Handle<T>& lhs, const Handle<T>& rhs) const {
146 50 : return lhs.address() < rhs.address();
147 : }
148 : };
149 :
150 : struct FunctionBlueprint {
151 : Handle<SharedFunctionInfo> shared;
152 : Handle<FeedbackVector> feedback_vector;
153 :
154 : bool operator<(const FunctionBlueprint& other) const {
155 : // A feedback vector is never used for more than one SFI, so it can
156 : // be used for strict ordering of blueprints.
157 : DCHECK_IMPLIES(feedback_vector.equals(other.feedback_vector),
158 : shared.equals(other.shared));
159 : return HandleComparator<FeedbackVector>()(feedback_vector,
160 20 : other.feedback_vector);
161 : }
162 : };
163 :
164 : class CompilationSubject {
165 : public:
166 : explicit CompilationSubject(FunctionBlueprint blueprint)
167 18 : : blueprint_(blueprint) {}
168 : CompilationSubject(Handle<JSFunction> closure, Isolate* isolate);
169 :
170 : FunctionBlueprint blueprint() const { return blueprint_; }
171 : MaybeHandle<JSFunction> closure() const { return closure_; }
172 :
173 : private:
174 : FunctionBlueprint blueprint_;
175 : MaybeHandle<JSFunction> closure_;
176 : };
177 :
178 : typedef ZoneSet<Handle<Object>, HandleComparator<Object>> ConstantsSet;
179 : typedef ZoneSet<Handle<Map>, HandleComparator<Map>> MapsSet;
180 : typedef ZoneSet<FunctionBlueprint> BlueprintsSet;
181 :
182 4992 : class Hints {
183 : public:
184 : explicit Hints(Zone* zone);
185 :
186 : const ConstantsSet& constants() const;
187 : const MapsSet& maps() const;
188 : const BlueprintsSet& function_blueprints() const;
189 :
190 : void AddConstant(Handle<Object> constant);
191 : void AddMap(Handle<Map> map);
192 : void AddFunctionBlueprint(FunctionBlueprint function_blueprint);
193 :
194 : void Add(const Hints& other);
195 :
196 : void Clear();
197 : bool IsEmpty() const;
198 :
199 : private:
200 : ConstantsSet constants_;
201 : MapsSet maps_;
202 : BlueprintsSet function_blueprints_;
203 : };
204 :
205 : typedef ZoneVector<Hints> HintsVector;
206 :
207 : // The SerializerForBackgroundCompilation makes sure that the relevant function
208 : // data such as bytecode, SharedFunctionInfo and FeedbackVector, used by later
209 : // optimizations in the compiler, is copied to the heap broker.
210 : class SerializerForBackgroundCompilation {
211 : public:
212 : SerializerForBackgroundCompilation(JSHeapBroker* broker, Zone* zone,
213 : Handle<JSFunction> closure);
214 : Hints Run(); // NOTE: Returns empty for an already-serialized function.
215 :
216 : class Environment;
217 :
218 : private:
219 : SerializerForBackgroundCompilation(JSHeapBroker* broker, Zone* zone,
220 : CompilationSubject function,
221 : base::Optional<Hints> new_target,
222 : const HintsVector& arguments);
223 :
224 : void TraverseBytecode();
225 :
226 : #define DECLARE_VISIT_BYTECODE(name, ...) \
227 : void Visit##name(interpreter::BytecodeArrayIterator* iterator);
228 : SUPPORTED_BYTECODE_LIST(DECLARE_VISIT_BYTECODE)
229 : #undef DECLARE_VISIT_BYTECODE
230 :
231 : void ProcessCallOrConstruct(Hints callee, base::Optional<Hints> new_target,
232 : const HintsVector& arguments, FeedbackSlot slot,
233 : bool with_spread = false);
234 : void ProcessCallVarArgs(interpreter::BytecodeArrayIterator* iterator,
235 : ConvertReceiverMode receiver_mode,
236 : bool with_spread = false);
237 : void ProcessJump(interpreter::BytecodeArrayIterator* iterator);
238 : void MergeAfterJump(interpreter::BytecodeArrayIterator* iterator);
239 :
240 : Hints RunChildSerializer(CompilationSubject function,
241 : base::Optional<Hints> new_target,
242 : const HintsVector& arguments, bool with_spread);
243 :
244 : JSHeapBroker* broker() const { return broker_; }
245 : Zone* zone() const { return zone_; }
246 : Environment* environment() const { return environment_; }
247 :
248 : JSHeapBroker* const broker_;
249 : Zone* const zone_;
250 : Environment* const environment_;
251 : ZoneUnorderedMap<int, Environment*> stashed_environments_;
252 : };
253 :
254 : } // namespace compiler
255 : } // namespace internal
256 : } // namespace v8
257 :
258 : #endif // V8_COMPILER_SERIALIZER_FOR_BACKGROUND_COMPILATION_H_
|