summaryrefslogtreecommitdiff
path: root/chromium/v8/src/objects/shared-function-info.h
blob: 06abe8a2c78d3c6bc73f246189166bdeabf33218 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_SHARED_FUNCTION_INFO_H_
#define V8_OBJECTS_SHARED_FUNCTION_INFO_H_

#include "src/objects.h"
#include "src/objects/script.h"

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

namespace v8 {
namespace internal {

class BytecodeArray;
class CoverageInfo;
class DebugInfo;

class PreParsedScopeData : public Struct {
 public:
  DECL_ACCESSORS(scope_data, PodArray<uint8_t>)
  DECL_ACCESSORS(child_data, FixedArray)

  static const int kScopeDataOffset = Struct::kHeaderSize;
  static const int kChildDataOffset = kScopeDataOffset + kPointerSize;
  static const int kSize = kChildDataOffset + kPointerSize;

  DECL_CAST(PreParsedScopeData)
  DECL_PRINTER(PreParsedScopeData)
  DECL_VERIFIER(PreParsedScopeData)

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(PreParsedScopeData);
};

class InterpreterData : public Struct {
 public:
  DECL_ACCESSORS(bytecode_array, BytecodeArray)
  DECL_ACCESSORS(interpreter_trampoline, Code)

  static const int kBytecodeArrayOffset = Struct::kHeaderSize;
  static const int kInterpreterTrampolineOffset =
      kBytecodeArrayOffset + kPointerSize;
  static const int kSize = kInterpreterTrampolineOffset + kPointerSize;

  DECL_CAST(InterpreterData)
  DECL_PRINTER(InterpreterData)
  DECL_VERIFIER(InterpreterData)

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(InterpreterData);
};

// SharedFunctionInfo describes the JSFunction information that can be
// shared by multiple instances of the function.
class SharedFunctionInfo : public HeapObject {
 public:
  static constexpr Object* const kNoSharedNameSentinel = Smi::kZero;

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

  // Get the code object which represents the execution of this function.
  inline Code* GetCode() const;

  // Get the abstract code associated with the function, which will either be
  // a Code object or a BytecodeArray.
  inline AbstractCode* abstract_code();

  // Tells whether or not this shared function info is interpreted.
  //
  // Note: function->IsInterpreted() does not necessarily return the same value
  // as function->shared()->IsInterpreted() because the closure might have been
  // optimized.
  inline bool IsInterpreted() const;

  // Set up the link between shared function info and the script. The shared
  // function info is added to the list on the script.
  V8_EXPORT_PRIVATE static void SetScript(
      Handle<SharedFunctionInfo> shared, Handle<Object> script_object,
      bool reset_preparsed_scope_data = true);

  // Layout description of the optimized code map.
  static const int kEntriesStart = 0;
  static const int kContextOffset = 0;
  static const int kCachedCodeOffset = 1;
  static const int kEntryLength = 2;
  static const int kInitialLength = kEntriesStart + kEntryLength;

  static const int kNotFound = -1;
  static const int kInvalidLength = -1;

  // Helpers for assembly code that does a backwards walk of the optimized code
  // map.
  static const int kOffsetToPreviousContext =
      FixedArray::kHeaderSize + kPointerSize * (kContextOffset - kEntryLength);
  static const int kOffsetToPreviousCachedCode =
      FixedArray::kHeaderSize +
      kPointerSize * (kCachedCodeOffset - kEntryLength);

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

  // End position of this function in the script source.
  inline int EndPosition() const;

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

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

  // Get the outer scope info whether this function is compiled or not.
  inline bool HasOuterScopeInfo() const;
  inline ScopeInfo* GetOuterScopeInfo() const;

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

  // Returns if this function has been compiled to native code yet.
  inline bool is_compiled() const;

  // [length]: The function length - usually the number of declared parameters.
  // Use up to 2^30 parameters. The value is only reliable when the function has
  // been compiled.
  inline int GetLength() const;
  inline bool HasLength() const;
  inline void set_length(int value);

