shared-function-info.h 29.3 KB
Newer Older
1 2 3 4 5 6 7
// 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_

Marja Hölttä's avatar
Marja Hölttä committed
8
#include "src/bailout-reason.h"
9
#include "src/objects.h"
10
#include "src/objects/builtin-function-id.h"
11
#include "src/objects/script.h"
12
#include "src/objects/smi.h"
13
#include "src/objects/struct.h"
14 15 16 17 18 19 20

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

21
class AsmWasmData;
22
class BytecodeArray;
23 24
class CoverageInfo;
class DebugInfo;
25
class IsCompiledScope;
26
class WasmExportedFunctionData;
27

28 29
// Data collected by the pre-parser storing information about scopes and inner
// functions.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
//
// PreparseData Layout:
// +-------------------------------+
// | data_length | children_length |
// +-------------------------------+
// | Scope Byte Data ...           |
// | ...                           |
// +-------------------------------+
// | [Padding]                     |
// +-------------------------------+
// | Inner PreparseData 1          |
// +-------------------------------+
// | ...                           |
// +-------------------------------+
// | Inner PreparseData N          |
// +-------------------------------+
46
class PreparseData : public HeapObject {
47
 public:
48 49
  DECL_INT_ACCESSORS(data_length)
  DECL_INT_ACCESSORS(children_length)
50

51 52
  inline int inner_start_offset() const;
  inline ObjectSlot inner_data_start() const;
53

54 55 56 57 58 59 60
  inline byte get(int index) const;
  inline void set(int index, byte value);
  inline void copy_in(int index, const byte* buffer, int length);

  inline PreparseData get_child(int index) const;
  inline void set_child(int index, PreparseData value,
                        WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
61 62 63

  // Clear uninitialized padding space.
  inline void clear_padding();
64

65
  DECL_CAST(PreparseData)
66 67
  DECL_PRINTER(PreparseData)
  DECL_VERIFIER(PreparseData)
68

69
// Layout description.
70 71 72 73 74 75
#define PREPARSE_DATA_FIELDS(V)     \
  V(kDataLengthOffset, kInt32Size)  \
  V(kInnerLengthOffset, kInt32Size) \
  /* Header size. */                \
  V(kDataStartOffset, 0)            \
  V(kHeaderSize, 0)
76

77 78
  DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, PREPARSE_DATA_FIELDS)
#undef PREPARSE_DATA_FIELDS
79 80 81

  class BodyDescriptor;

82 83 84 85 86 87
  static int InnerOffset(int data_length) {
    return RoundUp(kDataStartOffset + data_length * kByteSize, kTaggedSize);
  }

  static int SizeFor(int data_length, int children_length) {
    return InnerOffset(data_length) + children_length * kTaggedSize;
88 89
  }

90
  OBJECT_CONSTRUCTORS(PreparseData, HeapObject);
91 92 93

 private:
  inline Object get_child_raw(int index) const;
94 95
};

96 97
// Abstract class representing extra data for an uncompiled function, which is
// not stored in the SharedFunctionInfo.
98
class UncompiledData : public HeapObject {
99
 public:
100
  DECL_ACCESSORS(inferred_name, String)
101 102
  DECL_INT32_ACCESSORS(start_position)
  DECL_INT32_ACCESSORS(end_position)
103
  DECL_INT32_ACCESSORS(function_literal_id)
104

105
  DECL_CAST(UncompiledData)
106

107 108 109
  inline static void Initialize(
      UncompiledData data, String inferred_name, int start_position,
      int end_position, int function_literal_id,
110 111 112
      std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
          gc_notify_updated_slot =
              [](HeapObject object, ObjectSlot slot, HeapObject target) {});
113

114
  // Layout description.
115 116 117 118 119 120 121 122 123 124 125
#define UNCOMPILED_DATA_FIELDS(V)                                         \
  V(kStartOfPointerFieldsOffset, 0)                                       \
  V(kInferredNameOffset, kTaggedSize)                                     \
  V(kEndOfTaggedFieldsOffset, 0)                                          \
  /* Raw data fields. */                                                  \
  V(kStartPositionOffset, kInt32Size)                                     \
  V(kEndPositionOffset, kInt32Size)                                       \
  V(kFunctionLiteralIdOffset, kInt32Size)                                 \
  V(kOptionalPaddingOffset, POINTER_SIZE_PADDING(kOptionalPaddingOffset)) \
  /* Header size. */                                                      \
  V(kSize, 0)
126 127 128 129

  DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, UNCOMPILED_DATA_FIELDS)
#undef UNCOMPILED_DATA_FIELDS

130
  typedef FixedBodyDescriptor<kStartOfPointerFieldsOffset,
131
                              kEndOfTaggedFieldsOffset, kSize>
132 133
      BodyDescriptor;

134 135 136
  // Clear uninitialized padding space.
  inline void clear_padding();

137
  OBJECT_CONSTRUCTORS(UncompiledData, HeapObject);
138 139 140 141 142
};

// 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.
143
class UncompiledDataWithoutPreparseData : public UncompiledData {
144
 public:
145
  DECL_CAST(UncompiledDataWithoutPreparseData)
146 147
  DECL_PRINTER(UncompiledDataWithoutPreparseData)
  DECL_VERIFIER(UncompiledDataWithoutPreparseData)
148 149 150

  static const int kSize = UncompiledData::kSize;

151 152 153
  // No extra fields compared to UncompiledData.
  typedef UncompiledData::BodyDescriptor BodyDescriptor;

154
  OBJECT_CONSTRUCTORS(UncompiledDataWithoutPreparseData, UncompiledData);
155 156 157 158
};

// Class representing data for an uncompiled function that has pre-parsed scope
// data.
159
class UncompiledDataWithPreparseData : public UncompiledData {
160
 public:
161
  DECL_ACCESSORS(preparse_data, PreparseData)
162

163
  DECL_CAST(UncompiledDataWithPreparseData)
164 165
  DECL_PRINTER(UncompiledDataWithPreparseData)
  DECL_VERIFIER(UncompiledDataWithPreparseData)
166

167
  inline static void Initialize(
168
      UncompiledDataWithPreparseData data, String inferred_name,
169
      int start_position, int end_position, int function_literal_id,
170
      PreparseData scope_data,
171 172 173
      std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
          gc_notify_updated_slot =
              [](HeapObject object, ObjectSlot slot, HeapObject target) {});
174

175
  // Layout description.
176

177 178 179 180 181
#define UNCOMPILED_DATA_WITH_PREPARSE_DATA_FIELDS(V) \
  V(kStartOfPointerFieldsOffset, 0)                  \
  V(kPreparseDataOffset, kTaggedSize)                \
  V(kEndOfTaggedFieldsOffset, 0)                     \
  /* Total size. */                                  \
182
  V(kSize, 0)
183 184

  DEFINE_FIELD_OFFSET_CONSTANTS(UncompiledData::kSize,
185 186
                                UNCOMPILED_DATA_WITH_PREPARSE_DATA_FIELDS)
#undef UNCOMPILED_DATA_WITH_PREPARSE_DATA_FIELDS
187

188 189
  // Make sure the size is aligned
  STATIC_ASSERT(kSize == POINTER_SIZE_ALIGN(kSize));
190

191 192
  typedef SubclassBodyDescriptor<
      UncompiledData::BodyDescriptor,
193 194
      FixedBodyDescriptor<kStartOfPointerFieldsOffset, kEndOfTaggedFieldsOffset,
                          kSize>>
195 196
      BodyDescriptor;

197
  OBJECT_CONSTRUCTORS(UncompiledDataWithPreparseData, UncompiledData);
198 199
};

