LCOV - code coverage report
Current view: top level - src/objects - code-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 238 252 94.4 %
Date: 2019-03-21 Functions: 72 75 96.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             : OBJECT_CONSTRUCTORS_IMPL(DeoptimizationData, FixedArray)
      28             : OBJECT_CONSTRUCTORS_IMPL(BytecodeArray, FixedArrayBase)
      29      111384 : OBJECT_CONSTRUCTORS_IMPL(AbstractCode, HeapObject)
      30        2912 : OBJECT_CONSTRUCTORS_IMPL(DependentCode, WeakFixedArray)
      31        1680 : OBJECT_CONSTRUCTORS_IMPL(CodeDataContainer, HeapObject)
      32             : OBJECT_CONSTRUCTORS_IMPL(SourcePositionTableWithFrameCache, Tuple2)
      33             : 
      34             : NEVER_READ_ONLY_SPACE_IMPL(AbstractCode)
      35             : 
      36      111384 : CAST_ACCESSOR(AbstractCode)
      37             : CAST_ACCESSOR(BytecodeArray)
      38     1635690 : CAST_ACCESSOR(Code)
      39        1680 : CAST_ACCESSOR(CodeDataContainer)
      40        2912 : CAST_ACCESSOR(DependentCode)
      41             : CAST_ACCESSOR(DeoptimizationData)
      42             : CAST_ACCESSOR(SourcePositionTableWithFrameCache)
      43             : 
      44      269568 : ACCESSORS(SourcePositionTableWithFrameCache, source_position_table, ByteArray,
      45             :           kSourcePositionTableIndex)
      46       98647 : 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      660766 : int AbstractCode::InstructionSize() {
      58     1321532 :   if (IsCode()) {
      59      315334 :     return GetCode()->InstructionSize();
      60             :   } else {
      61             :     return GetBytecodeArray()->length();
      62             :   }
      63             : }
      64             : 
      65     2140404 : ByteArray AbstractCode::source_position_table() {
      66     4280808 :   if (IsCode()) {
      67      103249 :     return GetCode()->SourcePositionTable();
      68             :   } else {
      69     2037155 :     return GetBytecodeArray()->SourcePositionTable();
      70             :   }
      71             : }
      72             : 
      73       72305 : Object AbstractCode::stack_frame_cache() {
      74             :   Object maybe_table;
      75      144610 :   if (IsCode()) {
      76             :     maybe_table = GetCode()->source_position_table();
      77             :   } else {
      78             :     maybe_table = GetBytecodeArray()->source_position_table();
      79             :   }
      80       72305 :   if (maybe_table->IsSourcePositionTableWithFrameCache()) {
      81             :     return SourcePositionTableWithFrameCache::cast(maybe_table)
      82       55907 :         ->stack_frame_cache();
      83             :   }
      84       16398 :   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     1292907 : Address AbstractCode::InstructionStart() {
     111     2585814 :   if (IsCode()) {
     112      572138 :     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       89310 : AbstractCode::Kind AbstractCode::kind() {
     141      178620 :   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       93383 :   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      329923 :   Set(kFlagsIndex, MaybeObject::FromObject(Smi::FromInt(flags)));
     166             : }
     167             : 
     168      547070 : int DependentCode::count() { return CountField::decode(flags()); }
     169             : 
     170      246619 : void DependentCode::set_count(int value) {
     171      493238 :   set_flags(CountField::update(flags(), value));
     172      246619 : }
     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      274059 :   Set(kCodesStartIndex + i, object);
     180             : }
     181             : 
     182             : MaybeObject DependentCode::object_at(int i) {
     183             :   return Get(kCodesStartIndex + i);
     184             : }
     185             : 
     186       11272 : void DependentCode::clear_at(int i) {
     187       11272 :   Set(kCodesStartIndex + i,
     188       22544 :       HeapObjectReference::Strong(GetReadOnlyRoots().undefined_value()));
     189       11272 : }
     190             : 
     191        2300 : void DependentCode::copy(int from, int to) {
     192        2300 :   Set(kCodesStartIndex + to, Get(kCodesStartIndex + from));
     193        2300 : }
     194             : 
     195     3101700 : OBJECT_CONSTRUCTORS_IMPL(Code, HeapObject)
     196             : NEVER_READ_ONLY_SPACE_IMPL(Code)
     197             : 
     198   463663185 : INT_ACCESSORS(Code, raw_instruction_size, kInstructionSizeOffset)
     199     4846333 : INT_ACCESSORS(Code, safepoint_table_offset, kSafepointTableOffsetOffset)
     200     6652314 : INT_ACCESSORS(Code, handler_table_offset, kHandlerTableOffsetOffset)
     201     6056866 : 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    10758737 : CODE_ACCESSORS(relocation_info, ByteArray, kRelocationInfoOffset)
     210    14215950 : CODE_ACCESSORS(deoptimization_data, FixedArray, kDeoptimizationDataOffset)
     211    10995598 : CODE_ACCESSORS(source_position_table, Object, kSourcePositionTableOffset)
     212             : // Concurrent marker needs to access kind specific flags in code data container.
     213    45863039 : SYNCHRONIZED_CODE_ACCESSORS(code_data_container, CodeDataContainer,
     214             :                             kCodeDataContainerOffset)
     215             : #undef CODE_ACCESSORS
     216             : #undef SYNCHRONIZED_CODE_ACCESSORS
     217             : 
     218      396205 : void Code::WipeOutHeader() {
     219      396205 :   WRITE_FIELD(*this, kRelocationInfoOffset, Smi::FromInt(0));
     220      396205 :   WRITE_FIELD(*this, kDeoptimizationDataOffset, Smi::FromInt(0));
     221      396205 :   WRITE_FIELD(*this, kSourcePositionTableOffset, Smi::FromInt(0));
     222      396205 :   WRITE_FIELD(*this, kCodeDataContainerOffset, Smi::FromInt(0));
     223      396205 : }
     224             : 
     225     1903466 : void Code::clear_padding() {
     226             :   if (FIELD_SIZE(kOptionalPaddingOffset) != 0) {
     227     1903466 :     memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
     228             :            FIELD_SIZE(kOptionalPaddingOffset));
     229             :   }
     230             :   Address data_end =
     231     1903466 :       has_unwinding_info() ? unwinding_info_end() : raw_instruction_end();
     232     3806932 :   memset(reinterpret_cast<void*>(data_end), 0,
     233     1903466 :          CodeSize() - (data_end - address()));
     234     1903466 : }
     235             : 
     236      107032 : ByteArray Code::SourcePositionTable() const {
     237             :   Object maybe_table = source_position_table();
     238      107032 :   if (maybe_table->IsByteArray()) return ByteArray::cast(maybe_table);
     239             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
     240             :   return SourcePositionTableWithFrameCache::cast(maybe_table)
     241             :       ->source_position_table();
     242             : }
     243             : 
     244     9565400 : Object Code::next_code_link() const {
     245     9565400 :   return code_data_container()->next_code_link();
     246             : }
     247             : 
     248      741309 : void Code::set_next_code_link(Object value) {
     249      741309 :   code_data_container()->set_next_code_link(value);
     250      741308 : }
     251             : 
     252             : int Code::InstructionSize() const {
     253      166101 :   if (is_off_heap_trampoline()) {
     254             :     DCHECK(FLAG_embedded_builtins);
     255       64581 :     return OffHeapInstructionSize();
     256             :   }
     257             :   return raw_instruction_size();
     258             : }
     259             : 
     260      475664 : Address Code::raw_instruction_start() const {
     261   291922436 :   return FIELD_ADDR(*this, kHeaderSize);
     262             : }
     263             : 
     264             : Address Code::InstructionStart() const {
     265   160511431 :   if (is_off_heap_trampoline()) {
     266             :     DCHECK(FLAG_embedded_builtins);
     267   151363577 :     return OffHeapInstructionStart();
     268             :   }
     269             :   return raw_instruction_start();
     270             : }
     271             : 
     272             : Address Code::raw_instruction_end() const {
     273     1903702 :   return raw_instruction_start() + raw_instruction_size();
     274             : }
     275             : 
     276         255 : Address Code::InstructionEnd() const {
     277         255 :   if (is_off_heap_trampoline()) {
     278             :     DCHECK(FLAG_embedded_builtins);
     279           0 :     return OffHeapInstructionEnd();
     280             :   }
     281         255 :   return raw_instruction_end();
     282             : }
     283             : 
     284             : int Code::GetUnwindingInfoSizeOffset() const {
     285             :   DCHECK(has_unwinding_info());
     286         119 :   return RoundUp(kHeaderSize + raw_instruction_size(), kInt64Size);
     287             : }
     288             : 
     289             : int Code::unwinding_info_size() const {
     290             :   DCHECK(has_unwinding_info());
     291             :   return static_cast<int>(
     292         130 :       READ_UINT64_FIELD(*this, GetUnwindingInfoSizeOffset()));
     293             : }
     294             : 
     295          27 : void Code::set_unwinding_info_size(int value) {
     296             :   DCHECK(has_unwinding_info());
     297          54 :   WRITE_UINT64_FIELD(*this, GetUnwindingInfoSizeOffset(), value);
     298          27 : }
     299             : 
     300             : Address Code::unwinding_info_start() const {
     301             :   DCHECK(has_unwinding_info());
     302          92 :   return FIELD_ADDR(*this, GetUnwindingInfoSizeOffset()) + kInt64Size;
     303             : }
     304             : 
     305             : Address Code::unwinding_info_end() const {
     306             :   DCHECK(has_unwinding_info());
     307          65 :   return unwinding_info_start() + unwinding_info_size();
     308             : }
     309             : 
     310   456017489 : int Code::body_size() const {
     311             :   int unpadded_body_size =
     312             :       has_unwinding_info()
     313             :           ? static_cast<int>(unwinding_info_end() - raw_instruction_start())
     314   456017555 :           : raw_instruction_size();
     315   456017489 :   return RoundUp(unpadded_body_size, kObjectAlignment);
     316             : }
     317             : 
     318           0 : int Code::SizeIncludingMetadata() const {
     319             :   int size = CodeSize();
     320           0 :   size += relocation_info()->Size();
     321           0 :   size += deoptimization_data()->Size();
     322           0 :   return size;
     323             : }
     324             : 
     325             : ByteArray Code::unchecked_relocation_info() const {
     326   214354754 :   return ByteArray::unchecked_cast(READ_FIELD(*this, kRelocationInfoOffset));
     327             : }
     328             : 
     329             : byte* Code::relocation_start() const {
     330             :   return unchecked_relocation_info()->GetDataStartAddress();
     331             : }
     332             : 
     333           0 : byte* Code::relocation_end() const {
     334           0 :   return unchecked_relocation_info()->GetDataEndAddress();
     335             : }
     336             : 
     337       85593 : int Code::relocation_size() const {
     338       85593 :   return unchecked_relocation_info()->length();
     339             : }
     340             : 
     341             : Address Code::entry() const { return raw_instruction_start(); }
     342             : 
     343    11575084 : bool Code::contains(Address inner_pointer) {
     344    11575084 :   if (is_off_heap_trampoline()) {
     345             :     DCHECK(FLAG_embedded_builtins);
     346     1040078 :     if (OffHeapInstructionStart() <= inner_pointer &&
     347      359612 :         inner_pointer < OffHeapInstructionEnd()) {
     348             :       return true;
     349             :     }
     350             :   }
     351    11225984 :   return (address() <= inner_pointer) && (inner_pointer < address() + Size());
     352             : }
     353             : 
     354             : int Code::ExecutableSize() const {
     355             :   // Check that the assumptions about the layout of the code object holds.
     356             :   DCHECK_EQ(static_cast<int>(raw_instruction_start() - address()),
     357             :             Code::kHeaderSize);
     358           2 :   return raw_instruction_size() + Code::kHeaderSize;
     359             : }
     360             : 
     361             : // static
     362             : void Code::CopyRelocInfoToByteArray(ByteArray dest, const CodeDesc& desc) {
     363             :   DCHECK_EQ(dest->length(), desc.reloc_size);
     364     3807040 :   CopyBytes(dest->GetDataStartAddress(),
     365     1903520 :             desc.buffer + desc.buffer_size - desc.reloc_size,
     366             :             static_cast<size_t>(desc.reloc_size));
     367             : }
     368             : 
     369   455847115 : int Code::CodeSize() const { return SizeFor(body_size()); }
     370             : 
     371             : Code::Kind Code::kind() const {
     372    67925403 :   return KindField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     373             : }
     374             : 
     375     1988306 : void Code::initialize_flags(Kind kind, bool has_unwinding_info,
     376             :                             bool is_turbofanned, int stack_slots,
     377             :                             bool is_off_heap_trampoline) {
     378     1988306 :   CHECK(0 <= stack_slots && stack_slots < StackSlotsField::kMax);
     379             :   static_assert(Code::NUMBER_OF_KINDS <= KindField::kMax + 1, "field overflow");
     380     1988306 :   uint32_t flags = HasUnwindingInfoField::encode(has_unwinding_info) |
     381     1988306 :                    KindField::encode(kind) |
     382     1988306 :                    IsTurbofannedField::encode(is_turbofanned) |
     383             :                    StackSlotsField::encode(stack_slots) |
     384     1988306 :                    IsOffHeapTrampoline::encode(is_off_heap_trampoline);
     385     1988306 :   WRITE_UINT32_FIELD(*this, kFlagsOffset, flags);
     386             :   DCHECK_IMPLIES(stack_slots != 0, has_safepoint_info());
     387     1988306 : }
     388             : 
     389             : inline bool Code::is_interpreter_trampoline_builtin() const {
     390             :   bool is_interpreter_trampoline =
     391     1614944 :       (builtin_index() == Builtins::kInterpreterEntryTrampoline ||
     392    29584650 :        builtin_index() == Builtins::kInterpreterEnterBytecodeAdvance ||
     393             :        builtin_index() == Builtins::kInterpreterEnterBytecodeDispatch);
     394             :   return is_interpreter_trampoline;
     395             : }
     396             : 
     397             : inline bool Code::checks_optimization_marker() const {
     398             :   bool checks_marker =
     399             :       (builtin_index() == Builtins::kCompileLazy ||
     400             :        builtin_index() == Builtins::kInterpreterEntryTrampoline);
     401             :   return checks_marker ||
     402             :          (kind() == OPTIMIZED_FUNCTION && marked_for_deoptimization());
     403             : }
     404             : 
     405             : inline bool Code::has_tagged_params() const {
     406      881804 :   return kind() != JS_TO_WASM_FUNCTION && kind() != C_WASM_ENTRY &&
     407             :          kind() != WASM_FUNCTION;
     408             : }
     409             : 
     410             : inline bool Code::has_unwinding_info() const {
     411   457920969 :   return HasUnwindingInfoField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     412             : }
     413             : 
     414             : inline bool Code::is_turbofanned() const {
     415      222140 :   return IsTurbofannedField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     416             : }
     417             : 
     418      458541 : inline bool Code::can_have_weak_objects() const {
     419             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     420             :   int32_t flags = code_data_container()->kind_specific_flags();
     421      458529 :   return CanHaveWeakObjectsField::decode(flags);
     422             : }
     423             : 
     424      460320 : inline void Code::set_can_have_weak_objects(bool value) {
     425             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     426             :   int32_t previous = code_data_container()->kind_specific_flags();
     427             :   int32_t updated = CanHaveWeakObjectsField::update(previous, value);
     428             :   code_data_container()->set_kind_specific_flags(updated);
     429      460320 : }
     430             : 
     431        7025 : inline bool Code::is_promise_rejection() const {
     432             :   DCHECK(kind() == BUILTIN);
     433             :   int32_t flags = code_data_container()->kind_specific_flags();
     434        7025 :   return IsPromiseRejectionField::decode(flags);
     435             : }
     436             : 
     437         784 : inline void Code::set_is_promise_rejection(bool value) {
     438             :   DCHECK(kind() == BUILTIN);
     439         784 :   int32_t previous = code_data_container()->kind_specific_flags();
     440         784 :   int32_t updated = IsPromiseRejectionField::update(previous, value);
     441         784 :   code_data_container()->set_kind_specific_flags(updated);
     442         784 : }
     443             : 
     444        5212 : inline bool Code::is_exception_caught() const {
     445             :   DCHECK(kind() == BUILTIN);
     446             :   int32_t flags = code_data_container()->kind_specific_flags();
     447        5212 :   return IsExceptionCaughtField::decode(flags);
     448             : }
     449             : 
     450          56 : inline void Code::set_is_exception_caught(bool value) {
     451             :   DCHECK(kind() == BUILTIN);
     452          56 :   int32_t previous = code_data_container()->kind_specific_flags();
     453          56 :   int32_t updated = IsExceptionCaughtField::update(previous, value);
     454          56 :   code_data_container()->set_kind_specific_flags(updated);
     455          56 : }
     456             : 
     457             : inline bool Code::is_off_heap_trampoline() const {
     458   169481941 :   return IsOffHeapTrampoline::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     459             : }
     460             : 
     461        7025 : inline HandlerTable::CatchPrediction Code::GetBuiltinCatchPrediction() {
     462        7025 :   if (is_promise_rejection()) return HandlerTable::PROMISE;
     463        5212 :   if (is_exception_caught()) return HandlerTable::CAUGHT;
     464        5144 :   return HandlerTable::UNCAUGHT;
     465             : }
     466             : 
     467      804832 : int Code::builtin_index() const {
     468   193723344 :   int index = READ_INT_FIELD(*this, kBuiltinIndexOffset);
     469             :   DCHECK(index == -1 || Builtins::IsBuiltinId(index));
     470      804832 :   return index;
     471             : }
     472             : 
     473             : void Code::set_builtin_index(int index) {
     474             :   DCHECK(index == -1 || Builtins::IsBuiltinId(index));
     475     1988305 :   WRITE_INT_FIELD(*this, kBuiltinIndexOffset, index);
     476             : }
     477             : 
     478      402416 : bool Code::is_builtin() const { return builtin_index() != -1; }
     479             : 
     480             : bool Code::has_safepoint_info() const {
     481      104969 :   return is_turbofanned() || is_wasm_code();
     482             : }
     483             : 
     484             : int Code::stack_slots() const {
     485             :   DCHECK(has_safepoint_info());
     486     6838850 :   return StackSlotsField::decode(READ_UINT32_FIELD(*this, kFlagsOffset));
     487             : }
     488             : 
     489     5041408 : bool Code::marked_for_deoptimization() const {
     490             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     491             :   int32_t flags = code_data_container()->kind_specific_flags();
     492     5041408 :   return MarkedForDeoptimizationField::decode(flags);
     493             : }
     494             : 
     495      278039 : void Code::set_marked_for_deoptimization(bool flag) {
     496             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     497             :   DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
     498             :   int32_t previous = code_data_container()->kind_specific_flags();
     499             :   int32_t updated = MarkedForDeoptimizationField::update(previous, flag);
     500             :   code_data_container()->set_kind_specific_flags(updated);
     501      278039 : }
     502             : 
     503         852 : bool Code::embedded_objects_cleared() const {
     504             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     505             :   int32_t flags = code_data_container()->kind_specific_flags();
     506         852 :   return EmbeddedObjectsClearedField::decode(flags);
     507             : }
     508             : 
     509         278 : void Code::set_embedded_objects_cleared(bool flag) {
     510             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     511             :   DCHECK_IMPLIES(flag, marked_for_deoptimization());
     512             :   int32_t previous = code_data_container()->kind_specific_flags();
     513             :   int32_t updated = EmbeddedObjectsClearedField::update(previous, flag);
     514             :   code_data_container()->set_kind_specific_flags(updated);
     515         278 : }
     516             : 
     517       87074 : bool Code::deopt_already_counted() const {
     518             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     519             :   int32_t flags = code_data_container()->kind_specific_flags();
     520       87074 :   return DeoptAlreadyCountedField::decode(flags);
     521             : }
     522             : 
     523       61761 : void Code::set_deopt_already_counted(bool flag) {
     524             :   DCHECK(kind() == OPTIMIZED_FUNCTION);
     525             :   DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
     526             :   int32_t previous = code_data_container()->kind_specific_flags();
     527             :   int32_t updated = DeoptAlreadyCountedField::update(previous, flag);
     528             :   code_data_container()->set_kind_specific_flags(updated);
     529       61761 : }
     530             : 
     531             : bool Code::is_optimized_code() const { return kind() == OPTIMIZED_FUNCTION; }
     532             : bool Code::is_wasm_code() const { return kind() == WASM_FUNCTION; }
     533             : 
     534             : int Code::constant_pool_offset() const {
     535             :   if (!FLAG_enable_embedded_constant_pool) return code_comments_offset();
     536             :   return READ_INT_FIELD(*this, kConstantPoolOffsetOffset);
     537             : }
     538             : 
     539             : void Code::set_constant_pool_offset(int value) {
     540             :   if (!FLAG_enable_embedded_constant_pool) return;
     541             :   DCHECK_LE(value, InstructionSize());
     542             :   WRITE_INT_FIELD(*this, kConstantPoolOffsetOffset, value);
     543             : }
     544             : 
     545   213241074 : Address Code::constant_pool() const {
     546   213241074 :   if (!has_constant_pool()) return kNullAddress;
     547           0 :   return InstructionStart() + constant_pool_offset();
     548             : }
     549             : 
     550           8 : Address Code::code_comments() const {
     551           8 :   if (!has_code_comments()) return kNullAddress;
     552           8 :   return InstructionStart() + code_comments_offset();
     553             : }
     554             : 
     555     3269739 : Code Code::GetCodeFromTargetAddress(Address address) {
     556             :   {
     557             :     // TODO(jgruber,v8:6666): Support embedded builtins here. We'd need to pass
     558             :     // in the current isolate.
     559     3269739 :     Address start = reinterpret_cast<Address>(Isolate::CurrentEmbeddedBlob());
     560     3269717 :     Address end = start + Isolate::CurrentEmbeddedBlobSize();
     561     3269695 :     CHECK(address < start || address >= end);
     562             :   }
     563             : 
     564      402416 :   HeapObject code = HeapObject::FromAddress(address - Code::kHeaderSize);
     565             :   // Unchecked cast because we can't rely on the map currently
     566             :   // not being a forwarding pointer.
     567     3269695 :   return Code::unchecked_cast(code);
     568             : }
     569             : 
     570             : Code Code::GetObjectFromEntryAddress(Address location_of_address) {
     571           0 :   Address code_entry = Memory<Address>(location_of_address);
     572             :   HeapObject code = HeapObject::FromAddress(code_entry - Code::kHeaderSize);
     573             :   // Unchecked cast because we can't rely on the map currently
     574             :   // not being a forwarding pointer.
     575             :   return Code::unchecked_cast(code);
     576             : }
     577             : 
     578      459782 : bool Code::CanContainWeakObjects() {
     579      459782 :   return is_optimized_code() && can_have_weak_objects();
     580             : }
     581             : 
     582      459782 : bool Code::IsWeakObject(HeapObject object) {
     583      459782 :   return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object));
     584             : }
     585             : 
     586     5589681 : bool Code::IsWeakObjectInOptimizedCode(HeapObject object) {
     587             :   Map map = object->synchronized_map();
     588             :   InstanceType instance_type = map->instance_type();
     589     5589681 :   if (InstanceTypeChecker::IsMap(instance_type)) {
     590             :     return Map::cast(object)->CanTransition();
     591             :   }
     592     5396211 :   return InstanceTypeChecker::IsPropertyCell(instance_type) ||
     593    10637074 :          InstanceTypeChecker::IsJSReceiver(instance_type) ||
     594             :          InstanceTypeChecker::IsContext(instance_type);
     595             : }
     596             : 
     597             : // This field has to have relaxed atomic accessors because it is accessed in the
     598             : // concurrent marker.
     599     9275786 : RELAXED_INT32_ACCESSORS(CodeDataContainer, kind_specific_flags,
     600             :                         kKindSpecificFlagsOffset)
     601    16398620 : ACCESSORS(CodeDataContainer, next_code_link, Object, kNextCodeLinkOffset)
     602             : 
     603             : void CodeDataContainer::clear_padding() {
     604     1903496 :   memset(reinterpret_cast<void*>(address() + kUnalignedSize), 0,
     605             :          kSize - kUnalignedSize);
     606             : }
     607             : 
     608             : byte BytecodeArray::get(int index) const {
     609             :   DCHECK(index >= 0 && index < this->length());
     610   284255141 :   return READ_BYTE_FIELD(*this, kHeaderSize + index * kCharSize);
     611             : }
     612             : 
     613             : void BytecodeArray::set(int index, byte value) {
     614             :   DCHECK(index >= 0 && index < this->length());
     615    14273286 :   WRITE_BYTE_FIELD(*this, kHeaderSize + index * kCharSize, value);
     616             : }
     617             : 
     618             : void BytecodeArray::set_frame_size(int frame_size) {
     619             :   DCHECK_GE(frame_size, 0);
     620             :   DCHECK(IsAligned(frame_size, kSystemPointerSize));
     621     2102862 :   WRITE_INT_FIELD(*this, kFrameSizeOffset, frame_size);
     622             : }
     623             : 
     624             : int BytecodeArray::frame_size() const {
     625    31016874 :   return READ_INT_FIELD(*this, kFrameSizeOffset);
     626             : }
     627             : 
     628             : int BytecodeArray::register_count() const {
     629    31003931 :   return frame_size() / kSystemPointerSize;
     630             : }
     631             : 
     632             : void BytecodeArray::set_parameter_count(int number_of_parameters) {
     633             :   DCHECK_GE(number_of_parameters, 0);
     634             :   // Parameter count is stored as the size on stack of the parameters to allow
     635             :   // it to be used directly by generated code.
     636     4205724 :   WRITE_INT_FIELD(*this, kParameterSizeOffset,
     637     4205724 :                   (number_of_parameters << kSystemPointerSizeLog2));
     638             : }
     639             : 
     640             : interpreter::Register BytecodeArray::incoming_new_target_or_generator_register()
     641             :     const {
     642             :   int register_operand =
     643      539645 :       READ_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset);
     644      539645 :   if (register_operand == 0) {
     645             :     return interpreter::Register::invalid_value();
     646             :   } else {
     647             :     return interpreter::Register::FromOperand(register_operand);
     648             :   }
     649             : }
     650             : 
     651             : void BytecodeArray::set_incoming_new_target_or_generator_register(
     652             :     interpreter::Register incoming_new_target_or_generator_register) {
     653      115716 :   if (!incoming_new_target_or_generator_register.is_valid()) {
     654     2102289 :     WRITE_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset, 0);
     655             :   } else {
     656             :     DCHECK(incoming_new_target_or_generator_register.index() <
     657             :            register_count());
     658             :     DCHECK_NE(0, incoming_new_target_or_generator_register.ToOperand());
     659      105697 :     WRITE_INT_FIELD(*this, kIncomingNewTargetOrGeneratorRegisterOffset,
     660      211394 :                     incoming_new_target_or_generator_register.ToOperand());
     661             :   }
     662             : }
     663             : 
     664             : int BytecodeArray::interrupt_budget() const {
     665       10597 :   return READ_INT_FIELD(*this, kInterruptBudgetOffset);
     666             : }
     667             : 
     668             : void BytecodeArray::set_interrupt_budget(int interrupt_budget) {
     669             :   DCHECK_GE(interrupt_budget, 0);
     670     2103587 :   WRITE_INT_FIELD(*this, kInterruptBudgetOffset, interrupt_budget);
     671             : }
     672             : 
     673             : int BytecodeArray::osr_loop_nesting_level() const {
     674       41187 :   return READ_INT8_FIELD(*this, kOSRNestingLevelOffset);
     675             : }
     676             : 
     677             : void BytecodeArray::set_osr_loop_nesting_level(int depth) {
     678             :   DCHECK(0 <= depth && depth <= AbstractCode::kMaxLoopNestingMarker);
     679             :   STATIC_ASSERT(AbstractCode::kMaxLoopNestingMarker < kMaxInt8);
     680     2146188 :   WRITE_INT8_FIELD(*this, kOSRNestingLevelOffset, depth);
     681             : }
     682             : 
     683             : BytecodeArray::Age BytecodeArray::bytecode_age() const {
     684             :   // Bytecode is aged by the concurrent marker.
     685     5159851 :   return static_cast<Age>(RELAXED_READ_INT8_FIELD(*this, kBytecodeAgeOffset));
     686             : }
     687             : 
     688             : void BytecodeArray::set_bytecode_age(BytecodeArray::Age age) {
     689             :   DCHECK_GE(age, kFirstBytecodeAge);
     690             :   DCHECK_LE(age, kLastBytecodeAge);
     691             :   STATIC_ASSERT(kLastBytecodeAge <= kMaxInt8);
     692             :   // Bytecode is aged by the concurrent marker.
     693     2102853 :   RELAXED_WRITE_INT8_FIELD(*this, kBytecodeAgeOffset, static_cast<int8_t>(age));
     694             : }
     695             : 
     696             : int BytecodeArray::parameter_count() const {
     697             :   // Parameter count is stored as the size on stack of the parameters to allow
     698             :   // it to be used directly by generated code.
     699     1745389 :   return READ_INT_FIELD(*this, kParameterSizeOffset) >> kSystemPointerSizeLog2;
     700             : }
     701             : 
     702    15773040 : ACCESSORS(BytecodeArray, constant_pool, FixedArray, kConstantPoolOffset)
     703    60345081 : ACCESSORS(BytecodeArray, handler_table, ByteArray, kHandlerTableOffset)
     704    27892779 : ACCESSORS(BytecodeArray, source_position_table, Object,
     705             :           kSourcePositionTableOffset)
     706             : 
     707     2092267 : void BytecodeArray::clear_padding() {
     708     2092267 :   int data_size = kHeaderSize + length();
     709     4184534 :   memset(reinterpret_cast<void*>(address() + data_size), 0,
     710     2092267 :          SizeFor(length()) - data_size);
     711     2092267 : }
     712             : 
     713             : Address BytecodeArray::GetFirstBytecodeAddress() {
     714    35155416 :   return ptr() - kHeapObjectTag + kHeaderSize;
     715             : }
     716             : 
     717          10 : bool BytecodeArray::HasSourcePositionTable() {
     718             :   Object maybe_table = source_position_table();
     719          10 :   return !maybe_table->IsUndefined();
     720             : }
     721             : 
     722     6778126 : ByteArray BytecodeArray::SourcePositionTable() {
     723             :   Object maybe_table = source_position_table();
     724     6778131 :   if (maybe_table->IsByteArray()) return ByteArray::cast(maybe_table);
     725             :   ReadOnlyRoots roots = GetReadOnlyRoots();
     726      228578 :   if (maybe_table->IsUndefined(roots)) return roots.empty_byte_array();
     727             : 
     728             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
     729             :   return SourcePositionTableWithFrameCache::cast(maybe_table)
     730             :       ->source_position_table();
     731             : }
     732             : 
     733        1529 : void BytecodeArray::ClearFrameCacheFromSourcePositionTable() {
     734             :   Object maybe_table = source_position_table();
     735        3058 :   if (maybe_table->IsUndefined() || maybe_table->IsByteArray()) return;
     736             :   DCHECK(maybe_table->IsSourcePositionTableWithFrameCache());
     737             :   set_source_position_table(SourcePositionTableWithFrameCache::cast(maybe_table)
     738           0 :                                 ->source_position_table());
     739             : }
     740             : 
     741             : int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); }
     742             : 
     743     2072805 : int BytecodeArray::SizeIncludingMetadata() {
     744             :   int size = BytecodeArraySize();
     745     2072805 :   size += constant_pool()->Size();
     746     2072799 :   size += handler_table()->Size();
     747     4145597 :   size += SourcePositionTable()->Size();
     748     2072798 :   return size;
     749             : }
     750             : 
     751      463633 : DEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
     752             : DEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
     753      463633 : DEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
     754             : DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrBytecodeOffset, Smi)
     755        9368 : DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
     756             : DEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi)
     757      463812 : DEFINE_DEOPT_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>)
     758             : 
     759      104424 : DEFINE_DEOPT_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi)
     760     4224828 : DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
     761      450330 : DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
     762             : 
     763             : BailoutId DeoptimizationData::BytecodeOffset(int i) {
     764      104424 :   return BailoutId(BytecodeOffsetRaw(i)->value());
     765             : }
     766             : 
     767             : void DeoptimizationData::SetBytecodeOffset(int i, BailoutId value) {
     768             :   SetBytecodeOffsetRaw(i, Smi::FromInt(value.ToInt()));
     769             : }
     770             : 
     771             : int DeoptimizationData::DeoptCount() {
     772       88137 :   return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
     773             : }
     774             : 
     775             : }  // namespace internal
     776             : }  // namespace v8
     777             : 
     778             : #include "src/objects/object-macros-undef.h"
     779             : 
     780             : #endif  // V8_OBJECTS_CODE_INL_H_

Generated by: LCOV version 1.10