  // [internal formal parameter count]: The declared number of parameters.
  // For subclass constructors, also includes new.target.
  // The size of function's frame is internal_formal_parameter_count + 1.
  DECL_INT_ACCESSORS(internal_formal_parameter_count)

  // Set the formal parameter count so the function code will be
  // called without using argument adaptor frames.
  inline void DontAdaptArguments();

  // [expected_nof_properties]: Expected number of properties for the
  // function. The value is only reliable when the function has been compiled.
  DECL_INT_ACCESSORS(expected_nof_properties)

  // [function_literal_id] - uniquely identifies the FunctionLiteral this
  // SharedFunctionInfo represents within its script, or -1 if this
  // SharedFunctionInfo object doesn't correspond to a parsed FunctionLiteral.
  DECL_INT_ACCESSORS(function_literal_id)

#if V8_SFI_HAS_UNIQUE_ID
  // [unique_id] - For --trace-maps purposes, an identifier that's persistent
  // even if the GC moves this SharedFunctionInfo.
  DECL_INT_ACCESSORS(unique_id)
#endif

  // [function data]: This field holds some additional data for function.
  // Currently it has one of:
  //  - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
  //  - a BytecodeArray for the interpreter [HasBytecodeArray()].
  //  - a InterpreterData with the BytecodeArray and a copy of the
  //    interpreter trampoline [HasInterpreterData()]
  //  - a FixedArray with Asm->Wasm conversion [HasAsmWasmData()].
  //  - a Smi containing the builtin id [HasBuiltinId()]
  //  - a PreParsedScopeData for the parser [HasPreParsedScopeData()]
  //  - a Code object otherwise [HasCodeObject()]
  DECL_ACCESSORS(function_data, Object)

  inline bool IsApiFunction() const;
  inline FunctionTemplateInfo* get_api_func_data();
  inline void set_api_func_data(FunctionTemplateInfo* data);
  inline bool HasBytecodeArray() const;
  inline BytecodeArray* GetBytecodeArray() const;
  inline void set_bytecode_array(class BytecodeArray* bytecode);
  inline Code* InterpreterTrampoline() const;
  inline bool HasInterpreterData() const;
  inline InterpreterData* interpreter_data() const;
  inline void set_interpreter_data(InterpreterData* interpreter_data);
  inline bool HasAsmWasmData() const;
  inline FixedArray* asm_wasm_data() const;
  inline void set_asm_wasm_data(FixedArray* data);
  // A brief note to clear up possible confusion:
  // builtin_id corresponds to the auto-generated
  // Builtins::Name id, while builtin_function_id corresponds to
  // BuiltinFunctionId (a manually maintained list of 'interesting' functions
  // mainly used during optimization).
  inline bool HasBuiltinId() const;
  inline int builtin_id() const;
  inline void set_builtin_id(int builtin_id);
  inline bool HasPreParsedScopeData() const;
  inline PreParsedScopeData* preparsed_scope_data() const;
  inline void set_preparsed_scope_data(PreParsedScopeData* data);
  inline void ClearPreParsedScopeData();
  inline bool HasCodeObject() const;
  inline Code* code_object() const;
  inline void set_code_object();

  // [function identifier]: This field holds an additional identifier for the
  // function.
  //  - a Smi identifying a builtin function [HasBuiltinFunctionId()].
  //  - a String identifying the function's inferred name [HasInferredName()].
  // 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.
  DECL_ACCESSORS(function_identifier, Object)

  inline bool HasBuiltinFunctionId();
  inline BuiltinFunctionId builtin_function_id();
  inline void set_builtin_function_id(BuiltinFunctionId id);
  inline bool HasInferredName();
  inline String* inferred_name();
  inline void set_inferred_name(String* inferred_name);

  // [script]: Script from which the function originates.
  DECL_ACCESSORS(script, Object)

  // The function is subject to debugging if a debug info is attached.
  inline bool HasDebugInfo() const;
  DebugInfo* GetDebugInfo() const;

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

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

