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