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 SizeFor(int length)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(); CurrentIndex()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) valueSourceCodeOf697 : 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