LCOV - code coverage report
Current view: top level - src/objects - code-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 296 311 95.2 %
Date: 2019-02-19 Functions: 100 102 98.0 %

          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     9375948 : OBJECT_CONSTRUCTORS_IMPL(DeoptimizationData, FixedArray)
      28   330080668 : OBJECT_CONSTRUCTORS_IMPL(BytecodeArray, FixedArrayBase)
      29    32878882 : OBJECT_CONSTRUCTORS_IMPL(AbstractCode, HeapObject)
      30   113458252 : OBJECT_CONSTRUCTORS_IMPL(DependentCode, WeakFixedArray)
      31   270846752 : OBJECT_CONSTRUCTORS_IMPL(CodeDataContainer, HeapObject)
      32      594114 : OBJECT_CONSTRUCTORS_IMPL(SourcePositionTableWithFrameCache, Tuple2)
      33             : 
      34             : NEVER_READ_ONLY_SPACE_IMPL(AbstractCode)
      35             : 
      36    16494598 : CAST_ACCESSOR(AbstractCode)
      37   165048574 : CAST_ACCESSOR(BytecodeArray)
      38   569708919 : CAST_ACCESSOR(Code)
      39   135988811 : CAST_ACCESSOR(CodeDataContainer)
      40    56730615 : CAST_ACCESSOR(DependentCode)
      41     4687973 : CAST_ACCESSOR(DeoptimizationData)
      42      297057 : CAST_ACCESSOR(SourcePositionTableWithFrameCache)
      43             : 
      44      724399 : ACCESSORS(SourcePositionTableWithFrameCache, source_position_table, ByteArray,
      45             :           kSourcePositionTableIndex)
      46      224457 : 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      660830 : int AbstractCode::InstructionSize() {
      58     1321660 :   if (IsCode()) {
      59      158024 :     return GetCode()->InstructionSize();
      60             :   } else {
      61     1005612 :     return GetBytecodeArray()->length();
      62             :   }
      63             : }
      64             : 
      65     2134993 : ByteArray AbstractCode::source_position_table() {
      66     4269986 :   if (IsCode()) {
      67      103104 :     return GetCode()->SourcePositionTable();
      68             :   } else {
      69     2031889 :     return GetBytecodeArray()->SourcePositionTable();
      70             :   }
      71             : }
      72             : 
      73       76951 : Object AbstractCode::stack_frame_cache() {
      74       76951 :   Object maybe_table;
      75      153902 :   if (IsCode()) {
      76           0 :     maybe_table = GetCode()->source_position_table();
      77             :   } else {
      78      153902 :     maybe_table = GetBytecodeArray()->source_position_table();
      79             :   }
      80       76951 :   if (maybe_table->IsSourcePositionTableWithFrameCache()) {
      81             :     return SourcePositionTableWithFrameCache::cast(maybe_table)
      82       60669 :         ->stack_frame_cache();
      83             :   }
      84       16282 :   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           4 :     return GetCode()->ExecutableSize();
      97             :   } else {
      98           8 :     return GetBytecodeArray()->BytecodeArraySize();
      99             :   }
     100             : }
     101             : 
     102          24 : Address AbstractCode::raw_instruction_start() {
     103          48 :   if (IsCode()) {
     104          14 :     return GetCode()->raw_instruction_start();
     105             :   } else {
     106          34 :     return GetBytecodeArray()->GetFirstBytecodeAddress();
     107             :   }
     108             : }
     109             : 
     110     1292280 : Address AbstractCode::InstructionStart() {
     111     2584560 :   if (IsCode()) {
     112      286034 :     return GetCode()->InstructionStart();
     113             :   } else {
     114     2012492 :     return GetBytecodeArray()->GetFirstBytecodeAddress();
     115             :   }
     116             : }
     117             : 
     118          15 : Address AbstractCode::raw_instruction_end() {
     119          30 :   if (IsCode()) {
     120           6 :     return GetCode()->raw_instruction_end();
     121             :   } else {
     122          36 :     return GetBytecodeArray()->GetFirstBytecodeAddress() +
     123          24 :            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          20 : bool AbstractCode::contains(Address inner_pointer) {
     137          20 :   return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
     138             : }
     139             : 
     140       92050 : AbstractCode::Kind AbstractCode::kind() {
     141      184100 :   if (IsCode()) {
     142      177610 :     return static_cast<AbstractCode::Kind>(GetCode()->kind());
     143             :   } else {
     144             :     return INTERPRETED_FUNCTION;
     145             :   }
     146             : }
     147             : 
     148     2894850 : Code AbstractCode::GetCode() { return Code::cast(*this); }
     149             : 
     150     3629507 : BytecodeArray AbstractCode::GetBytecodeArray() {
     151     3629507 :   return BytecodeArray::cast(*this);
     152             : }
     153             : 
     154       66903 : DependentCode DependentCode::next_link() {
     155      133806 :   return DependentCode::cast(Get(kNextLinkIndex)->GetHeapObjectAssumeStrong());
     156             : }
     157             : 
     158             : void DependentCode::set_next_link(DependentCode next) {
     159       94525 :   Set(kNextLinkIndex, HeapObjectReference::Strong(next));
     160             : }
     161             : 
     162     1728416 : int DependentCode::flags() { return Smi::ToInt(Get(kFlagsIndex)->ToSmi()); }
     163             : 
     164             : void DependentCode::set_flags(int flags) {
     165      327751 :   Set(kFlagsIndex, MaybeObject::FromObject(Smi::FromInt(flags)));
     166             : }
     167             : 
     168      554063 : int DependentCode::count() { return CountField::decode(flags()); }
     169             : 
     170      243338 : void DependentCode::set_count(int value) {
     171      486676 :   set_flags(CountField::update(flags(), value));
     172      243338 : }
     173             : 
     174             : DependentCode::DependencyGroup DependentCode::group() {
     175      931024 :   return static_cast<DependencyGroup>(GroupField::decode(flags()));
     176             : }
     177             : 
     178             : void DependentCode::set_object_at(int i, MaybeObject object) {
     179      272003 :   Set(kCodesStartIndex + i, object);
     180             : }
     181             : 
     182             : MaybeObject DependentCode::object_at(int i) {
     183    45707679 :   return Get(kCodesStartIndex + i);
     184             : }
     185             : 
     186       17928 : void DependentCode::clear_at(int i) {
     187             :   Set(kCodesStartIndex + i,
     188       35856 :       HeapObjectReference::Strong(GetReadOnlyRoots().undefined_value()));
     189       17928 : }
     190             : 
     191        3106 : void DependentCode::copy(int from, int to) {
     192        3106 :   Set(kCodesStartIndex + to, Get(kCodesStartIndex + from));
     193        3106 : }
     194             : 
     195  1133655981 : OBJECT_CONSTRUCTORS_IMPL(Code, HeapObject)
     196             : NEVER_READ_ONLY_SPACE_IMPL(Code)
     197             : 
     198   496309562 : INT_ACCESSORS(Code, raw_instruction_size, kInstructionSizeOffset)
     199     4922499 : INT_ACCESSORS(Code, safepoint_table_offset, kSafepointTableOffsetOffset)
     200     6709157 : INT_ACCESSORS(Code, handler_table_offset, kHandlerTableOffsetOffset)
     201     6116335 : 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    14104630 : CODE_ACCESSORS(relocation_info, ByteArray, kRelocationInfoOffset)
     210    22937480 : CODE_ACCESSORS(deoptimization_data, FixedArray, kDeoptimizationDataOffset)
     211    11515652 : CODE_ACCESSORS(source_position_table, Object, kSourcePositionTableOffset)
     212             : // Concurrent marker needs to access kind specific flags in code data container.
     213    61079663 : SYNCHRONIZED_CODE_ACCESSORS(code_data_container, CodeDataContainer,
     214             :                             kCodeDataContainerOffset)
     215             : #undef CODE_ACCESSORS
     216             : #undef SYNCHRONIZED_CODE_ACCESSORS
     217             : 
     218      386055 : void Code::WipeOutHeader() {
     219      386055 :   WRITE_FIELD(*this, kRelocationInfoOffset, Smi::FromInt(0));
     220      386055 :   WRITE_FIELD(*this, kDeoptimizationDataOffset, Smi::FromInt(0));
     221      386055 :   WRITE_FIELD(*this, kSourcePositionTableOffset, Smi::FromInt(0));
     222      386055 :   WRITE_FIELD(*this, kCodeDataContainerOffset, Smi::FromInt(0));
     223      386055 : }
     224             : 
     225     1893229 : void Code::clear_padding() {
     226     1893229 :   memset(reinterpret_cast<void*>(address() + kHeaderPaddingStart), 0,
     227     1893229 :          kHeaderSize - kHeaderPaddingStart);
     228             :   Address data_end =
     229     1893229 :       has_unwinding_info() ? unwinding_info_end() : raw_instruction_end();
     230             :   memset(reinterpret_cast<void*>(data_end), 0,
     231     3786458 :          CodeSize() - (data_end - address()));
     232     1893229 : }
     233             : 
     234      109438 : ByteArray Code::SourcePositionTable() const {
     235      109438 :   Object maybe_table = source_position_table();
     236      109438 :   if (maybe_table->IsByteArray()) return ByteArray::cast(maybe_table);
     237             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
     238             :   return SourcePositionTableWithFrameCache::cast(maybe_table)
     239           0 :       ->source_position_table();
     240             : }
     241             : 
     242             : Object Code::next_code_link() const {
     243    17259500 :   return code_data_container()->next_code_link();
     244             : }
     245             : 
     246      765743 : void Code::set_next_code_link(Object value) {
     247      765743 :   code_data_container()->set_next_code_link(value);
     248      765743 : }
     249             : 
     250      168979 : int Code::InstructionSize() const {
     251      168979 :   if (is_off_heap_trampoline()) {
     252             :     DCHECK(FLAG_embedded_builtins);
     253       67549 :     return OffHeapInstructionSize();
     254             :   }
     255      101430 :   return raw_instruction_size();
     256             : }
     257             : 
     258      488936 : Address Code::raw_instruction_start() const {
     259   294470821 :   return FIELD_ADDR(*this, kHeaderSize);
     260             : }
     261             : 
     262   164037553 : Address Code::InstructionStart() const {
     263   164037553 :   if (is_off_heap_trampoline()) {
     264             :     DCHECK(FLAG_embedded_builtins);
     265   154391176 :     return OffHeapInstructionStart();
     266             :   }
     267     9646377 :   return raw_instruction_start();
     268             : }
     269             : 
     270             : Address Code::raw_instruction_end() const {
     271     1893457 :   return raw_instruction_start() + raw_instruction_size();
     272             : }
     273             : 
     274         247 : Address Code::InstructionEnd() const {
     275         247 :   if (is_off_heap_trampoline()) {
     276             :     DCHECK(FLAG_embedded_builtins);
     277           0 :     return OffHeapInstructionEnd();
     278             :   }
     279         247 :   return raw_instruction_end();
     280             : }
     281             : 
     282             : int Code::GetUnwindingInfoSizeOffset() const {
     283             :   DCHECK(has_unwinding_info());
     284         134 :   return RoundUp(kHeaderSize + raw_instruction_size(), kInt64Size);
     285             : }
     286             : 
     287             : int Code::unwinding_info_size() const {
     288             :   DCHECK(has_unwinding_info());
     289             :   return static_cast<int>(
     290          70 :       READ_UINT64_FIELD(*this, GetUnwindingInfoSizeOffset()));
     291             : }
     292             : 
     293             : void Code::set_unwinding_info_size(int value) {
     294             :   DCHECK(has_unwinding_info());
     295          27 :   WRITE_UINT64_FIELD(*this, GetUnwindingInfoSizeOffset(), value);
     296             : }
     297             : 
     298             : Address Code::unwinding_info_start() const {
     299             :   DCHECK(has_unwinding_info());
     300         102 :   return FIELD_ADDR(*this, GetUnwindingInfoSizeOffset()) + kInt64Size;
     301             : }
     302             : 
     303             : Address Code::unwinding_info_end() const {
     304             :   DCHECK(has_unwinding_info());
     305          65 :   return unwinding_info_start() + unwinding_info_size();
     306             : }
     307             : 
     308   488704891 : int Code::body_size() const {
     309             :   int unpadded_body_size =
     310             :       has_unwinding_info()
     311             :           ? static_cast<int>(unwinding_info_end() - raw_instruction_start())
     312   488704957 :           : raw_instruction_size();
     313   488704891 :   return RoundUp(unpadded_body_size, kObjectAlignment);
     314             : }
     315             : 
     316           0 : int Code::SizeIncludingMetadata() const {
     317             :   int size = CodeSize();
     318           0 :   size += relocation_info()->Size();
     319           0 :   size += deoptimization_data()->Size();
     320           0 :   return size;
     321             : }
     322             : 
     323             : ByteArray Code::unchecked_relocation_info() const {
     324   215962023 :   return ByteArray::unchecked_cast(READ_FIELD(*this, kRelocationInfoOffset));
     325             : }
     326             : 
     327             : byte* Code::relocation_start() const {
     328             :   return unchecked_relocation_info()->GetDataStartAddress();
     329             : }
     330             : 
     331             : byte* Code::relocation_end() const {
     332           0 :   return unchecked_relocation_info()->GetDataEndAddress();
     333             : }
     334             : 
     335       85033 : int Code::relocation_size() const {
     336       85033 :   return unchecked_relocation_info()->length();
     337             : }
     338             : 
     339             : Address Code::entry() const { return raw_instruction_start(); }
     340             : 
     341    10467890 : bool Code::contains(Address inner_pointer) {
     342    10467890 :   if (is_off_heap_trampoline()) {
     343             :     DCHECK(FLAG_embedded_builtins);
     344      430715 :     if (OffHeapInstructionStart() <= inner_pointer &&
     345       95506 :         inner_pointer < OffHeapInstructionEnd()) {
     346             :       return true;
     347             :     }
     348             :   }
     349    10384495 :   return (address() <= inner_pointer) && (inner_pointer < address() + Size());
     350             : }
     351             : 
     352             : int Code::ExecutableSize() const {
     353             :   // Check that the assumptions about the layout of the code object holds.
     354             :   DCHECK_EQ(static_cast<int>(raw_instruction_start() - address()),
     355             :             Code::kHeaderSize);
     356           2 :   return raw_instruction_size() + Code::kHeaderSize;
     357             : }
     358             : 
     359             : // static
     360             : void Code::CopyRelocInfoToByteArray(ByteArray dest, const CodeDesc& desc) {
     361             :   DCHECK_EQ(dest->length(), desc.reloc_size);
     362             :   CopyBytes(dest->GetDataStartAddress(),
     363     1893285 :             desc.buffer + desc.buffer_size - desc.reloc_size,
     364     5679855 :             static_cast<size_t>(desc.reloc_size));
     365             : }
     366             : 
     367   488493762 : int Code::CodeSize() const { return SizeFor(body_size()); }
     368             : 
     369        5017 : Code::Kind Code::kind() const {
     370    68476658 :   return KindField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     371             : }
     372             : 
     373     1977509 : void Code::initialize_flags(Kind kind, bool has_unwinding_info,
     374             :                             bool is_turbofanned, int stack_slots,
     375             :                             bool is_off_heap_trampoline) {
     376     1977509 :   CHECK(0 <= stack_slots && stack_slots < StackSlotsField::kMax);
     377             :   static_assert(Code::NUMBER_OF_KINDS <= KindField::kMax + 1, "field overflow");
     378     1977509 :   uint32_t flags = HasUnwindingInfoField::encode(has_unwinding_info) |
     379     1977509 :                    KindField::encode(kind) |
     380     1977509 :                    IsTurbofannedField::encode(is_turbofanned) |
     381             :                    StackSlotsField::encode(stack_slots) |
     382     1977509 :                    IsOffHeapTrampoline::encode(is_off_heap_trampoline);
     383     1977509 :   WRITE_UINT32_FIELD(*this, kFlagsOffset, flags);
     384             :   DCHECK_IMPLIES(stack_slots != 0, has_safepoint_info());
     385     1977509 : }
     386             : 
     387             : inline bool Code::is_interpreter_trampoline_builtin() const {
     388             :   bool is_interpreter_trampoline =
     389     1604287 :       (builtin_index() == Builtins::kInterpreterEntryTrampoline ||
     390    30115724 :        builtin_index() == Builtins::kInterpreterEnterBytecodeAdvance ||
     391             :        builtin_index() == Builtins::kInterpreterEnterBytecodeDispatch);
     392             :   return is_interpreter_trampoline;
     393             : }
     394             : 
     395             : inline bool Code::checks_optimization_marker() const {
     396             :   bool checks_marker =
     397             :       (builtin_index() == Builtins::kCompileLazy ||
     398             :        builtin_index() == Builtins::kInterpreterEntryTrampoline);
     399             :   return checks_marker ||
     400             :          (kind() == OPTIMIZED_FUNCTION && marked_for_deoptimization());
     401             : }
     402             : 
     403             : inline bool Code::has_tagged_params() const {
     404     1215491 :   return kind() != JS_TO_WASM_FUNCTION && kind() != C_WASM_ENTRY &&
     405             :          kind() != WASM_FUNCTION;
     406             : }
     407             : 
     408             : inline bool Code::has_unwinding_info() const {
     409   490682414 :   return HasUnwindingInfoField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     410             : }
     411             : 
     412        4745 : inline bool Code::is_turbofanned() const {
     413      228295 :   return IsTurbofannedField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     414             : }
     415             : 
     416      499792 : inline bool Code::can_have_weak_objects() const {
     417             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     418      999582 :   int32_t flags = code_data_container()->kind_specific_flags();
     419      499790 :   return CanHaveWeakObjectsField::decode(flags);
     420             : }
     421             : 
     422      453149 : inline void Code::set_can_have_weak_objects(bool value) {
     423             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     424      906298 :   int32_t previous = code_data_container()->kind_specific_flags();
     425             :   int32_t updated = CanHaveWeakObjectsField::update(previous, value);
     426      906298 :   code_data_container()->set_kind_specific_flags(updated);
     427      453149 : }
     428             : 
     429        6975 : inline bool Code::is_promise_rejection() const {
     430             :   DCHECK(kind() == BUILTIN);
     431       13950 :   int32_t flags = code_data_container()->kind_specific_flags();
     432        6975 :   return IsPromiseRejectionField::decode(flags);
     433             : }
     434             : 
     435         784 : inline void Code::set_is_promise_rejection(bool value) {
     436             :   DCHECK(kind() == BUILTIN);
     437         784 :   int32_t previous = code_data_container()->kind_specific_flags();
     438         784 :   int32_t updated = IsPromiseRejectionField::update(previous, value);
     439         784 :   code_data_container()->set_kind_specific_flags(updated);
     440         784 : }
     441             : 
     442        5162 : inline bool Code::is_exception_caught() const {
     443             :   DCHECK(kind() == BUILTIN);
     444       10324 :   int32_t flags = code_data_container()->kind_specific_flags();
     445        5162 :   return IsExceptionCaughtField::decode(flags);
     446             : }
     447             : 
     448          56 : inline void Code::set_is_exception_caught(bool value) {
     449             :   DCHECK(kind() == BUILTIN);
     450          56 :   int32_t previous = code_data_container()->kind_specific_flags();
     451          56 :   int32_t updated = IsExceptionCaughtField::update(previous, value);
     452          56 :   code_data_container()->set_kind_specific_flags(updated);
     453          56 : }
     454             : 
     455             : inline bool Code::is_off_heap_trampoline() const {
     456   205659341 :   return IsOffHeapTrampoline::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     457             : }
     458             : 
     459        6975 : inline HandlerTable::CatchPrediction Code::GetBuiltinCatchPrediction() {
     460        6975 :   if (is_promise_rejection()) return HandlerTable::PROMISE;
     461        5162 :   if (is_exception_caught()) return HandlerTable::CAUGHT;
     462        5094 :   return HandlerTable::UNCAUGHT;
     463             : }
     464             : 
     465      832384 : int Code::builtin_index() const {
     466   227386956 :   int index = READ_INT_FIELD(*this, kBuiltinIndexOffset);
     467             :   DCHECK(index == -1 || Builtins::IsBuiltinId(index));
     468      832384 :   return index;
     469             : }
     470             : 
     471             : void Code::set_builtin_index(int index) {
     472             :   DCHECK(index == -1 || Builtins::IsBuiltinId(index));
     473     1977509 :   WRITE_INT_FIELD(*this, kBuiltinIndexOffset, index);
     474             : }
     475             : 
     476      416192 : bool Code::is_builtin() const { return builtin_index() != -1; }
     477             : 
     478             : bool Code::has_safepoint_info() const {
     479      109551 :   return is_turbofanned() || is_wasm_code();
     480             : }
     481             : 
     482             : int Code::stack_slots() const {
     483             :   DCHECK(has_safepoint_info());
     484     7365079 :   return StackSlotsField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     485             : }
     486             : 
     487     4968258 : bool Code::marked_for_deoptimization() const {
     488             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     489     9936516 :   int32_t flags = code_data_container()->kind_specific_flags();
     490     4968258 :   return MarkedForDeoptimizationField::decode(flags);
     491             : }
     492             : 
     493      309524 : void Code::set_marked_for_deoptimization(bool flag) {
     494             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     495             :   DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
     496      619048 :   int32_t previous = code_data_container()->kind_specific_flags();
     497             :   int32_t updated = MarkedForDeoptimizationField::update(previous, flag);
     498      619048 :   code_data_container()->set_kind_specific_flags(updated);
     499      309524 : }
     500             : 
     501         832 : bool Code::embedded_objects_cleared() const {
     502             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     503        1664 :   int32_t flags = code_data_container()->kind_specific_flags();
     504         832 :   return EmbeddedObjectsClearedField::decode(flags);
     505             : }
     506             : 
     507         266 : void Code::set_embedded_objects_cleared(bool flag) {
     508             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     509             :   DCHECK_IMPLIES(flag, marked_for_deoptimization());
     510         532 :   int32_t previous = code_data_container()->kind_specific_flags();
     511             :   int32_t updated = EmbeddedObjectsClearedField::update(previous, flag);
     512         532 :   code_data_container()->set_kind_specific_flags(updated);
     513         266 : }
     514             : 
     515       82157 : bool Code::deopt_already_counted() const {
     516             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     517      164314 :   int32_t flags = code_data_container()->kind_specific_flags();
     518       82157 :   return DeoptAlreadyCountedField::decode(flags);
     519             : }
     520             : 
     521       61344 : void Code::set_deopt_already_counted(bool flag) {
     522             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     523             :   DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
     524      122688 :   int32_t previous = code_data_container()->kind_specific_flags();
     525             :   int32_t updated = DeoptAlreadyCountedField::update(previous, flag);
     526      122688 :   code_data_container()->set_kind_specific_flags(updated);
     527       61344 : }
     528             : 
     529             : bool Code::is_optimized_code() const { return kind() == OPTIMIZED_FUNCTION; }
     530             : bool Code::is_wasm_code() const { return kind() == WASM_FUNCTION; }
     531             : 
     532             : int Code::constant_pool_offset() const {
     533             :   if (!FLAG_enable_embedded_constant_pool) return code_comments_offset();
     534             :   return READ_INT_FIELD(*this, kConstantPoolOffsetOffset);
     535             : }
     536             : 
     537             : void Code::set_constant_pool_offset(int value) {
     538             :   if (!FLAG_enable_embedded_constant_pool) return;
     539             :   DCHECK_LE(value, InstructionSize());
     540             :   WRITE_INT_FIELD(*this, kConstantPoolOffsetOffset, value);
     541             : }
     542             : 
     543   214877137 : Address Code::constant_pool() const {
     544   214877137 :   if (!has_constant_pool()) return kNullAddress;
     545           0 :   return InstructionStart() + constant_pool_offset();
     546             : }
     547             : 
     548           8 : Address Code::code_comments() const {
     549           8 :   if (!has_code_comments()) return kNullAddress;
     550          16 :   return InstructionStart() + code_comments_offset();
     551             : }
     552             : 
     553     3315994 : Code Code::GetCodeFromTargetAddress(Address address) {
     554             :   {
     555             :     // TODO(jgruber,v8:6666): Support embedded builtins here. We'd need to pass
     556             :     // in the current isolate.
     557     3315994 :     Address start = reinterpret_cast<Address>(Isolate::CurrentEmbeddedBlob());
     558     3316000 :     Address end = start + Isolate::CurrentEmbeddedBlobSize();
     559     3315994 :     CHECK(address < start || address >= end);
     560             :   }
     561             : 
     562      416192 :   HeapObject code = HeapObject::FromAddress(address - Code::kHeaderSize);
     563             :   // Unchecked cast because we can't rely on the map currently
     564             :   // not being a forwarding pointer.
     565     3315994 :   return Code::unchecked_cast(code);
     566             : }
     567             : 
     568             : Code Code::GetObjectFromEntryAddress(Address location_of_address) {
     569           0 :   Address code_entry = Memory<Address>(location_of_address);
     570             :   HeapObject code = HeapObject::FromAddress(code_entry - Code::kHeaderSize);
     571             :   // Unchecked cast because we can't rely on the map currently
     572             :   // not being a forwarding pointer.
     573             :   return Code::unchecked_cast(code);
     574             : }
     575             : 
     576      501021 : bool Code::CanContainWeakObjects() {
     577      501021 :   return is_optimized_code() && can_have_weak_objects();
     578             : }
     579             : 
     580      501014 : bool Code::IsWeakObject(HeapObject object) {
     581      501014 :   return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object));
     582             : }
     583             : 
     584     5554961 : bool Code::IsWeakObjectInOptimizedCode(HeapObject object) {
     585             :   Map map = object->synchronized_map();
     586             :   InstanceType instance_type = map->instance_type();
     587     5554961 :   if (InstanceTypeChecker::IsMap(instance_type)) {
     588             :     return Map::cast(object)->CanTransition();
     589             :   }
     590     5336992 :   return InstanceTypeChecker::IsPropertyCell(instance_type) ||
     591    10509993 :          InstanceTypeChecker::IsJSReceiver(instance_type) ||
     592     5387026 :          InstanceTypeChecker::IsContext(instance_type);
     593             : }
     594             : 
     595             : // This field has to have relaxed atomic accessors because it is accessed in the
     596             : // concurrent marker.
     597     9275288 : RELAXED_INT32_ACCESSORS(CodeDataContainer, kind_specific_flags,
     598             :                         kKindSpecificFlagsOffset)
     599    19184931 : ACCESSORS(CodeDataContainer, next_code_link, Object, kNextCodeLinkOffset)
     600             : 
     601     1893268 : void CodeDataContainer::clear_padding() {
     602     1893268 :   memset(reinterpret_cast<void*>(address() + kUnalignedSize), 0,
     603     1893268 :          kSize - kUnalignedSize);
     604     1893268 : }
     605             : 
     606       66643 : byte BytecodeArray::get(int index) const {
     607             :   DCHECK(index >= 0 && index < this->length());
     608   304174404 :   return READ_BYTE_FIELD(*this, kHeaderSize + index * kCharSize);
     609             : }
     610             : 
     611             : void BytecodeArray::set(int index, byte value) {
     612             :   DCHECK(index >= 0 && index < this->length());
     613    14273890 :   WRITE_BYTE_FIELD(*this, kHeaderSize + index * kCharSize, value);
     614             : }
     615             : 
     616             : void BytecodeArray::set_frame_size(int frame_size) {
     617             :   DCHECK_GE(frame_size, 0);
     618             :   DCHECK(IsAligned(frame_size, kSystemPointerSize));
     619     2093560 :   WRITE_INT_FIELD(*this, kFrameSizeOffset, frame_size);
     620             : }
     621             : 
     622             : int BytecodeArray::frame_size() const {
     623    30972073 :   return READ_INT_FIELD(*this, kFrameSizeOffset);
     624             : }
     625             : 
     626        8653 : int BytecodeArray::register_count() const {
     627    30959145 :   return frame_size() / kSystemPointerSize;
     628             : }
     629             : 
     630             : void BytecodeArray::set_parameter_count(int number_of_parameters) {
     631             :   DCHECK_GE(number_of_parameters, 0);
     632             :   // Parameter count is stored as the size on stack of the parameters to allow
     633             :   // it to be used directly by generated code.
     634     4187114 :   WRITE_INT_FIELD(*this, kParameterSizeOffset,
     635     4187114 :                   (number_of_parameters << kSystemPointerSizeLog2));
     636             : }
     637             : 
     638             : interpreter::Register BytecodeArray::incoming_new_target_or_generator_register()
     639             :     const {
     640             :   int register_operand =
     641      533484 :       READ_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset);
     642      533484 :   if (register_operand == 0) {
     643             :     return interpreter::Register::invalid_value();
     644             :   } else {
     645             :     return interpreter::Register::FromOperand(register_operand);
     646             :   }
     647             : }
     648             : 
     649             : void BytecodeArray::set_incoming_new_target_or_generator_register(
     650             :     interpreter::Register incoming_new_target_or_generator_register) {
     651      116101 :   if (!incoming_new_target_or_generator_register.is_valid()) {
     652     2092984 :     WRITE_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset, 0);
     653             :   } else {
     654             :     DCHECK(incoming_new_target_or_generator_register.index() <
     655             :            register_count());
     656             :     DCHECK_NE(0, incoming_new_target_or_generator_register.ToOperand());
     657      106097 :     WRITE_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset,
     658      212194 :                     incoming_new_target_or_generator_register.ToOperand());
     659             :   }
     660             : }
     661             : 
     662             : int BytecodeArray::interrupt_budget() const {
     663       10582 :   return READ_INT_FIELD(*this, kInterruptBudgetOffset);
     664             : }
     665             : 
     666             : void BytecodeArray::set_interrupt_budget(int interrupt_budget) {
     667             :   DCHECK_GE(interrupt_budget, 0);
     668     2094298 :   WRITE_INT_FIELD(*this, kInterruptBudgetOffset, interrupt_budget);
     669             : }
     670             : 
     671             : int BytecodeArray::osr_loop_nesting_level() const {
     672       42238 :   return READ_INT8_FIELD(*this, kOSRNestingLevelOffset);
     673             : }
     674             : 
     675             : void BytecodeArray::set_osr_loop_nesting_level(int depth) {
     676             :   DCHECK(0 <= depth && depth <= AbstractCode::kMaxLoopNestingMarker);
     677             :   STATIC_ASSERT(AbstractCode::kMaxLoopNestingMarker < kMaxInt8);
     678     2138257 :   WRITE_INT8_FIELD(*this, kOSRNestingLevelOffset, depth);
     679             : }
     680             : 
     681             : BytecodeArray::Age BytecodeArray::bytecode_age() const {
     682             :   // Bytecode is aged by the concurrent marker.
     683     7783222 :   return static_cast<Age>(RELAXED_READ_INT8_FIELD(*this, kBytecodeAgeOffset));
     684             : }
     685             : 
     686             : void BytecodeArray::set_bytecode_age(BytecodeArray::Age age) {
     687             :   DCHECK_GE(age, kFirstBytecodeAge);
     688             :   DCHECK_LE(age, kLastBytecodeAge);
     689             :   STATIC_ASSERT(kLastBytecodeAge <= kMaxInt8);
     690             :   // Bytecode is aged by the concurrent marker.
     691     2093565 :   RELAXED_WRITE_INT8_FIELD(*this, kBytecodeAgeOffset, static_cast<int8_t>(age));
     692             : }
     693             : 
     694             : int BytecodeArray::parameter_count() const {
     695             :   // Parameter count is stored as the size on stack of the parameters to allow
     696             :   // it to be used directly by generated code.
     697     1728941 :   return READ_INT_FIELD(*this, kParameterSizeOffset) >> kSystemPointerSizeLog2;
     698             : }
     699             : 
     700    26145160 : ACCESSORS(BytecodeArray, constant_pool, FixedArray, kConstantPoolOffset)
     701   138727526 : ACCESSORS(BytecodeArray, handler_table, ByteArray, kHandlerTableOffset)
     702    27782150 : ACCESSORS(BytecodeArray, source_position_table, Object,
     703             :           kSourcePositionTableOffset)
     704             : 
     705     2082982 : void BytecodeArray::clear_padding() {
     706     2082985 :   int data_size = kHeaderSize + length();
     707     2082983 :   memset(reinterpret_cast<void*>(address() + data_size), 0,
     708     4165966 :          SizeFor(length()) - data_size);
     709     2082983 : }
     710             : 
     711             : Address BytecodeArray::GetFirstBytecodeAddress() {
     712    35113823 :   return ptr() - kHeapObjectTag + kHeaderSize;
     713             : }
     714             : 
     715          10 : bool BytecodeArray::HasSourcePositionTable() {
     716          10 :   Object maybe_table = source_position_table();
     717          10 :   return !maybe_table->IsUndefined();
     718             : }
     719             : 
     720     6756162 : ByteArray BytecodeArray::SourcePositionTable() {
     721     6756162 :   Object maybe_table = source_position_table();
     722     6756170 :   if (maybe_table->IsByteArray()) return ByteArray::cast(maybe_table);
     723      227911 :   ReadOnlyRoots roots = GetReadOnlyRoots();
     724      227911 :   if (maybe_table->IsUndefined(roots)) return roots.empty_byte_array();
     725             : 
     726             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
     727             :   return SourcePositionTableWithFrameCache::cast(maybe_table)
     728      227878 :       ->source_position_table();
     729             : }
     730             : 
     731        1529 : void BytecodeArray::ClearFrameCacheFromSourcePositionTable() {
     732        1529 :   Object maybe_table = source_position_table();
     733        4587 :   if (maybe_table->IsUndefined() || maybe_table->IsByteArray()) return;
     734             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
     735             :   set_source_position_table(SourcePositionTableWithFrameCache::cast(maybe_table)
     736           0 :                                 ->source_position_table());
     737             : }
     738             : 
     739     4127065 : int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); }
     740             : 
     741     2063520 : int BytecodeArray::SizeIncludingMetadata() {
     742     2063520 :   int size = BytecodeArraySize();
     743     2063520 :   size += constant_pool()->Size();
     744     2063516 :   size += handler_table()->Size();
     745     2063516 :   size += SourcePositionTable()->Size();
     746     2063520 :   return size;
     747             : }
     748             : 
     749     3335502 : DEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
     750       33962 : DEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
     751     3369638 : DEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
     752             : DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrBytecodeOffset, Smi)
     753        9954 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
     754         492 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi)
     755      456745 : DEFINE_DEOPT_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>)
     756             : 
     757     6651512 : DEFINE_DEOPT_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi)
     758    10863613 : DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
     759     7047845 : DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
     760             : 
     761             : BailoutId DeoptimizationData::BytecodeOffset(int i) {
     762      106294 :   return BailoutId(BytecodeOffsetRaw(i)->value());
     763             : }
     764             : 
     765             : void DeoptimizationData::SetBytecodeOffset(int i, BailoutId value) {
     766     3272609 :   SetBytecodeOffsetRaw(i, Smi::FromInt(value.ToInt()));
     767             : }
     768             : 
     769      100230 : int DeoptimizationData::DeoptCount() {
     770      100230 :   return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
     771             : }
     772             : 
     773             : }  // namespace internal
     774             : }  // namespace v8
     775             : 
     776             : #include "src/objects/object-macros-undef.h"
     777             : 
     778             : #endif  // V8_OBJECTS_CODE_INL_H_

Generated by: LCOV version 1.10