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 656598 : INT_ACCESSORS(PreparseData, data_length, kDataLengthOffset)
28 359969 : 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 63499 : void PreparseData::clear_padding() {
39 63499 : int data_end_offset = kDataStartOffset + data_length();
40 63499 : int padding_size = inner_start_offset() - data_end_offset;
41 : DCHECK_LE(0, padding_size);
42 63499 : if (padding_size == 0) return;
43 102532 : 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 578418 : int offset = kDataStartOffset + index * kByteSize;
50 578418 : 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 63499 : Address dst_addr = FIELD_ADDR(*this, kDataStartOffset + index * kByteSize);
64 63499 : memcpy(reinterpret_cast<void*>(dst_addr), buffer, length);
65 : }
66 :
67 : PreparseData PreparseData::get_child(int index) const {
68 3187 : return PreparseData::cast(get_child_raw(index));
69 : }
70 :
71 3187 : Object PreparseData::get_child_raw(int index) const {
72 : DCHECK_LE(0, index);
73 : DCHECK_LT(index, this->children_length());
74 3187 : int offset = inner_start_offset() + index * kTaggedSize;
75 6374 : return RELAXED_READ_FIELD(*this, offset);
76 : }
77 :
78 6808 : void PreparseData::set_child(int index, PreparseData value,
79 : WriteBarrierMode mode) {
80 : DCHECK_LE(0, index);
81 : DCHECK_LT(index, this->children_length());
82 6808 : int offset = inner_start_offset() + index * kTaggedSize;
83 6808 : RELAXED_WRITE_FIELD(*this, offset, value);
84 13616 : CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);
85 6808 : }
86 :
87 : OBJECT_CONSTRUCTORS_IMPL(UncompiledData, HeapObject)
88 : OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithoutPreparseData, UncompiledData)
89 : OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithPreparseData, UncompiledData)
90 : CAST_ACCESSOR(UncompiledData)
91 12253099 : ACCESSORS(UncompiledData, inferred_name, String, kInferredNameOffset)
92 5067532 : INT32_ACCESSORS(UncompiledData, start_position, kStartPositionOffset)
93 4024315 : INT32_ACCESSORS(UncompiledData, end_position, kEndPositionOffset)
94 3420254 : 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 2203825 : memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
100 : FIELD_SIZE(kOptionalPaddingOffset));
101 : }
102 :
103 : CAST_ACCESSOR(UncompiledDataWithoutPreparseData)
104 :
105 : CAST_ACCESSOR(UncompiledDataWithPreparseData)
106 334086 : ACCESSORS(UncompiledDataWithPreparseData, preparse_data, PreparseData,
107 : kPreparseDataOffset)
108 :
109 : bool HeapObject::IsUncompiledData() const {
110 132887048 : return IsUncompiledDataWithoutPreparseData() ||
111 : IsUncompiledDataWithPreparseData();
112 : }
113 :
114 : OBJECT_CONSTRUCTORS_IMPL(InterpreterData, Struct)
115 :
116 : CAST_ACCESSOR(InterpreterData)
117 232 : 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 463634 : DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
125 :
126 110633237 : ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object,
127 : kNameOrScopeInfoOffset)
128 134396297 : ACCESSORS(SharedFunctionInfo, script_or_debug_info, Object,
129 : kScriptOrDebugInfoOffset)
130 :
131 22716659 : UINT16_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
132 35658741 : UINT16_ACCESSORS(SharedFunctionInfo, internal_formal_parameter_count,
133 : kFormalParameterCountOffset)
134 13929522 : UINT16_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
135 : kExpectedNofPropertiesOffset)
136 14845674 : UINT16_ACCESSORS(SharedFunctionInfo, raw_function_token_offset,
137 : kFunctionTokenOffsetOffset)
138 464882167 : RELAXED_INT32_ACCESSORS(SharedFunctionInfo, flags, kFlagsOffset)
139 :
140 28605290 : bool SharedFunctionInfo::HasSharedName() const {
141 : Object value = name_or_scope_info();
142 28605298 : if (value->IsScopeInfo()) {
143 3191003 : return ScopeInfo::cast(value)->HasSharedFunctionName();
144 : }
145 25414295 : return value != kNoSharedNameSentinel;
146 : }
147 :
148 9759413 : String SharedFunctionInfo::Name() const {
149 9759413 : if (!HasSharedName()) return GetReadOnlyRoots().empty_string();
150 : Object value = name_or_scope_info();
151 9747682 : if (value->IsScopeInfo()) {
152 3121143 : if (ScopeInfo::cast(value)->HasFunctionName()) {
153 3121141 : 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 3662138 : AbstractCode SharedFunctionInfo::abstract_code() {
173 3662138 : if (HasBytecodeArray()) {
174 2608728 : return AbstractCode::cast(GetBytecodeArray());
175 : } else {
176 1053410 : return AbstractCode::cast(GetCode());
177 : }
178 : }
179 :
180 : Object SharedFunctionInfo::function_data() const {
181 801275703 : return ACQUIRE_READ_FIELD(*this, kFunctionDataOffset);
182 : }
183 :
184 8160352 : void SharedFunctionInfo::set_function_data(Object data, WriteBarrierMode mode) {
185 13771212 : RELEASE_WRITE_FIELD(*this, kFunctionDataOffset, data);
186 16320709 : CONDITIONAL_WRITE_BARRIER(*this, kFunctionDataOffset, data, mode);
187 8160356 : }
188 :
189 : int SharedFunctionInfo::function_token_position() const {
190 1790319 : int offset = raw_function_token_offset();
191 1790319 : if (offset == kFunctionTokenOutOfRange) {
192 : return kNoSourcePosition;
193 : } else {
194 1790247 : return StartPosition() - offset;
195 : }
196 : }
197 :
198 7205360 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_wrapped,
199 : SharedFunctionInfo::IsWrappedBit)
200 7205346 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, allows_lazy_compilation,
201 : SharedFunctionInfo::AllowLazyCompilationBit)
202 7166370 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, has_duplicate_parameters,
203 : SharedFunctionInfo::HasDuplicateParametersBit)
204 7205336 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_declaration,
205 : SharedFunctionInfo::IsDeclarationBit)
206 :
207 3885382 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, native,
208 : SharedFunctionInfo::IsNativeBit)
209 350 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_asm_wasm_broken,
210 : SharedFunctionInfo::IsAsmWasmBrokenBit)
211 7205338 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags,
212 : requires_instance_members_initializer,
213 : SharedFunctionInfo::RequiresInstanceMembersInitializer)
214 :
215 2170188 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, name_should_print_as_anonymous,
216 : SharedFunctionInfo::NameShouldPrintAsAnonymousBit)
217 7205342 : 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 7205340 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_named_expression,
223 : SharedFunctionInfo::IsNamedExpressionBit)
224 7205348 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_toplevel,
225 : SharedFunctionInfo::IsTopLevelBit)
226 4150520 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_oneshot_iife,
227 : SharedFunctionInfo::IsOneshotIIFEBit)
228 11355894 : BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags,
229 : is_safe_to_skip_arguments_adaptor,
230 : SharedFunctionInfo::IsSafeToSkipArgumentsAdaptorBit)
231 :
232 : bool SharedFunctionInfo::optimization_disabled() const {
233 : return disable_optimization_reason() != BailoutReason::kNoReason;
234 : }
235 :
236 : BailoutReason SharedFunctionInfo::disable_optimization_reason() const {
237 : return DisabledOptimizationReasonBits::decode(flags());
238 : }
239 :
240 : LanguageMode SharedFunctionInfo::language_mode() const {
241 : STATIC_ASSERT(LanguageModeSize == 2);
242 : return construct_language_mode(IsStrictBit::decode(flags()));
243 : }
244 :
245 5607250 : void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
246 : STATIC_ASSERT(LanguageModeSize == 2);
247 : // We only allow language mode transitions that set the same language mode
248 : // again or go up in the chain:
249 : DCHECK(is_sloppy(this->language_mode()) || is_strict(language_mode));
250 : int hints = flags();
251 : hints = IsStrictBit::update(hints, is_strict(language_mode));
252 : set_flags(hints);
253 5607250 : UpdateFunctionMapIndex();
254 5607258 : }
255 :
256 : FunctionKind SharedFunctionInfo::kind() const {
257 : return FunctionKindBits::decode(flags());
258 : }
259 :
260 9451547 : void SharedFunctionInfo::set_kind(FunctionKind kind) {
261 : int hints = flags();
262 : hints = FunctionKindBits::update(hints, kind);
263 : hints = IsClassConstructorBit::update(hints, IsClassConstructor(kind));
264 : set_flags(hints);
265 9451547 : UpdateFunctionMapIndex();
266 9451558 : }
267 :
268 : bool SharedFunctionInfo::needs_home_object() const {
269 : return NeedsHomeObjectBit::decode(flags());
270 : }
271 :
272 3602670 : void SharedFunctionInfo::set_needs_home_object(bool value) {
273 : int hints = flags();
274 : hints = NeedsHomeObjectBit::update(hints, value);
275 : set_flags(hints);
276 3602670 : UpdateFunctionMapIndex();
277 3602671 : }
278 :
279 : bool SharedFunctionInfo::construct_as_builtin() const {
280 : return ConstructAsBuiltinBit::decode(flags());
281 : }
282 :
283 9451542 : void SharedFunctionInfo::CalculateConstructAsBuiltin() {
284 : bool uses_builtins_construct_stub = false;
285 9451543 : if (HasBuiltinId()) {
286 : int id = builtin_id();
287 5610859 : if (id != Builtins::kCompileLazy && id != Builtins::kEmptyFunction) {
288 : uses_builtins_construct_stub = true;
289 : }
290 3840684 : } else if (IsApiFunction()) {
291 : uses_builtins_construct_stub = true;
292 : }
293 :
294 : int f = flags();
295 : f = ConstructAsBuiltinBit::update(f, uses_builtins_construct_stub);
296 : set_flags(f);
297 9451545 : }
298 :
299 : int SharedFunctionInfo::function_map_index() const {
300 : // Note: Must be kept in sync with the FastNewClosure builtin.
301 : int index =
302 7015580 : Context::FIRST_FUNCTION_MAP_INDEX + FunctionMapIndexBits::decode(flags());
303 : DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
304 : return index;
305 : }
306 :
307 18662324 : void SharedFunctionInfo::set_function_map_index(int index) {
308 : STATIC_ASSERT(Context::LAST_FUNCTION_MAP_INDEX <=
309 : Context::FIRST_FUNCTION_MAP_INDEX + FunctionMapIndexBits::kMax);
310 : DCHECK_LE(Context::FIRST_FUNCTION_MAP_INDEX, index);
311 : DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
312 18662324 : index -= Context::FIRST_FUNCTION_MAP_INDEX;
313 : set_flags(FunctionMapIndexBits::update(flags(), index));
314 18662324 : }
315 :
316 : void SharedFunctionInfo::clear_padding() {
317 9451558 : memset(reinterpret_cast<void*>(this->address() + kSize), 0,
318 : kAlignedSize - kSize);
319 : }
320 :
321 18662081 : void SharedFunctionInfo::UpdateFunctionMapIndex() {
322 55986271 : int map_index = Context::FunctionMapIndex(
323 37324176 : language_mode(), kind(), HasSharedName(), needs_home_object());
324 18662099 : set_function_map_index(map_index);
325 18662104 : }
326 :
327 : void SharedFunctionInfo::DontAdaptArguments() {
328 : // TODO(leszeks): Revise this DCHECK now that the code field is gone.
329 : DCHECK(!HasWasmExportedFunctionData());
330 : set_internal_formal_parameter_count(kDontAdaptArgumentsSentinel);
331 : }
332 :
333 589716 : bool SharedFunctionInfo::IsInterpreted() const { return HasBytecodeArray(); }
334 :
335 4203921 : ScopeInfo SharedFunctionInfo::scope_info() const {
336 : Object maybe_scope_info = name_or_scope_info();
337 4203916 : if (maybe_scope_info->IsScopeInfo()) {
338 : return ScopeInfo::cast(maybe_scope_info);
339 : }
340 3602680 : return ScopeInfo::Empty(GetIsolate());
341 : }
342 :
343 2075380 : void SharedFunctionInfo::set_scope_info(ScopeInfo scope_info,
344 : WriteBarrierMode mode) {
345 : // Move the existing name onto the ScopeInfo.
346 : Object name = name_or_scope_info();
347 2075380 : if (name->IsScopeInfo()) {
348 4546 : name = ScopeInfo::cast(name)->FunctionName();
349 : }
350 : DCHECK(name->IsString() || name == kNoSharedNameSentinel);
351 : // Only set the function name for function scopes.
352 2075380 : scope_info->SetFunctionName(name);
353 2642716 : if (HasInferredName() && inferred_name()->length() != 0) {
354 52645 : scope_info->SetInferredFunctionName(inferred_name());
355 : }
356 2075369 : WRITE_FIELD(*this, kNameOrScopeInfoOffset, scope_info);
357 4150738 : CONDITIONAL_WRITE_BARRIER(*this, kNameOrScopeInfoOffset, scope_info, mode);
358 2075371 : }
359 :
360 86746607 : ACCESSORS(SharedFunctionInfo, raw_outer_scope_info_or_feedback_metadata,
361 : HeapObject, kOuterScopeInfoOrFeedbackMetadataOffset)
362 :
363 : HeapObject SharedFunctionInfo::outer_scope_info() const {
364 : DCHECK(!is_compiled());
365 : DCHECK(!HasFeedbackMetadata());
366 : return raw_outer_scope_info_or_feedback_metadata();
367 : }
368 :
369 718804 : bool SharedFunctionInfo::HasOuterScopeInfo() const {
370 : ScopeInfo outer_info;
371 718804 : if (!is_compiled()) {
372 610222 : if (!outer_scope_info()->IsScopeInfo()) return false;
373 : outer_info = ScopeInfo::cast(outer_scope_info());
374 : } else {
375 108582 : if (!scope_info()->HasOuterScopeInfo()) return false;
376 21549 : outer_info = scope_info()->OuterScopeInfo();
377 : }
378 460530 : return outer_info->length() > 0;
379 : }
380 :
381 442532 : ScopeInfo SharedFunctionInfo::GetOuterScopeInfo() const {
382 : DCHECK(HasOuterScopeInfo());
383 442532 : if (!is_compiled()) return ScopeInfo::cast(outer_scope_info());
384 21549 : return scope_info()->OuterScopeInfo();
385 : }
386 :
387 : void SharedFunctionInfo::set_outer_scope_info(HeapObject value,
388 : WriteBarrierMode mode) {
389 : DCHECK(!is_compiled());
390 : DCHECK(raw_outer_scope_info_or_feedback_metadata()->IsTheHole());
391 : DCHECK(value->IsScopeInfo() || value->IsTheHole());
392 2211225 : set_raw_outer_scope_info_or_feedback_metadata(value, mode);
393 : }
394 :
395 276 : bool SharedFunctionInfo::HasFeedbackMetadata() const {
396 552 : return raw_outer_scope_info_or_feedback_metadata()->IsFeedbackMetadata();
397 : }
398 :
399 : FeedbackMetadata SharedFunctionInfo::feedback_metadata() const {
400 : DCHECK(HasFeedbackMetadata());
401 : return FeedbackMetadata::cast(raw_outer_scope_info_or_feedback_metadata());
402 : }
403 :
404 : void SharedFunctionInfo::set_feedback_metadata(FeedbackMetadata value,
405 : WriteBarrierMode mode) {
406 : DCHECK(!HasFeedbackMetadata());
407 : DCHECK(value->IsFeedbackMetadata());
408 2075265 : set_raw_outer_scope_info_or_feedback_metadata(value, mode);
409 : }
410 :
411 122799469 : bool SharedFunctionInfo::is_compiled() const {
412 : Object data = function_data();
413 243818315 : return data != Smi::FromEnum(Builtins::kCompileLazy) &&
414 122658630 : !data->IsUncompiledData();
415 : }
416 :
417 21811640 : IsCompiledScope SharedFunctionInfo::is_compiled_scope() const {
418 21811640 : return IsCompiledScope(*this, GetIsolate());
419 : }
420 :
421 21811643 : IsCompiledScope::IsCompiledScope(const SharedFunctionInfo shared,
422 : Isolate* isolate)
423 21811643 : : retain_bytecode_(shared->HasBytecodeArray()
424 : ? handle(shared->GetBytecodeArray(), isolate)
425 : : MaybeHandle<BytecodeArray>()),
426 29797314 : is_compiled_(shared->is_compiled()) {
427 : DCHECK_IMPLIES(!retain_bytecode_.is_null(), is_compiled());
428 21811666 : }
429 :
430 : uint16_t SharedFunctionInfo::GetLength() const {
431 : DCHECK(is_compiled());
432 : DCHECK(HasLength());
433 : return length();
434 : }
435 :
436 : bool SharedFunctionInfo::HasLength() const {
437 : return length() != kInvalidLength;
438 : }
439 :
440 64246 : bool SharedFunctionInfo::has_simple_parameters() {
441 128492 : return scope_info()->HasSimpleParameters();
442 : }
443 :
444 28799186 : bool SharedFunctionInfo::IsApiFunction() const {
445 28799182 : return function_data()->IsFunctionTemplateInfo();
446 : }
447 :
448 : FunctionTemplateInfo SharedFunctionInfo::get_api_func_data() {
449 : DCHECK(IsApiFunction());
450 : return FunctionTemplateInfo::cast(function_data());
451 : }
452 :
453 51407436 : bool SharedFunctionInfo::HasBytecodeArray() const {
454 77445228 : return function_data()->IsBytecodeArray() ||
455 51407437 : function_data()->IsInterpreterData();
456 : }
457 :
458 20104082 : BytecodeArray SharedFunctionInfo::GetBytecodeArray() const {
459 : DCHECK(HasBytecodeArray());
460 20483371 : if (HasDebugInfo() && GetDebugInfo()->HasInstrumentedBytecodeArray()) {
461 : return GetDebugInfo()->OriginalBytecodeArray();
462 19834370 : } else if (function_data()->IsBytecodeArray()) {
463 : return BytecodeArray::cast(function_data());
464 : } else {
465 : DCHECK(function_data()->IsInterpreterData());
466 : return InterpreterData::cast(function_data())->bytecode_array();
467 : }
468 : }
469 :
470 : BytecodeArray SharedFunctionInfo::GetDebugBytecodeArray() const {
471 : DCHECK(HasBytecodeArray());
472 : DCHECK(HasDebugInfo() && GetDebugInfo()->HasInstrumentedBytecodeArray());
473 : if (function_data()->IsBytecodeArray()) {
474 : return BytecodeArray::cast(function_data());
475 : } else {
476 : DCHECK(function_data()->IsInterpreterData());
477 : return InterpreterData::cast(function_data())->bytecode_array();
478 : }
479 : }
480 :
481 21184 : void SharedFunctionInfo::SetDebugBytecodeArray(BytecodeArray bytecode) {
482 : DCHECK(HasBytecodeArray());
483 21184 : if (function_data()->IsBytecodeArray()) {
484 21184 : set_function_data(bytecode);
485 : } else {
486 : DCHECK(function_data()->IsInterpreterData());
487 0 : interpreter_data()->set_bytecode_array(bytecode);
488 : }
489 21184 : }
490 :
491 : void SharedFunctionInfo::set_bytecode_array(BytecodeArray bytecode) {
492 : DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy) ||
493 : HasUncompiledData());
494 2072775 : set_function_data(bytecode);
495 : }
496 :
497 59375503 : bool SharedFunctionInfo::ShouldFlushBytecode() {
498 59375503 : if (!FLAG_flush_bytecode) return false;
499 :
500 : // TODO(rmcilroy): Enable bytecode flushing for resumable functions.
501 119240192 : if (IsResumableFunction(kind()) || !allows_lazy_compilation()) {
502 : return false;
503 : }
504 :
505 : // Get a snapshot of the function data field, and if it is a bytecode array,
506 : // check if it is old. Note, this is done this way since this function can be
507 : // called by the concurrent marker.
508 : Object data = function_data();
509 11482154 : if (!data->IsBytecodeArray()) return false;
510 :
511 1764420 : if (FLAG_stress_flush_bytecode) return true;
512 :
513 1764208 : BytecodeArray bytecode = BytecodeArray::cast(data);
514 :
515 1764208 : return bytecode->IsOld();
516 : }
517 :
518 44 : Code SharedFunctionInfo::InterpreterTrampoline() const {
519 : DCHECK(HasInterpreterData());
520 44 : return interpreter_data()->interpreter_trampoline();
521 : }
522 :
523 : bool SharedFunctionInfo::HasInterpreterData() const {
524 : return function_data()->IsInterpreterData();
525 : }
526 :
527 : InterpreterData SharedFunctionInfo::interpreter_data() const {
528 : DCHECK(HasInterpreterData());
529 : return InterpreterData::cast(function_data());
530 : }
531 :
532 : void SharedFunctionInfo::set_interpreter_data(
533 : InterpreterData interpreter_data) {
534 : DCHECK(FLAG_interpreted_frames_native_stack);
535 29 : set_function_data(interpreter_data);
536 : }
537 :
538 10609794 : bool SharedFunctionInfo::HasAsmWasmData() const {
539 10609798 : return function_data()->IsAsmWasmData();
540 : }
541 :
542 : AsmWasmData SharedFunctionInfo::asm_wasm_data() const {
543 : DCHECK(HasAsmWasmData());
544 : return AsmWasmData::cast(function_data());
545 : }
546 :
547 : void SharedFunctionInfo::set_asm_wasm_data(AsmWasmData data) {
548 : DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy) ||
549 : HasUncompiledData() || HasAsmWasmData());
550 2457 : set_function_data(data);
551 : }
552 :
553 3022 : bool SharedFunctionInfo::HasBuiltinId() const {
554 3022 : return function_data()->IsSmi();
555 : }
556 :
557 0 : int SharedFunctionInfo::builtin_id() const {
558 : DCHECK(HasBuiltinId());
559 : int id = Smi::ToInt(function_data());
560 : DCHECK(Builtins::IsBuiltinId(id));
561 0 : return id;
562 : }
563 :
564 : void SharedFunctionInfo::set_builtin_id(int builtin_id) {
565 : DCHECK(Builtins::IsBuiltinId(builtin_id));
566 : set_function_data(Smi::FromInt(builtin_id), SKIP_WRITE_BARRIER);
567 : }
568 :
569 10537718 : bool SharedFunctionInfo::HasUncompiledData() const {
570 10537720 : return function_data()->IsUncompiledData();
571 : }
572 :
573 : UncompiledData SharedFunctionInfo::uncompiled_data() const {
574 : DCHECK(HasUncompiledData());
575 : return UncompiledData::cast(function_data());
576 : }
577 :
578 : void SharedFunctionInfo::set_uncompiled_data(UncompiledData uncompiled_data) {
579 : DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy));
580 : DCHECK(uncompiled_data->IsUncompiledData());
581 2094772 : set_function_data(uncompiled_data);
582 : }
583 :
584 740480 : bool SharedFunctionInfo::HasUncompiledDataWithPreparseData() const {
585 740480 : return function_data()->IsUncompiledDataWithPreparseData();
586 : }
587 :
588 : UncompiledDataWithPreparseData
589 : SharedFunctionInfo::uncompiled_data_with_preparse_data() const {
590 : DCHECK(HasUncompiledDataWithPreparseData());
591 : return UncompiledDataWithPreparseData::cast(function_data());
592 : }
593 :
594 : void SharedFunctionInfo::set_uncompiled_data_with_preparse_data(
595 : UncompiledDataWithPreparseData uncompiled_data_with_preparse_data) {
596 : DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy));
597 : DCHECK(
598 : uncompiled_data_with_preparse_data->IsUncompiledDataWithPreparseData());
599 : set_function_data(uncompiled_data_with_preparse_data);
600 : }
601 :
602 : bool SharedFunctionInfo::HasUncompiledDataWithoutPreparseData() const {
603 : return function_data()->IsUncompiledDataWithoutPreparseData();
604 : }
605 :
606 21 : void SharedFunctionInfo::ClearPreparseData() {
607 : DCHECK(HasUncompiledDataWithPreparseData());
608 21 : UncompiledDataWithPreparseData data = uncompiled_data_with_preparse_data();
609 :
610 : // Trim off the pre-parsed scope data from the uncompiled data by swapping the
611 : // map, leaving only an uncompiled data without pre-parsed scope.
612 : DisallowHeapAllocation no_gc;
613 : Heap* heap = GetHeapFromWritableObject(data);
614 :
615 : // Swap the map.
616 : heap->NotifyObjectLayoutChange(data, UncompiledDataWithPreparseData::kSize,
617 21 : no_gc);
618 : STATIC_ASSERT(UncompiledDataWithoutPreparseData::kSize <
619 : UncompiledDataWithPreparseData::kSize);
620 : STATIC_ASSERT(UncompiledDataWithoutPreparseData::kSize ==
621 : UncompiledData::kSize);
622 : data->synchronized_set_map(
623 21 : GetReadOnlyRoots().uncompiled_data_without_preparse_data_map());
624 :
625 : // Fill the remaining space with filler.
626 : heap->CreateFillerObjectAt(
627 : data->address() + UncompiledDataWithoutPreparseData::kSize,
628 : UncompiledDataWithPreparseData::kSize -
629 : UncompiledDataWithoutPreparseData::kSize,
630 21 : ClearRecordedSlots::kNo);
631 :
632 : // Ensure that the clear was successful.
633 : DCHECK(HasUncompiledDataWithoutPreparseData());
634 21 : }
635 :
636 : OBJECT_CONSTRUCTORS_IMPL(SharedFunctionInfoWithID, SharedFunctionInfo)
637 : CAST_ACCESSOR(SharedFunctionInfoWithID)
638 : INT_ACCESSORS(SharedFunctionInfoWithID, unique_id, kUniqueIdOffset)
639 :
640 : // static
641 2203826 : void UncompiledData::Initialize(
642 : UncompiledData data, String inferred_name, int start_position,
643 : int end_position, int function_literal_id,
644 : std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
645 : gc_notify_updated_slot) {
646 2203826 : data->set_inferred_name(inferred_name);
647 : gc_notify_updated_slot(
648 : data, data->RawField(UncompiledData::kInferredNameOffset), inferred_name);
649 : data->set_start_position(start_position);
650 : data->set_end_position(end_position);
651 : data->set_function_literal_id(function_literal_id);
652 : data->clear_padding();
653 2203825 : }
654 :
655 59478 : void UncompiledDataWithPreparseData::Initialize(
656 : UncompiledDataWithPreparseData data, String inferred_name,
657 : int start_position, int end_position, int function_literal_id,
658 : PreparseData scope_data,
659 : std::function<void(HeapObject object, ObjectSlot slot, HeapObject target)>
660 : gc_notify_updated_slot) {
661 59478 : UncompiledData::Initialize(data, inferred_name, start_position, end_position,
662 59478 : function_literal_id, gc_notify_updated_slot);
663 59478 : data->set_preparse_data(scope_data);
664 : gc_notify_updated_slot(
665 : data, data->RawField(UncompiledDataWithPreparseData::kPreparseDataOffset),
666 : scope_data);
667 59478 : }
668 :
669 : bool UncompiledData::has_function_literal_id() {
670 : return function_literal_id() != kFunctionLiteralIdInvalid;
671 : }
672 :
673 : bool SharedFunctionInfo::HasWasmExportedFunctionData() const {
674 : return function_data()->IsWasmExportedFunctionData();
675 : }
676 :
677 69328534 : Object SharedFunctionInfo::script() const {
678 : Object maybe_script = script_or_debug_info();
679 69328537 : if (maybe_script->IsDebugInfo()) {
680 : return DebugInfo::cast(maybe_script)->script();
681 : }
682 66932209 : return maybe_script;
683 : }
684 :
685 3603945 : void SharedFunctionInfo::set_script(Object script) {
686 : Object maybe_debug_info = script_or_debug_info();
687 3603945 : if (maybe_debug_info->IsDebugInfo()) {
688 83 : DebugInfo::cast(maybe_debug_info)->set_script(script);
689 : } else {
690 3603862 : set_script_or_debug_info(script);
691 : }
692 3603935 : }
693 :
694 31032294 : bool SharedFunctionInfo::HasDebugInfo() const {
695 31032301 : return script_or_debug_info()->IsDebugInfo();
696 : }
697 :
698 : DebugInfo SharedFunctionInfo::GetDebugInfo() const {
699 : DCHECK(HasDebugInfo());
700 : return DebugInfo::cast(script_or_debug_info());
701 : }
702 :
703 : void SharedFunctionInfo::SetDebugInfo(DebugInfo debug_info) {
704 : DCHECK(!HasDebugInfo());
705 : DCHECK_EQ(debug_info->script(), script_or_debug_info());
706 28634 : set_script_or_debug_info(debug_info);
707 : }
708 :
709 2075371 : bool SharedFunctionInfo::HasInferredName() {
710 : Object scope_info = name_or_scope_info();
711 2075371 : if (scope_info->IsScopeInfo()) {
712 4546 : return ScopeInfo::cast(scope_info)->HasInferredFunctionName();
713 : }
714 2070825 : return HasUncompiledData();
715 : }
716 :
717 3401842 : String SharedFunctionInfo::inferred_name() {
718 : Object maybe_scope_info = name_or_scope_info();
719 3401842 : if (maybe_scope_info->IsScopeInfo()) {
720 1511728 : ScopeInfo scope_info = ScopeInfo::cast(maybe_scope_info);
721 1511728 : if (scope_info->HasInferredFunctionName()) {
722 740162 : Object name = ScopeInfo::cast(maybe_scope_info)->InferredFunctionName();
723 740162 : if (name->IsString()) return String::cast(name);
724 : }
725 1890114 : } else if (HasUncompiledData()) {
726 : return uncompiled_data()->inferred_name();
727 : }
728 : return GetReadOnlyRoots().empty_string();
729 : }
730 :
731 12835124 : bool SharedFunctionInfo::IsUserJavaScript() {
732 12835124 : Object script_obj = script();
733 12835129 : if (script_obj->IsUndefined()) return false;
734 9842965 : Script script = Script::cast(script_obj);
735 10865981 : return script->IsUserJavaScript();
736 : }
737 :
738 4464104 : bool SharedFunctionInfo::IsSubjectToDebugging() {
739 4464104 : return IsUserJavaScript() && !HasAsmWasmData();
740 : }
741 :
742 153626 : bool SharedFunctionInfo::CanDiscardCompiled() const {
743 307222 : bool can_decompile = (HasBytecodeArray() || HasAsmWasmData() ||
744 153596 : HasUncompiledDataWithPreparseData());
745 153626 : return can_decompile;
746 : }
747 :
748 : } // namespace internal
749 : } // namespace v8
750 :
751 : #include "src/objects/object-macros-undef.h"
752 :
753 : #endif // V8_OBJECTS_SHARED_FUNCTION_INFO_INL_H_
|