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