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