  // [debug info]: Debug information.
  DECL_ACCESSORS(debug_info, Object)

  // Bit field containing various information collected for debugging.
  // This field is either stored on the kDebugInfo slot or inside the
  // debug info struct.
  int debugger_hints() const;
  void set_debugger_hints(int value);

  // 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 cannot cause side-effects.
  DECL_BOOLEAN_ACCESSORS(has_no_side_effect)

  // Indicates that the function requires runtime side-effect checks.
  DECL_BOOLEAN_ACCESSORS(requires_runtime_side_effect_checks);

  // Indicates that |has_no_side_effect| has been computed and set.
  DECL_BOOLEAN_ACCESSORS(computed_has_no_side_effect)

  // Indicates that the function should be skipped during stepping.
  DECL_BOOLEAN_ACCESSORS(debug_is_blackboxed)

  // Indicates that |debug_is_blackboxed| has been computed and set.
  DECL_BOOLEAN_ACCESSORS(computed_debug_is_blackboxed)

  // Indicates that the function has been reported for binary code coverage.
  DECL_BOOLEAN_ACCESSORS(has_reported_binary_coverage)

  // Id assigned to the function for debugging.
  // This could also be implemented as a weak hash table.
  inline int debugging_id() const;
  inline void set_debugging_id(int value);

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

  // The function cannot cause any side effects.
  static bool HasNoSideEffect(Handle<SharedFunctionInfo> info);

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

  // Position of the 'function' token in the script source.
  DECL_INT_ACCESSORS(function_token_position)

  // [raw_start_position_and_type]: Field used to store both the source code
  // position, whether or not the function is a function expression,
  // and whether or not the function is a toplevel function. The two
  // least significants bit indicates whether the function is an
  // expression and the rest contains the source code position.
  // TODO(cbruni): start_position should be removed from SFI.
  DECL_INT_ACCESSORS(raw_start_position_and_type)

  // Position of this function in the script source.
  // TODO(cbruni): start_position should be removed from SFI.
  DECL_INT_ACCESSORS(raw_start_position)

  // End position of this function in the script source.
  // TODO(cbruni): end_position should be removed from SFI.
  DECL_INT_ACCESSORS(raw_end_position)

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

  // 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)

  // [flags] Bit field containing various flags about the function.
  DECL_INT_ACCESSORS(flags)

  // Indicates if this function can be lazy compiled.
  DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)

  // Indicates the language mode.
  inline LanguageMode language_mode();
  inline void set_language_mode(LanguageMode language_mode);

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

  // True if the function has any duplicated parameter names.
  DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)

  // Indicates whether the function is a native function.
  // These needs special treatment in .call and .apply since
  // null passed as the receiver should not be translated to the
  // global object.
  DECL_BOOLEAN_ACCESSORS(native)

  // Whether this function was created from a FunctionDeclaration.
  DECL_BOOLEAN_ACCESSORS(is_declaration)

  // Indicates that asm->wasm conversion failed and should not be re-attempted.
  DECL_BOOLEAN_ACCESSORS(is_asm_wasm_broken)

  inline FunctionKind kind() const;

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

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

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

  // Indicates whether optimizations have been disabled for this shared function
  // info. If we cannot optimize the function we disable optimization to avoid
  // spending time attempting to optimize it again.
  inline bool optimization_disabled() const;

  // The reason why optimization was disabled.
  inline BailoutReason disable_optimization_reason() const;

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

  // This class constructor needs to call out to an instance fields
  // initializer. This flag is set when creating the
  // SharedFunctionInfo as a reminder to emit the initializer call
  // when generating code later.
  DECL_BOOLEAN_ACCESSORS(requires_instance_fields_initializer)

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

  // Tells whether this function should be subject to debugging, e.g. for
  // - scope inspection
  // - internal break points
  // - coverage and type profile
  // - error stack trace
  inline bool IsSubjectToDebugging();

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

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

