Home | History | Annotate | Download | only in objects
      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/handles-inl.h"
     11 #include "src/heap/heap-inl.h"
     12 #include "src/objects/debug-objects-inl.h"
     13 #include "src/objects/scope-info.h"
     14 #include "src/objects/templates.h"
     15 
     16 // Has to be the last include (doesn't have include guards):
     17 #include "src/objects/object-macros.h"
     18 
     19 namespace v8 {
     20 namespace internal {
     21 
     22 CAST_ACCESSOR(PreParsedScopeData)
     23 ACCESSORS(PreParsedScopeData, scope_data, PodArray<uint8_t>, kScopeDataOffset)
     24 INT_ACCESSORS(PreParsedScopeData, length, kLengthOffset)
     25 
     26 Object* PreParsedScopeData::child_data(int index) const {
     27   DCHECK_GE(index, 0);
     28   DCHECK_LT(index, this->length());
     29   int offset = kChildDataStartOffset + index * kPointerSize;
     30   return RELAXED_READ_FIELD(this, offset);
     31 }
     32 
     33 void PreParsedScopeData::set_child_data(int index, Object* value,
     34                                         WriteBarrierMode mode) {
     35   DCHECK_GE(index, 0);
     36   DCHECK_LT(index, this->length());
     37   int offset = kChildDataStartOffset + index * kPointerSize;
     38   RELAXED_WRITE_FIELD(this, offset, value);
     39   CONDITIONAL_WRITE_BARRIER(this, offset, value, mode);
     40 }
     41 
     42 Object** PreParsedScopeData::child_data_start() const {
     43   return HeapObject::RawField(this, kChildDataStartOffset);
     44 }
     45 
     46 void PreParsedScopeData::clear_padding() {
     47   // For archs where kIntSize < kPointerSize, there will be padding between the
     48   // length field and the start of the child data.
     49   if (kUnalignedChildDataStartOffset < kChildDataStartOffset) {
     50     memset(reinterpret_cast<void*>(address() + kUnalignedChildDataStartOffset),
     51            0, kChildDataStartOffset - kUnalignedChildDataStartOffset);
     52   }
     53 }
     54 
     55 CAST_ACCESSOR(UncompiledData)
     56 ACCESSORS(UncompiledData, inferred_name, String, kInferredNameOffset)
     57 INT32_ACCESSORS(UncompiledData, start_position, kStartPositionOffset)
     58 INT32_ACCESSORS(UncompiledData, end_position, kEndPositionOffset)
     59 INT32_ACCESSORS(UncompiledData, function_literal_id, kFunctionLiteralIdOffset)
     60 
     61 void UncompiledData::clear_padding() {
     62   // For archs where kIntSize < kPointerSize, there will be padding at the end
     63   // of the data.
     64   if (kUnalignedSize < kSize) {
     65     memset(reinterpret_cast<void*>(address() + kUnalignedSize), 0,
     66            kSize - kUnalignedSize);
     67   }
     68 }
     69 
     70 CAST_ACCESSOR(UncompiledDataWithoutPreParsedScope)
     71 
     72 CAST_ACCESSOR(UncompiledDataWithPreParsedScope)
     73 ACCESSORS(UncompiledDataWithPreParsedScope, pre_parsed_scope_data,
     74           PreParsedScopeData, kPreParsedScopeDataOffset)
     75 
     76 CAST_ACCESSOR(InterpreterData)
     77 ACCESSORS(InterpreterData, bytecode_array, BytecodeArray, kBytecodeArrayOffset)
     78 ACCESSORS(InterpreterData, interpreter_trampoline, Code,
     79           kInterpreterTrampolineOffset)
     80 
     81 CAST_ACCESSOR(SharedFunctionInfo)
     82 DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
     83 
     84 ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object,
     85           kNameOrScopeInfoOffset)
     86 ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
     87 ACCESSORS(SharedFunctionInfo, script_or_debug_info, Object,
     88           kScriptOrDebugInfoOffset)
     89 
     90 #if V8_SFI_HAS_UNIQUE_ID
     91 INT_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset)
     92 #endif
     93 UINT16_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
     94 UINT16_ACCESSORS(SharedFunctionInfo, internal_formal_parameter_count,
     95                  kFormalParameterCountOffset)
     96 UINT8_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
     97                 kExpectedNofPropertiesOffset)
     98 UINT8_ACCESSORS(SharedFunctionInfo, raw_builtin_function_id, kBuiltinFunctionId)
     99 UINT16_ACCESSORS(SharedFunctionInfo, raw_function_token_offset,
    100                  kFunctionTokenOffsetOffset)
    101 INT_ACCESSORS(SharedFunctionInfo, flags, kFlagsOffset)
    102 
    103 bool SharedFunctionInfo::HasSharedName() const {
    104   Object* value = name_or_scope_info();
    105   if (value->IsScopeInfo()) {
    106     return ScopeInfo::cast(value)->HasSharedFunctionName();
    107   }
    108   return value != kNoSharedNameSentinel;
    109 }
    110 
    111 String* SharedFunctionInfo::Name() const {
    112   if (!HasSharedName()) return GetReadOnlyRoots().empty_string();
    113   Object* value = name_or_scope_info();
    114   if (value->IsScopeInfo()) {
    115     if (ScopeInfo::cast(value)->HasFunctionName()) {
    116       return String::cast(ScopeInfo::cast(value)->FunctionName());
    117     }
    118     return GetReadOnlyRoots().empty_string();
    119   }
    120   return String::cast(value);
    121 }
    122 
    123 void SharedFunctionInfo::SetName(String* name) {
    124   Object* maybe_scope_info = name_or_scope_info();
    125   if (maybe_scope_info->IsScopeInfo()) {
    126     ScopeInfo::cast(maybe_scope_info)->SetFunctionName(name);
    127   } else {
    128     DCHECK(maybe_scope_info->IsString() ||
    129            maybe_scope_info == kNoSharedNameSentinel);
    130     set_name_or_scope_info(name);
    131   }
    132   UpdateFunctionMapIndex();
    133 }
    134 
    135 AbstractCode* SharedFunctionInfo::abstract_code() {
    136   if (HasBytecodeArray()) {
    137     return AbstractCode::cast(GetBytecodeArray());
    138   } else {
    139     return AbstractCode::cast(GetCode());
    140   }
    141 }
    142 
    143 int SharedFunctionInfo::function_token_position() const {
    144   int offset = raw_function_token_offset();
    145   if (offset == kFunctionTokenOutOfRange) {
    146     return kNoSourcePosition;
    147   } else {
    148     return StartPosition() - offset;
    149   }
    150 }
    151 
    152 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_wrapped,
    153                     SharedFunctionInfo::IsWrappedBit)
    154 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, allows_lazy_compilation,
    155                     SharedFunctionInfo::AllowLazyCompilationBit)
    156 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, has_duplicate_parameters,
    157                     SharedFunctionInfo::HasDuplicateParametersBit)
    158 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_declaration,
    159                     SharedFunctionInfo::IsDeclarationBit)
    160 
    161 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, native,
    162                     SharedFunctionInfo::IsNativeBit)
    163 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_asm_wasm_broken,
    164                     SharedFunctionInfo::IsAsmWasmBrokenBit)
    165 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags,
    166                     requires_instance_fields_initializer,
    167                     SharedFunctionInfo::RequiresInstanceFieldsInitializer)
    168 
    169 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, name_should_print_as_anonymous,
    170                     SharedFunctionInfo::NameShouldPrintAsAnonymousBit)
    171 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_anonymous_expression,
    172                     SharedFunctionInfo::IsAnonymousExpressionBit)
    173 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, deserialized,
    174                     SharedFunctionInfo::IsDeserializedBit)
    175 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, has_reported_binary_coverage,
    176                     SharedFunctionInfo::HasReportedBinaryCoverageBit)
    177 
    178 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_named_expression,
    179                     SharedFunctionInfo::IsNamedExpressionBit)
    180 BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_toplevel,
    181                     SharedFunctionInfo::IsTopLevelBit)
    182 
    183 bool SharedFunctionInfo::optimization_disabled() const {
    184   return disable_optimization_reason() != BailoutReason::kNoReason;
    185 }
    186 
    187 BailoutReason SharedFunctionInfo::disable_optimization_reason() const {
    188   return DisabledOptimizationReasonBits::decode(flags());
    189 }
    190 
    191 LanguageMode SharedFunctionInfo::language_mode() const {
    192   STATIC_ASSERT(LanguageModeSize == 2);
    193   return construct_language_mode(IsStrictBit::decode(flags()));
    194 }
    195 
    196 void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
    197   STATIC_ASSERT(LanguageModeSize == 2);
    198   // We only allow language mode transitions that set the same language mode
    199   // again or go up in the chain:
    200   DCHECK(is_sloppy(this->language_mode()) || is_strict(language_mode));
    201   int hints = flags();
    202   hints = IsStrictBit::update(hints, is_strict(language_mode));
    203   set_flags(hints);
    204   UpdateFunctionMapIndex();
    205 }
    206 
    207 FunctionKind SharedFunctionInfo::kind() const {
    208   return FunctionKindBits::decode(flags());
    209 }
    210 
    211 void SharedFunctionInfo::set_kind(FunctionKind kind) {
    212   int hints = flags();
    213   hints = FunctionKindBits::update(hints, kind);
    214   hints = IsClassConstructorBit::update(hints, IsClassConstructor(kind));
    215   hints = IsDerivedConstructorBit::update(hints, IsDerivedConstructor(kind));
    216   set_flags(hints);
    217   UpdateFunctionMapIndex();
    218 }
    219 
    220 bool SharedFunctionInfo::needs_home_object() const {
    221   return NeedsHomeObjectBit::decode(flags());
    222 }
    223 
    224 void SharedFunctionInfo::set_needs_home_object(bool value) {
    225   int hints = flags();
    226   hints = NeedsHomeObjectBit::update(hints, value);
    227   set_flags(hints);
    228   UpdateFunctionMapIndex();
    229 }
    230 
    231 bool SharedFunctionInfo::construct_as_builtin() const {
    232   return ConstructAsBuiltinBit::decode(flags());
    233 }
    234 
    235 void SharedFunctionInfo::CalculateConstructAsBuiltin() {
    236   bool uses_builtins_construct_stub = false;
    237   if (HasBuiltinId()) {
    238     int id = builtin_id();
    239     if (id != Builtins::kCompileLazy && id != Builtins::kEmptyFunction) {
    240       uses_builtins_construct_stub = true;
    241     }
    242   } else if (IsApiFunction()) {
    243     uses_builtins_construct_stub = true;
    244   }
    245 
    246   int f = flags();
    247   f = ConstructAsBuiltinBit::update(f, uses_builtins_construct_stub);
    248   set_flags(f);
    249 }
    250 
    251 int SharedFunctionInfo::function_map_index() const {
    252   // Note: Must be kept in sync with the FastNewClosure builtin.
    253   int index =
    254       Context::FIRST_FUNCTION_MAP_INDEX + FunctionMapIndexBits::decode(flags());
    255   DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
    256   return index;
    257 }
    258 
    259 void SharedFunctionInfo::set_function_map_index(int index) {
    260   STATIC_ASSERT(Context::LAST_FUNCTION_MAP_INDEX <=
    261                 Context::FIRST_FUNCTION_MAP_INDEX + FunctionMapIndexBits::kMax);
    262   DCHECK_LE(Context::FIRST_FUNCTION_MAP_INDEX, index);
    263   DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
    264   index -= Context::FIRST_FUNCTION_MAP_INDEX;
    265   set_flags(FunctionMapIndexBits::update(flags(), index));
    266 }
    267 
    268 void SharedFunctionInfo::clear_padding() {
    269   memset(reinterpret_cast<void*>(this->address() + kSize), 0,
    270          kAlignedSize - kSize);
    271 }
    272 
    273 void SharedFunctionInfo::UpdateFunctionMapIndex() {
    274   int map_index = Context::FunctionMapIndex(
    275       language_mode(), kind(), true, HasSharedName(), needs_home_object());
    276   set_function_map_index(map_index);
    277 }
    278 
    279 void SharedFunctionInfo::DontAdaptArguments() {
    280   // TODO(leszeks): Revise this DCHECK now that the code field is gone.
    281   DCHECK(!HasWasmExportedFunctionData());
    282   set_internal_formal_parameter_count(kDontAdaptArgumentsSentinel);
    283 }
    284 
    285 int SharedFunctionInfo::StartPosition() const {
    286   Object* maybe_scope_info = name_or_scope_info();
    287   if (maybe_scope_info->IsScopeInfo()) {
    288     ScopeInfo* info = ScopeInfo::cast(maybe_scope_info);
    289     if (info->HasPositionInfo()) {
    290       return info->StartPosition();
    291     }
    292   } else if (HasUncompiledData()) {
    293     // Works with or without scope.
    294     return uncompiled_data()->start_position();
    295   } else if (IsApiFunction() || HasBuiltinId()) {
    296     DCHECK_IMPLIES(HasBuiltinId(), builtin_id() != Builtins::kCompileLazy);
    297     return 0;
    298   }
    299   return kNoSourcePosition;
    300 }
    301 
    302 int SharedFunctionInfo::EndPosition() const {
    303   Object* maybe_scope_info = name_or_scope_info();
    304   if (maybe_scope_info->IsScopeInfo()) {
    305     ScopeInfo* info = ScopeInfo::cast(maybe_scope_info);
    306     if (info->HasPositionInfo()) {
    307       return info->EndPosition();
    308     }
    309   } else if (HasUncompiledData()) {
    310     // Works with or without scope.
    311     return uncompiled_data()->end_position();
    312   } else if (IsApiFunction() || HasBuiltinId()) {
    313     DCHECK_IMPLIES(HasBuiltinId(), builtin_id() != Builtins::kCompileLazy);
    314     return 0;
    315   }
    316   return kNoSourcePosition;
    317 }
    318 
    319 void SharedFunctionInfo::SetPosition(int start_position, int end_position) {
    320   Object* maybe_scope_info = name_or_scope_info();
    321   if (maybe_scope_info->IsScopeInfo()) {
    322     ScopeInfo* info = ScopeInfo::cast(maybe_scope_info);
    323     if (info->HasPositionInfo()) {
    324       info->SetPositionInfo(start_position, end_position);
    325     }
    326   } else if (HasUncompiledData()) {
    327     if (HasUncompiledDataWithPreParsedScope()) {
    328       // Clear out preparsed scope data, since the position setter invalidates
    329       // any scope data.
    330       ClearPreParsedScopeData();
    331     }
    332     uncompiled_data()->set_start_position(start_position);
    333     uncompiled_data()->set_end_position(end_position);
    334   } else {
    335     UNREACHABLE();
    336   }
    337 }
    338 
    339 bool SharedFunctionInfo::IsInterpreted() const { return HasBytecodeArray(); }
    340 
    341 ScopeInfo* SharedFunctionInfo::scope_info() const {
    342   Object* maybe_scope_info = name_or_scope_info();
    343   if (maybe_scope_info->IsScopeInfo()) {
    344     return ScopeInfo::cast(maybe_scope_info);
    345   }
    346   return ScopeInfo::Empty(GetIsolate());
    347 }
    348 
    349 void SharedFunctionInfo::set_scope_info(ScopeInfo* scope_info,
    350                                         WriteBarrierMode mode) {
    351   // Move the existing name onto the ScopeInfo.
    352   Object* name = name_or_scope_info();
    353   if (name->IsScopeInfo()) {
    354     name = ScopeInfo::cast(name)->FunctionName();
    355   }
    356   DCHECK(name->IsString() || name == kNoSharedNameSentinel);
    357   // Only set the function name for function scopes.
    358   scope_info->SetFunctionName(name);
    359   if (HasInferredName() && inferred_name()->length() != 0) {
    360     scope_info->SetInferredFunctionName(inferred_name());
    361   }
    362   WRITE_FIELD(this, kNameOrScopeInfoOffset,
    363               reinterpret_cast<Object*>(scope_info));
    364   CONDITIONAL_WRITE_BARRIER(this, kNameOrScopeInfoOffset,
    365                             reinterpret_cast<Object*>(scope_info), mode);
    366 }
    367 
    368 ACCESSORS(SharedFunctionInfo, raw_outer_scope_info_or_feedback_metadata,
    369           HeapObject, kOuterScopeInfoOrFeedbackMetadataOffset)
    370 
    371 HeapObject* SharedFunctionInfo::outer_scope_info() const {
    372   DCHECK(!is_compiled());
    373   DCHECK(!HasFeedbackMetadata());
    374   return raw_outer_scope_info_or_feedback_metadata();
    375 }
    376 
    377 bool SharedFunctionInfo::HasOuterScopeInfo() const {
    378   ScopeInfo* outer_info = nullptr;
    379   if (!is_compiled()) {
    380     if (!outer_scope_info()->IsScopeInfo()) return false;
    381     outer_info = ScopeInfo::cast(outer_scope_info());
    382   } else {
    383     if (!scope_info()->HasOuterScopeInfo()) return false;
    384     outer_info = scope_info()->OuterScopeInfo();
    385   }
    386   return outer_info->length() > 0;
    387 }
    388 
    389 ScopeInfo* SharedFunctionInfo::GetOuterScopeInfo() const {
    390   DCHECK(HasOuterScopeInfo());
    391   if (!is_compiled()) return ScopeInfo::cast(outer_scope_info());
    392   return scope_info()->OuterScopeInfo();
    393 }
    394 
    395 void SharedFunctionInfo::set_outer_scope_info(HeapObject* value,
    396                                               WriteBarrierMode mode) {
    397   DCHECK(!is_compiled());
    398   DCHECK(raw_outer_scope_info_or_feedback_metadata()->IsTheHole());
    399   DCHECK(value->IsScopeInfo() || value->IsTheHole());
    400   return set_raw_outer_scope_info_or_feedback_metadata(value, mode);
    401 }
    402 
    403 bool SharedFunctionInfo::HasFeedbackMetadata() const {
    404   return raw_outer_scope_info_or_feedback_metadata()->IsFeedbackMetadata();
    405 }
    406 
    407 FeedbackMetadata* SharedFunctionInfo::feedback_metadata() const {
    408   DCHECK(HasFeedbackMetadata());
    409   return FeedbackMetadata::cast(raw_outer_scope_info_or_feedback_metadata());
    410 }
    411 
    412 void SharedFunctionInfo::set_feedback_metadata(FeedbackMetadata* value,
    413                                                WriteBarrierMode mode) {
    414   DCHECK(!HasFeedbackMetadata());
    415   DCHECK(value->IsFeedbackMetadata());
    416   return set_raw_outer_scope_info_or_feedback_metadata(value, mode);
    417 }
    418 
    419 bool SharedFunctionInfo::is_compiled() const {
    420   Object* data = function_data();
    421   return data != Smi::FromEnum(Builtins::kCompileLazy) &&
    422          !data->IsUncompiledData();
    423 }
    424 
    425 uint16_t SharedFunctionInfo::GetLength() const {
    426   DCHECK(is_compiled());
    427   DCHECK(HasLength());
    428   return length();
    429 }
    430 
    431 bool SharedFunctionInfo::HasLength() const {
    432   return length() != kInvalidLength;
    433 }
    434 
    435 bool SharedFunctionInfo::has_simple_parameters() {
    436   return scope_info()->HasSimpleParameters();
    437 }
    438 
    439 bool SharedFunctionInfo::IsApiFunction() const {
    440   return function_data()->IsFunctionTemplateInfo();
    441 }
    442 
    443 FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
    444   DCHECK(IsApiFunction());
    445   return FunctionTemplateInfo::cast(function_data());
    446 }
    447 
    448 bool SharedFunctionInfo::HasBytecodeArray() const {
    449   return function_data()->IsBytecodeArray() ||
    450          function_data()->IsInterpreterData();
    451 }
    452 
    453 BytecodeArray* SharedFunctionInfo::GetBytecodeArray() const {
    454   DCHECK(HasBytecodeArray());
    455   if (HasDebugInfo() && GetDebugInfo()->HasInstrumentedBytecodeArray()) {
    456     return GetDebugInfo()->OriginalBytecodeArray();
    457   } else if (function_data()->IsBytecodeArray()) {
    458     return BytecodeArray::cast(function_data());
    459   } else {
    460     DCHECK(function_data()->IsInterpreterData());
    461     return InterpreterData::cast(function_data())->bytecode_array();
    462   }
    463 }
    464 
    465 BytecodeArray* SharedFunctionInfo::GetDebugBytecodeArray() const {
    466   DCHECK(HasBytecodeArray());
    467   DCHECK(HasDebugInfo() && GetDebugInfo()->HasInstrumentedBytecodeArray());
    468   if (function_data()->IsBytecodeArray()) {
    469     return BytecodeArray::cast(function_data());
    470   } else {
    471     DCHECK(function_data()->IsInterpreterData());
    472     return InterpreterData::cast(function_data())->bytecode_array();
    473   }
    474 }
    475 
    476 void SharedFunctionInfo::SetDebugBytecodeArray(BytecodeArray* bytecode) {
    477   DCHECK(HasBytecodeArray());
    478   if (function_data()->IsBytecodeArray()) {
    479     set_function_data(bytecode);
    480   } else {
    481     DCHECK(function_data()->IsInterpreterData());
    482     interpreter_data()->set_bytecode_array(bytecode);
    483   }
    484 }
    485 
    486 void SharedFunctionInfo::set_bytecode_array(BytecodeArray* bytecode) {
    487   DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy) ||
    488          HasUncompiledData());
    489   set_function_data(bytecode);
    490 }
    491 
    492 Code* SharedFunctionInfo::InterpreterTrampoline() const {
    493   DCHECK(HasInterpreterData());
    494   return interpreter_data()->interpreter_trampoline();
    495 }
    496 
    497 bool SharedFunctionInfo::HasInterpreterData() const {
    498   return function_data()->IsInterpreterData();
    499 }
    500 
    501 InterpreterData* SharedFunctionInfo::interpreter_data() const {
    502   DCHECK(HasInterpreterData());
    503   return InterpreterData::cast(function_data());
    504 }
    505 
    506 void SharedFunctionInfo::set_interpreter_data(
    507     InterpreterData* interpreter_data) {
    508   DCHECK(FLAG_interpreted_frames_native_stack);
    509   set_function_data(interpreter_data);
    510 }
    511 
    512 bool SharedFunctionInfo::HasAsmWasmData() const {
    513   return function_data()->IsFixedArray();
    514 }
    515 
    516 FixedArray* SharedFunctionInfo::asm_wasm_data() const {
    517   DCHECK(HasAsmWasmData());
    518   return FixedArray::cast(function_data());
    519 }
    520 
    521 void SharedFunctionInfo::set_asm_wasm_data(FixedArray* data) {
    522   DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy) ||
    523          HasUncompiledData() || HasAsmWasmData());
    524   set_function_data(data);
    525 }
    526 
    527 bool SharedFunctionInfo::HasBuiltinId() const {
    528   return function_data()->IsSmi();
    529 }
    530 
    531 int SharedFunctionInfo::builtin_id() const {
    532   DCHECK(HasBuiltinId());
    533   int id = Smi::ToInt(function_data());
    534   DCHECK(Builtins::IsBuiltinId(id));
    535   return id;
    536 }
    537 
    538 void SharedFunctionInfo::set_builtin_id(int builtin_id) {
    539   DCHECK(Builtins::IsBuiltinId(builtin_id));
    540   DCHECK_NE(builtin_id, Builtins::kDeserializeLazy);
    541   set_function_data(Smi::FromInt(builtin_id), SKIP_WRITE_BARRIER);
    542 }
    543 
    544 bool SharedFunctionInfo::HasUncompiledData() const {
    545   return function_data()->IsUncompiledData();
    546 }
    547 
    548 UncompiledData* SharedFunctionInfo::uncompiled_data() const {
    549   DCHECK(HasUncompiledData());
    550   return UncompiledData::cast(function_data());
    551 }
    552 
    553 void SharedFunctionInfo::set_uncompiled_data(UncompiledData* uncompiled_data) {
    554   DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy));
    555   DCHECK(uncompiled_data->IsUncompiledData());
    556   set_function_data(uncompiled_data);
    557 }
    558 
    559 bool SharedFunctionInfo::HasUncompiledDataWithPreParsedScope() const {
    560   return function_data()->IsUncompiledDataWithPreParsedScope();
    561 }
    562 
    563 UncompiledDataWithPreParsedScope*
    564 SharedFunctionInfo::uncompiled_data_with_pre_parsed_scope() const {
    565   DCHECK(HasUncompiledDataWithPreParsedScope());
    566   return UncompiledDataWithPreParsedScope::cast(function_data());
    567 }
    568 
    569 void SharedFunctionInfo::set_uncompiled_data_with_pre_parsed_scope(
    570     UncompiledDataWithPreParsedScope* uncompiled_data_with_pre_parsed_scope) {
    571   DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy));
    572   DCHECK(uncompiled_data_with_pre_parsed_scope
    573              ->IsUncompiledDataWithPreParsedScope());
    574   set_function_data(uncompiled_data_with_pre_parsed_scope);
    575 }
    576 
    577 bool SharedFunctionInfo::HasUncompiledDataWithoutPreParsedScope() const {
    578   return function_data()->IsUncompiledDataWithoutPreParsedScope();
    579 }
    580 
    581 void SharedFunctionInfo::ClearPreParsedScopeData() {
    582   DCHECK(HasUncompiledDataWithPreParsedScope());
    583   UncompiledDataWithPreParsedScope* data =
    584       uncompiled_data_with_pre_parsed_scope();
    585 
    586   // Trim off the pre-parsed scope data from the uncompiled data by swapping the
    587   // map, leaving only an uncompiled data without pre-parsed scope.
    588   DisallowHeapAllocation no_gc;
    589   Heap* heap = Heap::FromWritableHeapObject(data);
    590 
    591   // Swap the map.
    592   heap->NotifyObjectLayoutChange(data, UncompiledDataWithPreParsedScope::kSize,
    593                                  no_gc);
    594   STATIC_ASSERT(UncompiledDataWithoutPreParsedScope::kSize <
    595                 UncompiledDataWithPreParsedScope::kSize);
    596   STATIC_ASSERT(UncompiledDataWithoutPreParsedScope::kSize ==
    597                 UncompiledData::kSize);
    598   data->synchronized_set_map(
    599       GetReadOnlyRoots().uncompiled_data_without_pre_parsed_scope_map());
    600 
    601   // Fill the remaining space with filler.
    602   heap->CreateFillerObjectAt(
    603       data->address() + UncompiledDataWithoutPreParsedScope::kSize,
    604       UncompiledDataWithPreParsedScope::kSize -
    605           UncompiledDataWithoutPreParsedScope::kSize,
    606       ClearRecordedSlots::kNo);
    607 
    608   // Ensure that the clear was successful.
    609   DCHECK(HasUncompiledDataWithoutPreParsedScope());
    610 }
    611 
    612 bool SharedFunctionInfo::HasWasmExportedFunctionData() const {
    613   return function_data()->IsWasmExportedFunctionData();
    614 }
    615 
    616 int SharedFunctionInfo::FunctionLiteralId(Isolate* isolate) const {
    617   // Fast path for the common case when the SFI is uncompiled and so the
    618   // function literal id is already in the uncompiled data.
    619   if (HasUncompiledData()) {
    620     int id = uncompiled_data()->function_literal_id();
    621     // Make sure the id is what we should have found with the slow path.
    622     DCHECK_EQ(id, FindIndexInScript(isolate));
    623     return id;
    624   }
    625 
    626   // Otherwise, search for the function in the SFI's script's function list,
    627   // and return its index in that list.e
    628   return FindIndexInScript(isolate);
    629 }
    630 
    631 Object* SharedFunctionInfo::script() const {
    632   Object* maybe_script = script_or_debug_info();
    633   if (maybe_script->IsDebugInfo()) {
    634     return DebugInfo::cast(maybe_script)->script();
    635   }
    636   return maybe_script;
    637 }
    638 
    639 void SharedFunctionInfo::set_script(Object* script) {
    640   Object* maybe_debug_info = script_or_debug_info();
    641   if (maybe_debug_info->IsDebugInfo()) {
    642     DebugInfo::cast(maybe_debug_info)->set_script(script);
    643   } else {
    644     set_script_or_debug_info(script);
    645   }
    646 }
    647 
    648 bool SharedFunctionInfo::HasDebugInfo() const {
    649   return script_or_debug_info()->IsDebugInfo();
    650 }
    651 
    652 DebugInfo* SharedFunctionInfo::GetDebugInfo() const {
    653   DCHECK(HasDebugInfo());
    654   return DebugInfo::cast(script_or_debug_info());
    655 }
    656 
    657 void SharedFunctionInfo::SetDebugInfo(DebugInfo* debug_info) {
    658   DCHECK(!HasDebugInfo());
    659   DCHECK_EQ(debug_info->script(), script_or_debug_info());
    660   set_script_or_debug_info(debug_info);
    661 }
    662 
    663 bool SharedFunctionInfo::HasBuiltinFunctionId() {
    664   return builtin_function_id() != BuiltinFunctionId::kInvalidBuiltinFunctionId;
    665 }
    666 
    667 BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
    668   return static_cast<BuiltinFunctionId>(raw_builtin_function_id());
    669 }
    670 
    671 void SharedFunctionInfo::set_builtin_function_id(BuiltinFunctionId id) {
    672   set_raw_builtin_function_id(static_cast<uint8_t>(id));
    673 }
    674 
    675 bool SharedFunctionInfo::HasInferredName() {
    676   Object* scope_info = name_or_scope_info();
    677   if (scope_info->IsScopeInfo()) {
    678     return ScopeInfo::cast(scope_info)->HasInferredFunctionName();
    679   }
    680   return HasUncompiledData();
    681 }
    682 
    683 String* SharedFunctionInfo::inferred_name() {
    684   Object* maybe_scope_info = name_or_scope_info();
    685   if (maybe_scope_info->IsScopeInfo()) {
    686     ScopeInfo* scope_info = ScopeInfo::cast(maybe_scope_info);
    687     if (scope_info->HasInferredFunctionName()) {
    688       Object* name = ScopeInfo::cast(maybe_scope_info)->InferredFunctionName();
    689       if (name->IsString()) return String::cast(name);
    690     }
    691   } else if (HasUncompiledData()) {
    692     return uncompiled_data()->inferred_name();
    693   }
    694   return GetReadOnlyRoots().empty_string();
    695 }
    696 
    697 bool SharedFunctionInfo::IsUserJavaScript() {
    698   Object* script_obj = script();
    699   if (script_obj->IsUndefined()) return false;
    700   Script* script = Script::cast(script_obj);
    701   return script->IsUserJavaScript();
    702 }
    703 
    704 bool SharedFunctionInfo::IsSubjectToDebugging() {
    705   return IsUserJavaScript() && !HasAsmWasmData();
    706 }
    707 
    708 bool SharedFunctionInfo::CanDiscardCompiled() const {
    709   bool can_decompile = (HasBytecodeArray() || HasAsmWasmData() ||
    710                         HasUncompiledDataWithPreParsedScope());
    711   return can_decompile;
    712 }
    713 
    714 // static
    715 void SharedFunctionInfo::DiscardCompiled(
    716     Isolate* isolate, Handle<SharedFunctionInfo> shared_info) {
    717   DCHECK(shared_info->CanDiscardCompiled());
    718 
    719   int start_position = shared_info->StartPosition();
    720   int end_position = shared_info->EndPosition();
    721   int function_literal_id = shared_info->FunctionLiteralId(isolate);
    722 
    723   if (shared_info->is_compiled()) {
    724     DisallowHeapAllocation no_gc;
    725 
    726     HeapObject* outer_scope_info;
    727     if (shared_info->scope_info()->HasOuterScopeInfo()) {
    728       outer_scope_info = shared_info->scope_info()->OuterScopeInfo();
    729     } else {
    730       outer_scope_info = ReadOnlyRoots(isolate).the_hole_value();
    731     }
    732     // Raw setter to avoid validity checks, since we're performing the unusual
    733     // task of decompiling.
    734     shared_info->set_raw_outer_scope_info_or_feedback_metadata(
    735         outer_scope_info);
    736   } else {
    737     DCHECK(shared_info->outer_scope_info()->IsScopeInfo() ||
    738            shared_info->outer_scope_info()->IsTheHole());
    739   }
    740 
    741   if (shared_info->HasUncompiledDataWithPreParsedScope()) {
    742     // If this is uncompiled data with a pre-parsed scope data, we can just
    743     // clear out the scope data and keep the uncompiled data.
    744     shared_info->ClearPreParsedScopeData();
    745   } else {
    746     // Create a new UncompiledData, without pre-parsed scope, and update the
    747     // function data to point to it. Use the raw function data setter to avoid
    748     // validity checks, since we're performing the unusual task of decompiling.
    749     Handle<UncompiledData> data =
    750         isolate->factory()->NewUncompiledDataWithoutPreParsedScope(
    751             handle(shared_info->inferred_name(), isolate), start_position,
    752             end_position, function_literal_id);
    753     shared_info->set_function_data(*data);
    754   }
    755 }
    756 
    757 }  // namespace internal
    758 }  // namespace v8
    759 
    760 #include "src/objects/object-macros-undef.h"
    761 
    762 #endif  // V8_OBJECTS_SHARED_FUNCTION_INFO_INL_H_
    763