200
class InterpreterData : public Struct {
201
 public:
202 203
  DECL_ACCESSORS(bytecode_array, BytecodeArray)
  DECL_ACCESSORS(interpreter_trampoline, Code)
204

205 206 207 208 209 210 211 212 213
// Layout description.
#define INTERPRETER_DATA_FIELDS(V)             \
  V(kBytecodeArrayOffset, kTaggedSize)         \
  V(kInterpreterTrampolineOffset, kTaggedSize) \
  /* Total size. */                            \
  V(kSize, 0)

  DEFINE_FIELD_OFFSET_CONSTANTS(Struct::kHeaderSize, INTERPRETER_DATA_FIELDS)
#undef INTERPRETER_DATA_FIELDS
214

215
  DECL_CAST(InterpreterData)
216 217 218
  DECL_PRINTER(InterpreterData)
  DECL_VERIFIER(InterpreterData)

219
  OBJECT_CONSTRUCTORS(InterpreterData, Struct);
220 221
};

222 223
// SharedFunctionInfo describes the JSFunction information that can be
// shared by multiple instances of the function.
224
class SharedFunctionInfo : public HeapObject {
225
 public:
226
  NEVER_READ_ONLY_SPACE
227
  static constexpr Object const kNoSharedNameSentinel = Smi::kZero;
228 229

  // [name]: Returns shared name if it exists or an empty string otherwise.
230 231
  inline String Name() const;
  inline void SetName(String name);
232

233
  // Get the code object which represents the execution of this function.
234
  Code GetCode() const;
235 236 237

  // Get the abstract code associated with the function, which will either be
  // a Code object or a BytecodeArray.
238
  inline AbstractCode abstract_code();
239 240 241 242 243 244 245 246 247 248

  // 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.
249 250
  V8_EXPORT_PRIVATE static void SetScript(
      Handle<SharedFunctionInfo> shared, Handle<Object> script_object,
251
      int function_literal_id, bool reset_preparsed_scope_data = true);
252 253 254 255 256 257 258 259 260

  // 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;
261
  static const uint16_t kInvalidLength = static_cast<uint16_t>(-1);
262 263

  // [scope_info]: Scope info.
264
  DECL_ACCESSORS(scope_info, ScopeInfo)
265

266
  // End position of this function in the script source.
267
  V8_EXPORT_PRIVATE int EndPosition() const;
268 269

  // Start position of this function in the script source.
270
  V8_EXPORT_PRIVATE int StartPosition() const;
271

272 273
  // Set the start and end position of this function in the script source.
  // Updates the scope info if available.
274
  V8_EXPORT_PRIVATE void SetPosition(int start_position, int end_position);
275

276 277
  // [outer scope info | feedback metadata] Shared storage for outer scope info
  // (on uncompiled functions) and feedback metadata (on compiled functions).
278
  DECL_ACCESSORS(raw_outer_scope_info_or_feedback_metadata, HeapObject)
279 280 281

  // Get the outer scope info whether this function is compiled or not.
  inline bool HasOuterScopeInfo() const;
282
  inline ScopeInfo GetOuterScopeInfo() const;
283 284 285 286

  // [feedback metadata] Metadata template for feedback vectors of instances of
  // this function.
  inline bool HasFeedbackMetadata() const;
287
  DECL_ACCESSORS(feedback_metadata, FeedbackMetadata)
288

289 290 291 292
  // Returns if this function has been compiled yet. Note: with bytecode
  // flushing, any GC after this call is made could cause the function
  // to become uncompiled. If you need to ensure the function remains compiled
  // for some period of time, use IsCompiledScope instead.
293 294
  inline bool is_compiled() const;

295 296 297 298 299
  // Returns an IsCompiledScope which reports whether the function is compiled,
  // and if compiled, will avoid the function becoming uncompiled while it is
  // held.
  inline IsCompiledScope is_compiled_scope() const;

300
  // [length]: The function length - usually the number of declared parameters.
301 302 303 304
  // 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;
305 306 307 308 309 310
  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.
311
  DECL_UINT16_ACCESSORS(internal_formal_parameter_count)
312 313 314 315 316 317 318

