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_INL_H_
6 : #define V8_OBJECTS_SHARED_FUNCTION_INFO_INL_H_
7 :
8 : #include "src/objects/shared-function-info.h"
9 :
10 : #include "src/feedback-vector-inl.h"
11 : #include "src/handles-inl.h"
12 : #include "src/heap/heap-write-barrier-inl.h"
13 : #include "src/objects/debug-objects-inl.h"
14 : #include "src/objects/scope-info.h"
15 : #include "src/objects/templates.h"
16 : #include "src/wasm/wasm-objects-inl.h"
17 :
18 : // Has to be the last include (doesn't have include guards):
19 : #include "src/objects/object-macros.h"
20 :
21 : namespace v8 {
22 : namespace internal {
23 :
24 : OBJECT_CONSTRUCTORS_IMPL(PreparseData, HeapObject)
25 :
26 : CAST_ACCESSOR(PreparseData)
27 672816 : INT_ACCESSORS(PreparseData, data_length, kDataLengthOffset)
28 375376 : INT_ACCESSORS(PreparseData, children_length, kInnerLengthOffset)
29 :
30 : int PreparseData::inner_start_offset() const {
31 : return InnerOffset(data_length());
32 : }
33 :
34 : ObjectSlot PreparseData::inner_data_start() const {
35 : return RawField(inner_start_offset());
36 : }
37 :
38 63699 : void PreparseData::clear_padding() {
39 63699 : int data_end_offset = kDataStartOffset + data_length();
40 63699 : int padding_size = inner_start_offset() - data_end_offset;
41 : DCHECK_LE(0, padding_size);
42 63699 : if (padding_size == 0) return;
43 112782 : memset(reinterpret_cast<void*>(address() + data_end_offset), 0, padding_size);
44 : }
45 :
46 : byte PreparseData::get(int index) const {
47 : DCHECK_LE(0, index);
48 : DCHECK_LT(index, data_length());
49 579780 : int offset = kDataStartOffset + index * kByteSize;
50 579780 : return READ_BYTE_FIELD(*this, offset);
51 : }
52 :
53 : void PreparseData::set(int index, byte value) {
54 : DCHECK_LE(0, index);
55 : DCHECK_LT(index, data_length());
56 : int offset = kDataStartOffset + index * kByteSize;
57 : WRITE_BYTE_FIELD(*this, offset, value);
58 : }
59 :
60 : void PreparseData::copy_in(int index, const byte* buffer, int length) {
61 : DCHECK(index >= 0 && length >= 0 && length <= kMaxInt - index &&
62 : index + length <= this->data_length());
63 63699 : Address dst_addr = FIELD_ADDR(*this, kDataStartOffset + index * kByteSize);
64 63699 : memcpy(reinterpret_cast<void*>(dst_addr), buffer, length);
65 : }
66 :
67 : PreparseData PreparseData::get_child(int index) const {
68 3197 : return PreparseData::cast(get_child_raw(index));
69 : }
70 :
71 3197 : Object PreparseData::get_child_raw(int index) const {
72 : DCHECK_LE(0, index);
73 : DCHECK_LT(index, this->children_length());
74 3197 : int offset = inner_start_offset() + index * kTaggedSize;
75 6394 : return RELAXED_READ_FIELD(*this, offset);
76 : }
77 :
78 6844 : void PreparseData::set_child(int index, PreparseData value,
79 : WriteBarrierMode mode) {
80 : DCHECK_LE(0, index);
81 : DCHECK_LT(index, this->children_length());
82 6844 : int offset = inner_start_offset() + index * kTaggedSize;
83 6844 : RELAXED_WRITE_FIELD(*this, offset, value);
84 13688 : CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);
85 6844 : }
86 :
87 : OBJECT_CONSTRUCTORS_IMPL(UncompiledData, HeapObject)
88 : OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithoutPreparseData, UncompiledData)
89 : OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithPreparseData, UncompiledData)
90 : CAST_ACCESSOR(UncompiledData)
91 12396755 : ACCESSORS(UncompiledData, inferred_name, String, kInferredNameOffset)
92 5111945 : INT32_ACCESSORS(UncompiledData, start_position, kStartPositionOffset)
93 4066213 : INT32_ACCESSORS(UncompiledData, end_position, kEndPositionOffset)
94 3459834 : INT32_ACCESSORS(UncompiledData, function_literal_id, kFunctionLiteralIdOffset)
95 :
96 : void UncompiledData::clear_padding() {
97 : if (FIELD_SIZE(kOptionalPaddingOffset) == 0) return;
98 : DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
99 2229695 : memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
100 : FIELD_SIZE(kOptionalPaddingOffset));
101 : }
102 :
103 : CAST_ACCESSOR(UncompiledDataWithoutPreparseData)
104 :
105 : CAST_ACCESSOR(UncompiledDataWithPreparseData)
106 335029 : ACCESSORS(UncompiledDataWithPreparseData, preparse_data, PreparseData,
107 : kPreparseDataOffset)
108 :
109 : bool HeapObject::IsUncompiledData() const {
110 135292214 : return IsUncompiledDataWithoutPreparseData() ||
111 : IsUncompiledDataWithPreparseData();
112 : }
113 :
114 : OBJECT_CONSTRUCTORS_IMPL(InterpreterData, Struct)
115 :
116 : CAST_ACCESSOR(InterpreterData)
117 226 : ACCESSORS(InterpreterData, bytecode_array, BytecodeArray, kBytecodeArrayOffset)
118 189 : ACCESSORS(InterpreterData, interpreter_trampoline, Code,
119 : kInterpreterTrampolineOffset)
120 :
121 : OBJECT_CONSTRUCTORS_IMPL(SharedFunctionInfo, HeapObject)
122 : NEVER_READ_ONLY_SPACE_IMPL(SharedFunctionInfo)
123 : CAST_ACCESSOR(SharedFunctionInfo)
124 463997 : DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
125 :
126 111965950 : ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object,
127 : kNameOrScopeInfoOffset)
128 135590660 : ACCESSORS(SharedFunctionInfo, script_or_debug_info, Object,
129 : kScriptOrDebugInfoOffset)
130 :
131 20414764 : UINT16_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
132 36080349 : UINT16_ACCESSORS(SharedFunctionInfo, internal_formal_parameter_count,
133 : kFormalParameterCountOffset)
134 16311889 : UINT16_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
135 : kExpectedNofPropertiesOffset)
136 15047559 : UINT16_ACCESSORS(SharedFunctionInfo, raw_function_token_offset,
137 : kFunctionTokenOffsetOffset)
138 487377524 : RELAXED_INT32_ACCESSORS(SharedFunctionInfo, flags, kFlagsOffset)
139 :
140 28886663 : bool SharedFunctionInfo::HasSharedName() const {
141 : Object value = name_or_scope_info();
142 28886668 : if (value->IsScopeInfo()) {
143 3166254 : return ScopeInfo::cast(value)->HasSharedFunctionName();
144 : }
145 25720414 : return value != kNoSharedNameSentinel;
146 : }
147 :
148 9779192 : String SharedFunctionInfo::Name() const {
149 9779192 : if (!HasSharedName()) return GetReadOnlyRoots().empty_string();
150 : Object value = name_or_scope_info();
151 9767310 : if (value->IsScopeInfo()) {
152 3096306 : if (ScopeInfo::cast(value)->HasFunctionName()) {
153 3096305 : return String::cast(ScopeInfo::cast(value)->FunctionName());
154 : }
155 : return GetReadOnlyRoots().empty_string();
156 : }
157 : return String::cast(value);
158 : }
159 :
160 640 : void SharedFunctionInfo::SetName(String name) {
161 : Object maybe_scope_info = name_or_scope_info();
162 640 : if (maybe_scope_info->IsScopeInfo()) {
163 5 : ScopeInfo::cast(maybe_scope_info)->SetFunctionName(name);
164 : } else {
165 : DCHECK(maybe_scope_info->IsString() ||
166 : maybe_scope_info == kNoSharedNameSentinel);
167 635 : set_name_or_scope_info(name);
168 : }
169 640 : UpdateFunctionMapIndex();
170 640 : }
171 :
172 3704313 : AbstractCode SharedFunctionInfo::abstract_code() {
173 3704313 : if (HasBytecodeArray()) {
174 2635936 : return AbstractCode::cast(GetBytecodeArray());
175 : } else {
176 1068374 : return AbstractCode::cast(GetCode());
177 : }
178 : }
179 :
180 : Object SharedFunctionInfo::function_data() const {
181 405777565 : return ACQUIRE_READ_FIELD(*this, kFunctionDataOffset);
182 : }
183 :
184 8300810 : void SharedFunctionInfo::set_function_data(Object data, WriteBarrierMode mode) {
185 13977130 : RELEASE_WRITE_FIELD(*this, kFunctionDataOffset, data);
186 16601620 : CONDITIONAL_WRITE_BARRIER(*this, kFunctionDataOffset, data, mode);
187 8300813 : }
188 :
189 : int SharedFunctionInfo::function_token_position() const {
190 1795279 : int offset = raw_function_token_offset();
191 1795279 : if (offset == kFunctionTokenOutOfRange) {
192 : return kNoSourcePosition;
193 : } else {
194 1795207 : return StartPosition() - offset;
195 : }
196 : }
197 :
198 7278972 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_wrapped,
199 : SharedFunctionInfo::IsWrappedBit)
200 7278956 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, allows_lazy_compilation,
201 : SharedFunctionInfo::AllowLazyCompilationBit)
202 7231234 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, has_duplicate_parameters,
203 : SharedFunctionInfo::HasDuplicateParametersBit)
204 7278954 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_declaration,
205 : SharedFunctionInfo::IsDeclarationBit)
206 :
207 3938252 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, native,
208 : SharedFunctionInfo::IsNativeBit)
209 350 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_asm_wasm_broken,
210 : SharedFunctionInfo::IsAsmWasmBrokenBit)
211 7278944 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags,
212 : requires_instance_members_initializer,
213 : SharedFunctionInfo::RequiresInstanceMembersInitializer)
214 :
215 2170562 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, name_should_print_as_anonymous,
216 : SharedFunctionInfo::NameShouldPrintAsAnonymousBit)
217 7278958 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_anonymous_expression,
218 : SharedFunctionInfo::IsAnonymousExpressionBit)
219 32976 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, has_reported_binary_coverage,
220 : SharedFunctionInfo::HasReportedBinaryCoverageBit)
221 :
222 7278956 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_named_expression,
223 : SharedFunctionInfo::IsNamedExpressionBit)
224 7278948 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_toplevel,
225 : SharedFunctionInfo::IsTopLevelBit)
226 4190066 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags,
227 : is_oneshot_iife_or_properties_are_final,
228 : SharedFunctionInfo::IsOneshotIIFEOrPropertiesAreFinalBit)
229 11469300 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags,
230 : is_safe_to_skip_arguments_adaptor,
231 : SharedFunctionInfo::IsSafeToSkipArgumentsAdaptorBit)
232 :
233 : bool SharedFunctionInfo::optimization_disabled() const {
234 : return disable_optimization_reason() != BailoutReason::kNoReason;
235 : }
236 :
237 : BailoutReason SharedFunctionInfo::disable_optimization_reason() const {
238 : return DisabledOptimizationReasonBits::decode(flags());
239 : }
240 :
241 : LanguageMode SharedFunctionInfo::language_mode() const {
242 : STATIC_ASSERT(LanguageModeSize == 2);
243 : return construct_language_mode(IsStrictBit::decode(flags()));
244 : }
245 :
246 5671896 : void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
247 : STATIC_ASSERT(LanguageModeSize == 2);
248 : // We only allow language mode transitions that set the same language mode
249 : // again or go up in the chain:
250 : DCHECK(is_sloppy(this->language_mode()) || is_strict(language_mode));
251 : int hints = flags();
252 : hints = IsStrictBit::update(hints, is_strict(language_mode));
253 : set_flags(hints);
254 5671896 : UpdateFunctionMapIndex();
255 5671907 : }
256 :
257 : FunctionKind SharedFunctionInfo::kind() const {
258 : return FunctionKindBits::decode(flags());
259 : }
260 :
261 9611660 : void SharedFunctionInfo::set_kind(FunctionKind kind) {
262 : int hints = flags();
263 : hints = FunctionKindBits::update(hints, kind);
264 : hints = IsClassConstructorBit::update(hints, IsClassConstructor(kind));
265 : set_flags(hints);
266 9611660 : UpdateFunctionMapIndex();
267 9611673 : }
268 :
269 : bool SharedFunctionInfo::needs_home_object() const {
270 : return NeedsHomeObjectBit::decode(flags());
271 : }
272 :
273 3639473 : void SharedFunctionInfo::set_needs_home_object(bool value) {
274 : int hints = flags();
275 : hints = NeedsHomeObjectBit::update(hints, value);
276 : set_flags(hints);
277 3639473 : UpdateFunctionMapIndex();
278 3639472 : }
279 :
280 : bool SharedFunctionInfo::construct_as_builtin() const {
281 : return ConstructAsBuiltinBit::decode(flags());
282 : }
283 :
284 9611664 : void SharedFunctionInfo::CalculateConstructAsBuiltin() {
285 : bool uses_builtins_construct_stub = false;
286 9611664 : if (HasBuiltinId()) {
287 : int id = builtin_id();
288 5676317 : if (id != Builtins::kCompileLazy && id != Builtins::kEmptyFunction) {
289 : uses_builtins_construct_stub = true;
290 : }
291 3935347 : } else if (IsApiFunction()) {
292 : uses_builtins_construct_stub = true;
293 : }
294 :
295 : int f = flags();
296 : f = ConstructAsBuiltinBit::update(f, uses_builtins_construct_stub);
297 : set_flags(f);
298 9611665 : }
299 :
300 : int SharedFunctionInfo::function_map_index() const {
301 : // Note: Must be kept in sync with the FastNewClosure builtin.
302 : int index =
303 7020190 : Context::FIRST_FUNCTION_MAP_INDEX + FunctionMapIndexBits::decode(flags());
304 : DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
305 : return index;
306 : }
307 :
308 18923886 : void SharedFunctionInfo::set_function_map_index(int index) {
309 : STATIC_ASSERT(Context::LAST_FUNCTION_MAP_INDEX <=
310 : Context::FIRST_FUNCTION_MAP_INDEX + FunctionMapIndexBits::kMax);
311 : DCHECK_LE(Context::FIRST_FUNCTION_MAP_INDEX, index);
312 : DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
313 18923886 : index -= Context::FIRST_FUNCTION_MAP_INDEX;
314 : set_flags(FunctionMapIndexBits::update(flags(), index));
315 18923886 : }
316 :
317 : void SharedFunctionInfo::clear_padding() {
318 9611673 : memset(reinterpret_cast<void*>(this->address() + kSize), 0,
319 : kAlignedSize - kSize);
320 : }
321 :
322 18923643 : void SharedFunctionInfo::UpdateFunctionMapIndex() {
323 56770935 : int map_index = Context::FunctionMapIndex(
324 37847289 : language_mode(), kind(), HasSharedName(), needs_home_object());
325 18923660 : set_function_map_index(map_index);
326 18923671 : }
327 :
328 : void SharedFunctionInfo::DontAdaptArguments() {
329 : // TODO(leszeks): Revise this DCHECK now that the code field is gone.
330 : DCHECK(!HasWasmExportedFunctionData());
331 : set_internal_formal_parameter_count(kDontAdaptArgumentsSentinel);
332 : }
333 :
334 698430 : bool SharedFunctionInfo::IsInterpreted() const { return HasBytecodeArray(); }
335 :
336 4244465 : ScopeInfo SharedFunctionInfo::scope_info() const {
337 : Object maybe_scope_info = name_or_scope_info();
338 4244466 : if (maybe_scope_info->IsScopeInfo()) {
339 : return ScopeInfo::cast(maybe_scope_info);
340 : }
341 3639491 : return ScopeInfo::Empty(GetIsolate());
342 : }
343 :
344 2095263 : void SharedFunctionInfo::set_scope_info(ScopeInfo scope_info,
345 : WriteBarrierMode mode) {
346 : // Move the existing name onto the ScopeInfo.
347 : Object name = name_or_scope_info();
348 2095263 : if (name->IsScopeInfo()) {
349 4726 : name = ScopeInfo::cast(name)->FunctionName();
350 : }
351 : DCHECK(name->IsString() || name == kNoSharedNameSentinel);
352 : // Only set the function name for function scopes.
353 2095263 : scope_info->SetFunctionName(name);
354 2669936 : if (HasInferredName() && inferred_name()->length() != 0) {
355 52657 : scope_info->SetInferredFunctionName(inferred_name());
356 : }
357 2095268 : WRITE_FIELD(*this, kNameOrScopeInfoOffset, scope_info);
358 4190537 : CONDITIONAL_WRITE_BARRIER(*this, kNameOrScopeInfoOffset, scope_info, mode);
359 2095269 : }
360 :
361 86993187 : ACCESSORS(SharedFunctionInfo, raw_outer_scope_info_or_feedback_metadata,
362 : HeapObject, kOuterScopeInfoOrFeedbackMetadataOffset)
363 :
364 : HeapObject SharedFunctionInfo::outer_scope_info() const {
365 : DCHECK(!is_compiled());
366 : DCHECK(!HasFeedbackMetadata());
367 : return raw_outer_scope_info_or_feedback_metadata();
368 : }
369 :
370 726109 : bool SharedFunctionInfo::HasOuterScopeInfo() const {
371 : ScopeInfo outer_info;
372 726109 : if (!is_compiled()) {
373 617168 : if (!outer_scope_info()->IsScopeInfo()) return false;
374 : outer_info = ScopeInfo::cast(outer_scope_info());
375 : } else {
376 108945 : if (!scope_info()->HasOuterScopeInfo()) return false;
377 21882 : outer_info = scope_info()->OuterScopeInfo();
378 : }
379 467313 : return outer_info->length() > 0;
380 : }
381 :
382 449310 : ScopeInfo SharedFunctionInfo::GetOuterScopeInfo() const {
383 : DCHECK(HasOuterScopeInfo());
384 449310 : if (!is_compiled()) return ScopeInfo::cast(outer_scope_info());
385 21882 : return scope_info()->OuterScopeInfo();
386 : }
387 :
388 : void SharedFunctionInfo::set_outer_scope_info(HeapObject value,
389 : WriteBarrierMode mode) {
390 : DCHECK(!is_compiled());
391 : DCHECK(raw_outer_scope_info_or_feedback_metadata()->IsTheHole());
392 : DCHECK(value->IsScopeInfo() || value->IsTheHole());
393 2237020 : set_raw_outer_scope_info_or_feedback_metadata(value, mode);
394 : }
395 :
396 276 : bool SharedFunctionInfo::HasFeedbackMetadata() const {
397 552 : return raw_outer_scope_info_or_feedback_metadata()->IsFeedbackMetadata();
398 : }
399 :
400 : FeedbackMetadata SharedFunctionInfo::feedback_metadata() const {
401 : DCHECK(HasFeedbackMetadata());
402 : return FeedbackMetadata::cast(raw_outer_scope_info_or_feedback_metadata());
403 : }
404 :
405 : void SharedFunctionInfo::set_feedback_metadata(FeedbackMetadata value,
406 : WriteBarrierMode mode) {
407 : DCHECK(!HasFeedbackMetadata());
408 : DCHECK(value->IsFeedbackMetadata());
409 2095170 : set_raw_outer_scope_info_or_feedback_metadata(value, mode);
410 : }
411 :
412 126040726 : bool SharedFunctionInfo::is_compiled() const {
413 : Object data = function_data();
414 250569878 : return data != Smi::FromEnum(Builtins::kCompileLazy) &&
415 126025636 : !data->IsUncompiledData();
416 : }
417 :
418 21935823 : IsCompiledScope SharedFunctionInfo::is_compiled_scope() const {
419 21935823 : return IsCompiledScope(*this, GetIsolate());
420 : }
421 :
422 21935827 : IsCompiledScope::IsCompiledScope(const SharedFunctionInfo shared,
423 : Isolate* isolate)
424 21935827 : : retain_bytecode_(shared->HasBytecodeArray()
425 : ? handle(shared->GetBytecodeArray(), isolate)
426 : : MaybeHandle<BytecodeArray>()),
427 30063837 : is_compiled_(shared->is_compiled()) {
428 : DCHECK_IMPLIES(!retain_bytecode_.is_null(), is_compiled());
429 21935854 : }
430 :
431 64272 : bool SharedFunctionInfo::has_simple_parameters() {
432 128544 : return scope_info()->HasSimpleParameters();
433 : }
434 :
435 29089134 : bool SharedFunctionInfo::IsApiFunction() const {
436 29089134 : return function_data()->IsFunctionTemplateInfo();
437 : }
438 :
439 : FunctionTemplateInfo SharedFunctionInfo::get_api_func_data() {
440 : DCHECK(IsApiFunction());
441 : return FunctionTemplateInfo::cast(function_data());
442 : }
443 :
444 51805442 : bool SharedFunctionInfo::HasBytecodeArray() const {
445 78104829 : return function_data()->IsBytecodeArray() ||
446 51805442 : function_data()->IsInterpreterData();
447 : }
448 :
449 19767633 : BytecodeArray SharedFunctionInfo::GetBytecodeArray() const {
450 : DCHECK(HasBytecodeArray());
451 20146732 : if (HasDebugInfo() && GetDebugInfo()->HasInstrumentedBytecodeArray()) {
452 : return GetDebugInfo()->OriginalBytecodeArray();
453 19497895 : } else if (function_data()->IsBytecodeArray()) {
454 : return BytecodeArray::cast(function_data());
455 : } else {
456 : DCHECK(function_data()->IsInterpreterData());
457 : return InterpreterData::cast(function_data())->bytecode_array();
458 : }
459 : }
460 :
461 0 : BytecodeArray SharedFunctionInfo::GetDebugBytecodeArray() const {
462 : DCHECK(HasBytecodeArray());
463 : DCHECK(HasDebugInfo() && GetDebugInfo()->HasInstrumentedBytecodeArray());
464 0 : if (function_data()->IsBytecodeArray()) {
465 : return BytecodeArray::cast(function_data());
466 : } else {
467 : DCHECK(function_data()->IsInterpreterData());
468 : return InterpreterData::cast(function_data())->bytecode_array();
469 : }
470 : }
471 :
472 21202 : void SharedFunctionInfo::SetDebugBytecodeArray(BytecodeArray bytecode) {
473 : DCHECK(HasBytecodeArray());
474 21202 : if (function_data()->IsBytecodeArray()) {
475 21202 : set_function_data(bytecode);
476 : } else {
477 : DCHECK(function_data()->IsInterpreterData());
478 0 : interpreter_data()->set_bytecode_array(bytecode);
479 : }
480 21202 : }
481 :
482 : void SharedFunctionInfo::set_bytecode_array(BytecodeArray bytecode) {
483 : DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy) ||
484 : HasUncompiledData());
485 2092659 : set_function_data(bytecode);
486 : }
487 :
488 61102440 : bool SharedFunctionInfo::ShouldFlushBytecode(BytecodeFlushMode mode) {
489 61102440 : if (mode == BytecodeFlushMode::kDoNotFlushBytecode) return false;
490 :
491 : // TODO(rmcilroy): Enable bytecode flushing for resumable functions.
492 122642699 : if (IsResumableFunction(kind()) || !allows_lazy_compilation()) {
493 : return false;
494 : }
495 :
496 : // Get a snapshot of the function data field, and if it is a bytecode array,
497 : // check if it is old. Note, this is done this way since this function can be
498 : // called by the concurrent marker.
499 : Object data = function_data();
500 11857259 : if (!data->IsBytecodeArray()) return false;
501 :
502 1906113 : if (mode == BytecodeFlushMode::kStressFlushBytecode) return true;
503 :
504 1905535 : BytecodeArray bytecode = BytecodeArray::cast(data);
505 :
506 1905535 : return bytecode->IsOld();
507 : }
508 :
509 : Code SharedFunctionInfo::InterpreterTrampoline() const {
510 : DCHECK(HasInterpreterData());
511 : return interpreter_data()->interpreter_trampoline();
512 : }
513 :
514 : bool SharedFunctionInfo::HasInterpreterData() const {
515 : return function_data()->IsInterpreterData();
516 : }
517 :
518 : InterpreterData SharedFunctionInfo::interpreter_data() const {
519 : DCHECK(HasInterpreterData());
520 : return InterpreterData::cast(function_data());
521 : }
522 :
523 : void SharedFunctionInfo::set_interpreter_data(
524 : InterpreterData interpreter_data) {
525 : DCHECK(FLAG_interpreted_frames_native_stack);
526 29 : set_function_data(interpreter_data);
527 : }
528 :
529 10655292 : bool SharedFunctionInfo::HasAsmWasmData() const {
530 10655292 : return function_data()->IsAsmWasmData();
531 : }
532 :
533 : AsmWasmData SharedFunctionInfo::asm_wasm_data() const {
534 : DCHECK(HasAsmWasmData());
535 : return AsmWasmData::cast(function_data());
536 : }
537 :
538 : void SharedFunctionInfo::set_asm_wasm_data(AsmWasmData data) {
539 : DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy) ||
540 : HasUncompiledData() || HasAsmWasmData());
541 2469 : set_function_data(data);
542 : }
543 :
544 3030 : bool SharedFunctionInfo::HasBuiltinId() const {
545 3030 : return function_data()->IsSmi();
546 : }
547 :
548 0 : int SharedFunctionInfo::builtin_id() const {
549 : DCHECK(HasBuiltinId());
550 : int id = Smi::ToInt(function_data());
551 : DCHECK(Builtins::IsBuiltinId(id));
552 0 : return id;
553 : }
554 :
555 : void SharedFunctionInfo::set_builtin_id(int builtin_id) {
556 : DCHECK(Builtins::IsBuiltinId(builtin_id));
557 : set_function_data(Smi::FromInt(builtin_id), SKIP_WRITE_BARRIER);
558 : }
559 :
560 10617501 : bool SharedFunctionInfo::HasUncompiledData() const {
561 10617501 : return function_data()->IsUncompiledData();
562 : }
563 :
564 : UncompiledData SharedFunctionInfo::uncompiled_data() const {
565 : DCHECK(HasUncompiledData());
566 : return UncompiledData::cast(function_data());
567 : }
568 :
569 : void SharedFunctionInfo::set_uncompiled_data(UncompiledData uncompiled_data) {
570 : DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy));
571 : DCHECK(uncompiled_data->IsUncompiledData());
572 2119016 : set_function_data(uncompiled_data);
573 : }
574 :
575 747429 : bool SharedFunctionInfo::HasUncompiledDataWithPreparseData() const {
576 747429 : return function_data()->IsUncompiledDataWithPreparseData();
577 : }
578 :
579 : UncompiledDataWithPreparseData
580 : SharedFunctionInfo::uncompiled_data_with_preparse_data() const {
581 : DCHECK(HasUncompiledDataWithPreparseData());
582 : return UncompiledDataWithPreparseData::cast(function_data());
583 : }
584 :
585 : void SharedFunctionInfo::set_uncompiled_data_with_preparse_data(
586 : UncompiledDataWithPreparseData uncompiled_data_with_preparse_data) {
587 : DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy));
588 : DCHECK(
589 : uncompiled_data_with_preparse_data->IsUncompiledDataWithPreparseData());
590 : set_function_data(uncompiled_data_with_preparse_data);
591 : }
592 :
593 : bool SharedFunctionInfo::HasUncompiledDataWithoutPreparseData() const {
594 : return function_data()->IsUncompiledDataWithoutPreparseData();
595 : }
596 :
597 21 : void SharedFunctionInfo::ClearPreparseData() {
598 : DCHECK(HasUncompiledDataWithPreparseData());
599 21 : UncompiledDataWithPreparseData data = uncompiled_data_with_preparse_data();
600 :
601 : // Trim off the pre-parsed scope data from the uncompiled data by swapping the
602 : // map, leaving only an uncompiled data without pre-parsed scope.
603 : DisallowHeapAllocation no_gc;
604 : Heap* heap = GetHeapFromWritableObject(data);
605 :
606 : // Swap the map.
607 : heap->NotifyObjectLayoutChange(data, UncompiledDataWithPreparseData::kSize,
608 21 : no_gc);
609 : STATIC_ASSERT(UncompiledDataWithoutPreparseData::kSize <
610 : UncompiledDataWithPreparseData::kSize);
611 : STATIC_ASSERT(UncompiledDataWithoutPreparseData::kSize ==
612 : UncompiledData::kSize);
613 : data->synchronized_set_map(
614 21 : GetReadOnlyRoots().uncompiled_data_without_preparse_data_map());
615 :
616 : // Fill the remaining space with filler.
617 : heap->CreateFillerObjectAt(
618 : data->address() + UncompiledDataWithoutPreparseData::kSize,
619 : UncompiledDataWithPreparseData::kSize -
620 : UncompiledDataWithoutPreparseData::kSize,
621 21 : ClearRecordedSlots::kNo);
622 :
623 : // Ensure that the clear was successful.
624 : DCHECK(HasUncompiledDataWithoutPreparseData());
625 21 : }
626 :
627 : OBJECT_CONSTRUCTORS_IMPL(SharedFunctionInfoWithID, SharedFunctionInfo)
628 : CAST_ACCESSOR(SharedFunctionInfoWithID)
629 : INT_ACCESSORS(SharedFunctionInfoWithID, unique_id, kUniqueIdOffset)
630 :
631 : // static
632 2229696 : void UncompiledData::Initialize(
633 : UncompiledData data, String inferred_name, int start_position,
634 : int end_position, int function_literal_id,
635 : std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
636 : gc_notify_updated_slot) {
637 2229696 : data->set_inferred_name(inferred_name);
638 : gc_notify_updated_slot(
639 : data, data->RawField(UncompiledData::kInferredNameOffset), inferred_name);
640 : data->set_start_position(start_position);
641 : data->set_end_position(end_position);
642 : data->set_function_literal_id(function_literal_id);
643 : data->clear_padding();
644 2229695 : }
645 :
646 59652 : void UncompiledDataWithPreparseData::Initialize(
647 : UncompiledDataWithPreparseData data, String inferred_name,
648 : int start_position, int end_position, int function_literal_id,
649 : PreparseData scope_data,
650 : std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
651 : gc_notify_updated_slot) {
652 59652 : UncompiledData::Initialize(data, inferred_name, start_position, end_position,
653 59652 : function_literal_id, gc_notify_updated_slot);
654 59652 : data->set_preparse_data(scope_data);
655 : gc_notify_updated_slot(
656 : data, data->RawField(UncompiledDataWithPreparseData::kPreparseDataOffset),
657 : scope_data);
658 59652 : }
659 :
660 : bool UncompiledData::has_function_literal_id() {
661 : return function_literal_id() != kFunctionLiteralIdInvalid;
662 : }
663 :
664 : bool SharedFunctionInfo::HasWasmExportedFunctionData() const {
665 : return function_data()->IsWasmExportedFunctionData();
666 : }
667 :
668 70178234 : Object SharedFunctionInfo::script() const {
669 : Object maybe_script = script_or_debug_info();
670 70178173 : if (maybe_script->IsDebugInfo()) {
671 : return DebugInfo::cast(maybe_script)->script();
672 : }
673 67781755 : return maybe_script;
674 : }
675 :
676 3640757 : void SharedFunctionInfo::set_script(Object script) {
677 : Object maybe_debug_info = script_or_debug_info();
678 3640757 : if (maybe_debug_info->IsDebugInfo()) {
679 83 : DebugInfo::cast(maybe_debug_info)->set_script(script);
680 : } else {
681 3640674 : set_script_or_debug_info(script);
682 : }
683 3640745 : }
684 :
685 30995685 : bool SharedFunctionInfo::HasDebugInfo() const {
686 30995687 : return script_or_debug_info()->IsDebugInfo();
687 : }
688 :
689 : DebugInfo SharedFunctionInfo::GetDebugInfo() const {
690 : DCHECK(HasDebugInfo());
691 : return DebugInfo::cast(script_or_debug_info());
692 : }
693 :
694 : void SharedFunctionInfo::SetDebugInfo(DebugInfo debug_info) {
695 : DCHECK(!HasDebugInfo());
696 : DCHECK_EQ(debug_info->script(), script_or_debug_info());
697 28670 : set_script_or_debug_info(debug_info);
698 : }
699 :
700 2095268 : bool SharedFunctionInfo::HasInferredName() {
701 : Object scope_info = name_or_scope_info();
702 2095268 : if (scope_info->IsScopeInfo()) {
703 4726 : return ScopeInfo::cast(scope_info)->HasInferredFunctionName();
704 : }
705 2090542 : return HasUncompiledData();
706 : }
707 :
708 3416043 : String SharedFunctionInfo::inferred_name() {
709 : Object maybe_scope_info = name_or_scope_info();
710 3416043 : if (maybe_scope_info->IsScopeInfo()) {
711 1511503 : ScopeInfo scope_info = ScopeInfo::cast(maybe_scope_info);
712 1511503 : if (scope_info->HasInferredFunctionName()) {
713 739356 : Object name = ScopeInfo::cast(maybe_scope_info)->InferredFunctionName();
714 739356 : if (name->IsString()) return String::cast(name);
715 : }
716 1904540 : } else if (HasUncompiledData()) {
717 : return uncompiled_data()->inferred_name();
718 : }
719 : return GetReadOnlyRoots().empty_string();
720 : }
721 :
722 12854838 : bool SharedFunctionInfo::IsUserJavaScript() {
723 12854838 : Object script_obj = script();
724 12854839 : if (script_obj->IsUndefined()) return false;
725 9861725 : Script script = Script::cast(script_obj);
726 10883227 : return script->IsUserJavaScript();
727 : }
728 :
729 4471431 : bool SharedFunctionInfo::IsSubjectToDebugging() {
730 4471431 : return IsUserJavaScript() && !HasAsmWasmData();
731 : }
732 :
733 153626 : bool SharedFunctionInfo::CanDiscardCompiled() const {
734 307222 : bool can_decompile = (HasBytecodeArray() || HasAsmWasmData() ||
735 153596 : HasUncompiledDataWithPreparseData());
736 153626 : return can_decompile;
737 : }
738 :
739 : bool SharedFunctionInfo::is_class_constructor() const {
740 : return IsClassConstructorBit::decode(flags());
741 : }
742 :
743 726109 : bool SharedFunctionInfo::is_oneshot_iife() const {
744 : bool bit = is_oneshot_iife_or_properties_are_final();
745 728316 : return bit && !is_class_constructor();
746 : }
747 :
748 2095146 : void SharedFunctionInfo::set_is_oneshot_iife(bool value) {
749 : DCHECK(!value || !is_class_constructor());
750 2095146 : if (!is_class_constructor()) {
751 2072900 : set_is_oneshot_iife_or_properties_are_final(value);
752 : }
753 2095156 : }
754 :
755 3615476 : void SharedFunctionInfo::set_are_properties_final(bool value) {
756 3615476 : if (is_class_constructor()) {
757 22131 : set_is_oneshot_iife_or_properties_are_final(value);
758 : }
759 3615476 : }
760 :
761 3615627 : bool SharedFunctionInfo::are_properties_final() const {
762 : bool bit = is_oneshot_iife_or_properties_are_final();
763 3663412 : return bit && is_class_constructor();
764 : }
765 :
766 : } // namespace internal
767 : } // namespace v8
768 :
769 : #include "src/objects/object-macros-undef.h"
770 :
771 : #endif // V8_OBJECTS_SHARED_FUNCTION_INFO_INL_H_
|