LCOV - code coverage report
Current view: top level - src/objects - code-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 218 230 94.8 %
Date: 2019-04-17 Functions: 59 61 96.7 %

          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_CODE_INL_H_
       6             : #define V8_OBJECTS_CODE_INL_H_
       7             : 
       8             : #include "src/objects/code.h"
       9             : 
      10             : #include "src/code-desc.h"
      11             : #include "src/interpreter/bytecode-register.h"
      12             : #include "src/isolate.h"
      13             : #include "src/objects/dictionary.h"
      14             : #include "src/objects/instance-type-inl.h"
      15             : #include "src/objects/map-inl.h"
      16             : #include "src/objects/maybe-object-inl.h"
      17             : #include "src/objects/oddball.h"
      18             : #include "src/objects/smi-inl.h"
      19             : #include "src/v8memory.h"
      20             : 
      21             : // Has to be the last include (doesn't have include guards):
      22             : #include "src/objects/object-macros.h"
      23             : 
      24             : namespace v8 {
      25             : namespace internal {
      26             : 
      27             : OBJECT_CONSTRUCTORS_IMPL(DeoptimizationData, FixedArray)
      28             : OBJECT_CONSTRUCTORS_IMPL(BytecodeArray, FixedArrayBase)
      29             : OBJECT_CONSTRUCTORS_IMPL(AbstractCode, HeapObject)
      30             : OBJECT_CONSTRUCTORS_IMPL(DependentCode, WeakFixedArray)
      31             : OBJECT_CONSTRUCTORS_IMPL(CodeDataContainer, HeapObject)
      32             : OBJECT_CONSTRUCTORS_IMPL(SourcePositionTableWithFrameCache, Tuple2)
      33             : 
      34             : NEVER_READ_ONLY_SPACE_IMPL(AbstractCode)
      35             : 
      36             : CAST_ACCESSOR(AbstractCode)
      37             : CAST_ACCESSOR(BytecodeArray)
      38     1471133 : CAST_ACCESSOR(Code)
      39             : CAST_ACCESSOR(CodeDataContainer)
      40             : CAST_ACCESSOR(DependentCode)
      41             : CAST_ACCESSOR(DeoptimizationData)
      42             : CAST_ACCESSOR(SourcePositionTableWithFrameCache)
      43             : 
      44      269711 : ACCESSORS(SourcePositionTableWithFrameCache, source_position_table, ByteArray,
      45             :           kSourcePositionTableIndex)
      46       98733 : ACCESSORS(SourcePositionTableWithFrameCache, stack_frame_cache,
      47             :           SimpleNumberDictionary, kStackFrameCacheIndex)
      48             : 
      49             : int AbstractCode::raw_instruction_size() {
      50             :   if (IsCode()) {
      51             :     return GetCode()->raw_instruction_size();
      52             :   } else {
      53             :     return GetBytecodeArray()->length();
      54             :   }
      55             : }
      56             : 
      57      661179 : int AbstractCode::InstructionSize() {
      58     1322358 :   if (IsCode()) {
      59      316184 :     return GetCode()->InstructionSize();
      60             :   } else {
      61             :     return GetBytecodeArray()->length();
      62             :   }
      63             : }
      64             : 
      65     2142737 : ByteArray AbstractCode::source_position_table() {
      66     4285474 :   if (IsCode()) {
      67      103528 :     return GetCode()->SourcePositionTable();
      68             :   } else {
      69     2039209 :     return GetBytecodeArray()->SourcePositionTable();
      70             :   }
      71             : }
      72             : 
      73       72406 : Object AbstractCode::stack_frame_cache() {
      74             :   Object maybe_table;
      75      144812 :   if (IsCode()) {
      76             :     maybe_table = GetCode()->source_position_table();
      77             :   } else {
      78             :     maybe_table = GetBytecodeArray()->source_position_table();
      79             :   }
      80       72406 :   if (maybe_table->IsSourcePositionTableWithFrameCache()) {
      81             :     return SourcePositionTableWithFrameCache::cast(maybe_table)
      82       56018 :         ->stack_frame_cache();
      83             :   }
      84       16388 :   return Smi::kZero;
      85             : }
      86             : 
      87           0 : int AbstractCode::SizeIncludingMetadata() {
      88           0 :   if (IsCode()) {
      89           0 :     return GetCode()->SizeIncludingMetadata();
      90             :   } else {
      91           0 :     return GetBytecodeArray()->SizeIncludingMetadata();
      92             :   }
      93             : }
      94          10 : int AbstractCode::ExecutableSize() {
      95          20 :   if (IsCode()) {
      96             :     return GetCode()->ExecutableSize();
      97             :   } else {
      98             :     return GetBytecodeArray()->BytecodeArraySize();
      99             :   }
     100             : }
     101             : 
     102          24 : Address AbstractCode::raw_instruction_start() {
     103          48 :   if (IsCode()) {
     104             :     return GetCode()->raw_instruction_start();
     105             :   } else {
     106             :     return GetBytecodeArray()->GetFirstBytecodeAddress();
     107             :   }
     108             : }
     109             : 
     110     1293551 : Address AbstractCode::InstructionStart() {
     111     2587102 :   if (IsCode()) {
     112      573474 :     return GetCode()->InstructionStart();
     113             :   } else {
     114             :     return GetBytecodeArray()->GetFirstBytecodeAddress();
     115             :   }
     116             : }
     117             : 
     118          15 : Address AbstractCode::raw_instruction_end() {
     119          30 :   if (IsCode()) {
     120             :     return GetCode()->raw_instruction_end();
     121             :   } else {
     122          12 :     return GetBytecodeArray()->GetFirstBytecodeAddress() +
     123          12 :            GetBytecodeArray()->length();
     124             :   }
     125             : }
     126             : 
     127             : Address AbstractCode::InstructionEnd() {
     128             :   if (IsCode()) {
     129             :     return GetCode()->InstructionEnd();
     130             :   } else {
     131             :     return GetBytecodeArray()->GetFirstBytecodeAddress() +
     132             :            GetBytecodeArray()->length();
     133             :   }
     134             : }
     135             : 
     136             : bool AbstractCode::contains(Address inner_pointer) {
     137          20 :   return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
     138             : }
     139             : 
     140       89664 : AbstractCode::Kind AbstractCode::kind() {
     141      179328 :   if (IsCode()) {
     142             :     return static_cast<AbstractCode::Kind>(GetCode()->kind());
     143             :   } else {
     144             :     return INTERPRETED_FUNCTION;
     145             :   }
     146             : }
     147             : 
     148             : Code AbstractCode::GetCode() { return Code::cast(*this); }
     149             : 
     150             : BytecodeArray AbstractCode::GetBytecodeArray() {
     151             :   return BytecodeArray::cast(*this);
     152             : }
     153             : 
     154             : DependentCode DependentCode::next_link() {
     155             :   return DependentCode::cast(Get(kNextLinkIndex)->GetHeapObjectAssumeStrong());
     156             : }
     157             : 
     158             : void DependentCode::set_next_link(DependentCode next) {
     159      138211 :   Set(kNextLinkIndex, HeapObjectReference::Strong(next));
     160             : }
     161             : 
     162             : int DependentCode::flags() { return Smi::ToInt(Get(kFlagsIndex)->ToSmi()); }
     163             : 
     164             : void DependentCode::set_flags(int flags) {
     165      374940 :   Set(kFlagsIndex, MaybeObject::FromObject(Smi::FromInt(flags)));
     166             : }
     167             : 
     168      666329 : int DependentCode::count() { return CountField::decode(flags()); }
     169             : 
     170      267336 : void DependentCode::set_count(int value) {
     171      534672 :   set_flags(CountField::update(flags(), value));
     172      267336 : }
     173             : 
     174             : DependentCode::DependencyGroup DependentCode::group() {
     175           9 :   return static_cast<DependencyGroup>(GroupField::decode(flags()));
     176             : }
     177             : 
     178             : void DependentCode::set_object_at(int i, MaybeObject object) {
     179      310866 :   Set(kCodesStartIndex + i, object);
     180             : }
     181             : 
     182             : MaybeObject DependentCode::object_at(int i) {
     183             :   return Get(kCodesStartIndex + i);
     184             : }
     185             : 
     186       13577 : void DependentCode::clear_at(int i) {
     187       13577 :   Set(kCodesStartIndex + i,
     188       27154 :       HeapObjectReference::Strong(GetReadOnlyRoots().undefined_value()));
     189       13577 : }
     190             : 
     191        1707 : void DependentCode::copy(int from, int to) {
     192        1707 :   Set(kCodesStartIndex + to, Get(kCodesStartIndex + from));
     193        1707 : }
     194             : 
     195     2942266 : OBJECT_CONSTRUCTORS_IMPL(Code, HeapObject)
     196             : NEVER_READ_ONLY_SPACE_IMPL(Code)
     197             : 
     198   440598521 : INT_ACCESSORS(Code, raw_instruction_size, kInstructionSizeOffset)
     199     4936099 : INT_ACCESSORS(Code, safepoint_table_offset, kSafepointTableOffsetOffset)
     200     6675167 : INT_ACCESSORS(Code, handler_table_offset, kHandlerTableOffsetOffset)
     201     6074017 : INT_ACCESSORS(Code, code_comments_offset, kCodeCommentsOffsetOffset)
     202             : #define CODE_ACCESSORS(name, type, offset)           \
     203             :   ACCESSORS_CHECKED2(Code, name, type, offset, true, \
     204             :                      !ObjectInYoungGeneration(value))
     205             : #define SYNCHRONIZED_CODE_ACCESSORS(name, type, offset)           \
     206             :   SYNCHRONIZED_ACCESSORS_CHECKED2(Code, name, type, offset, true, \
     207             :                                   !ObjectInYoungGeneration(value))
     208             : 
     209    10778287 : CODE_ACCESSORS(relocation_info, ByteArray, kRelocationInfoOffset)
     210    14514035 : CODE_ACCESSORS(deoptimization_data, FixedArray, kDeoptimizationDataOffset)
     211    11016139 : CODE_ACCESSORS(source_position_table, Object, kSourcePositionTableOffset)
     212             : // Concurrent marker needs to access kind specific flags in code data container.
     213    26808307 : SYNCHRONIZED_CODE_ACCESSORS(code_data_container, CodeDataContainer,
     214             :                             kCodeDataContainerOffset)
     215             : #undef CODE_ACCESSORS
     216             : #undef SYNCHRONIZED_CODE_ACCESSORS
     217             : 
     218      397771 : void Code::WipeOutHeader() {
     219      397771 :   WRITE_FIELD(*this, kRelocationInfoOffset, Smi::FromInt(0));
     220      397771 :   WRITE_FIELD(*this, kDeoptimizationDataOffset, Smi::FromInt(0));
     221      397771 :   WRITE_FIELD(*this, kSourcePositionTableOffset, Smi::FromInt(0));
     222      397771 :   WRITE_FIELD(*this, kCodeDataContainerOffset, Smi::FromInt(0));
     223      397771 : }
     224             : 
     225     1906428 : void Code::clear_padding() {
     226             :   if (FIELD_SIZE(kOptionalPaddingOffset) != 0) {
     227             :     memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
     228             :            FIELD_SIZE(kOptionalPaddingOffset));
     229             :   }
     230             :   Address data_end =
     231     1906428 :       has_unwinding_info() ? unwinding_info_end() : raw_instruction_end();
     232     3812856 :   memset(reinterpret_cast<void*>(data_end), 0,
     233     1906428 :          CodeSize() - (data_end - address()));
     234     1906428 : }
     235             : 
     236             : ByteArray Code::SourcePositionTableIfCollected() const {
     237             :   ReadOnlyRoots roots = GetReadOnlyRoots();
     238             :   Object maybe_table = source_position_table();
     239             :   if (maybe_table->IsUndefined(roots) || maybe_table->IsException(roots))
     240             :     return roots.empty_byte_array();
     241             :   return SourcePositionTable();
     242             : }
     243             : 
     244      107323 : ByteArray Code::SourcePositionTable() const {
     245             :   Object maybe_table = source_position_table();
     246             :   DCHECK(!maybe_table->IsUndefined() && !maybe_table->IsException());
     247      107323 :   if (maybe_table->IsByteArray()) return ByteArray::cast(maybe_table);
     248             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
     249             :   return SourcePositionTableWithFrameCache::cast(maybe_table)
     250             :       ->source_position_table();
     251             : }
     252             : 
     253             : Object Code::next_code_link() const {
     254             :   return code_data_container()->next_code_link();
     255             : }
     256             : 
     257      781981 : void Code::set_next_code_link(Object value) {
     258      781981 :   code_data_container()->set_next_code_link(value);
     259      781981 : }
     260             : 
     261             : int Code::InstructionSize() const {
     262      166552 :   if (is_off_heap_trampoline()) {
     263             :     DCHECK(FLAG_embedded_builtins);
     264       64937 :     return OffHeapInstructionSize();
     265             :   }
     266             :   return raw_instruction_size();
     267             : }
     268             : 
     269             : Address Code::raw_instruction_start() const {
     270   288084219 :   return FIELD_ADDR(*this, kHeaderSize);
     271             : }
     272             : 
     273             : Address Code::InstructionStart() const {
     274   164408292 :   if (is_off_heap_trampoline()) {
     275             :     DCHECK(FLAG_embedded_builtins);
     276   154680318 :     return OffHeapInstructionStart();
     277             :   }
     278             :   return raw_instruction_start();
     279             : }
     280             : 
     281             : Address Code::raw_instruction_end() const {
     282     1906661 :   return raw_instruction_start() + raw_instruction_size();
     283             : }
     284             : 
     285         252 : Address Code::InstructionEnd() const {
     286         252 :   if (is_off_heap_trampoline()) {
     287             :     DCHECK(FLAG_embedded_builtins);
     288           0 :     return OffHeapInstructionEnd();
     289             :   }
     290         252 :   return raw_instruction_end();
     291             : }
     292             : 
     293             : int Code::GetUnwindingInfoSizeOffset() const {
     294             :   DCHECK(has_unwinding_info());
     295         121 :   return RoundUp(kHeaderSize + raw_instruction_size(), kInt64Size);
     296             : }
     297             : 
     298             : int Code::unwinding_info_size() const {
     299             :   DCHECK(has_unwinding_info());
     300             :   return static_cast<int>(
     301          67 :       READ_UINT64_FIELD(*this, GetUnwindingInfoSizeOffset()));
     302             : }
     303             : 
     304             : void Code::set_unwinding_info_size(int value) {
     305             :   DCHECK(has_unwinding_info());
     306          27 :   WRITE_UINT64_FIELD(*this, GetUnwindingInfoSizeOffset(), value);
     307             : }
     308             : 
     309             : Address Code::unwinding_info_start() const {
     310             :   DCHECK(has_unwinding_info());
     311          94 :   return FIELD_ADDR(*this, GetUnwindingInfoSizeOffset()) + kInt64Size;
     312             : }
     313             : 
     314             : Address Code::unwinding_info_end() const {
     315             :   DCHECK(has_unwinding_info());
     316          67 :   return unwinding_info_start() + unwinding_info_size();
     317             : }
     318             : 
     319   432941814 : int Code::body_size() const {
     320             :   int unpadded_body_size =
     321             :       has_unwinding_info()
     322             :           ? static_cast<int>(unwinding_info_end() - raw_instruction_start())
     323   432941884 :           : raw_instruction_size();
     324   432941814 :   return RoundUp(unpadded_body_size, kObjectAlignment);
     325             : }
     326             : 
     327           0 : int Code::SizeIncludingMetadata() const {
     328             :   int size = CodeSize();
     329           0 :   size += relocation_info()->Size();
     330           0 :   size += deoptimization_data()->Size();
     331           0 :   return size;
     332             : }
     333             : 
     334             : ByteArray Code::unchecked_relocation_info() const {
     335   210025890 :   return ByteArray::unchecked_cast(READ_FIELD(*this, kRelocationInfoOffset));
     336             : }
     337             : 
     338             : byte* Code::relocation_start() const {
     339             :   return unchecked_relocation_info()->GetDataStartAddress();
     340             : }
     341             : 
     342             : byte* Code::relocation_end() const {
     343             :   return unchecked_relocation_info()->GetDataEndAddress();
     344             : }
     345             : 
     346             : int Code::relocation_size() const {
     347             :   return unchecked_relocation_info()->length();
     348             : }
     349             : 
     350             : Address Code::entry() const { return raw_instruction_start(); }
     351             : 
     352    10960813 : bool Code::contains(Address inner_pointer) {
     353    10960813 :   if (is_off_heap_trampoline()) {
     354             :     DCHECK(FLAG_embedded_builtins);
     355     1052307 :     if (OffHeapInstructionStart() <= inner_pointer &&
     356      390771 :         inner_pointer < OffHeapInstructionEnd()) {
     357             :       return true;
     358             :     }
     359             :   }
     360    10592407 :   return (address() <= inner_pointer) && (inner_pointer < address() + Size());
     361             : }
     362             : 
     363             : int Code::ExecutableSize() const {
     364             :   // Check that the assumptions about the layout of the code object holds.
     365             :   DCHECK_EQ(static_cast<int>(raw_instruction_start() - address()),
     366             :             Code::kHeaderSize);
     367           2 :   return raw_instruction_size() + Code::kHeaderSize;
     368             : }
     369             : 
     370             : // static
     371             : void Code::CopyRelocInfoToByteArray(ByteArray dest, const CodeDesc& desc) {
     372             :   DCHECK_EQ(dest->length(), desc.reloc_size);
     373     3812964 :   CopyBytes(dest->GetDataStartAddress(),
     374     1906482 :             desc.buffer + desc.buffer_size - desc.reloc_size,
     375             :             static_cast<size_t>(desc.reloc_size));
     376             : }
     377             : 
     378   432697722 : int Code::CodeSize() const { return SizeFor(body_size()); }
     379             : 
     380             : Code::Kind Code::kind() const {
     381    69108495 :   return KindField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     382             : }
     383             : 
     384     1991604 : void Code::initialize_flags(Kind kind, bool has_unwinding_info,
     385             :                             bool is_turbofanned, int stack_slots,
     386             :                             bool is_off_heap_trampoline) {
     387     1991604 :   CHECK(0 <= stack_slots && stack_slots < StackSlotsField::kMax);
     388             :   static_assert(Code::NUMBER_OF_KINDS <= KindField::kMax + 1, "field overflow");
     389     1991604 :   uint32_t flags = HasUnwindingInfoField::encode(has_unwinding_info) |
     390     1991604 :                    KindField::encode(kind) |
     391     1991604 :                    IsTurbofannedField::encode(is_turbofanned) |
     392             :                    StackSlotsField::encode(stack_slots) |
     393     1991604 :                    IsOffHeapTrampoline::encode(is_off_heap_trampoline);
     394     1991604 :   WRITE_UINT32_FIELD(*this, kFlagsOffset, flags);
     395             :   DCHECK_IMPLIES(stack_slots != 0, has_safepoint_info());
     396     1991604 : }
     397             : 
     398             : inline bool Code::is_interpreter_trampoline_builtin() const {
     399             :   bool is_interpreter_trampoline =
     400     1620003 :       (builtin_index() == Builtins::kInterpreterEntryTrampoline ||
     401    30435293 :        builtin_index() == Builtins::kInterpreterEnterBytecodeAdvance ||
     402             :        builtin_index() == Builtins::kInterpreterEnterBytecodeDispatch);
     403             :   return is_interpreter_trampoline;
     404             : }
     405             : 
     406             : inline bool Code::checks_optimization_marker() const {
     407             :   bool checks_marker =
     408             :       (builtin_index() == Builtins::kCompileLazy ||
     409             :        builtin_index() == Builtins::kInterpreterEntryTrampoline);
     410             :   return checks_marker ||
     411             :          (kind() == OPTIMIZED_FUNCTION && marked_for_deoptimization());
     412             : }
     413             : 
     414             : inline bool Code::has_tagged_params() const {
     415     1411599 :   return kind() != JS_TO_WASM_FUNCTION && kind() != C_WASM_ENTRY &&
     416             :          kind() != WASM_FUNCTION;
     417             : }
     418             : 
     419             : inline bool Code::has_unwinding_info() const {
     420   434848256 :   return HasUnwindingInfoField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     421             : }
     422             : 
     423             : inline bool Code::is_turbofanned() const {
     424      222900 :   return IsTurbofannedField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     425             : }
     426             : 
     427      381571 : inline bool Code::can_have_weak_objects() const {
     428             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     429             :   int32_t flags = code_data_container()->kind_specific_flags();
     430      381571 :   return CanHaveWeakObjectsField::decode(flags);
     431             : }
     432             : 
     433      460467 : inline void Code::set_can_have_weak_objects(bool value) {
     434             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     435             :   int32_t previous = code_data_container()->kind_specific_flags();
     436             :   int32_t updated = CanHaveWeakObjectsField::update(previous, value);
     437             :   code_data_container()->set_kind_specific_flags(updated);
     438      460467 : }
     439             : 
     440        7055 : inline bool Code::is_promise_rejection() const {
     441             :   DCHECK(kind() == BUILTIN);
     442             :   int32_t flags = code_data_container()->kind_specific_flags();
     443        7055 :   return IsPromiseRejectionField::decode(flags);
     444             : }
     445             : 
     446         784 : inline void Code::set_is_promise_rejection(bool value) {
     447             :   DCHECK(kind() == BUILTIN);
     448             :   int32_t previous = code_data_container()->kind_specific_flags();
     449             :   int32_t updated = IsPromiseRejectionField::update(previous, value);
     450             :   code_data_container()->set_kind_specific_flags(updated);
     451         784 : }
     452             : 
     453        5242 : inline bool Code::is_exception_caught() const {
     454             :   DCHECK(kind() == BUILTIN);
     455             :   int32_t flags = code_data_container()->kind_specific_flags();
     456        5242 :   return IsExceptionCaughtField::decode(flags);
     457             : }
     458             : 
     459          56 : inline void Code::set_is_exception_caught(bool value) {
     460             :   DCHECK(kind() == BUILTIN);
     461             :   int32_t previous = code_data_container()->kind_specific_flags();
     462             :   int32_t updated = IsExceptionCaughtField::update(previous, value);
     463             :   code_data_container()->set_kind_specific_flags(updated);
     464          56 : }
     465             : 
     466             : inline bool Code::is_off_heap_trampoline() const {
     467   172678849 :   return IsOffHeapTrampoline::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     468             : }
     469             : 
     470        7055 : inline HandlerTable::CatchPrediction Code::GetBuiltinCatchPrediction() {
     471        7055 :   if (is_promise_rejection()) return HandlerTable::PROMISE;
     472        5242 :   if (is_exception_caught()) return HandlerTable::CAUGHT;
     473        5174 :   return HandlerTable::UNCAUGHT;
     474             : }
     475             : 
     476             : int Code::builtin_index() const {
     477   197312161 :   int index = READ_INT_FIELD(*this, kBuiltinIndexOffset);
     478             :   DCHECK(index == -1 || Builtins::IsBuiltinId(index));
     479             :   return index;
     480             : }
     481             : 
     482             : void Code::set_builtin_index(int index) {
     483             :   DCHECK(index == -1 || Builtins::IsBuiltinId(index));
     484     1991604 :   WRITE_INT_FIELD(*this, kBuiltinIndexOffset, index);
     485             : }
     486             : 
     487             : bool Code::is_builtin() const { return builtin_index() != -1; }
     488             : 
     489             : bool Code::has_safepoint_info() const {
     490      105417 :   return is_turbofanned() || is_wasm_code();
     491             : }
     492             : 
     493             : int Code::stack_slots() const {
     494             :   DCHECK(has_safepoint_info());
     495     7445447 :   return StackSlotsField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     496             : }
     497             : 
     498     4952992 : bool Code::marked_for_deoptimization() const {
     499             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     500             :   int32_t flags = code_data_container()->kind_specific_flags();
     501     4952992 :   return MarkedForDeoptimizationField::decode(flags);
     502             : }
     503             : 
     504      318573 : void Code::set_marked_for_deoptimization(bool flag) {
     505             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     506             :   DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
     507             :   int32_t previous = code_data_container()->kind_specific_flags();
     508             :   int32_t updated = MarkedForDeoptimizationField::update(previous, flag);
     509             :   code_data_container()->set_kind_specific_flags(updated);
     510      318573 : }
     511             : 
     512         870 : bool Code::embedded_objects_cleared() const {
     513             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     514             :   int32_t flags = code_data_container()->kind_specific_flags();
     515         870 :   return EmbeddedObjectsClearedField::decode(flags);
     516             : }
     517             : 
     518         291 : void Code::set_embedded_objects_cleared(bool flag) {
     519             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     520             :   DCHECK_IMPLIES(flag, marked_for_deoptimization());
     521             :   int32_t previous = code_data_container()->kind_specific_flags();
     522             :   int32_t updated = EmbeddedObjectsClearedField::update(previous, flag);
     523             :   code_data_container()->set_kind_specific_flags(updated);
     524         291 : }
     525             : 
     526       90669 : bool Code::deopt_already_counted() const {
     527             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     528             :   int32_t flags = code_data_container()->kind_specific_flags();
     529       90669 :   return DeoptAlreadyCountedField::decode(flags);
     530             : }
     531             : 
     532       69501 : void Code::set_deopt_already_counted(bool flag) {
     533             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     534             :   DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
     535             :   int32_t previous = code_data_container()->kind_specific_flags();
     536             :   int32_t updated = DeoptAlreadyCountedField::update(previous, flag);
     537             :   code_data_container()->set_kind_specific_flags(updated);
     538       69501 : }
     539             : 
     540             : bool Code::is_optimized_code() const { return kind() == OPTIMIZED_FUNCTION; }
     541             : bool Code::is_wasm_code() const { return kind() == WASM_FUNCTION; }
     542             : 
     543             : int Code::constant_pool_offset() const {
     544             :   if (!FLAG_enable_embedded_constant_pool) return code_comments_offset();
     545             :   return READ_INT_FIELD(*this, kConstantPoolOffsetOffset);
     546             : }
     547             : 
     548             : void Code::set_constant_pool_offset(int value) {
     549             :   if (!FLAG_enable_embedded_constant_pool) return;
     550             :   DCHECK_LE(value, InstructionSize());
     551             :   WRITE_INT_FIELD(*this, kConstantPoolOffsetOffset, value);
     552             : }
     553             : 
     554   208958188 : Address Code::constant_pool() const {
     555   208958188 :   if (!has_constant_pool()) return kNullAddress;
     556           0 :   return InstructionStart() + constant_pool_offset();
     557             : }
     558             : 
     559           8 : Address Code::code_comments() const {
     560           8 :   return InstructionStart() + code_comments_offset();
     561             : }
     562             : 
     563     3144021 : Code Code::GetCodeFromTargetAddress(Address address) {
     564             :   {
     565             :     // TODO(jgruber,v8:6666): Support embedded builtins here. We'd need to pass
     566             :     // in the current isolate.
     567     3144021 :     Address start = reinterpret_cast<Address>(Isolate::CurrentEmbeddedBlob());
     568     3144012 :     Address end = start + Isolate::CurrentEmbeddedBlobSize();
     569     3143999 :     CHECK(address < start || address >= end);
     570             :   }
     571             : 
     572             :   HeapObject code = HeapObject::FromAddress(address - Code::kHeaderSize);
     573             :   // Unchecked cast because we can't rely on the map currently
     574             :   // not being a forwarding pointer.
     575     3143999 :   return Code::unchecked_cast(code);
     576             : }
     577             : 
     578             : Code Code::GetObjectFromEntryAddress(Address location_of_address) {
     579           0 :   Address code_entry = Memory<Address>(location_of_address);
     580             :   HeapObject code = HeapObject::FromAddress(code_entry - Code::kHeaderSize);
     581             :   // Unchecked cast because we can't rely on the map currently
     582             :   // not being a forwarding pointer.
     583             :   return Code::unchecked_cast(code);
     584             : }
     585             : 
     586      382806 : bool Code::CanContainWeakObjects() {
     587      382806 :   return is_optimized_code() && can_have_weak_objects();
     588             : }
     589             : 
     590      382809 : bool Code::IsWeakObject(HeapObject object) {
     591      382809 :   return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object));
     592             : }
     593             : 
     594     5466739 : bool Code::IsWeakObjectInOptimizedCode(HeapObject object) {
     595             :   Map map = object->synchronized_map();
     596             :   InstanceType instance_type = map->instance_type();
     597     5466739 :   if (InstanceTypeChecker::IsMap(instance_type)) {
     598             :     return Map::cast(object)->CanTransition();
     599             :   }
     600     5270933 :   return InstanceTypeChecker::IsPropertyCell(instance_type) ||
     601    10380240 :          InstanceTypeChecker::IsJSReceiver(instance_type) ||
     602             :          InstanceTypeChecker::IsContext(instance_type);
     603             : }
     604             : 
     605             : // This field has to have relaxed atomic accessors because it is accessed in the
     606             : // concurrent marker.
     607     9214591 : RELAXED_INT32_ACCESSORS(CodeDataContainer, kind_specific_flags,
     608             :                         kKindSpecificFlagsOffset)
     609    15552670 : ACCESSORS(CodeDataContainer, next_code_link, Object, kNextCodeLinkOffset)
     610             : 
     611             : void CodeDataContainer::clear_padding() {
     612     1906462 :   memset(reinterpret_cast<void*>(address() + kUnalignedSize), 0,
     613             :          kSize - kUnalignedSize);
     614             : }
     615             : 
     616             : byte BytecodeArray::get(int index) const {
     617             :   DCHECK(index >= 0 && index < this->length());
     618   277610393 :   return READ_BYTE_FIELD(*this, kHeaderSize + index * kCharSize);
     619             : }
     620             : 
     621             : void BytecodeArray::set(int index, byte value) {
     622             :   DCHECK(index >= 0 && index < this->length());
     623    14273385 :   WRITE_BYTE_FIELD(*this, kHeaderSize + index * kCharSize, value);
     624             : }
     625             : 
     626             : void BytecodeArray::set_frame_size(int frame_size) {
     627             :   DCHECK_GE(frame_size, 0);
     628             :   DCHECK(IsAligned(frame_size, kSystemPointerSize));
     629     2122111 :   WRITE_INT_FIELD(*this, kFrameSizeOffset, frame_size);
     630             : }
     631             : 
     632             : int BytecodeArray::frame_size() const {
     633    30232214 :   return READ_INT_FIELD(*this, kFrameSizeOffset);
     634             : }
     635             : 
     636             : int BytecodeArray::register_count() const {
     637    30219262 :   return frame_size() / kSystemPointerSize;
     638             : }
     639             : 
     640             : void BytecodeArray::set_parameter_count(int number_of_parameters) {
     641             :   DCHECK_GE(number_of_parameters, 0);
     642             :   // Parameter count is stored as the size on stack of the parameters to allow
     643             :   // it to be used directly by generated code.
     644     4244222 :   WRITE_INT_FIELD(*this, kParameterSizeOffset,
     645     4244222 :                   (number_of_parameters << kSystemPointerSizeLog2));
     646             : }
     647             : 
     648             : interpreter::Register BytecodeArray::incoming_new_target_or_generator_register()
     649             :     const {
     650             :   int register_operand =
     651      540716 :       READ_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset);
     652      540716 :   if (register_operand == 0) {
     653             :     return interpreter::Register::invalid_value();
     654             :   } else {
     655             :     return interpreter::Register::FromOperand(register_operand);
     656             :   }
     657             : }
     658             : 
     659             : void BytecodeArray::set_incoming_new_target_or_generator_register(
     660             :     interpreter::Register incoming_new_target_or_generator_register) {
     661      115803 :   if (!incoming_new_target_or_generator_register.is_valid()) {
     662     2121538 :     WRITE_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset, 0);
     663             :   } else {
     664             :     DCHECK(incoming_new_target_or_generator_register.index() <
     665             :            register_count());
     666             :     DCHECK_NE(0, incoming_new_target_or_generator_register.ToOperand());
     667      105775 :     WRITE_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset,
     668      211550 :                     incoming_new_target_or_generator_register.ToOperand());
     669             :   }
     670             : }
     671             : 
     672             : int BytecodeArray::osr_loop_nesting_level() const {
     673       41144 :   return READ_INT8_FIELD(*this, kOSRNestingLevelOffset);
     674             : }
     675             : 
     676             : void BytecodeArray::set_osr_loop_nesting_level(int depth) {
     677             :   DCHECK(0 <= depth && depth <= AbstractCode::kMaxLoopNestingMarker);
     678             :   STATIC_ASSERT(AbstractCode::kMaxLoopNestingMarker < kMaxInt8);
     679     2165304 :   WRITE_INT8_FIELD(*this, kOSRNestingLevelOffset, depth);
     680             : }
     681             : 
     682             : BytecodeArray::Age BytecodeArray::bytecode_age() const {
     683             :   // Bytecode is aged by the concurrent marker.
     684     5403159 :   return static_cast<Age>(RELAXED_READ_INT8_FIELD(*this, kBytecodeAgeOffset));
     685             : }
     686             : 
     687             : void BytecodeArray::set_bytecode_age(BytecodeArray::Age age) {
     688             :   DCHECK_GE(age, kFirstBytecodeAge);
     689             :   DCHECK_LE(age, kLastBytecodeAge);
     690             :   STATIC_ASSERT(kLastBytecodeAge <= kMaxInt8);
     691             :   // Bytecode is aged by the concurrent marker.
     692     2122116 :   RELAXED_WRITE_INT8_FIELD(*this, kBytecodeAgeOffset, static_cast<int8_t>(age));
     693             : }
     694             : 
     695             : int BytecodeArray::parameter_count() const {
     696             :   // Parameter count is stored as the size on stack of the parameters to allow
     697             :   // it to be used directly by generated code.
     698     1745678 :   return READ_INT_FIELD(*this, kParameterSizeOffset) >> kSystemPointerSizeLog2;
     699             : }
     700             : 
     701    15589110 : ACCESSORS(BytecodeArray, constant_pool, FixedArray, kConstantPoolOffset)
     702    59496374 : ACCESSORS(BytecodeArray, handler_table, ByteArray, kHandlerTableOffset)
     703    30729677 : ACCESSORS(BytecodeArray, source_position_table, Object,
     704             :           kSourcePositionTableOffset)
     705             : 
     706     2111503 : void BytecodeArray::clear_padding() {
     707     2111503 :   int data_size = kHeaderSize + length();
     708     4223006 :   memset(reinterpret_cast<void*>(address() + data_size), 0,
     709     2111503 :          SizeFor(length()) - data_size);
     710     2111503 : }
     711             : 
     712             : Address BytecodeArray::GetFirstBytecodeAddress() {
     713    34048585 :   return ptr() - kHeapObjectTag + kHeaderSize;
     714             : }
     715             : 
     716     2622117 : bool BytecodeArray::HasSourcePositionTable() const {
     717             :   Object maybe_table = source_position_table();
     718     5244152 :   return !(maybe_table->IsUndefined() || DidSourcePositionGenerationFail());
     719             : }
     720             : 
     721             : bool BytecodeArray::DidSourcePositionGenerationFail() const {
     722             :   return source_position_table()->IsException();
     723             : }
     724             : 
     725           5 : void BytecodeArray::SetSourcePositionsFailedToCollect() {
     726           5 :   set_source_position_table(GetReadOnlyRoots().exception());
     727           5 : }
     728             : 
     729     6800557 : ByteArray BytecodeArray::SourcePositionTable() const {
     730             :   Object maybe_table = source_position_table();
     731     6800557 :   if (maybe_table->IsByteArray()) return ByteArray::cast(maybe_table);
     732             :   ReadOnlyRoots roots = GetReadOnlyRoots();
     733      228718 :   if (maybe_table->IsException(roots)) return roots.empty_byte_array();
     734             : 
     735             :   DCHECK(!maybe_table->IsUndefined(roots));
     736             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
     737             :   return SourcePositionTableWithFrameCache::cast(maybe_table)
     738             :       ->source_position_table();
     739             : }
     740             : 
     741      530027 : ByteArray BytecodeArray::SourcePositionTableIfCollected() const {
     742      530027 :   if (!HasSourcePositionTable()) return GetReadOnlyRoots().empty_byte_array();
     743             : 
     744      530021 :   return SourcePositionTable();
     745             : }
     746             : 
     747        1529 : void BytecodeArray::ClearFrameCacheFromSourcePositionTable() {
     748             :   Object maybe_table = source_position_table();
     749        3058 :   if (maybe_table->IsUndefined() || maybe_table->IsByteArray()) return;
     750             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
     751             :   set_source_position_table(SourcePositionTableWithFrameCache::cast(maybe_table)
     752           0 :                                 ->source_position_table());
     753             : }
     754             : 
     755             : int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); }
     756             : 
     757     2092015 : int BytecodeArray::SizeIncludingMetadata() {
     758             :   int size = BytecodeArraySize();
     759     2092015 :   size += constant_pool()->Size();
     760     2092027 :   size += handler_table()->Size();
     761     2092027 :   if (HasSourcePositionTable()) {
     762     4183966 :     size += SourcePositionTable()->Size();
     763             :   }
     764     2092028 :   return size;
     765             : }
     766             : 
     767      463911 : DEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
     768             : DEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
     769      463912 : DEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
     770             : DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrBytecodeOffset, Smi)
     771        9266 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
     772             : DEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi)
     773      464120 : DEFINE_DEOPT_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>)
     774             : 
     775             : DEFINE_DEOPT_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi)
     776     1461399 : DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
     777       87353 : DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
     778             : 
     779       59463 : BailoutId DeoptimizationData::BytecodeOffset(int i) {
     780       59463 :   return BailoutId(BytecodeOffsetRaw(i)->value());
     781             : }
     782             : 
     783             : void DeoptimizationData::SetBytecodeOffset(int i, BailoutId value) {
     784             :   SetBytecodeOffsetRaw(i, Smi::FromInt(value.ToInt()));
     785             : }
     786             : 
     787             : int DeoptimizationData::DeoptCount() {
     788       88767 :   return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
     789             : }
     790             : 
     791             : }  // namespace internal
     792             : }  // namespace v8
     793             : 
     794             : #include "src/objects/object-macros-undef.h"
     795             : 
     796             : #endif  // V8_OBJECTS_CODE_INL_H_

Generated by: LCOV version 1.10