| // Copyright 2017 the V8 project authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef V8_OBJECTS_SHARED_FUNCTION_INFO_H_ | |
| #define V8_OBJECTS_SHARED_FUNCTION_INFO_H_ | |
| #include "src/bailout-reason.h" | |
| #include "src/objects.h" | |
| #include "src/objects/script.h" | |
| // Has to be the last include (doesn't have include guards): | |
| #include "src/objects/object-macros.h" | |
| namespace v8 { | |
| namespace internal { | |
| class BytecodeArray; | |
| class CoverageInfo; | |
| class DebugInfo; | |
| class WasmExportedFunctionData; | |
| // Data collected by the pre-parser storing information about scopes and inner | |
| // functions. | |
| class PreParsedScopeData : public HeapObject { | |
| public: | |
| DECL_ACCESSORS(scope_data, PodArray<uint8_t>) | |
| DECL_INT_ACCESSORS(length) | |
| inline Object* child_data(int index) const; | |
| inline void set_child_data(int index, Object* value, | |
| WriteBarrierMode mode = UPDATE_WRITE_BARRIER); | |
| inline Object** child_data_start() const; | |
| // Clear uninitialized padding space. | |
| inline void clear_padding(); | |
| DECL_CAST(PreParsedScopeData) | |
| DECL_PRINTER(PreParsedScopeData) | |
| DECL_VERIFIER(PreParsedScopeData) | |
| #define PRE_PARSED_SCOPE_DATA_FIELDS(V) \ | |
| V(kScopeDataOffset, kPointerSize) \ | |
| V(kLengthOffset, kIntSize) \ | |
| V(kUnalignedChildDataStartOffset, 0) | |
| DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, | |
| PRE_PARSED_SCOPE_DATA_FIELDS) | |
| #undef PRE_PARSED_SCOPE_DATA_FIELDS | |
| static const int kChildDataStartOffset = | |
| POINTER_SIZE_ALIGN(kUnalignedChildDataStartOffset); | |
| class BodyDescriptor; | |
| // No weak fields. | |
| typedef BodyDescriptor BodyDescriptorWeak; | |
| static constexpr int SizeFor(int length) { | |
| return kChildDataStartOffset + length * kPointerSize; | |
| } | |
| private: | |
| DISALLOW_IMPLICIT_CONSTRUCTORS(PreParsedScopeData); | |
| }; | |
| // Abstract class representing extra data for an uncompiled function, which is | |
| // not stored in the SharedFunctionInfo. | |
| class UncompiledData : public HeapObject { | |
| public: | |
| DECL_ACCESSORS(inferred_name, String) | |
| DECL_INT32_ACCESSORS(start_position) | |
| DECL_INT32_ACCESSORS(end_position) | |
| DECL_INT32_ACCESSORS(function_literal_id) | |
| DECL_CAST(UncompiledData) | |
| #define UNCOMPILED_DATA_FIELDS(V) \ | |
| V(kStartOfPointerFieldsOffset, 0) \ | |
| V(kInferredNameOffset, kPointerSize) \ | |
| V(kEndOfPointerFieldsOffset, 0) \ | |
| V(kStartPositionOffset, kInt32Size) \ | |
| V(kEndPositionOffset, kInt32Size) \ | |
| V(kFunctionLiteralIdOffset, kInt32Size) \ | |
| /* Total size. */ \ | |
| V(kUnalignedSize, 0) | |
| DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, UNCOMPILED_DATA_FIELDS) | |
| #undef UNCOMPILED_DATA_FIELDS | |
| static const int kSize = POINTER_SIZE_ALIGN(kUnalignedSize); | |
| typedef FixedBodyDescriptor<kStartOfPointerFieldsOffset, | |
| kEndOfPointerFieldsOffset, kSize> | |
| BodyDescriptor; | |
| // Clear uninitialized padding space. | |
| inline void clear_padding(); | |
| private: | |
| DISALLOW_IMPLICIT_CONSTRUCTORS(UncompiledData); | |
| }; | |
| // Class representing data for an uncompiled function that does not have any | |
| // data from the pre-parser, either because it's a leaf function or because the | |
| // pre-parser bailed out. | |
| class UncompiledDataWithoutPreParsedScope : public UncompiledData { | |
| public: | |
| DECL_CAST(UncompiledDataWithoutPreParsedScope) | |
| DECL_PRINTER(UncompiledDataWithoutPreParsedScope) | |
| DECL_VERIFIER(UncompiledDataWithoutPreParsedScope) | |
| static const int kSize = UncompiledData::kSize; | |
| // No extra fields compared to UncompiledData. | |
| typedef UncompiledData::BodyDescriptor BodyDescriptor; | |
| // No weak fields. | |
| typedef BodyDescriptor BodyDescriptorWeak; | |
| private: | |
| DISALLOW_IMPLICIT_CONSTRUCTORS(UncompiledDataWithoutPreParsedScope); | |
| }; | |
| // Class representing data for an uncompiled function that has pre-parsed scope | |
| // data. | |
| class UncompiledDataWithPreParsedScope : public UncompiledData { | |
| public: | |
| DECL_ACCESSORS(pre_parsed_scope_data, PreParsedScopeData) | |
| DECL_CAST(UncompiledDataWithPreParsedScope) | |
| DECL_PRINTER(UncompiledDataWithPreParsedScope) | |
| DECL_VERIFIER(UncompiledDataWithPreParsedScope) | |
| #define UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_FIELDS(V) \ | |
| V(kStartOfPointerFieldsOffset, 0) \ | |
| V(kPreParsedScopeDataOffset, kPointerSize) \ | |
| V(kEndOfPointerFieldsOffset, 0) \ | |
| /* Total size. */ \ | |
| V(kSize, 0) | |
| DEFINE_FIELD_OFFSET_CONSTANTS(UncompiledData::kSize, | |
| UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_FIELDS) | |
| #undef UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_FIELDS | |
| // Make sure the size is aligned | |
| STATIC_ASSERT(kSize == POINTER_SIZE_ALIGN(kSize)); | |
| typedef SubclassBodyDescriptor< | |
| UncompiledData::BodyDescriptor, | |
| FixedBodyDescriptor<kStartOfPointerFieldsOffset, | |
| kEndOfPointerFieldsOffset, kSize>> | |
| BodyDescriptor; | |
| // No weak fields. | |
| typedef BodyDescriptor BodyDescriptorWeak; | |
| private: | |
| DISALLOW_IMPLICIT_CONSTRUCTORS(UncompiledDataWithPreParsedScope); | |
| }; | |
| class InterpreterData : public Struct { | |
| public: | |
| DECL_ACCESSORS(bytecode_array, BytecodeArray) | |
| DECL_ACCESSORS(interpreter_trampoline, Code) | |
| static const int kBytecodeArrayOffset = Struct::kHeaderSize; | |
| static const int kInterpreterTrampolineOffset = | |
| kBytecodeArrayOffset + kPointerSize; | |
| static const int kSize = kInterpreterTrampolineOffset + kPointerSize; | |
| DECL_CAST(InterpreterData) | |
| DECL_PRINTER(InterpreterData) | |
| DECL_VERIFIER(InterpreterData) | |
| private: | |
| DISALLOW_IMPLICIT_CONSTRUCTORS(InterpreterData); | |
| }; | |
| // SharedFunctionInfo describes the JSFunction information that can be | |
| // shared by multiple instances of the function. | |
| class SharedFunctionInfo : public HeapObject, public NeverReadOnlySpaceObject { | |
| public: | |
| using NeverReadOnlySpaceObject::GetHeap; | |
| using NeverReadOnlySpaceObject::GetIsolate; | |
| static constexpr Object* const kNoSharedNameSentinel = Smi::kZero; | |
| // [name]: Returns shared name if it exists or an empty string otherwise. | |
| inline String* Name() const; | |
| inline void SetName(String* name); | |
| // Get the code object which represents the execution of this function. | |
| Code* GetCode() const; | |
| // Get the abstract code associated with the function, which will either be | |
| // a Code object or a BytecodeArray. | |
| inline AbstractCode* abstract_code(); | |
| // Tells whether or not this shared function info is interpreted. | |
| // | |
| // Note: function->IsInterpreted() does not necessarily return the same value | |
| // as function->shared()->IsInterpreted() because the closure might have been | |
| // optimized. | |
| inline bool IsInterpreted() const; | |
| // Set up the link between shared function info and the script. The shared | |
| // function info is added to the list on the script. | |
| V8_EXPORT_PRIVATE static void SetScript( | |
| Handle<SharedFunctionInfo> shared, Handle<Object> script_object, | |
| int function_literal_id, bool reset_preparsed_scope_data = true); | |
| // Layout description of the optimized code map. | |
| static const int kEntriesStart = 0; | |
| static const int kContextOffset = 0; | |
| static const int kCachedCodeOffset = 1; | |
| static const int kEntryLength = 2; | |
| static const int kInitialLength = kEntriesStart + kEntryLength; | |
| static const int kNotFound = -1; | |
| static const uint16_t kInvalidLength = static_cast<uint16_t>(-1); | |
| // Helpers for assembly code that does a backwards walk of the optimized code | |
| // map. | |
| static const int kOffsetToPreviousContext = | |
| FixedArray::kHeaderSize + kPointerSize * (kContextOffset - kEntryLength); | |
| static const int kOffsetToPreviousCachedCode = | |
| FixedArray::kHeaderSize + | |
| kPointerSize * (kCachedCodeOffset - kEntryLength); | |
| // [scope_info]: Scope info. | |
| DECL_ACCESSORS(scope_info, ScopeInfo) | |
| // End position of this function in the script source. | |
| inline int EndPosition() const; | |
| // Start position of this function in the script source. | |
| inline int StartPosition() const; | |
| // Set the start and end position of this function in the script source. | |
| // Updates the scope info if available. | |
| inline void SetPosition(int start_position, int end_position); | |
| // [outer scope info | feedback metadata] Shared storage for outer scope info | |
| // (on uncompiled functions) and feedback metadata (on compiled functions). | |
| DECL_ACCESSORS(raw_outer_scope_info_or_feedback_metadata, HeapObject) | |
| // Get the outer scope info whether this function is compiled or not. | |
| inline bool HasOuterScopeInfo() const; | |
| inline ScopeInfo* GetOuterScopeInfo() const; | |
| // [feedback metadata] Metadata template for feedback vectors of instances of | |
| // this function. | |
| inline bool HasFeedbackMetadata() const; | |
| DECL_ACCESSORS(feedback_metadata, FeedbackMetadata) | |
| // Returns if this function has been compiled to native code yet. | |
| inline bool is_compiled() const; | |
| // [length]: The function length - usually the number of declared parameters. | |
| // Use up to 2^16-2 parameters (16 bits of values, where one is reserved for | |
| // kDontAdaptArgumentsSentinel). The value is only reliable when the function | |
| // has been compiled. | |
| inline uint16_t GetLength() const; | |
| inline bool HasLength() const; | |
| inline void set_length(int value); | |
| // [internal formal parameter count]: The declared number of parameters. | |
| // For subclass constructors, also includes new.target. | |
| // The size of function's frame is internal_formal_parameter_count + 1. | |
| DECL_UINT16_ACCESSORS(internal_formal_parameter_count) | |
| // Set the formal parameter count so the function code will be | |
| // called without using argument adaptor frames. | |
| inline void DontAdaptArguments(); | |
| // [expected_nof_properties]: Expected number of properties for the | |
| // function. The value is only reliable when the function has been compiled. | |
| DECL_UINT8_ACCESSORS(expected_nof_properties) | |
| #if V8_SFI_HAS_UNIQUE_ID | |
| // [unique_id] - For --trace-maps purposes, an identifier that's persistent | |
| // even if the GC moves this SharedFunctionInfo. | |
| DECL_INT_ACCESSORS(unique_id) | |
| #endif | |
| // [function data]: This field holds some additional data for function. | |
| // Currently it has one of: | |
| // - a FunctionTemplateInfo to make benefit the API [IsApiFunction()]. | |
| // - a BytecodeArray for the interpreter [HasBytecodeArray()]. | |
| // - a InterpreterData with the BytecodeArray and a copy of the | |
| // interpreter trampoline [HasInterpreterData()] | |
| // - a FixedArray with Asm->Wasm conversion [HasAsmWasmData()]. | |
| // - a Smi containing the builtin id [HasBuiltinId()] | |
| // - a UncompiledDataWithoutPreParsedScope for lazy compilation | |
| // [HasUncompiledDataWithoutPreParsedScope()] | |
| // - a UncompiledDataWithPreParsedScope for lazy compilation | |
| // [HasUncompiledDataWithPreParsedScope()] | |
| // - a WasmExportedFunctionData for Wasm [HasWasmExportedFunctionData()] | |
| DECL_ACCESSORS(function_data, Object) | |
| inline bool IsApiFunction() const; | |
| inline FunctionTemplateInfo* get_api_func_data(); | |
| inline void set_api_func_data(FunctionTemplateInfo* data); | |
| inline bool HasBytecodeArray() const; | |
| inline BytecodeArray* GetBytecodeArray() const; | |
| inline void set_bytecode_array(BytecodeArray* bytecode); | |
| inline Code* InterpreterTrampoline() const; | |
| inline bool HasInterpreterData() const; | |
| inline InterpreterData* interpreter_data() const; | |
| inline void set_interpreter_data(InterpreterData* interpreter_data); | |
| inline BytecodeArray* GetDebugBytecodeArray() const; | |
| inline void SetDebugBytecodeArray(BytecodeArray* bytecode); | |
| inline bool HasAsmWasmData() const; | |
| inline FixedArray* asm_wasm_data() const; | |
| inline void set_asm_wasm_data(FixedArray* data); | |
| // A brief note to clear up possible confusion: | |
| // builtin_id corresponds to the auto-generated | |
| // Builtins::Name id, while builtin_function_id corresponds to | |
| // BuiltinFunctionId (a manually maintained list of 'interesting' functions | |
| // mainly used during optimization). | |
| inline bool HasBuiltinId() const; | |
| inline int builtin_id() const; | |
| inline void set_builtin_id(int builtin_id); | |
| inline bool HasUncompiledData() const; | |
| inline UncompiledData* uncompiled_data() const; | |
| inline void set_uncompiled_data(UncompiledData* data); | |
| inline bool HasUncompiledDataWithPreParsedScope() const; | |
| inline UncompiledDataWithPreParsedScope* | |
| uncompiled_data_with_pre_parsed_scope() const; | |
| inline void set_uncompiled_data_with_pre_parsed_scope( | |
| UncompiledDataWithPreParsedScope* data); | |
| inline bool HasUncompiledDataWithoutPreParsedScope() const; | |
| inline bool HasWasmExportedFunctionData() const; | |
| WasmExportedFunctionData* wasm_exported_function_data() const; | |
| inline void set_wasm_exported_function_data(WasmExportedFunctionData* data); | |
| // Clear out pre-parsed scope data from UncompiledDataWithPreParsedScope, | |
| // turning it into UncompiledDataWithoutPreParsedScope. | |
| inline void ClearPreParsedScopeData(); | |
| // [raw_builtin_function_id]: The id of the built-in function this function | |
| // represents, used during optimization to improve code generation. | |
| // TODO(leszeks): Once there are no more JS builtins, this can be replaced | |
| // by BuiltinId. | |
| DECL_UINT8_ACCESSORS(raw_builtin_function_id) | |
| inline bool HasBuiltinFunctionId(); | |
| inline BuiltinFunctionId builtin_function_id(); | |
| inline void set_builtin_function_id(BuiltinFunctionId id); | |
| // Make sure BuiltinFunctionIds fit in a uint8_t | |
| STATIC_ASSERT((std::is_same<std::underlying_type<BuiltinFunctionId>::type, | |
| uint8_t>::value)); | |
| // The inferred_name is inferred from variable or property assignment of this | |
| // function. It is used to facilitate debugging and profiling of JavaScript | |
| // code written in OO style, where almost all functions are anonymous but are | |
| // assigned to object properties. | |
| inline bool HasInferredName(); | |
| inline String* inferred_name(); | |
| // Get the function literal id associated with this function, for parsing. | |
| inline int FunctionLiteralId(Isolate* isolate) const; | |
| // Break infos are contained in DebugInfo, this is a convenience method | |
| // to simplify access. | |
| bool HasBreakInfo() const; | |
| bool BreakAtEntry() const; | |
| // Coverage infos are contained in DebugInfo, this is a convenience method | |
| // to simplify access. | |
| bool HasCoverageInfo() const; | |
| CoverageInfo* GetCoverageInfo() const; | |
| // The function's name if it is non-empty, otherwise the inferred name. | |
| String* DebugName(); | |
| // Used for flags such as --turbo-filter. | |
| bool PassesFilter(const char* raw_filter); | |
| // [script_or_debug_info]: One of: | |
| // - Script from which the function originates. | |
| // - a DebugInfo which holds the actual script [HasDebugInfo()]. | |
| DECL_ACCESSORS(script_or_debug_info, Object) | |
| inline Object* script() const; | |
| inline void set_script(Object* script); | |
| // The function is subject to debugging if a debug info is attached. | |
| inline bool HasDebugInfo() const; | |
| inline DebugInfo* GetDebugInfo() const; | |
| inline void SetDebugInfo(DebugInfo* debug_info); | |
| // The offset of the 'function' token in the script source relative to the | |
| // start position. Can return kFunctionTokenOutOfRange if offset doesn't | |
| // fit in 16 bits. | |
| DECL_UINT16_ACCESSORS(raw_function_token_offset) | |
| // The position of the 'function' token in the script source. Can return | |
| // kNoSourcePosition if raw_function_token_offset() returns | |
| // kFunctionTokenOutOfRange. | |
| inline int function_token_position() const; | |
| // Returns true if the function has shared name. | |
| inline bool HasSharedName() const; | |
| // [flags] Bit field containing various flags about the function. | |
| DECL_INT_ACCESSORS(flags) | |
| // Is this function a named function expression in the source code. | |
| DECL_BOOLEAN_ACCESSORS(is_named_expression) | |
| // Is this function a top-level function (scripts, evals). | |
| DECL_BOOLEAN_ACCESSORS(is_toplevel) | |
| // Indicates if this function can be lazy compiled. | |
| DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation) | |
| // Indicates the language mode. | |
| inline LanguageMode language_mode() const; | |
| inline void set_language_mode(LanguageMode language_mode); | |
| // Indicates whether the source is implicitly wrapped in a function. | |
| DECL_BOOLEAN_ACCESSORS(is_wrapped) | |
| // True if the function has any duplicated parameter names. | |
| DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters) | |
| // Indicates whether the function is a native function. | |
| // These needs special treatment in .call and .apply since | |
| // null passed as the receiver should not be translated to the | |
| // global object. | |
| DECL_BOOLEAN_ACCESSORS(native) | |
| // Whether this function was created from a FunctionDeclaration. | |
| DECL_BOOLEAN_ACCESSORS(is_declaration) | |
| // Indicates that asm->wasm conversion failed and should not be re-attempted. | |
| DECL_BOOLEAN_ACCESSORS(is_asm_wasm_broken) | |
| // Indicates that the function was created by the Function function. | |
| // Though it's anonymous, toString should treat it as if it had the name | |
| // "anonymous". We don't set the name itself so that the system does not | |
| // see a binding for it. | |
| DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous) | |
| // Indicates that the function is either an anonymous expression | |
| // or an arrow function (the name field can be set through the API, | |
| // which does not change this flag). | |
| DECL_BOOLEAN_ACCESSORS(is_anonymous_expression) | |
| // Indicates that the the shared function info is deserialized from cache. | |
| DECL_BOOLEAN_ACCESSORS(deserialized) | |
| // Indicates that the function has been reported for binary code coverage. | |
| DECL_BOOLEAN_ACCESSORS(has_reported_binary_coverage) | |
| inline FunctionKind kind() const; | |
| // Defines the index in a native context of closure's map instantiated using | |
| // this shared function info. | |
| DECL_INT_ACCESSORS(function_map_index) | |
| // Clear uninitialized padding space. This ensures that the snapshot content | |
| // is deterministic. | |
| inline void clear_padding(); | |
| // Recalculates the |map_index| value after modifications of this shared info. | |
| inline void UpdateFunctionMapIndex(); | |
| // Indicates whether optimizations have been disabled for this shared function | |
| // info. If we cannot optimize the function we disable optimization to avoid | |
| // spending time attempting to optimize it again. | |
| inline bool optimization_disabled() const; | |
| // The reason why optimization was disabled. | |
| inline BailoutReason disable_optimization_reason() const; | |
| // Disable (further) attempted optimization of all functions sharing this | |
| // shared function info. | |
| void DisableOptimization(BailoutReason reason); | |
| // This class constructor needs to call out to an instance fields | |
| // initializer. This flag is set when creating the | |
| // SharedFunctionInfo as a reminder to emit the initializer call | |
| // when generating code later. | |
| DECL_BOOLEAN_ACCESSORS(requires_instance_fields_initializer) | |
| // [source code]: Source code for the function. | |
| bool HasSourceCode() const; | |
| static Handle<Object> GetSourceCode(Handle<SharedFunctionInfo> shared); | |
| static Handle<Object> GetSourceCodeHarmony(Handle<SharedFunctionInfo> shared); | |
| // Tells whether this function should be subject to debugging, e.g. for | |
| // - scope inspection | |
| // - internal break points | |
| // - coverage and type profile | |
| // - error stack trace | |
| inline bool IsSubjectToDebugging(); | |
| // Whether this function is defined in user-provided JavaScript code. | |
| inline bool IsUserJavaScript(); | |
| // True if one can flush compiled code from this function, in such a way that | |
| // it can later be re-compiled. | |
| inline bool CanDiscardCompiled() const; | |
| // Flush compiled data from this function, setting it back to CompileLazy and | |
| // clearing any feedback metadata. | |
| static inline void DiscardCompiled(Isolate* isolate, | |
| Handle<SharedFunctionInfo> shared_info); | |
| // Check whether or not this function is inlineable. | |
| bool IsInlineable(); | |
| // Source size of this function. | |
| int SourceSize(); | |
| // Returns `false` if formal parameters include rest parameters, optional | |
| // parameters, or destructuring parameters. | |
| // TODO(caitp): make this a flag set during parsing | |
| inline bool has_simple_parameters(); | |
| // Initialize a SharedFunctionInfo from a parsed function literal. | |
| static void InitFromFunctionLiteral(Handle<SharedFunctionInfo> shared_info, | |
| FunctionLiteral* lit, bool is_toplevel); | |
| // Sets the expected number of properties based on estimate from parser. | |
| void SetExpectedNofPropertiesFromEstimate(FunctionLiteral* literal); | |
| // Sets the FunctionTokenOffset field based on the given token position and | |
| // start position. | |
| void SetFunctionTokenPosition(int function_token_position, | |
| int start_position); | |
| inline bool construct_as_builtin() const; | |
| // Determines and sets the ConstructAsBuiltinBit in |flags|, based on the | |
| // |function_data|. Must be called when creating the SFI after other fields | |
| // are initialized. The ConstructAsBuiltinBit determines whether | |
| // JSBuiltinsConstructStub or JSConstructStubGeneric should be called to | |
| // construct this function. | |
| inline void CalculateConstructAsBuiltin(); | |
| // Dispatched behavior. | |
| DECL_PRINTER(SharedFunctionInfo) | |
| DECL_VERIFIER(SharedFunctionInfo) | |
| #ifdef OBJECT_PRINT | |
| void PrintSourceCode(std::ostream& os); | |
| #endif | |
| // Iterate over all shared function infos in a given script. | |
| class ScriptIterator { | |
| public: | |
| ScriptIterator(Isolate* isolate, Script* script); | |
| ScriptIterator(Isolate* isolate, | |
| Handle<WeakFixedArray> shared_function_infos); | |
| SharedFunctionInfo* Next(); | |
| int CurrentIndex() const { return index_ - 1; } | |
| // Reset the iterator to run on |script|. | |
| void Reset(Script* script); | |
| private: | |
| Isolate* isolate_; | |
| Handle<WeakFixedArray> shared_function_infos_; | |
| int index_; | |
| DISALLOW_COPY_AND_ASSIGN(ScriptIterator); | |
| }; | |
| // Iterate over all shared function infos on the heap. | |
| class GlobalIterator { | |
| public: | |
| explicit GlobalIterator(Isolate* isolate); | |
| SharedFunctionInfo* Next(); | |
| private: | |
| Script::Iterator script_iterator_; | |
| WeakArrayList::Iterator noscript_sfi_iterator_; | |
| SharedFunctionInfo::ScriptIterator sfi_iterator_; | |
| DisallowHeapAllocation no_gc_; | |
| DISALLOW_COPY_AND_ASSIGN(GlobalIterator); | |
| }; | |
| DECL_CAST(SharedFunctionInfo) | |
| // Constants. | |
| static const uint16_t kDontAdaptArgumentsSentinel = static_cast<uint16_t>(-1); | |
| static const int kMaximumFunctionTokenOffset = kMaxUInt16 - 1; | |
| static const uint16_t kFunctionTokenOutOfRange = static_cast<uint16_t>(-1); | |
| STATIC_ASSERT(kMaximumFunctionTokenOffset + 1 == kFunctionTokenOutOfRange); | |
| #if V8_SFI_HAS_UNIQUE_ID | |
| static const int kUniqueIdFieldSize = kInt32Size; | |
| #else | |
| // Just to not break the postmortrem support with conditional offsets | |
| static const int kUniqueIdFieldSize = 0; | |
| #endif | |
| // Layout description. | |
| #define SHARED_FUNCTION_INFO_FIELDS(V) \ | |
| /* Pointer fields. */ \ | |
| V(kStartOfPointerFieldsOffset, 0) \ | |
| V(kFunctionDataOffset, kPointerSize) \ | |
| V(kNameOrScopeInfoOffset, kPointerSize) \ | |
| V(kOuterScopeInfoOrFeedbackMetadataOffset, kPointerSize) \ | |
| V(kScriptOrDebugInfoOffset, kPointerSize) \ | |
| V(kEndOfPointerFieldsOffset, 0) \ | |
| /* Raw data fields. */ \ | |
| V(kUniqueIdOffset, kUniqueIdFieldSize) \ | |
| V(kLengthOffset, kUInt16Size) \ | |
| V(kFormalParameterCountOffset, kUInt16Size) \ | |
| V(kExpectedNofPropertiesOffset, kUInt8Size) \ | |
| V(kBuiltinFunctionId, kUInt8Size) \ | |
| V(kFunctionTokenOffsetOffset, kUInt16Size) \ | |
| V(kFlagsOffset, kInt32Size) \ | |
| /* Total size. */ \ | |
| V(kSize, 0) | |
| DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, | |
| SHARED_FUNCTION_INFO_FIELDS) | |
| #undef SHARED_FUNCTION_INFO_FIELDS | |
| static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize); | |
| typedef FixedBodyDescriptor<kStartOfPointerFieldsOffset, | |
| kEndOfPointerFieldsOffset, kAlignedSize> | |
| BodyDescriptor; | |
| // No weak fields. | |
| typedef BodyDescriptor BodyDescriptorWeak; | |
| // Bit positions in |flags|. | |
| #define FLAGS_BIT_FIELDS(V, _) \ | |
| V(IsNativeBit, bool, 1, _) \ | |
| V(IsStrictBit, bool, 1, _) \ | |
| V(IsWrappedBit, bool, 1, _) \ | |
| V(IsClassConstructorBit, bool, 1, _) \ | |
| V(IsDerivedConstructorBit, bool, 1, _) \ | |
| V(FunctionKindBits, FunctionKind, 5, _) \ | |
| V(HasDuplicateParametersBit, bool, 1, _) \ | |
| V(AllowLazyCompilationBit, bool, 1, _) \ | |
| V(NeedsHomeObjectBit, bool, 1, _) \ | |
| V(IsDeclarationBit, bool, 1, _) \ | |
| V(IsAsmWasmBrokenBit, bool, 1, _) \ | |
| V(FunctionMapIndexBits, int, 5, _) \ | |
| V(DisabledOptimizationReasonBits, BailoutReason, 4, _) \ | |
| V(RequiresInstanceFieldsInitializer, bool, 1, _) \ | |
| V(ConstructAsBuiltinBit, bool, 1, _) \ | |
| V(IsAnonymousExpressionBit, bool, 1, _) \ | |
| V(NameShouldPrintAsAnonymousBit, bool, 1, _) \ | |
| V(IsDeserializedBit, bool, 1, _) \ | |
| V(HasReportedBinaryCoverageBit, bool, 1, _) \ | |
| V(IsNamedExpressionBit, bool, 1, _) \ | |
| V(IsTopLevelBit, bool, 1, _) | |
| DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS) | |
| #undef FLAGS_BIT_FIELDS | |
| // Bailout reasons must fit in the DisabledOptimizationReason bitfield. | |
| STATIC_ASSERT(BailoutReason::kLastErrorMessage <= | |
| DisabledOptimizationReasonBits::kMax); | |
| STATIC_ASSERT(kLastFunctionKind <= FunctionKindBits::kMax); | |
| // Indicates that this function uses a super property (or an eval that may | |
| // use a super property). | |
| // This is needed to set up the [[HomeObject]] on the function instance. | |
| inline bool needs_home_object() const; | |
| private: | |
| // [name_or_scope_info]: Function name string, kNoSharedNameSentinel or | |
| // ScopeInfo. | |
| DECL_ACCESSORS(name_or_scope_info, Object) | |
| // [outer scope info] The outer scope info, needed to lazily parse this | |
| // function. | |
| DECL_ACCESSORS(outer_scope_info, HeapObject) | |
| inline void set_kind(FunctionKind kind); | |
| inline void set_needs_home_object(bool value); | |
| friend class Factory; | |
| friend class V8HeapExplorer; | |
| FRIEND_TEST(PreParserTest, LazyFunctionLength); | |
| inline uint16_t length() const; | |
| // Find the index of this function in the parent script. Slow path of | |
| // FunctionLiteralId. | |
| int FindIndexInScript(Isolate* isolate) const; | |
| DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo); | |
| }; | |
| // Printing support. | |
| struct SourceCodeOf { | |
| explicit SourceCodeOf(SharedFunctionInfo* v, int max = -1) | |
| : value(v), max_length(max) {} | |
| const SharedFunctionInfo* value; | |
| int max_length; | |
| }; | |
| std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v); | |
| } // namespace internal | |
| } // namespace v8 | |
| #include "src/objects/object-macros-undef.h" | |
| #endif // V8_OBJECTS_SHARED_FUNCTION_INFO_H_ |