LCOV - code coverage report
Current view: top level - src/objects - code-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 278 292 95.2 %
Date: 2019-01-20 Functions: 84 86 97.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/interpreter/bytecode-register.h"
      11             : #include "src/isolate.h"
      12             : #include "src/objects/dictionary.h"
      13             : #include "src/objects/instance-type-inl.h"
      14             : #include "src/objects/map-inl.h"
      15             : #include "src/objects/maybe-object-inl.h"
      16             : #include "src/objects/smi-inl.h"
      17             : #include "src/v8memory.h"
      18             : 
      19             : // Has to be the last include (doesn't have include guards):
      20             : #include "src/objects/object-macros.h"
      21             : 
      22             : namespace v8 {
      23             : namespace internal {
      24             : 
      25    10026358 : OBJECT_CONSTRUCTORS_IMPL(DeoptimizationData, FixedArray)
      26   336957336 : OBJECT_CONSTRUCTORS_IMPL(BytecodeArray, FixedArrayBase)
      27    32782758 : OBJECT_CONSTRUCTORS_IMPL(AbstractCode, HeapObject)
      28   121184480 : OBJECT_CONSTRUCTORS_IMPL(DependentCode, WeakFixedArray)
      29   294403074 : OBJECT_CONSTRUCTORS_IMPL(CodeDataContainer, HeapObject)
      30      672892 : OBJECT_CONSTRUCTORS_IMPL(SourcePositionTableWithFrameCache, Tuple2)
      31             : 
      32             : NEVER_READ_ONLY_SPACE_IMPL(AbstractCode)
      33             : 
      34    13728886 : CAST_ACCESSOR(AbstractCode)
      35   168496496 : CAST_ACCESSOR(BytecodeArray)
      36   443429471 : CAST_ACCESSOR(Code)
      37   147207280 : CAST_ACCESSOR(CodeDataContainer)
      38    60592278 : CAST_ACCESSOR(DependentCode)
      39     5013177 : CAST_ACCESSOR(DeoptimizationData)
      40      336446 : CAST_ACCESSOR(SourcePositionTableWithFrameCache)
      41             : 
      42      844275 : ACCESSORS(SourcePositionTableWithFrameCache, source_position_table, ByteArray,
      43             :           kSourcePositionTableIndex)
      44      226751 : ACCESSORS(SourcePositionTableWithFrameCache, stack_frame_cache,
      45             :           SimpleNumberDictionary, kStackFrameCacheIndex)
      46             : 
      47             : int AbstractCode::raw_instruction_size() {
      48             :   if (IsCode()) {
      49             :     return GetCode()->raw_instruction_size();
      50             :   } else {
      51             :     return GetBytecodeArray()->length();
      52             :   }
      53             : }
      54             : 
      55      661138 : int AbstractCode::InstructionSize() {
      56     1322276 :   if (IsCode()) {
      57      158264 :     return GetCode()->InstructionSize();
      58             :   } else {
      59     1005748 :     return GetBytecodeArray()->length();
      60             :   }
      61             : }
      62             : 
      63     2191504 : ByteArray AbstractCode::source_position_table() {
      64     4383008 :   if (IsCode()) {
      65      103042 :     return GetCode()->SourcePositionTable();
      66             :   } else {
      67     2088462 :     return GetBytecodeArray()->SourcePositionTable();
      68             :   }
      69             : }
      70             : 
      71       66151 : Object AbstractCode::stack_frame_cache() {
      72       66151 :   Object maybe_table;
      73      132302 :   if (IsCode()) {
      74           0 :     maybe_table = GetCode()->source_position_table();
      75             :   } else {
      76       66151 :     maybe_table = GetBytecodeArray()->source_position_table();
      77             :   }
      78       66151 :   if (maybe_table->IsSourcePositionTableWithFrameCache()) {
      79             :     return SourcePositionTableWithFrameCache::cast(maybe_table)
      80       58027 :         ->stack_frame_cache();
      81             :   }
      82        8124 :   return Smi::kZero;
      83             : }
      84             : 
      85           0 : int AbstractCode::SizeIncludingMetadata() {
      86           0 :   if (IsCode()) {
      87           0 :     return GetCode()->SizeIncludingMetadata();
      88             :   } else {
      89           0 :     return GetBytecodeArray()->SizeIncludingMetadata();
      90             :   }
      91             : }
      92          10 : int AbstractCode::ExecutableSize() {
      93          20 :   if (IsCode()) {
      94           4 :     return GetCode()->ExecutableSize();
      95             :   } else {
      96           8 :     return GetBytecodeArray()->BytecodeArraySize();
      97             :   }
      98             : }
      99             : 
     100          25 : Address AbstractCode::raw_instruction_start() {
     101          50 :   if (IsCode()) {
     102          16 :     return GetCode()->raw_instruction_start();
     103             :   } else {
     104          34 :     return GetBytecodeArray()->GetFirstBytecodeAddress();
     105             :   }
     106             : }
     107             : 
     108     1292665 : Address AbstractCode::InstructionStart() {
     109     2585330 :   if (IsCode()) {
     110      286293 :     return GetCode()->InstructionStart();
     111             :   } else {
     112     2012744 :     return GetBytecodeArray()->GetFirstBytecodeAddress();
     113             :   }
     114             : }
     115             : 
     116          15 : Address AbstractCode::raw_instruction_end() {
     117          30 :   if (IsCode()) {
     118           6 :     return GetCode()->raw_instruction_end();
     119             :   } else {
     120          36 :     return GetBytecodeArray()->GetFirstBytecodeAddress() +
     121          24 :            GetBytecodeArray()->length();
     122             :   }
     123             : }
     124             : 
     125             : Address AbstractCode::InstructionEnd() {
     126             :   if (IsCode()) {
     127             :     return GetCode()->InstructionEnd();
     128             :   } else {
     129             :     return GetBytecodeArray()->GetFirstBytecodeAddress() +
     130             :            GetBytecodeArray()->length();
     131             :   }
     132             : }
     133             : 
     134          20 : bool AbstractCode::contains(Address inner_pointer) {
     135          20 :   return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
     136             : }
     137             : 
     138       92225 : AbstractCode::Kind AbstractCode::kind() {
     139      184450 :   if (IsCode()) {
     140      177976 :     return static_cast<AbstractCode::Kind>(GetCode()->kind());
     141             :   } else {
     142             :     return INTERPRETED_FUNCTION;
     143             :   }
     144             : }
     145             : 
     146     3171560 : Code AbstractCode::GetCode() { return Code::cast(*this); }
     147             : 
     148     3677562 : BytecodeArray AbstractCode::GetBytecodeArray() {
     149     3677562 :   return BytecodeArray::cast(*this);
     150             : }
     151             : 
     152         685 : DependentCode DependentCode::next_link() {
     153        1370 :   return DependentCode::cast(Get(kNextLinkIndex)->GetHeapObjectAssumeStrong());
     154             : }
     155             : 
     156             : void DependentCode::set_next_link(DependentCode next) {
     157      219704 :   Set(kNextLinkIndex, HeapObjectReference::Strong(next));
     158             : }
     159             : 
     160     2665965 : int DependentCode::flags() { return Smi::ToInt(Get(kFlagsIndex)->ToSmi()); }
     161             : 
     162             : void DependentCode::set_flags(int flags) {
     163      625114 :   Set(kFlagsIndex, MaybeObject::FromObject(Smi::FromInt(flags)));
     164             : }
     165             : 
     166      950411 : int DependentCode::count() { return CountField::decode(flags()); }
     167             : 
     168      405712 : void DependentCode::set_count(int value) {
     169      811424 :   set_flags(CountField::update(flags(), value));
     170      405711 : }
     171             : 
     172             : DependentCode::DependencyGroup DependentCode::group() {
     173     1309852 :   return static_cast<DependencyGroup>(GroupField::decode(flags()));
     174             : }
     175             : 
     176             : void DependentCode::set_object_at(int i, MaybeObject object) {
     177      520296 :   Set(kCodesStartIndex + i, object);
     178             : }
     179             : 
     180             : MaybeObject DependentCode::object_at(int i) {
     181    84360436 :   return Get(kCodesStartIndex + i);
     182             : }
     183             : 
     184       58103 : void DependentCode::clear_at(int i) {
     185             :   Set(kCodesStartIndex + i,
     186      116206 :       HeapObjectReference::Strong(GetReadOnlyRoots().undefined_value()));
     187       58103 : }
     188             : 
     189       12396 : void DependentCode::copy(int from, int to) {
     190       12396 :   Set(kCodesStartIndex + to, Get(kCodesStartIndex + from));
     191       12396 : }
     192             : 
     193   883725560 : OBJECT_CONSTRUCTORS_IMPL(Code, HeapObject)
     194             : NEVER_READ_ONLY_SPACE_IMPL(Code)
     195             : 
     196   545301132 : INT_ACCESSORS(Code, raw_instruction_size, kInstructionSizeOffset)
     197    44651040 : INT_ACCESSORS(Code, handler_table_offset, kHandlerTableOffsetOffset)
     198             : #define CODE_ACCESSORS(name, type, offset) \
     199             :   ACCESSORS_CHECKED2(Code, name, type, offset, true, !Heap::InNewSpace(value))
     200             : #define SYNCHRONIZED_CODE_ACCESSORS(name, type, offset)           \
     201             :   SYNCHRONIZED_ACCESSORS_CHECKED2(Code, name, type, offset, true, \
     202             :                                   !Heap::InNewSpace(value))
     203             : 
     204    15739235 : CODE_ACCESSORS(relocation_info, ByteArray, kRelocationInfoOffset)
     205    24635641 : CODE_ACCESSORS(deoptimization_data, FixedArray, kDeoptimizationDataOffset)
     206   132294041 : CODE_ACCESSORS(source_position_table, Object, kSourcePositionTableOffset)
     207             : // Concurrent marker needs to access kind specific flags in code data container.
     208    67898271 : SYNCHRONIZED_CODE_ACCESSORS(code_data_container, CodeDataContainer,
     209             :                             kCodeDataContainerOffset)
     210             : #undef CODE_ACCESSORS
     211             : #undef SYNCHRONIZED_CODE_ACCESSORS
     212             : 
     213      379269 : void Code::WipeOutHeader() {
     214      379269 :   WRITE_FIELD(this, kRelocationInfoOffset, Smi::FromInt(0));
     215      379269 :   WRITE_FIELD(this, kDeoptimizationDataOffset, Smi::FromInt(0));
     216      379269 :   WRITE_FIELD(this, kSourcePositionTableOffset, Smi::FromInt(0));
     217      379269 :   WRITE_FIELD(this, kCodeDataContainerOffset, Smi::FromInt(0));
     218      379269 : }
     219             : 
     220     2200279 : void Code::clear_padding() {
     221     2200279 :   memset(reinterpret_cast<void*>(address() + kHeaderPaddingStart), 0,
     222     2200279 :          kHeaderSize - kHeaderPaddingStart);
     223             :   Address data_end =
     224     2200279 :       has_unwinding_info() ? unwinding_info_end() : raw_instruction_end();
     225             :   memset(reinterpret_cast<void*>(data_end), 0,
     226     4400558 :          CodeSize() - (data_end - address()));
     227     2200279 : }
     228             : 
     229    38347932 : ByteArray Code::SourcePositionTable() const {
     230    38347932 :   Object maybe_table = source_position_table();
     231    38347934 :   if (maybe_table->IsByteArray()) return ByteArray::cast(maybe_table);
     232             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
     233             :   return SourcePositionTableWithFrameCache::cast(maybe_table)
     234           0 :       ->source_position_table();
     235             : }
     236             : 
     237             : Object Code::next_code_link() const {
     238     9490039 :   return code_data_container()->next_code_link();
     239             : }
     240             : 
     241      785414 : void Code::set_next_code_link(Object value) {
     242      785414 :   code_data_container()->set_next_code_link(value);
     243      785414 : }
     244             : 
     245    38410815 : int Code::InstructionSize() const {
     246    38410815 :   if (is_off_heap_trampoline()) {
     247             :     DCHECK(FLAG_embedded_builtins);
     248    38309337 :     return OffHeapInstructionSize();
     249             :   }
     250      101478 :   return raw_instruction_size();
     251             : }
     252             : 
     253             : Address Code::raw_instruction_start() const {
     254   266829419 :   return FIELD_ADDR(this, kHeaderSize);
     255             : }
     256             : 
     257   245139968 : Address Code::InstructionStart() const {
     258   245139968 :   if (is_off_heap_trampoline()) {
     259             :     DCHECK(FLAG_embedded_builtins);
     260   235276716 :     return OffHeapInstructionStart();
     261             :   }
     262     9863252 :   return raw_instruction_start();
     263             : }
     264             : 
     265             : Address Code::raw_instruction_end() const {
     266     2200565 :   return raw_instruction_start() + raw_instruction_size();
     267             : }
     268             : 
     269         306 : Address Code::InstructionEnd() const {
     270         306 :   if (is_off_heap_trampoline()) {
     271             :     DCHECK(FLAG_embedded_builtins);
     272           0 :     return OffHeapInstructionEnd();
     273             :   }
     274         306 :   return raw_instruction_end();
     275             : }
     276             : 
     277             : int Code::GetUnwindingInfoSizeOffset() const {
     278             :   DCHECK(has_unwinding_info());
     279         140 :   return RoundUp(kHeaderSize + raw_instruction_size(), kInt64Size);
     280             : }
     281             : 
     282             : int Code::unwinding_info_size() const {
     283             :   DCHECK(has_unwinding_info());
     284             :   return static_cast<int>(
     285          74 :       READ_UINT64_FIELD(this, GetUnwindingInfoSizeOffset()));
     286             : }
     287             : 
     288             : void Code::set_unwinding_info_size(int value) {
     289             :   DCHECK(has_unwinding_info());
     290          28 :   WRITE_UINT64_FIELD(this, GetUnwindingInfoSizeOffset(), value);
     291             : }
     292             : 
     293             : Address Code::unwinding_info_start() const {
     294             :   DCHECK(has_unwinding_info());
     295         107 :   return FIELD_ADDR(this, GetUnwindingInfoSizeOffset()) + kInt64Size;
     296             : }
     297             : 
     298             : Address Code::unwinding_info_end() const {
     299             :   DCHECK(has_unwinding_info());
     300          69 :   return unwinding_info_start() + unwinding_info_size();
     301             : }
     302             : 
     303   536424274 : int Code::body_size() const {
     304             :   int unpadded_body_size =
     305             :       has_unwinding_info()
     306             :           ? static_cast<int>(unwinding_info_end() - raw_instruction_start())
     307   536424346 :           : raw_instruction_size();
     308   536424274 :   return RoundUp(unpadded_body_size, kObjectAlignment);
     309             : }
     310             : 
     311           0 : int Code::SizeIncludingMetadata() const {
     312             :   int size = CodeSize();
     313           0 :   size += relocation_info()->Size();
     314           0 :   size += deoptimization_data()->Size();
     315           0 :   return size;
     316             : }
     317             : 
     318             : ByteArray Code::unchecked_relocation_info() const {
     319   210360681 :   return ByteArray::unchecked_cast(READ_FIELD(this, kRelocationInfoOffset));
     320             : }
     321             : 
     322             : byte* Code::relocation_start() const {
     323             :   return unchecked_relocation_info()->GetDataStartAddress();
     324             : }
     325             : 
     326             : byte* Code::relocation_end() const {
     327           0 :   return unchecked_relocation_info()->GetDataEndAddress();
     328             : }
     329             : 
     330       85557 : int Code::relocation_size() const {
     331       85557 :   return unchecked_relocation_info()->length();
     332             : }
     333             : 
     334             : Address Code::entry() const { return raw_instruction_start(); }
     335             : 
     336    11192493 : bool Code::contains(Address inner_pointer) {
     337    11192493 :   if (is_off_heap_trampoline()) {
     338             :     DCHECK(FLAG_embedded_builtins);
     339      429452 :     if (OffHeapInstructionStart() <= inner_pointer &&
     340       96694 :         inner_pointer < OffHeapInstructionEnd()) {
     341             :       return true;
     342             :     }
     343             :   }
     344    11108462 :   return (address() <= inner_pointer) && (inner_pointer < address() + Size());
     345             : }
     346             : 
     347             : int Code::ExecutableSize() const {
     348             :   // Check that the assumptions about the layout of the code object holds.
     349             :   DCHECK_EQ(static_cast<int>(raw_instruction_start() - address()),
     350             :             Code::kHeaderSize);
     351           2 :   return raw_instruction_size() + Code::kHeaderSize;
     352             : }
     353             : 
     354             : // static
     355             : void Code::CopyRelocInfoToByteArray(ByteArray dest, const CodeDesc& desc) {
     356             :   DCHECK_EQ(dest->length(), desc.reloc_size);
     357             :   CopyBytes(dest->GetDataStartAddress(),
     358     2200327 :             desc.buffer + desc.buffer_size - desc.reloc_size,
     359     6600981 :             static_cast<size_t>(desc.reloc_size));
     360             : }
     361             : 
     362   536200770 : int Code::CodeSize() const { return SizeFor(body_size()); }
     363             : 
     364        4948 : Code::Kind Code::kind() const {
     365    68708135 :   return KindField::decode(READ_UINT32_FIELD(this, kFlagsOffset));
     366             : }
     367             : 
     368     2284895 : void Code::initialize_flags(Kind kind, bool has_unwinding_info,
     369             :                             bool is_turbofanned, int stack_slots,
     370             :                             bool is_off_heap_trampoline) {
     371     2284895 :   CHECK(0 <= stack_slots && stack_slots < StackSlotsField::kMax);
     372             :   static_assert(Code::NUMBER_OF_KINDS <= KindField::kMax + 1, "field overflow");
     373     2284895 :   uint32_t flags = HasUnwindingInfoField::encode(has_unwinding_info) |
     374     2284895 :                    KindField::encode(kind) |
     375     2284895 :                    IsTurbofannedField::encode(is_turbofanned) |
     376             :                    StackSlotsField::encode(stack_slots) |
     377     2284895 :                    IsOffHeapTrampoline::encode(is_off_heap_trampoline);
     378     2284895 :   WRITE_UINT32_FIELD(this, kFlagsOffset, flags);
     379             :   DCHECK_IMPLIES(stack_slots != 0, has_safepoint_info());
     380     2284895 : }
     381             : 
     382             : inline bool Code::is_interpreter_trampoline_builtin() const {
     383             :   bool is_interpreter_trampoline =
     384     1703871 :       (builtin_index() == Builtins::kInterpreterEntryTrampoline ||
     385    28608633 :        builtin_index() == Builtins::kInterpreterEnterBytecodeAdvance ||
     386             :        builtin_index() == Builtins::kInterpreterEnterBytecodeDispatch);
     387             :   return is_interpreter_trampoline;
     388             : }
     389             : 
     390             : inline bool Code::checks_optimization_marker() const {
     391             :   bool checks_marker =
     392             :       (builtin_index() == Builtins::kCompileLazy ||
     393             :        builtin_index() == Builtins::kInterpreterEntryTrampoline);
     394             :   return checks_marker ||
     395             :          (kind() == OPTIMIZED_FUNCTION && marked_for_deoptimization());
     396             : }
     397             : 
     398             : inline bool Code::has_tagged_params() const {
     399     1267064 :   return kind() != JS_TO_WASM_FUNCTION && kind() != C_WASM_ENTRY &&
     400             :          kind() != WASM_FUNCTION;
     401             : }
     402             : 
     403             : inline bool Code::has_unwinding_info() const {
     404   538709184 :   return HasUnwindingInfoField::decode(READ_UINT32_FIELD(this, kFlagsOffset));
     405             : }
     406             : 
     407        5653 : inline bool Code::is_turbofanned() const {
     408    76755848 :   return IsTurbofannedField::decode(READ_UINT32_FIELD(this, kFlagsOffset));
     409             : }
     410             : 
     411      644315 : inline bool Code::can_have_weak_objects() const {
     412             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     413     1288636 :   int32_t flags = code_data_container()->kind_specific_flags();
     414      644321 :   return CanHaveWeakObjectsField::decode(flags);
     415             : }
     416             : 
     417      451810 : inline void Code::set_can_have_weak_objects(bool value) {
     418             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     419      903620 :   int32_t previous = code_data_container()->kind_specific_flags();
     420             :   int32_t updated = CanHaveWeakObjectsField::update(previous, value);
     421      903620 :   code_data_container()->set_kind_specific_flags(updated);
     422      451810 : }
     423             : 
     424        7005 : inline bool Code::is_promise_rejection() const {
     425             :   DCHECK(kind() == BUILTIN);
     426       14010 :   int32_t flags = code_data_container()->kind_specific_flags();
     427        7005 :   return IsPromiseRejectionField::decode(flags);
     428             : }
     429             : 
     430         784 : inline void Code::set_is_promise_rejection(bool value) {
     431             :   DCHECK(kind() == BUILTIN);
     432        1568 :   int32_t previous = code_data_container()->kind_specific_flags();
     433             :   int32_t updated = IsPromiseRejectionField::update(previous, value);
     434        1568 :   code_data_container()->set_kind_specific_flags(updated);
     435         784 : }
     436             : 
     437        5192 : inline bool Code::is_exception_caught() const {
     438             :   DCHECK(kind() == BUILTIN);
     439       10384 :   int32_t flags = code_data_container()->kind_specific_flags();
     440        5192 :   return IsExceptionCaughtField::decode(flags);
     441             : }
     442             : 
     443          56 : inline void Code::set_is_exception_caught(bool value) {
     444             :   DCHECK(kind() == BUILTIN);
     445         112 :   int32_t previous = code_data_container()->kind_specific_flags();
     446             :   int32_t updated = IsExceptionCaughtField::update(previous, value);
     447         112 :   code_data_container()->set_kind_specific_flags(updated);
     448          56 : }
     449             : 
     450             : inline bool Code::is_off_heap_trampoline() const {
     451   332988475 :   return IsOffHeapTrampoline::decode(READ_UINT32_FIELD(this, kFlagsOffset));
     452             : }
     453             : 
     454        7005 : inline HandlerTable::CatchPrediction Code::GetBuiltinCatchPrediction() {
     455        7005 :   if (is_promise_rejection()) return HandlerTable::PROMISE;
     456        5192 :   if (is_exception_caught()) return HandlerTable::CAUGHT;
     457        5124 :   return HandlerTable::UNCAUGHT;
     458             : }
     459             : 
     460             : int Code::builtin_index() const {
     461   309955951 :   int index = READ_INT_FIELD(this, kBuiltinIndexOffset);
     462             :   DCHECK(index == -1 || Builtins::IsBuiltinId(index));
     463             :   return index;
     464             : }
     465             : 
     466             : void Code::set_builtin_index(int index) {
     467             :   DCHECK(index == -1 || Builtins::IsBuiltinId(index));
     468     2284895 :   WRITE_INT_FIELD(this, kBuiltinIndexOffset, index);
     469             : }
     470             : 
     471             : bool Code::is_builtin() const { return builtin_index() != -1; }
     472             : 
     473             : bool Code::has_safepoint_info() const {
     474    79763860 :   return is_turbofanned() || is_wasm_code();
     475             : }
     476             : 
     477             : int Code::stack_slots() const {
     478             :   DCHECK(has_safepoint_info());
     479    44288534 :   return StackSlotsField::decode(READ_UINT32_FIELD(this, kFlagsOffset));
     480             : }
     481             : 
     482             : int Code::safepoint_table_offset() const {
     483             :   DCHECK(has_safepoint_info());
     484    39799843 :   return READ_INT32_FIELD(this, kSafepointTableOffsetOffset);
     485             : }
     486             : 
     487     2265240 : void Code::set_safepoint_table_offset(int offset) {
     488     2265240 :   CHECK_LE(0, offset);
     489             :   DCHECK(has_safepoint_info() || offset == 0);  // Allow zero initialization.
     490             :   DCHECK(IsAligned(offset, static_cast<unsigned>(kIntSize)));
     491     2265240 :   WRITE_INT32_FIELD(this, kSafepointTableOffsetOffset, offset);
     492     2265240 : }
     493             : 
     494     5419944 : bool Code::marked_for_deoptimization() const {
     495             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     496    10839889 :   int32_t flags = code_data_container()->kind_specific_flags();
     497     5419945 :   return MarkedForDeoptimizationField::decode(flags);
     498             : }
     499             : 
     500      328405 : void Code::set_marked_for_deoptimization(bool flag) {
     501             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     502             :   DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
     503      656810 :   int32_t previous = code_data_container()->kind_specific_flags();
     504             :   int32_t updated = MarkedForDeoptimizationField::update(previous, flag);
     505      656810 :   code_data_container()->set_kind_specific_flags(updated);
     506      328405 : }
     507             : 
     508         808 : bool Code::embedded_objects_cleared() const {
     509             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     510        1616 :   int32_t flags = code_data_container()->kind_specific_flags();
     511         808 :   return EmbeddedObjectsClearedField::decode(flags);
     512             : }
     513             : 
     514         282 : void Code::set_embedded_objects_cleared(bool flag) {
     515             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     516             :   DCHECK_IMPLIES(flag, marked_for_deoptimization());
     517         564 :   int32_t previous = code_data_container()->kind_specific_flags();
     518             :   int32_t updated = EmbeddedObjectsClearedField::update(previous, flag);
     519         564 :   code_data_container()->set_kind_specific_flags(updated);
     520         282 : }
     521             : 
     522      180381 : bool Code::deopt_already_counted() const {
     523             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     524      360762 :   int32_t flags = code_data_container()->kind_specific_flags();
     525      180381 :   return DeoptAlreadyCountedField::decode(flags);
     526             : }
     527             : 
     528      157611 : void Code::set_deopt_already_counted(bool flag) {
     529             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     530             :   DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
     531      315222 :   int32_t previous = code_data_container()->kind_specific_flags();
     532             :   int32_t updated = DeoptAlreadyCountedField::update(previous, flag);
     533      315222 :   code_data_container()->set_kind_specific_flags(updated);
     534      157611 : }
     535             : 
     536             : bool Code::is_optimized_code() const { return kind() == OPTIMIZED_FUNCTION; }
     537             : bool Code::is_wasm_code() const { return kind() == WASM_FUNCTION; }
     538             : 
     539             : int Code::constant_pool_offset() const {
     540             :   if (!FLAG_enable_embedded_constant_pool) return code_comments_offset();
     541             :   return READ_INT_FIELD(this, kConstantPoolOffset);
     542             : }
     543             : 
     544             : void Code::set_constant_pool_offset(int value) {
     545             :   if (!FLAG_enable_embedded_constant_pool) return;
     546             :   DCHECK_LE(value, InstructionSize());
     547             :   WRITE_INT_FIELD(this, kConstantPoolOffset, value);
     548             : }
     549             : 
     550             : int Code::constant_pool_size() const {
     551             :   if (!FLAG_enable_embedded_constant_pool) return 0;
     552             :   return code_comments_offset() - constant_pool_offset();
     553             : }
     554             : Address Code::constant_pool() const {
     555             :   if (FLAG_enable_embedded_constant_pool) {
     556             :     int offset = constant_pool_offset();
     557             :     if (offset < code_comments_offset()) {
     558             :       return InstructionStart() + offset;
     559             :     }
     560             :   }
     561             :   return kNullAddress;
     562             : }
     563             : 
     564             : int Code::code_comments_offset() const {
     565    76574410 :   int offset = READ_INT_FIELD(this, kCodeCommentsOffset);
     566             :   DCHECK_LE(0, offset);
     567             :   DCHECK_LE(offset, InstructionSize());
     568             :   return offset;
     569             : }
     570             : 
     571             : void Code::set_code_comments_offset(int offset) {
     572             :   DCHECK_LE(0, offset);
     573             :   DCHECK_LE(offset, InstructionSize());
     574     2284894 :   WRITE_INT_FIELD(this, kCodeCommentsOffset, offset);
     575             : }
     576             : 
     577          10 : Address Code::code_comments() const {
     578             :   int offset = code_comments_offset();
     579          10 :   if (offset < InstructionSize()) {
     580          10 :     return InstructionStart() + offset;
     581             :   }
     582             :   return kNullAddress;
     583             : }
     584             : 
     585     3525006 : Code Code::GetCodeFromTargetAddress(Address address) {
     586             :   {
     587             :     // TODO(jgruber,v8:6666): Support embedded builtins here. We'd need to pass
     588             :     // in the current isolate.
     589     3525006 :     Address start = reinterpret_cast<Address>(Isolate::CurrentEmbeddedBlob());
     590     3525002 :     Address end = start + Isolate::CurrentEmbeddedBlobSize();
     591     3525005 :     CHECK(address < start || address >= end);
     592             :   }
     593             : 
     594             :   HeapObject code = HeapObject::FromAddress(address - Code::kHeaderSize);
     595             :   // Unchecked cast because we can't rely on the map currently
     596             :   // not being a forwarding pointer.
     597     3525005 :   return Code::unchecked_cast(code);
     598             : }
     599             : 
     600             : Code Code::GetObjectFromEntryAddress(Address location_of_address) {
     601           0 :   Address code_entry = Memory<Address>(location_of_address);
     602             :   HeapObject code = HeapObject::FromAddress(code_entry - Code::kHeaderSize);
     603             :   // Unchecked cast because we can't rely on the map currently
     604             :   // not being a forwarding pointer.
     605             :   return Code::unchecked_cast(code);
     606             : }
     607             : 
     608      646444 : bool Code::CanContainWeakObjects() {
     609      646444 :   return is_optimized_code() && can_have_weak_objects();
     610             : }
     611             : 
     612      646444 : bool Code::IsWeakObject(HeapObject object) {
     613      646444 :   return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object));
     614             : }
     615             : 
     616     5190103 : bool Code::IsWeakObjectInOptimizedCode(HeapObject object) {
     617             :   Map map = object->synchronized_map();
     618             :   InstanceType instance_type = map->instance_type();
     619     5190103 :   if (InstanceTypeChecker::IsMap(instance_type)) {
     620             :     return Map::cast(object)->CanTransition();
     621             :   }
     622     4916371 :   return InstanceTypeChecker::IsPropertyCell(instance_type) ||
     623     9104363 :          InstanceTypeChecker::IsJSReceiver(instance_type) ||
     624     5017752 :          InstanceTypeChecker::IsContext(instance_type);
     625             : }
     626             : 
     627             : // This field has to have relaxed atomic accessors because it is accessed in the
     628             : // concurrent marker.
     629    10505249 : RELAXED_INT32_ACCESSORS(CodeDataContainer, kind_specific_flags,
     630             :                         kKindSpecificFlagsOffset)
     631    40317030 : ACCESSORS(CodeDataContainer, next_code_link, Object, kNextCodeLinkOffset)
     632             : 
     633     2200371 : void CodeDataContainer::clear_padding() {
     634     2200371 :   memset(reinterpret_cast<void*>(address() + kUnalignedSize), 0,
     635     2200371 :          kSize - kUnalignedSize);
     636     2200371 : }
     637             : 
     638       66688 : byte BytecodeArray::get(int index) {
     639             :   DCHECK(index >= 0 && index < this->length());
     640   301160664 :   return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
     641             : }
     642             : 
     643             : void BytecodeArray::set(int index, byte value) {
     644             :   DCHECK(index >= 0 && index < this->length());
     645    14301404 :   WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
     646             : }
     647             : 
     648             : void BytecodeArray::set_frame_size(int frame_size) {
     649             :   DCHECK_GE(frame_size, 0);
     650             :   DCHECK(IsAligned(frame_size, kSystemPointerSize));
     651     2116378 :   WRITE_INT_FIELD(this, kFrameSizeOffset, frame_size);
     652             : }
     653             : 
     654             : int BytecodeArray::frame_size() const {
     655    29799480 :   return READ_INT_FIELD(this, kFrameSizeOffset);
     656             : }
     657             : 
     658        8619 : int BytecodeArray::register_count() const {
     659    29786596 :   return frame_size() / kSystemPointerSize;
     660             : }
     661             : 
     662             : void BytecodeArray::set_parameter_count(int number_of_parameters) {
     663             :   DCHECK_GE(number_of_parameters, 0);
     664             :   // Parameter count is stored as the size on stack of the parameters to allow
     665             :   // it to be used directly by generated code.
     666     4232742 :   WRITE_INT_FIELD(this, kParameterSizeOffset,
     667     4232742 :                   (number_of_parameters << kSystemPointerSizeLog2));
     668             : }
     669             : 
     670             : interpreter::Register BytecodeArray::incoming_new_target_or_generator_register()
     671             :     const {
     672             :   int register_operand =
     673      533670 :       READ_INT_FIELD(this, kIncomingNewTargetOrGeneratorRegisterOffset);
     674      533670 :   if (register_operand == 0) {
     675             :     return interpreter::Register::invalid_value();
     676             :   } else {
     677             :     return interpreter::Register::FromOperand(register_operand);
     678             :   }
     679             : }
     680             : 
     681             : void BytecodeArray::set_incoming_new_target_or_generator_register(
     682             :     interpreter::Register incoming_new_target_or_generator_register) {
     683      116684 :   if (!incoming_new_target_or_generator_register.is_valid()) {
     684     2115790 :     WRITE_INT_FIELD(this, kIncomingNewTargetOrGeneratorRegisterOffset, 0);
     685             :   } else {
     686             :     DCHECK(incoming_new_target_or_generator_register.index() <
     687             :            register_count());
     688             :     DCHECK_NE(0, incoming_new_target_or_generator_register.ToOperand());
     689      106719 :     WRITE_INT_FIELD(this, kIncomingNewTargetOrGeneratorRegisterOffset,
     690      213438 :                     incoming_new_target_or_generator_register.ToOperand());
     691             :   }
     692             : }
     693             : 
     694             : int BytecodeArray::interrupt_budget() const {
     695       10543 :   return READ_INT_FIELD(this, kInterruptBudgetOffset);
     696             : }
     697             : 
     698             : void BytecodeArray::set_interrupt_budget(int interrupt_budget) {
     699             :   DCHECK_GE(interrupt_budget, 0);
     700     2117117 :   WRITE_INT_FIELD(this, kInterruptBudgetOffset, interrupt_budget);
     701             : }
     702             : 
     703             : int BytecodeArray::osr_loop_nesting_level() const {
     704       42249 :   return READ_INT8_FIELD(this, kOSRNestingLevelOffset);
     705             : }
     706             : 
     707             : void BytecodeArray::set_osr_loop_nesting_level(int depth) {
     708             :   DCHECK(0 <= depth && depth <= AbstractCode::kMaxLoopNestingMarker);
     709             :   STATIC_ASSERT(AbstractCode::kMaxLoopNestingMarker < kMaxInt8);
     710     2161054 :   WRITE_INT8_FIELD(this, kOSRNestingLevelOffset, depth);
     711             : }
     712             : 
     713             : BytecodeArray::Age BytecodeArray::bytecode_age() const {
     714             :   // Bytecode is aged by the concurrent marker.
     715    10513318 :   return static_cast<Age>(RELAXED_READ_INT8_FIELD(this, kBytecodeAgeOffset));
     716             : }
     717             : 
     718             : void BytecodeArray::set_bytecode_age(BytecodeArray::Age age) {
     719             :   DCHECK_GE(age, kFirstBytecodeAge);
     720             :   DCHECK_LE(age, kLastBytecodeAge);
     721             :   STATIC_ASSERT(kLastBytecodeAge <= kMaxInt8);
     722             :   // Bytecode is aged by the concurrent marker.
     723     2116376 :   RELAXED_WRITE_INT8_FIELD(this, kBytecodeAgeOffset, static_cast<int8_t>(age));
     724             : }
     725             : 
     726             : int BytecodeArray::parameter_count() const {
     727             :   // Parameter count is stored as the size on stack of the parameters to allow
     728             :   // it to be used directly by generated code.
     729     1716325 :   return READ_INT_FIELD(this, kParameterSizeOffset) >> kSystemPointerSizeLog2;
     730             : }
     731             : 
     732    26254994 : ACCESSORS(BytecodeArray, constant_pool, FixedArray, kConstantPoolOffset)
     733   134997084 : ACCESSORS(BytecodeArray, handler_table, ByteArray, kHandlerTableOffset)
     734    41940668 : ACCESSORS(BytecodeArray, source_position_table, Object,
     735             :           kSourcePositionTableOffset)
     736             : 
     737     2105830 : void BytecodeArray::clear_padding() {
     738     2105837 :   int data_size = kHeaderSize + length();
     739     2105841 :   memset(reinterpret_cast<void*>(address() + data_size), 0,
     740     4211682 :          SizeFor(length()) - data_size);
     741     2105841 : }
     742             : 
     743             : Address BytecodeArray::GetFirstBytecodeAddress() {
     744    34569987 :   return ptr() - kHeapObjectTag + kHeaderSize;
     745             : }
     746             : 
     747     6838682 : ByteArray BytecodeArray::SourcePositionTable() {
     748     6838682 :   Object maybe_table = source_position_table();
     749     6838701 :   if (maybe_table->IsByteArray()) return ByteArray::cast(maybe_table);
     750             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
     751             :   return SourcePositionTableWithFrameCache::cast(maybe_table)
     752      267865 :       ->source_position_table();
     753             : }
     754             : 
     755        1485 : void BytecodeArray::ClearFrameCacheFromSourcePositionTable() {
     756        1485 :   Object maybe_table = source_position_table();
     757        2970 :   if (maybe_table->IsByteArray()) return;
     758             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
     759             :   set_source_position_table(SourcePositionTableWithFrameCache::cast(maybe_table)
     760           0 :                                 ->source_position_table());
     761             : }
     762             : 
     763     4172771 : int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); }
     764             : 
     765     2086370 : int BytecodeArray::SizeIncludingMetadata() {
     766     2086370 :   int size = BytecodeArraySize();
     767     2086376 :   size += constant_pool()->Size();
     768     2086373 :   size += handler_table()->Size();
     769     2086383 :   size += SourcePositionTable()->Size();
     770     2086387 :   return size;
     771             : }
     772             : 
     773             : BailoutId DeoptimizationData::BytecodeOffset(int i) {
     774      299254 :   return BailoutId(BytecodeOffsetRaw(i)->value());
     775             : }
     776             : 
     777             : void DeoptimizationData::SetBytecodeOffset(int i, BailoutId value) {
     778     2702441 :   SetBytecodeOffsetRaw(i, Smi::FromInt(value.ToInt()));
     779             : }
     780             : 
     781       92656 : int DeoptimizationData::DeoptCount() {
     782       92656 :   return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
     783             : }
     784             : 
     785             : }  // namespace internal
     786             : }  // namespace v8
     787             : 
     788             : #include "src/objects/object-macros-undef.h"
     789             : 
     790             : #endif  // V8_OBJECTS_CODE_INL_H_

Generated by: LCOV version 1.10