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