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