  // 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.
319
  DECL_UINT8_ACCESSORS(expected_nof_properties)
320 321 322 323

#if V8_SFI_HAS_UNIQUE_ID
  // [unique_id] - For --trace-maps purposes, an identifier that's persistent
  // even if the GC moves this SharedFunctionInfo.
324
  DECL_INT_ACCESSORS(unique_id)
325 326 327 328 329 330
#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()].
331 332
  //  - a InterpreterData with the BytecodeArray and a copy of the
  //    interpreter trampoline [HasInterpreterData()]
333
  //  - an AsmWasmData with Asm->Wasm conversion [HasAsmWasmData()].
334
  //  - a Smi containing the builtin id [HasBuiltinId()]
335 336 337 338
  //  - a UncompiledDataWithoutPreparseData for lazy compilation
  //    [HasUncompiledDataWithoutPreparseData()]
  //  - a UncompiledDataWithPreparseData for lazy compilation
  //    [HasUncompiledDataWithPreparseData()]
339
  //  - a WasmExportedFunctionData for Wasm [HasWasmExportedFunctionData()]
340 341
  DECL_ACCESSORS(function_data, Object)

342
  inline bool IsApiFunction() const;
343 344
  inline FunctionTemplateInfo get_api_func_data();
  inline void set_api_func_data(FunctionTemplateInfo data);
345
  inline bool HasBytecodeArray() const;
346 347
  inline BytecodeArray GetBytecodeArray() const;
  inline void set_bytecode_array(BytecodeArray bytecode);
348
  inline Code InterpreterTrampoline() const;
349
  inline bool HasInterpreterData() const;
350 351
  inline InterpreterData interpreter_data() const;
  inline void set_interpreter_data(InterpreterData interpreter_data);
352 353
  inline BytecodeArray GetDebugBytecodeArray() const;
  inline void SetDebugBytecodeArray(BytecodeArray bytecode);
354
  inline bool HasAsmWasmData() const;
355 356
  inline AsmWasmData asm_wasm_data() const;
  inline void set_asm_wasm_data(AsmWasmData data);
357

358
  // A brief note to clear up possible confusion:
359
  // builtin_id corresponds to the auto-generated
360 361 362
  // Builtins::Name id, while builtin_function_id corresponds to
  // BuiltinFunctionId (a manually maintained list of 'interesting' functions
  // mainly used during optimization).
363 364 365
  inline bool HasBuiltinId() const;
  inline int builtin_id() const;
  inline void set_builtin_id(int builtin_id);
366
  inline bool HasUncompiledData() const;
367 368
  inline UncompiledData uncompiled_data() const;
  inline void set_uncompiled_data(UncompiledData data);
369 370 371 372 373 374
  inline bool HasUncompiledDataWithPreparseData() const;
  inline UncompiledDataWithPreparseData uncompiled_data_with_preparse_data()
      const;
  inline void set_uncompiled_data_with_preparse_data(
      UncompiledDataWithPreparseData data);
  inline bool HasUncompiledDataWithoutPreparseData() const;
375
  inline bool HasWasmExportedFunctionData() const;
376
  WasmExportedFunctionData wasm_exported_function_data() const;
377

378 379 380
  // Clear out pre-parsed scope data from UncompiledDataWithPreparseData,
  // turning it into UncompiledDataWithoutPreparseData.
  inline void ClearPreparseData();
381

382 383 384 385 386
  // [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)
387 388 389
  inline bool HasBuiltinFunctionId();
  inline BuiltinFunctionId builtin_function_id();
  inline void set_builtin_function_id(BuiltinFunctionId id);
390 391 392 393 394 395 396 397
  // 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.
398
  inline bool HasInferredName();
399
  inline String inferred_name();
400

401
  // Get the function literal id associated with this function, for parsing.
402
  V8_EXPORT_PRIVATE int FunctionLiteralId(Isolate* isolate) const;
403

404 405 406
  // Break infos are contained in DebugInfo, this is a convenience method
  // to simplify access.
  bool HasBreakInfo() const;
407
  bool BreakAtEntry() const;
408

409 410 411
  // Coverage infos are contained in DebugInfo, this is a convenience method
  // to simplify access.
  bool HasCoverageInfo() const;
412
  CoverageInfo GetCoverageInfo() const;
413

414
  // The function's name if it is non-empty, otherwise the inferred name.
415
  String DebugName();
416

417
  // Used for flags such as --turbo-filter.
418 419
  bool PassesFilter(const char* raw_filter);

420 421 422 423 424
  // [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)

425 426
  inline Object script() const;
  inline void set_script(Object script);
427 428 429

