Line data Source code
1 : // Copyright 2017 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_OBJECTS_SHARED_FUNCTION_INFO_H_
6 : #define V8_OBJECTS_SHARED_FUNCTION_INFO_H_
7 :
8 : #include "src/bailout-reason.h"
9 : #include "src/function-kind.h"
10 : #include "src/objects.h"
11 : #include "src/objects/builtin-function-id.h"
12 : #include "src/objects/script.h"
13 : #include "src/objects/smi.h"
14 : #include "src/objects/struct.h"
15 : #include "torque-generated/class-definitions-from-dsl.h"
16 :
17 : // Has to be the last include (doesn't have include guards):
18 : #include "src/objects/object-macros.h"
19 :
20 : namespace v8 {
21 : namespace internal {
22 :
23 : class AsmWasmData;
24 : class BytecodeArray;
25 : class CoverageInfo;
26 : class DebugInfo;
27 : class IsCompiledScope;
28 : class WasmExportedFunctionData;
29 :
30 : // Data collected by the pre-parser storing information about scopes and inner
31 : // functions.
32 : //
33 : // PreparseData Layout:
34 : // +-------------------------------+
35 : // | data_length | children_length |
36 : // +-------------------------------+
37 : // | Scope Byte Data ... |
38 : // | ... |
39 : // +-------------------------------+
40 : // | [Padding] |
41 : // +-------------------------------+
42 : // | Inner PreparseData 1 |
43 : // +-------------------------------+
44 : // | ... |
45 : // +-------------------------------+
46 : // | Inner PreparseData N |
47 : // +-------------------------------+
48 : class PreparseData : public HeapObject {
49 : public:
50 : DECL_INT_ACCESSORS(data_length)
51 : DECL_INT_ACCESSORS(children_length)
52 :
53 : inline int inner_start_offset() const;
54 : inline ObjectSlot inner_data_start() const;
55 :
56 : inline byte get(int index) const;
57 : inline void set(int index, byte value);
58 : inline void copy_in(int index, const byte* buffer, int length);
59 :
60 : inline PreparseData get_child(int index) const;
61 : inline void set_child(int index, PreparseData value,
62 : WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
63 :
64 : // Clear uninitialized padding space.
65 : inline void clear_padding();
66 :
67 : DECL_CAST(PreparseData)
68 : DECL_PRINTER(PreparseData)
69 : DECL_VERIFIER(PreparseData)
70 :
71 : // Layout description.
72 : #define PREPARSE_DATA_FIELDS(V) \
73 : V(kDataLengthOffset, kInt32Size) \
74 : V(kInnerLengthOffset, kInt32Size) \
75 : /* Header size. */ \
76 : V(kDataStartOffset, 0) \
77 : V(kHeaderSize, 0)
78 :
79 : DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, PREPARSE_DATA_FIELDS)
80 : #undef PREPARSE_DATA_FIELDS
81 :
82 : class BodyDescriptor;
83 :
84 : static int InnerOffset(int data_length) {
85 454587 : return RoundUp(kDataStartOffset + data_length * kByteSize, kTaggedSize);
86 : }
87 :
88 : static int SizeFor(int data_length, int children_length) {
89 318454 : return InnerOffset(data_length) + children_length * kTaggedSize;
90 : }
91 :
92 49953 : OBJECT_CONSTRUCTORS(PreparseData, HeapObject);
93 :
94 : private:
95 : inline Object get_child_raw(int index) const;
96 : };
97 :
98 : // Abstract class representing extra data for an uncompiled function, which is
99 : // not stored in the SharedFunctionInfo.
100 : class UncompiledData : public HeapObject {
101 : public:
102 : DECL_ACCESSORS(inferred_name, String)
103 : DECL_INT32_ACCESSORS(start_position)
104 : DECL_INT32_ACCESSORS(end_position)
105 : DECL_INT32_ACCESSORS(function_literal_id)
106 :
107 : // Returns true if the UncompiledData contains a valid function_literal_id.
108 : inline bool has_function_literal_id();
109 :
110 : DECL_CAST(UncompiledData)
111 :
112 : inline static void Initialize(
113 : UncompiledData data, String inferred_name, int start_position,
114 : int end_position, int function_literal_id,
115 : std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
116 : gc_notify_updated_slot =
117 : [](HeapObject object, ObjectSlot slot, HeapObject target) {});
118 :
119 : // Layout description.
120 : #define UNCOMPILED_DATA_FIELDS(V) \
121 : V(kStartOfPointerFieldsOffset, 0) \
122 : V(kInferredNameOffset, kTaggedSize) \
123 : V(kEndOfTaggedFieldsOffset, 0) \
124 : /* Raw data fields. */ \
125 : V(kStartPositionOffset, kInt32Size) \
126 : V(kEndPositionOffset, kInt32Size) \
127 : V(kFunctionLiteralIdOffset, kInt32Size) \
128 : V(kOptionalPaddingOffset, POINTER_SIZE_PADDING(kOptionalPaddingOffset)) \
129 : /* Header size. */ \
130 : V(kSize, 0)
131 :
132 : DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, UNCOMPILED_DATA_FIELDS)
133 : #undef UNCOMPILED_DATA_FIELDS
134 :
135 : typedef FixedBodyDescriptor<kStartOfPointerFieldsOffset,
136 : kEndOfTaggedFieldsOffset, kSize>
137 : BodyDescriptor;
138 :
139 : // Clear uninitialized padding space.
140 : inline void clear_padding();
141 :
142 : OBJECT_CONSTRUCTORS(UncompiledData, HeapObject);
143 : };
144 :
145 : // Class representing data for an uncompiled function that does not have any
146 : // data from the pre-parser, either because it's a leaf function or because the
147 : // pre-parser bailed out.
148 : class UncompiledDataWithoutPreparseData : public UncompiledData {
149 : public:
150 : DECL_CAST(UncompiledDataWithoutPreparseData)
151 : DECL_PRINTER(UncompiledDataWithoutPreparseData)
152 : DECL_VERIFIER(UncompiledDataWithoutPreparseData)
153 :
154 : static const int kSize = UncompiledData::kSize;
155 :
156 : // No extra fields compared to UncompiledData.
157 : typedef UncompiledData::BodyDescriptor BodyDescriptor;
158 :
159 6868177 : OBJECT_CONSTRUCTORS(UncompiledDataWithoutPreparseData, UncompiledData);
160 : };
161 :
162 : // Class representing data for an uncompiled function that has pre-parsed scope
163 : // data.
164 : class UncompiledDataWithPreparseData : public UncompiledData {
165 : public:
166 : DECL_ACCESSORS(preparse_data, PreparseData)
167 :
168 : DECL_CAST(UncompiledDataWithPreparseData)
169 : DECL_PRINTER(UncompiledDataWithPreparseData)
170 : DECL_VERIFIER(UncompiledDataWithPreparseData)
171 :
172 : inline static void Initialize(
173 : UncompiledDataWithPreparseData data, String inferred_name,
174 : int start_position, int end_position, int function_literal_id,
175 : PreparseData scope_data,
176 : std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
177 : gc_notify_updated_slot =
178 : [](HeapObject object, ObjectSlot slot, HeapObject target) {});
179 :
180 : // Layout description.
181 :
182 : #define UNCOMPILED_DATA_WITH_PREPARSE_DATA_FIELDS(V) \
183 : V(kStartOfPointerFieldsOffset, 0) \
184 : V(kPreparseDataOffset, kTaggedSize) \
185 : V(kEndOfTaggedFieldsOffset, 0) \
186 : /* Total size. */ \
187 : V(kSize, 0)
188 :
189 : DEFINE_FIELD_OFFSET_CONSTANTS(UncompiledData::kSize,
190 : UNCOMPILED_DATA_WITH_PREPARSE_DATA_FIELDS)
191 : #undef UNCOMPILED_DATA_WITH_PREPARSE_DATA_FIELDS
192 :
193 : // Make sure the size is aligned
194 : STATIC_ASSERT(kSize == POINTER_SIZE_ALIGN(kSize));
195 :
196 : typedef SubclassBodyDescriptor<
197 : UncompiledData::BodyDescriptor,
198 : FixedBodyDescriptor<kStartOfPointerFieldsOffset, kEndOfTaggedFieldsOffset,
199 : kSize>>
200 : BodyDescriptor;
201 :
202 43488 : OBJECT_CONSTRUCTORS(UncompiledDataWithPreparseData, UncompiledData);
203 : };
204 :
205 : class InterpreterData : public Struct {
206 : public:
207 : DECL_ACCESSORS(bytecode_array, BytecodeArray)
208 : DECL_ACCESSORS(interpreter_trampoline, Code)
209 :
210 : // Layout description.
211 : #define INTERPRETER_DATA_FIELDS(V) \
212 : V(kBytecodeArrayOffset, kTaggedSize) \
213 : V(kInterpreterTrampolineOffset, kTaggedSize) \
214 : /* Total size. */ \
215 : V(kSize, 0)
216 :
217 : DEFINE_FIELD_OFFSET_CONSTANTS(Struct::kHeaderSize, INTERPRETER_DATA_FIELDS)
218 : #undef INTERPRETER_DATA_FIELDS
219 :
220 : DECL_CAST(InterpreterData)
221 : DECL_PRINTER(InterpreterData)
222 : DECL_VERIFIER(InterpreterData)
223 :
224 : OBJECT_CONSTRUCTORS(InterpreterData, Struct);
225 : };
226 :
227 : // SharedFunctionInfo describes the JSFunction information that can be
228 : // shared by multiple instances of the function.
229 : class SharedFunctionInfo : public HeapObject {
230 : public:
231 : NEVER_READ_ONLY_SPACE
232 : static constexpr Object const kNoSharedNameSentinel = Smi::kZero;
233 :
234 : // [name]: Returns shared name if it exists or an empty string otherwise.
235 : inline String Name() const;
236 : inline void SetName(String name);
237 :
238 : // Get the code object which represents the execution of this function.
239 : Code GetCode() const;
240 :
241 : // Get the abstract code associated with the function, which will either be
242 : // a Code object or a BytecodeArray.
243 : inline AbstractCode abstract_code();
244 :
245 : // Tells whether or not this shared function info is interpreted.
246 : //
247 : // Note: function->IsInterpreted() does not necessarily return the same value
248 : // as function->shared()->IsInterpreted() because the closure might have been
249 : // optimized.
250 : inline bool IsInterpreted() const;
251 :
252 : // Set up the link between shared function info and the script. The shared
253 : // function info is added to the list on the script.
254 : V8_EXPORT_PRIVATE static void SetScript(
255 : Handle<SharedFunctionInfo> shared, Handle<Object> script_object,
256 : int function_literal_id, bool reset_preparsed_scope_data = true);
257 :
258 : // Layout description of the optimized code map.
259 : static const int kEntriesStart = 0;
260 : static const int kContextOffset = 0;
261 : static const int kCachedCodeOffset = 1;
262 : static const int kEntryLength = 2;
263 : static const int kInitialLength = kEntriesStart + kEntryLength;
264 :
265 : static const int kNotFound = -1;
266 : static const uint16_t kInvalidLength = static_cast<uint16_t>(-1);
267 :
268 : // [scope_info]: Scope info.
269 : DECL_ACCESSORS(scope_info, ScopeInfo)
270 :
271 : // End position of this function in the script source.
272 : V8_EXPORT_PRIVATE int EndPosition() const;
273 :
274 : // Start position of this function in the script source.
275 : V8_EXPORT_PRIVATE int StartPosition() const;
276 :
277 : // Set the start and end position of this function in the script source.
278 : // Updates the scope info if available.
279 : V8_EXPORT_PRIVATE void SetPosition(int start_position, int end_position);
280 :
281 : // [outer scope info | feedback metadata] Shared storage for outer scope info
282 : // (on uncompiled functions) and feedback metadata (on compiled functions).
283 : DECL_ACCESSORS(raw_outer_scope_info_or_feedback_metadata, HeapObject)
284 :
285 : // Get the outer scope info whether this function is compiled or not.
286 : inline bool HasOuterScopeInfo() const;
287 : inline ScopeInfo GetOuterScopeInfo() const;
288 :
289 : // [feedback metadata] Metadata template for feedback vectors of instances of
290 : // this function.
291 : inline bool HasFeedbackMetadata() const;
292 : DECL_ACCESSORS(feedback_metadata, FeedbackMetadata)
293 :
294 : // Returns if this function has been compiled yet. Note: with bytecode
295 : // flushing, any GC after this call is made could cause the function
296 : // to become uncompiled. If you need to ensure the function remains compiled
297 : // for some period of time, use IsCompiledScope instead.
298 : inline bool is_compiled() const;
299 :
300 : // Returns an IsCompiledScope which reports whether the function is compiled,
301 : // and if compiled, will avoid the function becoming uncompiled while it is
302 : // held.
303 : inline IsCompiledScope is_compiled_scope() const;
304 :
305 : // [length]: The function length - usually the number of declared parameters.
306 : // Use up to 2^16-2 parameters (16 bits of values, where one is reserved for
307 : // kDontAdaptArgumentsSentinel). The value is only reliable when the function
308 : // has been compiled.
309 : inline uint16_t GetLength() const;
310 : inline bool HasLength() const;
311 : inline void set_length(int value);
312 :
313 : // [internal formal parameter count]: The declared number of parameters.
314 : // For subclass constructors, also includes new.target.
315 : // The size of function's frame is internal_formal_parameter_count + 1.
316 : DECL_UINT16_ACCESSORS(internal_formal_parameter_count)
317 :
318 : // Set the formal parameter count so the function code will be
319 : // called without using argument adaptor frames.
320 : inline void DontAdaptArguments();
321 :
322 : // [expected_nof_properties]: Expected number of properties for the
323 : // function. The value is only reliable when the function has been compiled.
324 : DECL_UINT8_ACCESSORS(expected_nof_properties)
325 :
326 : // [function data]: This field holds some additional data for function.
327 : // Currently it has one of:
328 : // - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
329 : // - a BytecodeArray for the interpreter [HasBytecodeArray()].
330 : // - a InterpreterData with the BytecodeArray and a copy of the
331 : // interpreter trampoline [HasInterpreterData()]
332 : // - an AsmWasmData with Asm->Wasm conversion [HasAsmWasmData()].
333 : // - a Smi containing the builtin id [HasBuiltinId()]
334 : // - a UncompiledDataWithoutPreparseData for lazy compilation
335 : // [HasUncompiledDataWithoutPreparseData()]
336 : // - a UncompiledDataWithPreparseData for lazy compilation
337 : // [HasUncompiledDataWithPreparseData()]
338 : // - a WasmExportedFunctionData for Wasm [HasWasmExportedFunctionData()]
339 : DECL_ACCESSORS(function_data, Object)
340 :
341 : inline bool IsApiFunction() const;
342 : inline FunctionTemplateInfo get_api_func_data();
343 : inline void set_api_func_data(FunctionTemplateInfo data);
344 : inline bool HasBytecodeArray() const;
345 : inline BytecodeArray GetBytecodeArray() const;
346 : inline void set_bytecode_array(BytecodeArray bytecode);
347 : inline Code InterpreterTrampoline() const;
348 : inline bool HasInterpreterData() const;
349 : inline InterpreterData interpreter_data() const;
350 : inline void set_interpreter_data(InterpreterData interpreter_data);
351 : inline BytecodeArray GetDebugBytecodeArray() const;
352 : inline void SetDebugBytecodeArray(BytecodeArray bytecode);
353 : inline bool HasAsmWasmData() const;
354 : inline AsmWasmData asm_wasm_data() const;
355 : inline void set_asm_wasm_data(AsmWasmData data);
356 :
357 : // A brief note to clear up possible confusion:
358 : // builtin_id corresponds to the auto-generated
359 : // Builtins::Name id, while builtin_function_id corresponds to
360 : // BuiltinFunctionId (a manually maintained list of 'interesting' functions
361 : // mainly used during optimization).
362 : inline bool HasBuiltinId() const;
363 : inline int builtin_id() const;
364 : inline void set_builtin_id(int builtin_id);
365 : inline bool HasUncompiledData() const;
366 : inline UncompiledData uncompiled_data() const;
367 : inline void set_uncompiled_data(UncompiledData data);
368 : inline bool HasUncompiledDataWithPreparseData() const;
369 : inline UncompiledDataWithPreparseData uncompiled_data_with_preparse_data()
370 : const;
371 : inline void set_uncompiled_data_with_preparse_data(
372 : UncompiledDataWithPreparseData data);
373 : inline bool HasUncompiledDataWithoutPreparseData() const;
374 : inline bool HasWasmExportedFunctionData() const;
375 : WasmExportedFunctionData wasm_exported_function_data() const;
376 :
377 : // Clear out pre-parsed scope data from UncompiledDataWithPreparseData,
378 : // turning it into UncompiledDataWithoutPreparseData.
379 : inline void ClearPreparseData();
380 :
381 : // [raw_builtin_function_id]: The id of the built-in function this function
382 : // represents, used during optimization to improve code generation.
383 : // TODO(leszeks): Once there are no more JS builtins, this can be replaced
384 : // by BuiltinId.
385 : DECL_UINT8_ACCESSORS(raw_builtin_function_id)
386 : inline bool HasBuiltinFunctionId();
387 : inline BuiltinFunctionId builtin_function_id();
388 : inline void set_builtin_function_id(BuiltinFunctionId id);
389 : // Make sure BuiltinFunctionIds fit in a uint8_t
390 : STATIC_ASSERT((std::is_same<std::underlying_type<BuiltinFunctionId>::type,
391 : uint8_t>::value));
392 :
393 : // The inferred_name is inferred from variable or property assignment of this
394 : // function. It is used to facilitate debugging and profiling of JavaScript
395 : // code written in OO style, where almost all functions are anonymous but are
396 : // assigned to object properties.
397 : inline bool HasInferredName();
398 : inline String inferred_name();
399 :
400 : // Get the function literal id associated with this function, for parsing.
401 : V8_EXPORT_PRIVATE int FunctionLiteralId(Isolate* isolate) const;
402 :
403 : // Break infos are contained in DebugInfo, this is a convenience method
404 : // to simplify access.
405 : bool HasBreakInfo() const;
406 : bool BreakAtEntry() const;
407 :
408 : // Coverage infos are contained in DebugInfo, this is a convenience method
409 : // to simplify access.
410 : bool HasCoverageInfo() const;
411 : CoverageInfo GetCoverageInfo() const;
412 :
413 : // The function's name if it is non-empty, otherwise the inferred name.
414 : String DebugName();
415 :
416 : // Used for flags such as --turbo-filter.
417 : bool PassesFilter(const char* raw_filter);
418 :
419 : // [script_or_debug_info]: One of:
420 : // - Script from which the function originates.
421 : // - a DebugInfo which holds the actual script [HasDebugInfo()].
422 : DECL_ACCESSORS(script_or_debug_info, Object)
423 :
424 : inline Object script() const;
425 : inline void set_script(Object script);
426 :
427 : // The function is subject to debugging if a debug info is attached.
428 : inline bool HasDebugInfo() const;
429 : inline DebugInfo GetDebugInfo() const;
430 : inline void SetDebugInfo(DebugInfo debug_info);
431 :
432 : // The offset of the 'function' token in the script source relative to the
433 : // start position. Can return kFunctionTokenOutOfRange if offset doesn't
434 : // fit in 16 bits.
435 : DECL_UINT16_ACCESSORS(raw_function_token_offset)
436 :
437 : // The position of the 'function' token in the script source. Can return
438 : // kNoSourcePosition if raw_function_token_offset() returns
439 : // kFunctionTokenOutOfRange.
440 : inline int function_token_position() const;
441 :
442 : // Returns true if the function has shared name.
443 : inline bool HasSharedName() const;
444 :
445 : // [flags] Bit field containing various flags about the function.
446 : DECL_INT32_ACCESSORS(flags)
447 :
448 : // Is this function a named function expression in the source code.
449 : DECL_BOOLEAN_ACCESSORS(is_named_expression)
450 :
451 : // Is this function a top-level function (scripts, evals).
452 : DECL_BOOLEAN_ACCESSORS(is_toplevel)
453 :
454 : // Indicates if this function can be lazy compiled.
455 : DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
456 :
457 : // Indicates the language mode.
458 : inline LanguageMode language_mode() const;
459 : inline void set_language_mode(LanguageMode language_mode);
460 :
461 : // Indicates whether the source is implicitly wrapped in a function.
462 : DECL_BOOLEAN_ACCESSORS(is_wrapped)
463 :
464 : // True if the function has any duplicated parameter names.
465 : DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
466 :
467 : // Indicates whether the function is a native function.
468 : // These needs special treatment in .call and .apply since
469 : // null passed as the receiver should not be translated to the
470 : // global object.
471 : DECL_BOOLEAN_ACCESSORS(native)
472 :
473 : // Whether this function was created from a FunctionDeclaration.
474 : DECL_BOOLEAN_ACCESSORS(is_declaration)
475 :
476 : // Indicates that asm->wasm conversion failed and should not be re-attempted.
477 : DECL_BOOLEAN_ACCESSORS(is_asm_wasm_broken)
478 :
479 : // Indicates that the function was created by the Function function.
480 : // Though it's anonymous, toString should treat it as if it had the name
481 : // "anonymous". We don't set the name itself so that the system does not
482 : // see a binding for it.
483 : DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous)
484 :
485 : // Indicates that the function is either an anonymous expression
486 : // or an arrow function (the name field can be set through the API,
487 : // which does not change this flag).
488 : DECL_BOOLEAN_ACCESSORS(is_anonymous_expression)
489 :
490 : // Indicates that the function represented by the shared function info was
491 : // classed as an immediately invoked function execution (IIFE) function and
492 : // is only executed once.
493 : DECL_BOOLEAN_ACCESSORS(is_oneshot_iife)
494 :
495 : // Indicates that the function has been reported for binary code coverage.
496 : DECL_BOOLEAN_ACCESSORS(has_reported_binary_coverage)
497 :
498 : inline FunctionKind kind() const;
499 :
500 : // Defines the index in a native context of closure's map instantiated using
501 : // this shared function info.
502 : DECL_INT_ACCESSORS(function_map_index)
503 :
504 : // Clear uninitialized padding space. This ensures that the snapshot content
505 : // is deterministic.
506 : inline void clear_padding();
507 :
508 : // Recalculates the |map_index| value after modifications of this shared info.
509 : inline void UpdateFunctionMapIndex();
510 :
511 : // Indicates whether optimizations have been disabled for this shared function
512 : // info. If we cannot optimize the function we disable optimization to avoid
513 : // spending time attempting to optimize it again.
514 : inline bool optimization_disabled() const;
515 :
516 : // The reason why optimization was disabled.
517 : inline BailoutReason disable_optimization_reason() const;
518 :
519 : // Disable (further) attempted optimization of all functions sharing this
520 : // shared function info.
521 : void DisableOptimization(BailoutReason reason);
522 :
523 : // This class constructor needs to call out to an instance fields
524 : // initializer. This flag is set when creating the
525 : // SharedFunctionInfo as a reminder to emit the initializer call
526 : // when generating code later.
527 : DECL_BOOLEAN_ACCESSORS(requires_instance_members_initializer)
528 :
529 : // [source code]: Source code for the function.
530 : bool HasSourceCode() const;
531 : static Handle<Object> GetSourceCode(Handle<SharedFunctionInfo> shared);
532 : static Handle<Object> GetSourceCodeHarmony(Handle<SharedFunctionInfo> shared);
533 :
534 : // Tells whether this function should be subject to debugging, e.g. for
535 : // - scope inspection
536 : // - internal break points
537 : // - coverage and type profile
538 : // - error stack trace
539 : inline bool IsSubjectToDebugging();
540 :
541 : // Whether this function is defined in user-provided JavaScript code.
542 : inline bool IsUserJavaScript();
543 :
544 : // True if one can flush compiled code from this function, in such a way that
545 : // it can later be re-compiled.
546 : inline bool CanDiscardCompiled() const;
547 :
548 : // Flush compiled data from this function, setting it back to CompileLazy and
549 : // clearing any compiled metadata.
550 : static void DiscardCompiled(Isolate* isolate,
551 : Handle<SharedFunctionInfo> shared_info);
552 :
553 : // Discard the compiled metadata. If called during GC then
554 : // |gc_notify_updated_slot| should be used to record any slot updates.
555 : void DiscardCompiledMetadata(
556 : Isolate* isolate,
557 : std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
558 : gc_notify_updated_slot =
559 : [](HeapObject object, ObjectSlot slot, HeapObject target) {});
560 :
561 : // Returns true if the function has old bytecode that could be flushed.
562 : inline bool ShouldFlushBytecode();
563 :
564 : // Check whether or not this function is inlineable.
565 : bool IsInlineable();
566 :
567 : // Source size of this function.
568 : int SourceSize();
569 :
570 : // Returns `false` if formal parameters include rest parameters, optional
571 : // parameters, or destructuring parameters.
572 : // TODO(caitp): make this a flag set during parsing
573 : inline bool has_simple_parameters();
574 :
575 : // Initialize a SharedFunctionInfo from a parsed function literal.
576 : static void InitFromFunctionLiteral(Handle<SharedFunctionInfo> shared_info,
577 : FunctionLiteral* lit, bool is_toplevel);
578 :
579 : // Sets the expected number of properties based on estimate from parser.
580 : void SetExpectedNofPropertiesFromEstimate(FunctionLiteral* literal);
581 :
582 : // Sets the FunctionTokenOffset field based on the given token position and
583 : // start position.
584 : void SetFunctionTokenPosition(int function_token_position,
585 : int start_position);
586 :
587 : static void EnsureSourcePositionsAvailable(
588 : Isolate* isolate, Handle<SharedFunctionInfo> shared_info);
589 :
590 : inline bool construct_as_builtin() const;
591 :
592 : // Determines and sets the ConstructAsBuiltinBit in |flags|, based on the
593 : // |function_data|. Must be called when creating the SFI after other fields
594 : // are initialized. The ConstructAsBuiltinBit determines whether
595 : // JSBuiltinsConstructStub or JSConstructStubGeneric should be called to
596 : // construct this function.
597 : inline void CalculateConstructAsBuiltin();
598 :
599 : // Dispatched behavior.
600 : DECL_PRINTER(SharedFunctionInfo)
601 : DECL_VERIFIER(SharedFunctionInfo)
602 : #ifdef OBJECT_PRINT
603 : void PrintSourceCode(std::ostream& os);
604 : #endif
605 :
606 : // Iterate over all shared function infos in a given script.
607 : class ScriptIterator {
608 : public:
609 : ScriptIterator(Isolate* isolate, Script script);
610 : ScriptIterator(Isolate* isolate,
611 : Handle<WeakFixedArray> shared_function_infos);
612 : SharedFunctionInfo Next();
613 112301 : int CurrentIndex() const { return index_ - 1; }
614 :
615 : // Reset the iterator to run on |script|.
616 : void Reset(Script script);
617 :
618 : private:
619 : Isolate* isolate_;
620 : Handle<WeakFixedArray> shared_function_infos_;
621 : int index_;
622 : DISALLOW_COPY_AND_ASSIGN(ScriptIterator);
623 : };
624 :
625 : // Iterate over all shared function infos on the heap.
626 : class GlobalIterator {
627 : public:
628 : explicit GlobalIterator(Isolate* isolate);
629 : SharedFunctionInfo Next();
630 :
631 : private:
632 : Script::Iterator script_iterator_;
633 : WeakArrayList::Iterator noscript_sfi_iterator_;
634 : SharedFunctionInfo::ScriptIterator sfi_iterator_;
635 : DISALLOW_HEAP_ALLOCATION(no_gc_)
636 : DISALLOW_COPY_AND_ASSIGN(GlobalIterator);
637 : };
638 :
639 : DECL_CAST(SharedFunctionInfo)
640 :
641 : // Constants.
642 : static const uint16_t kDontAdaptArgumentsSentinel = static_cast<uint16_t>(-1);
643 :
644 : static const int kMaximumFunctionTokenOffset = kMaxUInt16 - 1;
645 : static const uint16_t kFunctionTokenOutOfRange = static_cast<uint16_t>(-1);
646 : STATIC_ASSERT(kMaximumFunctionTokenOffset + 1 == kFunctionTokenOutOfRange);
647 :
648 : DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
649 : SHARED_FUNCTION_INFO_FIELDS)
650 :
651 : static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
652 :
653 : class BodyDescriptor;
654 :
655 : // Bit positions in |flags|.
656 : #define FLAGS_BIT_FIELDS(V, _) \
657 : V(IsNativeBit, bool, 1, _) \
658 : V(IsStrictBit, bool, 1, _) \
659 : V(IsWrappedBit, bool, 1, _) \
660 : V(IsClassConstructorBit, bool, 1, _) \
661 : V(IsDerivedConstructorBit, bool, 1, _) \
662 : V(FunctionKindBits, FunctionKind, 5, _) \
663 : V(HasDuplicateParametersBit, bool, 1, _) \
664 : V(AllowLazyCompilationBit, bool, 1, _) \
665 : V(NeedsHomeObjectBit, bool, 1, _) \
666 : V(IsDeclarationBit, bool, 1, _) \
667 : V(IsAsmWasmBrokenBit, bool, 1, _) \
668 : V(FunctionMapIndexBits, int, 5, _) \
669 : V(DisabledOptimizationReasonBits, BailoutReason, 4, _) \
670 : V(RequiresInstanceMembersInitializer, bool, 1, _) \
671 : V(ConstructAsBuiltinBit, bool, 1, _) \
672 : V(IsAnonymousExpressionBit, bool, 1, _) \
673 : V(NameShouldPrintAsAnonymousBit, bool, 1, _) \
674 : V(HasReportedBinaryCoverageBit, bool, 1, _) \
675 : V(IsNamedExpressionBit, bool, 1, _) \
676 : V(IsTopLevelBit, bool, 1, _) \
677 : V(IsOneshotIIFEBit, bool, 1, _)
678 : DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
679 : #undef FLAGS_BIT_FIELDS
680 :
681 : // Bailout reasons must fit in the DisabledOptimizationReason bitfield.
682 : STATIC_ASSERT(BailoutReason::kLastErrorMessage <=
683 : DisabledOptimizationReasonBits::kMax);
684 :
685 : STATIC_ASSERT(kLastFunctionKind <= FunctionKindBits::kMax);
686 :
687 : // Indicates that this function uses a super property (or an eval that may
688 : // use a super property).
689 : // This is needed to set up the [[HomeObject]] on the function instance.
690 : inline bool needs_home_object() const;
691 :
692 : V8_INLINE bool IsSharedFunctionInfoWithID() const {
693 : #if V8_SFI_HAS_UNIQUE_ID
694 : return true;
695 : #else
696 : return false;
697 : #endif
698 : }
699 :
700 : private:
701 : // [name_or_scope_info]: Function name string, kNoSharedNameSentinel or
702 : // ScopeInfo.
703 : DECL_ACCESSORS(name_or_scope_info, Object)
704 :
705 : // [outer scope info] The outer scope info, needed to lazily parse this
706 : // function.
707 : DECL_ACCESSORS(outer_scope_info, HeapObject)
708 :
709 : inline void set_kind(FunctionKind kind);
710 :
711 : inline void set_needs_home_object(bool value);
712 :
713 : friend class Factory;
714 : friend class V8HeapExplorer;
715 : FRIEND_TEST(PreParserTest, LazyFunctionLength);
716 :
717 : inline uint16_t length() const;
718 :
719 : // Find the index of this function in the parent script. Slow path of
720 : // FunctionLiteralId.
721 : int FindIndexInScript(Isolate* isolate) const;
722 :
723 20435736 : OBJECT_CONSTRUCTORS(SharedFunctionInfo, HeapObject);
724 : };
725 :
726 : class SharedFunctionInfoWithID : public SharedFunctionInfo {
727 : public:
728 : // [unique_id] - For --trace-maps purposes, an identifier that's persistent
729 : // even if the GC moves this SharedFunctionInfo.
730 : DECL_INT_ACCESSORS(unique_id)
731 :
732 : DECL_CAST(SharedFunctionInfoWithID)
733 :
734 : DEFINE_FIELD_OFFSET_CONSTANTS(SharedFunctionInfo::kSize,
735 : SHARED_FUNCTION_INFO_WITH_ID_FIELDS)
736 :
737 : static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
738 :
739 : OBJECT_CONSTRUCTORS(SharedFunctionInfoWithID, SharedFunctionInfo);
740 : };
741 :
742 : // Printing support.
743 : struct SourceCodeOf {
744 : explicit SourceCodeOf(SharedFunctionInfo v, int max = -1)
745 24 : : value(v), max_length(max) {}
746 : const SharedFunctionInfo value;
747 : int max_length;
748 : };
749 :
750 : // IsCompiledScope enables a caller to check if a function is compiled, and
751 : // ensure it remains compiled (i.e., doesn't have it's bytecode flushed) while
752 : // the scope is retained.
753 : class IsCompiledScope {
754 : public:
755 : inline IsCompiledScope(const SharedFunctionInfo shared, Isolate* isolate);
756 11557810 : inline IsCompiledScope() : retain_bytecode_(), is_compiled_(false) {}
757 :
758 279139 : inline bool is_compiled() const { return is_compiled_; }
759 :
760 : private:
761 : MaybeHandle<BytecodeArray> retain_bytecode_;
762 : bool is_compiled_;
763 : };
764 :
765 : std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v);
766 :
767 : } // namespace internal
768 : } // namespace v8
769 :
770 : #include "src/objects/object-macros-undef.h"
771 :
772 : #endif // V8_OBJECTS_SHARED_FUNCTION_INFO_H_
|