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/objects.h"
9 : #include "src/objects/script.h"
10 :
11 : // Has to be the last include (doesn't have include guards):
12 : #include "src/objects/object-macros.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : class BytecodeArray;
18 : class CoverageInfo;
19 : class DebugInfo;
20 :
21 : class PreParsedScopeData : public Struct {
22 : public:
23 : DECL_ACCESSORS(scope_data, PodArray<uint8_t>)
24 : DECL_ACCESSORS(child_data, FixedArray)
25 :
26 : static const int kScopeDataOffset = Struct::kHeaderSize;
27 : static const int kChildDataOffset = kScopeDataOffset + kPointerSize;
28 : static const int kSize = kChildDataOffset + kPointerSize;
29 :
30 : DECL_CAST(PreParsedScopeData)
31 : DECL_PRINTER(PreParsedScopeData)
32 : DECL_VERIFIER(PreParsedScopeData)
33 :
34 : private:
35 : DISALLOW_IMPLICIT_CONSTRUCTORS(PreParsedScopeData);
36 : };
37 :
38 : // SharedFunctionInfo describes the JSFunction information that can be
39 : // shared by multiple instances of the function.
40 : class SharedFunctionInfo : public HeapObject {
41 : public:
42 : static constexpr Object* const kNoSharedNameSentinel = Smi::kZero;
43 :
44 : // [name]: Returns shared name if it exists or an empty string otherwise.
45 : inline String* name() const;
46 : inline void set_name(String* name);
47 :
48 : // [code]: Function code.
49 : DECL_ACCESSORS(code, Code)
50 :
51 : // Get the abstract code associated with the function, which will either be
52 : // a Code object or a BytecodeArray.
53 : inline AbstractCode* abstract_code();
54 :
55 : // Tells whether or not this shared function info is interpreted.
56 : //
57 : // Note: function->IsInterpreted() does not necessarily return the same value
58 : // as function->shared()->IsInterpreted() because the closure might have been
59 : // optimized.
60 : inline bool IsInterpreted() const;
61 :
62 : // Set up the link between shared function info and the script. The shared
63 : // function info is added to the list on the script.
64 : V8_EXPORT_PRIVATE static void SetScript(
65 : Handle<SharedFunctionInfo> shared, Handle<Object> script_object,
66 : bool reset_preparsed_scope_data = true);
67 :
68 : // Layout description of the optimized code map.
69 : static const int kEntriesStart = 0;
70 : static const int kContextOffset = 0;
71 : static const int kCachedCodeOffset = 1;
72 : static const int kEntryLength = 2;
73 : static const int kInitialLength = kEntriesStart + kEntryLength;
74 :
75 : static const int kNotFound = -1;
76 : static const int kInvalidLength = -1;
77 :
78 : // Helpers for assembly code that does a backwards walk of the optimized code
79 : // map.
80 : static const int kOffsetToPreviousContext =
81 : FixedArray::kHeaderSize + kPointerSize * (kContextOffset - kEntryLength);
82 : static const int kOffsetToPreviousCachedCode =
83 : FixedArray::kHeaderSize +
84 : kPointerSize * (kCachedCodeOffset - kEntryLength);
85 :
86 : // [scope_info]: Scope info.
87 : DECL_ACCESSORS(scope_info, ScopeInfo)
88 :
89 : // The outer scope info for the purpose of parsing this function, or the hole
90 : // value if it isn't yet known.
91 : DECL_ACCESSORS(outer_scope_info, HeapObject)
92 :
93 : // [construct stub]: Code stub for constructing instances of this function.
94 : DECL_ACCESSORS(construct_stub, Code)
95 :
96 : // Sets the given code as the construct stub, and marks builtin code objects
97 : // as a construct stub.
98 : void SetConstructStub(Code* code);
99 :
100 : // Returns if this function has been compiled to native code yet.
101 : inline bool is_compiled() const;
102 :
103 : // [length]: The function length - usually the number of declared parameters.
104 : // Use up to 2^30 parameters. The value is only reliable when the function has
105 : // been compiled.
106 : inline int GetLength() const;
107 : inline bool HasLength() const;
108 : inline void set_length(int value);
109 :
110 : // [internal formal parameter count]: The declared number of parameters.
111 : // For subclass constructors, also includes new.target.
112 : // The size of function's frame is internal_formal_parameter_count + 1.
113 : DECL_INT_ACCESSORS(internal_formal_parameter_count)
114 :
115 : // Set the formal parameter count so the function code will be
116 : // called without using argument adaptor frames.
117 : inline void DontAdaptArguments();
118 :
119 : // [expected_nof_properties]: Expected number of properties for the
120 : // function. The value is only reliable when the function has been compiled.
121 : DECL_INT_ACCESSORS(expected_nof_properties)
122 :
123 : // [feedback_metadata] - describes ast node feedback from full-codegen and
124 : // (increasingly) from crankshafted code where sufficient feedback isn't
125 : // available.
126 : DECL_ACCESSORS(feedback_metadata, FeedbackMetadata)
127 :
128 : // [function_literal_id] - uniquely identifies the FunctionLiteral this
129 : // SharedFunctionInfo represents within its script, or -1 if this
130 : // SharedFunctionInfo object doesn't correspond to a parsed FunctionLiteral.
131 : DECL_INT_ACCESSORS(function_literal_id)
132 :
133 : #if V8_SFI_HAS_UNIQUE_ID
134 : // [unique_id] - For --trace-maps purposes, an identifier that's persistent
135 : // even if the GC moves this SharedFunctionInfo.
136 : DECL_INT_ACCESSORS(unique_id)
137 : #endif
138 :
139 : // [instance class name]: class name for instances.
140 : DECL_ACCESSORS(instance_class_name, Object)
141 :
142 : // [function data]: This field holds some additional data for function.
143 : // Currently it has one of:
144 : // - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
145 : // - a BytecodeArray for the interpreter [HasBytecodeArray()].
146 : // - a FixedArray with Asm->Wasm conversion [HasAsmWasmData()].
147 : // - a Smi containing the builtin id [HasLazyDeserializationBuiltinId()]
148 : DECL_ACCESSORS(function_data, Object)
149 :
150 : inline bool IsApiFunction();
151 : inline FunctionTemplateInfo* get_api_func_data();
152 : inline void set_api_func_data(FunctionTemplateInfo* data);
153 : inline bool HasBytecodeArray() const;
154 : inline BytecodeArray* bytecode_array() const;
155 : inline void set_bytecode_array(BytecodeArray* bytecode);
156 : inline void ClearBytecodeArray();
157 : inline bool HasAsmWasmData() const;
158 : inline FixedArray* asm_wasm_data() const;
159 : inline void set_asm_wasm_data(FixedArray* data);
160 : inline void ClearAsmWasmData();
161 : // A brief note to clear up possible confusion:
162 : // lazy_deserialization_builtin_id corresponds to the auto-generated
163 : // Builtins::Name id, while builtin_function_id corresponds to
164 : // BuiltinFunctionId (a manually maintained list of 'interesting' functions
165 : // mainly used during optimization).
166 : inline bool HasLazyDeserializationBuiltinId() const;
167 : inline int lazy_deserialization_builtin_id() const;
168 : inline void set_lazy_deserialization_builtin_id(int builtin_id);
169 :
170 : // [function identifier]: This field holds an additional identifier for the
171 : // function.
172 : // - a Smi identifying a builtin function [HasBuiltinFunctionId()].
173 : // - a String identifying the function's inferred name [HasInferredName()].
174 : // The inferred_name is inferred from variable or property
175 : // assignment of this function. It is used to facilitate debugging and
176 : // profiling of JavaScript code written in OO style, where almost
177 : // all functions are anonymous but are assigned to object
178 : // properties.
179 : DECL_ACCESSORS(function_identifier, Object)
180 :
181 : inline bool HasBuiltinFunctionId();
182 : inline BuiltinFunctionId builtin_function_id();
183 : inline void set_builtin_function_id(BuiltinFunctionId id);
184 : inline bool HasInferredName();
185 : inline String* inferred_name();
186 : inline void set_inferred_name(String* inferred_name);
187 :
188 : // [script]: Script from which the function originates.
189 : DECL_ACCESSORS(script, Object)
190 :
191 : // [start_position_and_type]: Field used to store both the source code
192 : // position, whether or not the function is a function expression,
193 : // and whether or not the function is a toplevel function. The two
194 : // least significants bit indicates whether the function is an
195 : // expression and the rest contains the source code position.
196 : DECL_INT_ACCESSORS(start_position_and_type)
197 :
198 : // The function is subject to debugging if a debug info is attached.
199 : inline bool HasDebugInfo() const;
200 : DebugInfo* GetDebugInfo() const;
201 :
202 : // Break infos are contained in DebugInfo, this is a convenience method
203 : // to simplify access.
204 : bool HasBreakInfo() const;
205 :
206 : // Coverage infos are contained in DebugInfo, this is a convenience method
207 : // to simplify access.
208 : bool HasCoverageInfo() const;
209 : CoverageInfo* GetCoverageInfo() const;
210 :
211 : // [debug info]: Debug information.
212 : DECL_ACCESSORS(debug_info, Object)
213 :
214 : // PreParsedScopeData or null.
215 : DECL_ACCESSORS(preparsed_scope_data, Object)
216 :
217 : inline bool HasPreParsedScopeData() const;
218 :
219 : // Bit field containing various information collected for debugging.
220 : // This field is either stored on the kDebugInfo slot or inside the
221 : // debug info struct.
222 : int debugger_hints() const;
223 : void set_debugger_hints(int value);
224 :
225 : // Indicates that the function was created by the Function function.
226 : // Though it's anonymous, toString should treat it as if it had the name
227 : // "anonymous". We don't set the name itself so that the system does not
228 : // see a binding for it.
229 : DECL_BOOLEAN_ACCESSORS(name_should_print_as_anonymous)
230 :
231 : // Indicates that the function is either an anonymous expression
232 : // or an arrow function (the name field can be set through the API,
233 : // which does not change this flag).
234 : DECL_BOOLEAN_ACCESSORS(is_anonymous_expression)
235 :
236 : // Indicates that the the shared function info is deserialized from cache.
237 : DECL_BOOLEAN_ACCESSORS(deserialized)
238 :
239 : // Indicates that the function cannot cause side-effects.
240 : DECL_BOOLEAN_ACCESSORS(has_no_side_effect)
241 :
242 : // Indicates that |has_no_side_effect| has been computed and set.
243 : DECL_BOOLEAN_ACCESSORS(computed_has_no_side_effect)
244 :
245 : // Indicates that the function should be skipped during stepping.
246 : DECL_BOOLEAN_ACCESSORS(debug_is_blackboxed)
247 :
248 : // Indicates that |debug_is_blackboxed| has been computed and set.
249 : DECL_BOOLEAN_ACCESSORS(computed_debug_is_blackboxed)
250 :
251 : // Indicates that the function has been reported for binary code coverage.
252 : DECL_BOOLEAN_ACCESSORS(has_reported_binary_coverage)
253 :
254 : // The function's name if it is non-empty, otherwise the inferred name.
255 : String* DebugName();
256 :
257 : // The function cannot cause any side effects.
258 : bool HasNoSideEffect();
259 :
260 : // Used for flags such as --turbo-filter.
261 : bool PassesFilter(const char* raw_filter);
262 :
263 : // Position of the 'function' token in the script source.
264 : DECL_INT_ACCESSORS(function_token_position)
265 :
266 : // Position of this function in the script source.
267 : DECL_INT_ACCESSORS(start_position)
268 :
269 : // End position of this function in the script source.
270 : DECL_INT_ACCESSORS(end_position)
271 :
272 : // Returns true if the function has shared name.
273 : inline bool has_shared_name() const;
274 :
275 : // Is this function a named function expression in the source code.
276 : DECL_BOOLEAN_ACCESSORS(is_named_expression)
277 :
278 : // Is this function a top-level function (scripts, evals).
279 : DECL_BOOLEAN_ACCESSORS(is_toplevel)
280 :
281 : // Bit field containing various information collected by the compiler to
282 : // drive optimization.
283 : DECL_INT_ACCESSORS(compiler_hints)
284 :
285 : // Indicates if this function can be lazy compiled.
286 : DECL_BOOLEAN_ACCESSORS(allows_lazy_compilation)
287 :
288 : // Indicates the language mode.
289 : inline LanguageMode language_mode();
290 : inline void set_language_mode(LanguageMode language_mode);
291 :
292 : // True if the function has any duplicated parameter names.
293 : DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
294 :
295 : // Indicates whether the function is a native function.
296 : // These needs special treatment in .call and .apply since
297 : // null passed as the receiver should not be translated to the
298 : // global object.
299 : DECL_BOOLEAN_ACCESSORS(native)
300 :
301 : // Whether this function was created from a FunctionDeclaration.
302 : DECL_BOOLEAN_ACCESSORS(is_declaration)
303 :
304 : // Indicates that asm->wasm conversion failed and should not be re-attempted.
305 : DECL_BOOLEAN_ACCESSORS(is_asm_wasm_broken)
306 :
307 : inline FunctionKind kind() const;
308 :
309 : // Defines the index in a native context of closure's map instantiated using
310 : // this shared function info.
311 : DECL_INT_ACCESSORS(function_map_index)
312 :
313 : // Clear uninitialized padding space. This ensures that the snapshot content
314 : // is deterministic.
315 : inline void clear_padding();
316 :
317 : // Recalculates the |map_index| value after modifications of this shared info.
318 : inline void UpdateFunctionMapIndex();
319 :
320 : // Indicates whether optimizations have been disabled for this shared function
321 : // info. If we cannot optimize the function we disable optimization to avoid
322 : // spending time attempting to optimize it again.
323 : inline bool optimization_disabled() const;
324 :
325 : // The reason why optimization was disabled.
326 : inline BailoutReason disable_optimization_reason() const;
327 :
328 : // Disable (further) attempted optimization of all functions sharing this
329 : // shared function info.
330 : void DisableOptimization(BailoutReason reason);
331 :
332 : // [source code]: Source code for the function.
333 : bool HasSourceCode() const;
334 : Handle<Object> GetSourceCode();
335 : Handle<Object> GetSourceCodeHarmony();
336 :
337 : // Tells whether this function should be subject to debugging.
338 : inline bool IsSubjectToDebugging();
339 :
340 : // Whether this function is defined in user-provided JavaScript code.
341 : inline bool IsUserJavaScript();
342 :
343 : // Check whether or not this function is inlineable.
344 : bool IsInlineable();
345 :
346 : // Source size of this function.
347 : int SourceSize();
348 :
349 : // Returns `false` if formal parameters include rest parameters, optional
350 : // parameters, or destructuring parameters.
351 : // TODO(caitp): make this a flag set during parsing
352 : inline bool has_simple_parameters();
353 :
354 : // Initialize a SharedFunctionInfo from a parsed function literal.
355 : static void InitFromFunctionLiteral(Handle<SharedFunctionInfo> shared_info,
356 : FunctionLiteral* lit);
357 :
358 : // Sets the expected number of properties based on estimate from parser.
359 : void SetExpectedNofPropertiesFromEstimate(FunctionLiteral* literal);
360 :
361 : // Dispatched behavior.
362 : DECL_PRINTER(SharedFunctionInfo)
363 : DECL_VERIFIER(SharedFunctionInfo)
364 : #ifdef OBJECT_PRINT
365 : void PrintSourceCode(std::ostream& os);
366 : #endif
367 :
368 : // Iterate over all shared function infos in a given script.
369 : class ScriptIterator {
370 : public:
371 : explicit ScriptIterator(Handle<Script> script);
372 : ScriptIterator(Isolate* isolate, Handle<FixedArray> shared_function_infos);
373 : SharedFunctionInfo* Next();
374 :
375 : // Reset the iterator to run on |script|.
376 : void Reset(Handle<Script> script);
377 :
378 : private:
379 : Isolate* isolate_;
380 : Handle<FixedArray> shared_function_infos_;
381 : int index_;
382 : DISALLOW_COPY_AND_ASSIGN(ScriptIterator);
383 : };
384 :
385 : // Iterate over all shared function infos on the heap.
386 : class GlobalIterator {
387 : public:
388 : explicit GlobalIterator(Isolate* isolate);
389 : SharedFunctionInfo* Next();
390 :
391 : private:
392 : Script::Iterator script_iterator_;
393 : WeakFixedArray::Iterator noscript_sfi_iterator_;
394 : SharedFunctionInfo::ScriptIterator sfi_iterator_;
395 : DisallowHeapAllocation no_gc_;
396 : DISALLOW_COPY_AND_ASSIGN(GlobalIterator);
397 : };
398 :
399 : DECL_CAST(SharedFunctionInfo)
400 :
401 : // Constants.
402 : static const int kDontAdaptArgumentsSentinel = -1;
403 :
404 : #if V8_SFI_HAS_UNIQUE_ID
405 : static const int kUniqueIdFieldSize = kInt32Size;
406 : #else
407 : // Just to not break the postmortrem support with conditional offsets
408 : static const int kUniqueIdFieldSize = 0;
409 : #endif
410 :
411 : // Layout description.
412 : #define SHARED_FUNCTION_INFO_FIELDS(V) \
413 : /* Pointer fields. */ \
414 : V(kCodeOffset, kPointerSize) \
415 : V(kNameOffset, kPointerSize) \
416 : V(kScopeInfoOffset, kPointerSize) \
417 : V(kOuterScopeInfoOffset, kPointerSize) \
418 : V(kConstructStubOffset, kPointerSize) \
419 : V(kInstanceClassNameOffset, kPointerSize) \
420 : V(kFunctionDataOffset, kPointerSize) \
421 : V(kScriptOffset, kPointerSize) \
422 : V(kDebugInfoOffset, kPointerSize) \
423 : V(kFunctionIdentifierOffset, kPointerSize) \
424 : V(kFeedbackMetadataOffset, kPointerSize) \
425 : V(kPreParsedScopeDataOffset, kPointerSize) \
426 : V(kEndOfPointerFieldsOffset, 0) \
427 : /* Raw data fields. */ \
428 : V(kFunctionLiteralIdOffset, kInt32Size) \
429 : V(kUniqueIdOffset, kUniqueIdFieldSize) \
430 : V(kLengthOffset, kInt32Size) \
431 : V(kFormalParameterCountOffset, kInt32Size) \
432 : V(kExpectedNofPropertiesOffset, kInt32Size) \
433 : V(kStartPositionAndTypeOffset, kInt32Size) \
434 : V(kEndPositionOffset, kInt32Size) \
435 : V(kFunctionTokenPositionOffset, kInt32Size) \
436 : V(kCompilerHintsOffset, kInt32Size) \
437 : /* Total size. */ \
438 : V(kSize, 0)
439 :
440 : DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
441 : SHARED_FUNCTION_INFO_FIELDS)
442 : #undef SHARED_FUNCTION_INFO_FIELDS
443 :
444 : static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
445 :
446 : typedef FixedBodyDescriptor<kCodeOffset, kEndOfPointerFieldsOffset, kSize>
447 : BodyDescriptor;
448 : // No weak fields.
449 : typedef BodyDescriptor BodyDescriptorWeak;
450 :
451 : // Bit fields in |start_position_and_type|.
452 : #define START_POSITION_AND_TYPE_BIT_FIELDS(V, _) \
453 : V(IsNamedExpressionBit, bool, 1, _) \
454 : V(IsTopLevelBit, bool, 1, _) \
455 : V(StartPositionBits, int, 30, _)
456 :
457 : DEFINE_BIT_FIELDS(START_POSITION_AND_TYPE_BIT_FIELDS)
458 : #undef START_POSITION_AND_TYPE_BIT_FIELDS
459 :
460 : // Bit positions in |compiler_hints|.
461 : #define COMPILER_HINTS_BIT_FIELDS(V, _) \
462 : V(IsNativeBit, bool, 1, _) \
463 : V(IsStrictBit, bool, 1, _) \
464 : V(FunctionKindBits, FunctionKind, 10, _) \
465 : V(HasDuplicateParametersBit, bool, 1, _) \
466 : V(AllowLazyCompilationBit, bool, 1, _) \
467 : V(NeedsHomeObjectBit, bool, 1, _) \
468 : V(IsDeclarationBit, bool, 1, _) \
469 : V(IsAsmWasmBrokenBit, bool, 1, _) \
470 : V(FunctionMapIndexBits, int, 5, _) \
471 : V(DisabledOptimizationReasonBits, BailoutReason, 7, _)
472 :
473 : DEFINE_BIT_FIELDS(COMPILER_HINTS_BIT_FIELDS)
474 : #undef COMPILER_HINTS_BIT_FIELDS
475 :
476 : // Bailout reasons must fit in the DisabledOptimizationReason bitfield.
477 : STATIC_ASSERT(kLastErrorMessage <= DisabledOptimizationReasonBits::kMax);
478 :
479 : // Masks for checking if certain FunctionKind bits are set without fully
480 : // decoding of the FunctionKind bit field.
481 : static const int kClassConstructorMask = FunctionKind::kClassConstructor
482 : << FunctionKindBits::kShift;
483 : static const int kDerivedConstructorMask = FunctionKind::kDerivedConstructor
484 : << FunctionKindBits::kShift;
485 :
486 : // Bit positions in |debugger_hints|.
487 : #define DEBUGGER_HINTS_BIT_FIELDS(V, _) \
488 : V(IsAnonymousExpressionBit, bool, 1, _) \
489 : V(NameShouldPrintAsAnonymousBit, bool, 1, _) \
490 : V(IsDeserializedBit, bool, 1, _) \
491 : V(HasNoSideEffectBit, bool, 1, _) \
492 : V(ComputedHasNoSideEffectBit, bool, 1, _) \
493 : V(DebugIsBlackboxedBit, bool, 1, _) \
494 : V(ComputedDebugIsBlackboxedBit, bool, 1, _) \
495 : V(HasReportedBinaryCoverageBit, bool, 1, _)
496 :
497 : DEFINE_BIT_FIELDS(DEBUGGER_HINTS_BIT_FIELDS)
498 : #undef DEBUGGER_HINTS_BIT_FIELDS
499 :
500 : private:
501 : // [raw_name]: Function name string or kNoSharedNameSentinel.
502 : DECL_ACCESSORS(raw_name, Object)
503 :
504 : inline void set_kind(FunctionKind kind);
505 :
506 : // Indicates that this function uses a super property (or an eval that may
507 : // use a super property).
508 : // This is needed to set up the [[HomeObject]] on the function instance.
509 : DECL_BOOLEAN_ACCESSORS(needs_home_object)
510 :
511 : friend class Factory;
512 : friend class V8HeapExplorer;
513 : FRIEND_TEST(PreParserTest, LazyFunctionLength);
514 :
515 : inline int length() const;
516 :
517 : DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
518 : };
519 :
520 : // Printing support.
521 : struct SourceCodeOf {
522 : explicit SourceCodeOf(SharedFunctionInfo* v, int max = -1)
523 0 : : value(v), max_length(max) {}
524 : const SharedFunctionInfo* value;
525 : int max_length;
526 : };
527 :
528 : std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v);
529 :
530 : } // namespace internal
531 : } // namespace v8
532 :
533 : #include "src/objects/object-macros-undef.h"
534 :
535 : #endif // V8_OBJECTS_SHARED_FUNCTION_INFO_H_
|