  // Flush compiled data from this function, setting it back to CompileLazy and
  // clearing any feedback metadata.
  inline void FlushCompiled();

  // Check whether or not this function is inlineable.
  bool IsInlineable();

  // Source size of this function.
  int SourceSize();

  // Returns `false` if formal parameters include rest parameters, optional
  // parameters, or destructuring parameters.
  // TODO(caitp): make this a flag set during parsing
  inline bool has_simple_parameters();

  // Initialize a SharedFunctionInfo from a parsed function literal.
  static void InitFromFunctionLiteral(Handle<SharedFunctionInfo> shared_info,
                                      FunctionLiteral* lit, bool is_toplevel);

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

  inline bool construct_as_builtin() const;

  // Determines and sets the ConstructAsBuiltinBit in |flags|, based on the
  // |function_data|. Must be called when creating the SFI after other fields
  // are initialized. The ConstructAsBuiltinBit determines whether
  // JSBuiltinsConstructStub or JSConstructStubGeneric should be called to
  // construct this function.
  inline void CalculateConstructAsBuiltin();

  // Dispatched behavior.
  DECL_PRINTER(SharedFunctionInfo)
  DECL_VERIFIER(SharedFunctionInfo)
#ifdef OBJECT_PRINT
  void PrintSourceCode(std::ostream& os);
#endif

  // Iterate over all shared function infos in a given script.
  class ScriptIterator {
   public:
    explicit ScriptIterator(Handle<Script> script);
    ScriptIterator(Isolate* isolate,
                   Handle<WeakFixedArray> shared_function_infos);
    SharedFunctionInfo* Next();

    // Reset the iterator to run on |script|.
    void Reset(Handle<Script> script);

   private:
    Isolate* isolate_;
    Handle<WeakFixedArray> shared_function_infos_;
    int index_;
    DISALLOW_COPY_AND_ASSIGN(ScriptIterator);
  };

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

   private:
    Script::Iterator script_iterator_;
    FixedArrayOfWeakCells::Iterator noscript_sfi_iterator_;
    SharedFunctionInfo::ScriptIterator sfi_iterator_;
    DisallowHeapAllocation no_gc_;
    DISALLOW_COPY_AND_ASSIGN(GlobalIterator);
  };

  DECL_CAST(SharedFunctionInfo)

  // Constants.
  static const int kDontAdaptArgumentsSentinel = -1;

#if V8_SFI_HAS_UNIQUE_ID
  static const int kUniqueIdFieldSize = kInt32Size;
#else
  // Just to not break the postmortrem support with conditional offsets
  static const int kUniqueIdFieldSize = 0;
#endif

// Layout description.
#define SHARED_FUNCTION_INFO_FIELDS(V)                     \
  /* Pointer fields. */                                    \
  V(kStartOfPointerFieldsOffset, 0)                        \
  V(kFunctionDataOffset, kPointerSize)                     \
  V(kNameOrScopeInfoOffset, kPointerSize)                  \
  V(kOuterScopeInfoOrFeedbackMetadataOffset, kPointerSize) \
  V(kScriptOffset, kPointerSize)                           \
  V(kDebugInfoOffset, kPointerSize)                        \
  V(kFunctionIdentifierOffset, kPointerSize)               \
  V(kEndOfPointerFieldsOffset, 0)                          \
  /* Raw data fields. */                                   \
  V(kFunctionLiteralIdOffset, kInt32Size)                  \
  V(kUniqueIdOffset, kUniqueIdFieldSize)                   \
  V(kLengthOffset, kInt32Size)                             \
  V(kFormalParameterCountOffset, kInt32Size)               \
  V(kExpectedNofPropertiesOffset, kInt32Size)              \
  V(kStartPositionAndTypeOffset, kInt32Size)               \
  V(kEndPositionOffset, kInt32Size)                        \
  V(kFunctionTokenPositionOffset, kInt32Size)              \
  V(kFlagsOffset, kInt32Size)                              \
  /* Total size. */                                        \
  V(kSize, 0)

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

  static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);

  typedef FixedBodyDescriptor<kStartOfPointerFieldsOffset,
                              kEndOfPointerFieldsOffset, kSize>
      BodyDescriptor;
  // No weak fields.
  typedef BodyDescriptor BodyDescriptorWeak;