  // The function is subject to debugging if a debug info is attached.
  inline bool HasDebugInfo() const;
430 431
  inline DebugInfo GetDebugInfo() const;
  inline void SetDebugInfo(DebugInfo debug_info);
432

433 434 435 436 437 438 439 440 441
  // 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;
442

443
  // Returns true if the function has shared name.
444
  inline bool HasSharedName() const;
445

446
  // [flags] Bit field containing various flags about the function.
447
  DECL_INT32_ACCESSORS(flags)
448

449 450 451 452 453 454 455 456 457 458
  // 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.
459
  inline LanguageMode language_mode() const;
460 461
  inline void set_language_mode(LanguageMode language_mode);

462 463 464
  // Indicates whether the source is implicitly wrapped in a function.
  DECL_BOOLEAN_ACCESSORS(is_wrapped)

465 466 467 468 469 470 471 472 473 474 475 476 477 478 479
  // 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)

480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
  // 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)

497 498
  inline FunctionKind kind() const;

499 500 501 502
  // Defines the index in a native context of closure's map instantiated using
  // this shared function info.
  DECL_INT_ACCESSORS(function_map_index)

503 504 505 506
  // Clear uninitialized padding space. This ensures that the snapshot content
  // is deterministic.
  inline void clear_padding();

507 508 509
  // Recalculates the |map_index| value after modifications of this shared info.
  inline void UpdateFunctionMapIndex();

510 511 512 513 514 515 516 517
  // 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;

518 519 520 521
  // Disable (further) attempted optimization of all functions sharing this
  // shared function info.
  void DisableOptimization(BailoutReason reason);

522 523 524 525
  // 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.
526
  DECL_BOOLEAN_ACCESSORS(requires_instance_members_initializer)
527

528 529
  // [source code]: Source code for the function.
  bool HasSourceCode() const;
530 531
  static Handle<Object> GetSourceCode(Handle<SharedFunctionInfo> shared);
  static Handle<Object> GetSourceCodeHarmony(Handle<SharedFunctionInfo> shared);
532

533 534 535 536 537
  // Tells whether this function should be subject to debugging, e.g. for
  // - scope inspection
  // - internal break points
  // - coverage and type profile
  // - error stack trace
538 539 540 541 542
  inline bool IsSubjectToDebugging();

  // Whether this function is defined in user-provided JavaScript code.
  inline bool IsUserJavaScript();

543 544
  // True if one can flush compiled code from this function, in such a way that
  // it can later be re-compiled.
545
  inline bool CanDiscardCompiled() const;
546 547

  // Flush compiled data from this function, setting it back to CompileLazy and
548 549 550 551 552 553 554 555
  // clearing any compiled metadata.
  static void DiscardCompiled(Isolate* isolate,
                              Handle<SharedFunctionInfo> shared_info);

  // Discard the compiled metadata. If called during GC then
  // |gc_notify_updated_slot| should be used to record any slot updates.
  void DiscardCompiledMetadata(
      Isolate* isolate,
556 557 558
      std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
          gc_notify_updated_slot =
              [](HeapObject object, ObjectSlot slot, HeapObject target) {});
559 560 561

  // Returns true if the function has old bytecode that could be flushed.
  inline bool ShouldFlushBytecode();
562

563 564 565 566 567 568 569 570 571 572 573 574 575
  // 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,
576
                                      FunctionLiteral* lit, bool is_toplevel);
