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