// Bit fields in |raw_start_position_and_type|.
#define START_POSITION_AND_TYPE_BIT_FIELDS(V, _) \
  V(IsNamedExpressionBit, bool, 1, _)            \
  V(IsTopLevelBit, bool, 1, _)                   \
  V(StartPositionBits, int, 30, _)

  DEFINE_BIT_FIELDS(START_POSITION_AND_TYPE_BIT_FIELDS)
#undef START_POSITION_AND_TYPE_BIT_FIELDS

// Bit positions in |flags|.
#define FLAGS_BIT_FIELDS(V, _)                           \
  V(IsNativeBit, bool, 1, _)                             \
  V(IsStrictBit, bool, 1, _)                             \
  V(IsWrappedBit, bool, 1, _)                            \
  V(IsClassConstructorBit, bool, 1, _)                   \
  V(IsDerivedConstructorBit, bool, 1, _)                 \
  V(FunctionKindBits, FunctionKind, 5, _)                \
  V(HasDuplicateParametersBit, bool, 1, _)               \
  V(AllowLazyCompilationBit, bool, 1, _)                 \
  V(NeedsHomeObjectBit, bool, 1, _)                      \
  V(IsDeclarationBit, bool, 1, _)                        \
  V(IsAsmWasmBrokenBit, bool, 1, _)                      \
  V(FunctionMapIndexBits, int, 5, _)                     \
  V(DisabledOptimizationReasonBits, BailoutReason, 4, _) \
  V(RequiresInstanceFieldsInitializer, bool, 1, _)       \
  V(ConstructAsBuiltinBit, bool, 1, _)

  DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
#undef FLAGS_BIT_FIELDS

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

  STATIC_ASSERT(kLastFunctionKind <= FunctionKindBits::kMax);

// Bit positions in |debugger_hints|.
#define DEBUGGER_HINTS_BIT_FIELDS(V, _)             \
  V(IsAnonymousExpressionBit, bool, 1, _)           \
  V(NameShouldPrintAsAnonymousBit, bool, 1, _)      \
  V(IsDeserializedBit, bool, 1, _)                  \
  V(HasNoSideEffectBit, bool, 1, _)                 \
  V(RequiresRuntimeSideEffectChecksBit, bool, 1, _) \
  V(ComputedHasNoSideEffectBit, bool, 1, _)         \
  V(DebugIsBlackboxedBit, bool, 1, _)               \
  V(ComputedDebugIsBlackboxedBit, bool, 1, _)       \
  V(HasReportedBinaryCoverageBit, bool, 1, _)       \
  V(DebuggingIdBits, int, 20, _)

  DEFINE_BIT_FIELDS(DEBUGGER_HINTS_BIT_FIELDS)
#undef DEBUGGER_HINTS_BIT_FIELDS

  static const int kNoDebuggingId = 0;

  // Indicates that this function uses a super property (or an eval that may
  // use a super property).
  // This is needed to set up the [[HomeObject]] on the function instance.
  inline bool needs_home_object() const;

 private:
  // [name_or_scope_info]: Function name string, kNoSharedNameSentinel or
  // ScopeInfo.
  DECL_ACCESSORS(name_or_scope_info, Object)

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

  inline void set_kind(FunctionKind kind);

  inline void set_needs_home_object(bool value);

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

  inline int length() const;

  DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
};

// Printing support.
struct SourceCodeOf {
  explicit SourceCodeOf(SharedFunctionInfo* v, int max = -1)
      : value(v), max_length(max) {}
  const SharedFunctionInfo* value;
  int max_length;
};

std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v);

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_SHARED_FUNCTION_INFO_H_