577 578 579 580

  // Sets the expected number of properties based on estimate from parser.
  void SetExpectedNofPropertiesFromEstimate(FunctionLiteral* literal);

581 582 583 584
  // Sets the FunctionTokenOffset field based on the given token position and
  // start position.
  void SetFunctionTokenPosition(int function_token_position,
                                int start_position);
585

586 587 588 589 590 591 592 593 594
  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();

595
  // Dispatched behavior.
596 597
  DECL_PRINTER(SharedFunctionInfo)
  DECL_VERIFIER(SharedFunctionInfo)
598 599 600
#ifdef OBJECT_PRINT
  void PrintSourceCode(std::ostream& os);
#endif
601 602 603 604

  // Iterate over all shared function infos in a given script.
  class ScriptIterator {
   public:
605
    ScriptIterator(Isolate* isolate, Script script);
606 607
    ScriptIterator(Isolate* isolate,
                   Handle<WeakFixedArray> shared_function_infos);
608
    SharedFunctionInfo Next();
609
    int CurrentIndex() const { return index_ - 1; }
610 611

    // Reset the iterator to run on |script|.
612
    void Reset(Script script);
613 614 615

   private:
    Isolate* isolate_;
616
    Handle<WeakFixedArray> shared_function_infos_;
617 618 619 620 621 622 623 624
    int index_;
    DISALLOW_COPY_AND_ASSIGN(ScriptIterator);
  };

  // Iterate over all shared function infos on the heap.
  class GlobalIterator {
   public:
    explicit GlobalIterator(Isolate* isolate);
625
    SharedFunctionInfo Next();
626 627 628

   private:
    Script::Iterator script_iterator_;
629
    WeakArrayList::Iterator noscript_sfi_iterator_;
630
    SharedFunctionInfo::ScriptIterator sfi_iterator_;
631
    DISALLOW_HEAP_ALLOCATION(no_gc_);
632 633 634
    DISALLOW_COPY_AND_ASSIGN(GlobalIterator);
  };

635
  DECL_CAST(SharedFunctionInfo)
636 637

  // Constants.
638
  static const uint16_t kDontAdaptArgumentsSentinel = static_cast<uint16_t>(-1);
639

640 641 642 643
  static const int kMaximumFunctionTokenOffset = kMaxUInt16 - 1;
  static const uint16_t kFunctionTokenOutOfRange = static_cast<uint16_t>(-1);
  STATIC_ASSERT(kMaximumFunctionTokenOffset + 1 == kFunctionTokenOutOfRange);

644
#if V8_SFI_HAS_UNIQUE_ID
645
  static const int kUniqueIdFieldSize = kInt32Size;
646 647
#else
  // Just to not break the postmortrem support with conditional offsets
648
  static const int kUniqueIdFieldSize = 0;
649 650
#endif

651
// Layout description.
652 653 654 655
#define SHARED_FUNCTION_INFO_FIELDS(V)                    \
  /* Pointer fields. */                                   \
  V(kStartOfPointerFieldsOffset, 0)                       \
  V(kFunctionDataOffset, kTaggedSize)                     \
656
  V(kStartOfAlwaysStrongPointerFieldsOffset, 0)           \
657 658 659 660 661 662 663 664 665 666 667 668 669
  V(kNameOrScopeInfoOffset, kTaggedSize)                  \
  V(kOuterScopeInfoOrFeedbackMetadataOffset, kTaggedSize) \
  V(kScriptOrDebugInfoOffset, kTaggedSize)                \
  V(kEndOfTaggedFieldsOffset, 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. */                                       \
670 671 672 673
  V(kSize, 0)

  DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
                                SHARED_FUNCTION_INFO_FIELDS)
674
#undef SHARED_FUNCTION_INFO_FIELDS
675 676 677

  static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);

678
  class BodyDescriptor;
679

