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