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