680 681
// Bit positions in |flags|.
#define FLAGS_BIT_FIELDS(V, _)                           \
682 683
  V(IsNativeBit, bool, 1, _)                             \
  V(IsStrictBit, bool, 1, _)                             \
684
  V(IsWrappedBit, bool, 1, _)                            \
685 686 687
  V(IsClassConstructorBit, bool, 1, _)                   \
  V(IsDerivedConstructorBit, bool, 1, _)                 \
  V(FunctionKindBits, FunctionKind, 5, _)                \
688 689 690 691 692 693
  V(HasDuplicateParametersBit, bool, 1, _)               \
  V(AllowLazyCompilationBit, bool, 1, _)                 \
  V(NeedsHomeObjectBit, bool, 1, _)                      \
  V(IsDeclarationBit, bool, 1, _)                        \
  V(IsAsmWasmBrokenBit, bool, 1, _)                      \
  V(FunctionMapIndexBits, int, 5, _)                     \
694
  V(DisabledOptimizationReasonBits, BailoutReason, 4, _) \
695
  V(RequiresInstanceMembersInitializer, bool, 1, _)      \
696 697 698 699
  V(ConstructAsBuiltinBit, bool, 1, _)                   \
  V(IsAnonymousExpressionBit, bool, 1, _)                \
  V(NameShouldPrintAsAnonymousBit, bool, 1, _)           \
  V(IsDeserializedBit, bool, 1, _)                       \
700 701 702
  V(HasReportedBinaryCoverageBit, bool, 1, _)            \
  V(IsNamedExpressionBit, bool, 1, _)                    \
  V(IsTopLevelBit, bool, 1, _)
703 704
  DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
#undef FLAGS_BIT_FIELDS
705

706
  // Bailout reasons must fit in the DisabledOptimizationReason bitfield.
707
  STATIC_ASSERT(BailoutReason::kLastErrorMessage <=
708
                DisabledOptimizationReasonBits::kMax);
709

710
  STATIC_ASSERT(kLastFunctionKind <= FunctionKindBits::kMax);
711

712 713 714 715 716
  // 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;

717
 private:
718 719 720
  // [name_or_scope_info]: Function name string, kNoSharedNameSentinel or
  // ScopeInfo.
  DECL_ACCESSORS(name_or_scope_info, Object)
721

722 723
  // [outer scope info] The outer scope info, needed to lazily parse this
  // function.
724
  DECL_ACCESSORS(outer_scope_info, HeapObject)
725

726 727
  inline void set_kind(FunctionKind kind);

728
  inline void set_needs_home_object(bool value);
729 730 731

  friend class Factory;
  friend class V8HeapExplorer;
732 733
  FRIEND_TEST(PreParserTest, LazyFunctionLength);

734
  inline uint16_t length() const;
735

736 737 738 739
  // Find the index of this function in the parent script. Slow path of
  // FunctionLiteralId.
  int FindIndexInScript(Isolate* isolate) const;

740
  OBJECT_CONSTRUCTORS(SharedFunctionInfo, HeapObject);
741 742 743 744
};

// Printing support.
struct SourceCodeOf {
745
  explicit SourceCodeOf(SharedFunctionInfo v, int max = -1)
746
      : value(v), max_length(max) {}
747
  const SharedFunctionInfo value;
748 749 750
  int max_length;
};

751 752 753 754 755 756 757 758 759 760 761 762 763 764 765
// IsCompiledScope enables a caller to check if a function is compiled, and
// ensure it remains compiled (i.e., doesn't have it's bytecode flushed) while
// the scope is retained.
class IsCompiledScope {
 public:
  inline IsCompiledScope(const SharedFunctionInfo shared, Isolate* isolate);
  inline IsCompiledScope() : retain_bytecode_(), is_compiled_(false) {}

  inline bool is_compiled() const { return is_compiled_; }

 private:
  MaybeHandle<BytecodeArray> retain_bytecode_;
  bool is_compiled_;
};

766 767 768 769 770 771 772 773
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_