LCOV - code coverage report
Current view: top level - src - assembler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 484 609 79.5 %
Date: 2017-10-20 Functions: 171 195 87.7 %

          Line data    Source code
       1             : // Copyright (c) 1994-2006 Sun Microsystems Inc.
       2             : // All Rights Reserved.
       3             : //
       4             : // Redistribution and use in source and binary forms, with or without
       5             : // modification, are permitted provided that the following conditions are
       6             : // met:
       7             : //
       8             : // - Redistributions of source code must retain the above copyright notice,
       9             : // this list of conditions and the following disclaimer.
      10             : //
      11             : // - Redistribution in binary form must reproduce the above copyright
      12             : // notice, this list of conditions and the following disclaimer in the
      13             : // documentation and/or other materials provided with the distribution.
      14             : //
      15             : // - Neither the name of Sun Microsystems or the names of contributors may
      16             : // be used to endorse or promote products derived from this software without
      17             : // specific prior written permission.
      18             : //
      19             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
      20             : // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
      21             : // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      22             : // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      23             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
      24             : // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      25             : // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
      26             : // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
      27             : // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
      28             : // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      29             : // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      30             : 
      31             : // The original source code covered by the above license above has been
      32             : // modified significantly by Google Inc.
      33             : // Copyright 2012 the V8 project authors. All rights reserved.
      34             : 
      35             : #include "src/assembler.h"
      36             : 
      37             : #include <math.h>
      38             : #include <string.h>
      39             : #include <cmath>
      40             : 
      41             : #include "src/api.h"
      42             : #include "src/assembler-inl.h"
      43             : #include "src/base/cpu.h"
      44             : #include "src/base/functional.h"
      45             : #include "src/base/ieee754.h"
      46             : #include "src/base/lazy-instance.h"
      47             : #include "src/base/platform/platform.h"
      48             : #include "src/base/utils/random-number-generator.h"
      49             : #include "src/codegen.h"
      50             : #include "src/compiler/code-assembler.h"
      51             : #include "src/counters.h"
      52             : #include "src/debug/debug.h"
      53             : #include "src/deoptimizer.h"
      54             : #include "src/disassembler.h"
      55             : #include "src/execution.h"
      56             : #include "src/ic/ic.h"
      57             : #include "src/ic/stub-cache.h"
      58             : #include "src/interpreter/bytecodes.h"
      59             : #include "src/interpreter/interpreter.h"
      60             : #include "src/isolate.h"
      61             : #include "src/ostreams.h"
      62             : #include "src/regexp/jsregexp.h"
      63             : #include "src/regexp/regexp-macro-assembler.h"
      64             : #include "src/regexp/regexp-stack.h"
      65             : #include "src/register-configuration.h"
      66             : #include "src/runtime/runtime.h"
      67             : #include "src/simulator.h"  // For flushing instruction cache.
      68             : #include "src/snapshot/serializer-common.h"
      69             : #include "src/string-search.h"
      70             : #include "src/wasm/wasm-external-refs.h"
      71             : 
      72             : // Include native regexp-macro-assembler.
      73             : #ifndef V8_INTERPRETED_REGEXP
      74             : #if V8_TARGET_ARCH_IA32
      75             : #include "src/regexp/ia32/regexp-macro-assembler-ia32.h"  // NOLINT
      76             : #elif V8_TARGET_ARCH_X64
      77             : #include "src/regexp/x64/regexp-macro-assembler-x64.h"  // NOLINT
      78             : #elif V8_TARGET_ARCH_ARM64
      79             : #include "src/regexp/arm64/regexp-macro-assembler-arm64.h"  // NOLINT
      80             : #elif V8_TARGET_ARCH_ARM
      81             : #include "src/regexp/arm/regexp-macro-assembler-arm.h"  // NOLINT
      82             : #elif V8_TARGET_ARCH_PPC
      83             : #include "src/regexp/ppc/regexp-macro-assembler-ppc.h"  // NOLINT
      84             : #elif V8_TARGET_ARCH_MIPS
      85             : #include "src/regexp/mips/regexp-macro-assembler-mips.h"  // NOLINT
      86             : #elif V8_TARGET_ARCH_MIPS64
      87             : #include "src/regexp/mips64/regexp-macro-assembler-mips64.h"  // NOLINT
      88             : #elif V8_TARGET_ARCH_S390
      89             : #include "src/regexp/s390/regexp-macro-assembler-s390.h"  // NOLINT
      90             : #else  // Unknown architecture.
      91             : #error "Unknown architecture."
      92             : #endif  // Target architecture.
      93             : #endif  // V8_INTERPRETED_REGEXP
      94             : 
      95             : #ifdef V8_INTL_SUPPORT
      96             : #include "src/intl.h"
      97             : #endif  // V8_INTL_SUPPORT
      98             : 
      99             : namespace v8 {
     100             : namespace internal {
     101             : 
     102             : // -----------------------------------------------------------------------------
     103             : // Common double constants.
     104             : 
     105             : struct DoubleConstant BASE_EMBEDDED {
     106             : double min_int;
     107             : double one_half;
     108             : double minus_one_half;
     109             : double negative_infinity;
     110             : uint64_t the_hole_nan;
     111             : double uint32_bias;
     112             : };
     113             : 
     114             : static DoubleConstant double_constants;
     115             : 
     116             : static struct V8_ALIGNED(16) {
     117             :   uint32_t a;
     118             :   uint32_t b;
     119             :   uint32_t c;
     120             :   uint32_t d;
     121             : } float_absolute_constant = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
     122             : 
     123             : static struct V8_ALIGNED(16) {
     124             :   uint32_t a;
     125             :   uint32_t b;
     126             :   uint32_t c;
     127             :   uint32_t d;
     128             : } float_negate_constant = {0x80000000, 0x80000000, 0x80000000, 0x80000000};
     129             : 
     130             : static struct V8_ALIGNED(16) {
     131             :   uint64_t a;
     132             :   uint64_t b;
     133             : } double_absolute_constant = {V8_UINT64_C(0x7FFFFFFFFFFFFFFF),
     134             :                               V8_UINT64_C(0x7FFFFFFFFFFFFFFF)};
     135             : 
     136             : static struct V8_ALIGNED(16) {
     137             :   uint64_t a;
     138             :   uint64_t b;
     139             : } double_negate_constant = {V8_UINT64_C(0x8000000000000000),
     140             :                             V8_UINT64_C(0x8000000000000000)};
     141             : 
     142             : const char* const RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING";
     143             : 
     144             : // -----------------------------------------------------------------------------
     145             : // Implementation of AssemblerBase
     146             : 
     147     1708918 : AssemblerBase::IsolateData::IsolateData(Isolate* isolate)
     148             :     : serializer_enabled_(isolate->serializer_enabled())
     149             : #if V8_TARGET_ARCH_X64
     150             :       ,
     151             :       code_range_start_(
     152     3417836 :           isolate->heap()->memory_allocator()->code_range()->start())
     153             : #endif
     154             : {
     155     1708918 : }
     156             : 
     157     1708946 : AssemblerBase::AssemblerBase(IsolateData isolate_data, void* buffer,
     158             :                              int buffer_size)
     159             :     : isolate_data_(isolate_data),
     160             :       enabled_cpu_features_(0),
     161             :       emit_debug_code_(FLAG_debug_code),
     162             :       predictable_code_size_(false),
     163             :       constant_pool_available_(false),
     164     1708946 :       jump_optimization_info_(nullptr) {
     165     1708946 :   own_buffer_ = buffer == nullptr;
     166     1708946 :   if (buffer_size == 0) buffer_size = kMinimalBufferSize;
     167             :   DCHECK_GT(buffer_size, 0);
     168     1708946 :   if (own_buffer_) buffer = NewArray<byte>(buffer_size);
     169     1709031 :   buffer_ = static_cast<byte*>(buffer);
     170     1709031 :   buffer_size_ = buffer_size;
     171     1709031 :   pc_ = buffer_;
     172     1709031 : }
     173             : 
     174     1709024 : AssemblerBase::~AssemblerBase() {
     175     1709024 :   if (own_buffer_) DeleteArray(buffer_);
     176     1709024 : }
     177             : 
     178   221943560 : void AssemblerBase::FlushICache(Isolate* isolate, void* start, size_t size) {
     179   443887334 :   if (size == 0) return;
     180             : 
     181             : #if defined(USE_SIMULATOR)
     182             :   base::LockGuard<base::Mutex> lock_guard(isolate->simulator_i_cache_mutex());
     183             :   Simulator::FlushICache(isolate->simulator_i_cache(), start, size);
     184             : #else
     185   221990691 :   CpuFeatures::FlushICache(start, size);
     186             : #endif  // USE_SIMULATOR
     187             : }
     188             : 
     189           0 : void AssemblerBase::Print(Isolate* isolate) {
     190           0 :   OFStream os(stdout);
     191           0 :   v8::internal::Disassembler::Decode(isolate, &os, buffer_, pc_, nullptr);
     192           0 : }
     193             : 
     194             : // -----------------------------------------------------------------------------
     195             : // Implementation of PredictableCodeSizeScope
     196             : 
     197           0 : PredictableCodeSizeScope::PredictableCodeSizeScope(AssemblerBase* assembler)
     198           0 :     : PredictableCodeSizeScope(assembler, -1) {}
     199             : 
     200           0 : PredictableCodeSizeScope::PredictableCodeSizeScope(AssemblerBase* assembler,
     201             :                                                    int expected_size)
     202             :     : assembler_(assembler),
     203             :       expected_size_(expected_size),
     204             :       start_offset_(assembler->pc_offset()),
     205           0 :       old_value_(assembler->predictable_code_size()) {
     206             :   assembler_->set_predictable_code_size(true);
     207           0 : }
     208             : 
     209           0 : PredictableCodeSizeScope::~PredictableCodeSizeScope() {
     210             :   // TODO(svenpanne) Remove the 'if' when everything works.
     211           0 :   if (expected_size_ >= 0) {
     212           0 :     CHECK_EQ(expected_size_, assembler_->pc_offset() - start_offset_);
     213             :   }
     214           0 :   assembler_->set_predictable_code_size(old_value_);
     215           0 : }
     216             : 
     217             : // -----------------------------------------------------------------------------
     218             : // Implementation of CpuFeatureScope
     219             : 
     220             : #ifdef DEBUG
     221             : CpuFeatureScope::CpuFeatureScope(AssemblerBase* assembler, CpuFeature f,
     222             :                                  CheckPolicy check)
     223             :     : assembler_(assembler) {
     224             :   DCHECK_IMPLIES(check == kCheckSupported, CpuFeatures::IsSupported(f));
     225             :   old_enabled_ = assembler_->enabled_cpu_features();
     226             :   assembler_->EnableCpuFeature(f);
     227             : }
     228             : 
     229             : CpuFeatureScope::~CpuFeatureScope() {
     230             :   assembler_->set_enabled_cpu_features(old_enabled_);
     231             : }
     232             : #endif
     233             : 
     234             : bool CpuFeatures::initialized_ = false;
     235             : unsigned CpuFeatures::supported_ = 0;
     236             : unsigned CpuFeatures::icache_line_size_ = 0;
     237             : unsigned CpuFeatures::dcache_line_size_ = 0;
     238             : 
     239             : // -----------------------------------------------------------------------------
     240             : // Implementation of RelocInfoWriter and RelocIterator
     241             : //
     242             : // Relocation information is written backwards in memory, from high addresses
     243             : // towards low addresses, byte by byte.  Therefore, in the encodings listed
     244             : // below, the first byte listed it at the highest address, and successive
     245             : // bytes in the record are at progressively lower addresses.
     246             : //
     247             : // Encoding
     248             : //
     249             : // The most common modes are given single-byte encodings.  Also, it is
     250             : // easy to identify the type of reloc info and skip unwanted modes in
     251             : // an iteration.
     252             : //
     253             : // The encoding relies on the fact that there are fewer than 14
     254             : // different relocation modes using standard non-compact encoding.
     255             : //
     256             : // The first byte of a relocation record has a tag in its low 2 bits:
     257             : // Here are the record schemes, depending on the low tag and optional higher
     258             : // tags.
     259             : //
     260             : // Low tag:
     261             : //   00: embedded_object:      [6-bit pc delta] 00
     262             : //
     263             : //   01: code_target:          [6-bit pc delta] 01
     264             : //
     265             : //   10: short_data_record:    [6-bit pc delta] 10 followed by
     266             : //                             [8-bit data delta]
     267             : //
     268             : //   11: long_record           [6 bit reloc mode] 11
     269             : //                             followed by pc delta
     270             : //                             followed by optional data depending on type.
     271             : //
     272             : //  If a pc delta exceeds 6 bits, it is split into a remainder that fits into
     273             : //  6 bits and a part that does not. The latter is encoded as a long record
     274             : //  with PC_JUMP as pseudo reloc info mode. The former is encoded as part of
     275             : //  the following record in the usual way. The long pc jump record has variable
     276             : //  length:
     277             : //               pc-jump:        [PC_JUMP] 11
     278             : //                               [7 bits data] 0
     279             : //                                  ...
     280             : //                               [7 bits data] 1
     281             : //               (Bits 6..31 of pc delta, with leading zeroes
     282             : //                dropped, and last non-zero chunk tagged with 1.)
     283             : 
     284             : const int kTagBits = 2;
     285             : const int kTagMask = (1 << kTagBits) - 1;
     286             : const int kLongTagBits = 6;
     287             : 
     288             : const int kEmbeddedObjectTag = 0;
     289             : const int kCodeTargetTag = 1;
     290             : const int kLocatableTag = 2;
     291             : const int kDefaultTag = 3;
     292             : 
     293             : const int kSmallPCDeltaBits = kBitsPerByte - kTagBits;
     294             : const int kSmallPCDeltaMask = (1 << kSmallPCDeltaBits) - 1;
     295             : const int RelocInfo::kMaxSmallPCDelta = kSmallPCDeltaMask;
     296             : 
     297             : const int kChunkBits = 7;
     298             : const int kChunkMask = (1 << kChunkBits) - 1;
     299             : const int kLastChunkTagBits = 1;
     300             : const int kLastChunkTagMask = 1;
     301             : const int kLastChunkTag = 1;
     302             : 
     303      186865 : void RelocInfo::set_wasm_context_reference(Isolate* isolate, Address address,
     304             :                                            ICacheFlushMode icache_flush_mode) {
     305             :   DCHECK(IsWasmContextReference(rmode_));
     306      186865 :   set_embedded_address(isolate, address, icache_flush_mode);
     307      186865 : }
     308             : 
     309        5627 : void RelocInfo::set_global_handle(Isolate* isolate, Address address,
     310             :                                   ICacheFlushMode icache_flush_mode) {
     311             :   DCHECK_EQ(rmode_, WASM_GLOBAL_HANDLE);
     312        5627 :   set_embedded_address(isolate, address, icache_flush_mode);
     313        5627 : }
     314             : 
     315        5627 : Address RelocInfo::global_handle() const {
     316             :   DCHECK_EQ(rmode_, WASM_GLOBAL_HANDLE);
     317        5627 :   return embedded_address();
     318             : }
     319             : 
     320           0 : uint32_t RelocInfo::wasm_function_table_size_reference() const {
     321             :   DCHECK(IsWasmFunctionTableSizeReference(rmode_));
     322           0 :   return embedded_size();
     323             : }
     324             : 
     325          12 : Address RelocInfo::wasm_context_reference() const {
     326             :   DCHECK(IsWasmContextReference(rmode_));
     327          12 :   return embedded_address();
     328             : }
     329             : 
     330        1266 : void RelocInfo::update_wasm_function_table_size_reference(
     331             :     Isolate* isolate, uint32_t old_size, uint32_t new_size,
     332             :     ICacheFlushMode icache_flush_mode) {
     333             :   DCHECK(IsWasmFunctionTableSizeReference(rmode_));
     334        1266 :   set_embedded_size(isolate, new_size, icache_flush_mode);
     335        1266 : }
     336             : 
     337     9612634 : void RelocInfo::set_target_address(Isolate* isolate, Address target,
     338             :                                    WriteBarrierMode write_barrier_mode,
     339    16147257 :                                    ICacheFlushMode icache_flush_mode) {
     340             :   DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
     341             :   Assembler::set_target_address_at(isolate, pc_, host_, target,
     342     9612634 :                                    icache_flush_mode);
     343    28837523 :   if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != nullptr &&
     344     9612255 :       IsCodeTarget(rmode_)) {
     345     6534623 :     Code* target_code = Code::GetCodeFromTargetAddress(target);
     346             :     host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this,
     347     6534623 :                                                                   target_code);
     348             :   }
     349     9612634 : }
     350             : 
     351    16208972 : uint32_t RelocInfoWriter::WriteLongPCJump(uint32_t pc_delta) {
     352             :   // Return if the pc_delta can fit in kSmallPCDeltaBits bits.
     353             :   // Otherwise write a variable length PC jump for the bits that do
     354             :   // not fit in the kSmallPCDeltaBits bits.
     355    32417944 :   if (is_uintn(pc_delta, kSmallPCDeltaBits)) return pc_delta;
     356             :   WriteMode(RelocInfo::PC_JUMP);
     357     1327651 :   uint32_t pc_jump = pc_delta >> kSmallPCDeltaBits;
     358             :   DCHECK_GT(pc_jump, 0);
     359             :   // Write kChunkBits size chunks of the pc_jump.
     360     2655663 :   for (; pc_jump > 0; pc_jump = pc_jump >> kChunkBits) {
     361     1328012 :     byte b = pc_jump & kChunkMask;
     362     1328012 :     *--pos_ = b << kLastChunkTagBits;
     363             :   }
     364             :   // Tag the last chunk so it can be identified.
     365     1327651 :   *pos_ = *pos_ | kLastChunkTag;
     366             :   // Return the remaining kSmallPCDeltaBits of the pc_delta.
     367     1327651 :   return pc_delta & kSmallPCDeltaMask;
     368             : }
     369             : 
     370             : void RelocInfoWriter::WriteShortTaggedPC(uint32_t pc_delta, int tag) {
     371             :   // Write a byte of tagged pc-delta, possibly preceded by an explicit pc-jump.
     372    11266685 :   pc_delta = WriteLongPCJump(pc_delta);
     373    11266735 :   *--pos_ = pc_delta << kTagBits | tag;
     374             : }
     375             : 
     376             : void RelocInfoWriter::WriteShortData(intptr_t data_delta) {
     377      236611 :   *--pos_ = static_cast<byte>(data_delta);
     378             : }
     379             : 
     380             : void RelocInfoWriter::WriteMode(RelocInfo::Mode rmode) {
     381             :   STATIC_ASSERT(RelocInfo::NUMBER_OF_MODES <= (1 << kLongTagBits));
     382     6269961 :   *--pos_ = static_cast<int>((rmode << kTagBits) | kDefaultTag);
     383             : }
     384             : 
     385     4942304 : void RelocInfoWriter::WriteModeAndPC(uint32_t pc_delta, RelocInfo::Mode rmode) {
     386             :   // Write two-byte tagged pc-delta, possibly preceded by var. length pc-jump.
     387     4942304 :   pc_delta = WriteLongPCJump(pc_delta);
     388             :   WriteMode(rmode);
     389     4942310 :   *--pos_ = pc_delta;
     390     4942310 : }
     391             : 
     392             : void RelocInfoWriter::WriteIntData(int number) {
     393     2860478 :   for (int i = 0; i < kIntSize; i++) {
     394     2860478 :     *--pos_ = static_cast<byte>(number);
     395             :     // Signed right shift is arithmetic shift.  Tested in test-utils.cc.
     396     2860478 :     number = number >> kBitsPerByte;
     397             :   }
     398             : }
     399             : 
     400             : void RelocInfoWriter::WriteData(intptr_t data_delta) {
     401           0 :   for (int i = 0; i < kIntptrSize; i++) {
     402           0 :     *--pos_ = static_cast<byte>(data_delta);
     403             :     // Signed right shift is arithmetic shift.  Tested in test-utils.cc.
     404           0 :     data_delta = data_delta >> kBitsPerByte;
     405             :   }
     406             : }
     407             : 
     408    33369765 : void RelocInfoWriter::Write(const RelocInfo* rinfo) {
     409             :   RelocInfo::Mode rmode = rinfo->rmode();
     410             : #ifdef DEBUG
     411             :   byte* begin_pos = pos_;
     412             : #endif
     413             :   DCHECK(rinfo->rmode() < RelocInfo::NUMBER_OF_MODES);
     414             :   DCHECK_GE(rinfo->pc() - last_pc_, 0);
     415             :   // Use unsigned delta-encoding for pc.
     416    16208988 :   uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_);
     417             : 
     418             :   // The two most common modes are given small tags, and usually fit in a byte.
     419    16208988 :   if (rmode == RelocInfo::EMBEDDED_OBJECT) {
     420             :     WriteShortTaggedPC(pc_delta, kEmbeddedObjectTag);
     421    11211285 :   } else if (rmode == RelocInfo::CODE_TARGET) {
     422             :     WriteShortTaggedPC(pc_delta, kCodeTargetTag);
     423             :     DCHECK_LE(begin_pos - pos_, RelocInfo::kMaxCallSize);
     424     5178914 :   } else if (rmode == RelocInfo::DEOPT_REASON) {
     425             :     DCHECK(rinfo->data() < (1 << kBitsPerByte));
     426             :     WriteShortTaggedPC(pc_delta, kLocatableTag);
     427             :     WriteShortData(rinfo->data());
     428             :   } else {
     429     4942303 :     WriteModeAndPC(pc_delta, rmode);
     430     4942312 :     if (RelocInfo::IsComment(rmode)) {
     431             :       WriteData(rinfo->data());
     432     9884621 :     } else if (RelocInfo::IsConstPool(rmode) ||
     433     9648011 :                RelocInfo::IsVeneerPool(rmode) || RelocInfo::IsDeoptId(rmode) ||
     434     9174795 :                RelocInfo::IsDeoptPosition(rmode) ||
     435             :                RelocInfo::IsWasmProtectedLanding(rmode)) {
     436      715119 :       WriteIntData(static_cast<int>(rinfo->data()));
     437             :     }
     438             :   }
     439    16209047 :   last_pc_ = rinfo->pc();
     440    16209047 :   last_mode_ = rmode;
     441             : #ifdef DEBUG
     442             :   DCHECK_LE(begin_pos - pos_, kMaxSize);
     443             : #endif
     444    16209047 : }
     445             : 
     446             : inline int RelocIterator::AdvanceGetTag() {
     447   613238966 :   return *--pos_ & kTagMask;
     448             : }
     449             : 
     450             : inline RelocInfo::Mode RelocIterator::GetMode() {
     451             :   return static_cast<RelocInfo::Mode>((*pos_ >> kTagBits) &
     452   373383402 :                                       ((1 << kLongTagBits) - 1));
     453             : }
     454             : 
     455             : inline void RelocIterator::ReadShortTaggedPC() {
     456   239855564 :   rinfo_.pc_ += *pos_ >> kTagBits;
     457             : }
     458             : 
     459             : inline void RelocIterator::AdvanceReadPC() {
     460   244391818 :   rinfo_.pc_ += *--pos_;
     461             : }
     462             : 
     463           0 : void RelocIterator::AdvanceReadInt() {
     464             :   int x = 0;
     465       41232 :   for (int i = 0; i < kIntSize; i++) {
     466       41232 :     x |= static_cast<int>(*--pos_) << i * kBitsPerByte;
     467             :   }
     468       10308 :   rinfo_.data_ = x;
     469           0 : }
     470             : 
     471           0 : void RelocIterator::AdvanceReadData() {
     472             :   intptr_t x = 0;
     473           0 :   for (int i = 0; i < kIntptrSize; i++) {
     474           0 :     x |= static_cast<intptr_t>(*--pos_) << i * kBitsPerByte;
     475             :   }
     476           0 :   rinfo_.data_ = x;
     477           0 : }
     478             : 
     479   128991587 : void RelocIterator::AdvanceReadLongPCJump() {
     480             :   // Read the 32-kSmallPCDeltaBits most significant bits of the
     481             :   // pc jump in kChunkBits bit chunks and shift them into place.
     482             :   // Stop when the last chunk is encountered.
     483             :   uint32_t pc_jump = 0;
     484   128992158 :   for (int i = 0; i < kIntSize; i++) {
     485   128992155 :     byte pc_jump_part = *--pos_;
     486   128992155 :     pc_jump |= (pc_jump_part >> kLastChunkTagBits) << i * kChunkBits;
     487   128992155 :     if ((pc_jump_part & kLastChunkTagMask) == 1) break;
     488             :   }
     489             :   // The least significant kSmallPCDeltaBits bits will be added
     490             :   // later.
     491   128991587 :   rinfo_.pc_ += pc_jump << kSmallPCDeltaBits;
     492   128991587 : }
     493             : 
     494             : inline void RelocIterator::ReadShortData() {
     495           6 :   uint8_t unsigned_b = *pos_;
     496           6 :   rinfo_.data_ = unsigned_b;
     497             : }
     498             : 
     499  1008272004 : void RelocIterator::next() {
     500             :   DCHECK(!done());
     501             :   // Basically, do the opposite of RelocInfoWriter::Write.
     502             :   // Reading of data is as far as possible avoided for unwanted modes,
     503             :   // but we must always update the pc.
     504             :   //
     505             :   // We exit this loop by returning when we find a mode we want.
     506  1197709433 :   while (pos_ > end_) {
     507             :     int tag = AdvanceGetTag();
     508   613238966 :     if (tag == kEmbeddedObjectTag) {
     509             :       ReadShortTaggedPC();
     510    20018899 :       if (SetMode(RelocInfo::EMBEDDED_OBJECT)) return;
     511   593220067 :     } else if (tag == kCodeTargetTag) {
     512             :       ReadShortTaggedPC();
     513   218543368 :       if (SetMode(RelocInfo::CODE_TARGET)) return;
     514   374676699 :     } else if (tag == kLocatableTag) {
     515             :       ReadShortTaggedPC();
     516             :       Advance();
     517     1293297 :       if (SetMode(RelocInfo::DEOPT_REASON)) {
     518             :         ReadShortData();
     519             :         return;
     520             :       }
     521             :     } else {
     522             :       DCHECK_EQ(tag, kDefaultTag);
     523             :       RelocInfo::Mode rmode = GetMode();
     524   373383402 :       if (rmode == RelocInfo::PC_JUMP) {
     525   128991584 :         AdvanceReadLongPCJump();
     526             :       } else {
     527             :         AdvanceReadPC();
     528   244391818 :         if (RelocInfo::IsComment(rmode)) {
     529           0 :           if (SetMode(rmode)) {
     530             :             AdvanceReadData();
     531             :             return;
     532             :           }
     533             :           Advance(kIntptrSize);
     534   488783512 :         } else if (RelocInfo::IsConstPool(rmode) ||
     535   244391717 :                    RelocInfo::IsVeneerPool(rmode) ||
     536   243098435 :                    RelocInfo::IsDeoptId(rmode) ||
     537   484903671 :                    RelocInfo::IsDeoptPosition(rmode) ||
     538             :                    RelocInfo::IsWasmProtectedLanding(rmode)) {
     539     3896683 :           if (SetMode(rmode)) {
     540             :             AdvanceReadInt();
     541             :             return;
     542             :           }
     543             :           Advance(kIntSize);
     544   240495135 :         } else if (SetMode(static_cast<RelocInfo::Mode>(rmode))) {
     545             :           return;
     546             :         }
     547             :       }
     548             :     }
     549             :   }
     550    60445845 :   done_ = true;
     551             : }
     552             : 
     553    60613419 : RelocIterator::RelocIterator(Code* code, int mode_mask) {
     554    60613419 :   rinfo_.host_ = code;
     555    60613419 :   rinfo_.pc_ = code->instruction_start();
     556    60613419 :   rinfo_.data_ = 0;
     557             :   // Relocation info is read backwards.
     558   121226838 :   pos_ = code->relocation_start() + code->relocation_size();
     559    60613419 :   end_ = code->relocation_start();
     560    60613419 :   done_ = false;
     561    60613419 :   mode_mask_ = mode_mask;
     562    60613419 :   if (mode_mask_ == 0) pos_ = end_;
     563    60613419 :   next();
     564    60613462 : }
     565             : 
     566           0 : RelocIterator::RelocIterator(const CodeDesc& desc, int mode_mask) {
     567           0 :   rinfo_.pc_ = desc.buffer;
     568           0 :   rinfo_.data_ = 0;
     569             :   // Relocation info is read backwards.
     570           0 :   pos_ = desc.buffer + desc.buffer_size;
     571           0 :   end_ = pos_ - desc.reloc_size;
     572           0 :   done_ = false;
     573           0 :   mode_mask_ = mode_mask;
     574           0 :   if (mode_mask_ == 0) pos_ = end_;
     575           0 :   next();
     576           0 : }
     577             : 
     578             : // -----------------------------------------------------------------------------
     579             : // Implementation of RelocInfo
     580             : 
     581             : #ifdef DEBUG
     582             : bool RelocInfo::RequiresRelocation(Isolate* isolate, const CodeDesc& desc) {
     583             :   // Ensure there are no code targets or embedded objects present in the
     584             :   // deoptimization entries, they would require relocation after code
     585             :   // generation.
     586             :   int mode_mask = RelocInfo::kCodeTargetMask |
     587             :                   RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
     588             :                   RelocInfo::kApplyMask;
     589             :   RelocIterator it(desc, mode_mask);
     590             :   return !it.done();
     591             : }
     592             : #endif
     593             : 
     594             : #ifdef ENABLE_DISASSEMBLER
     595             : const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
     596             :   switch (rmode) {
     597             :     case NONE32:
     598             :       return "no reloc 32";
     599             :     case NONE64:
     600             :       return "no reloc 64";
     601             :     case EMBEDDED_OBJECT:
     602             :       return "embedded object";
     603             :     case CODE_TARGET:
     604             :       return "code target";
     605             :     case RUNTIME_ENTRY:
     606             :       return "runtime entry";
     607             :     case COMMENT:
     608             :       return "comment";
     609             :     case EXTERNAL_REFERENCE:
     610             :       return "external reference";
     611             :     case INTERNAL_REFERENCE:
     612             :       return "internal reference";
     613             :     case INTERNAL_REFERENCE_ENCODED:
     614             :       return "encoded internal reference";
     615             :     case DEOPT_SCRIPT_OFFSET:
     616             :       return "deopt script offset";
     617             :     case DEOPT_INLINING_ID:
     618             :       return "deopt inlining id";
     619             :     case DEOPT_REASON:
     620             :       return "deopt reason";
     621             :     case DEOPT_ID:
     622             :       return "deopt index";
     623             :     case CONST_POOL:
     624             :       return "constant pool";
     625             :     case VENEER_POOL:
     626             :       return "veneer pool";
     627             :     case WASM_CONTEXT_REFERENCE:
     628             :       return "wasm context reference";
     629             :     case WASM_FUNCTION_TABLE_SIZE_REFERENCE:
     630             :       return "wasm function table size reference";
     631             :     case WASM_PROTECTED_INSTRUCTION_LANDING:
     632             :       return "wasm protected instruction landing";
     633             :     case WASM_GLOBAL_HANDLE:
     634             :       return "global handle";
     635             :     case NUMBER_OF_MODES:
     636             :     case PC_JUMP:
     637             :       UNREACHABLE();
     638             :   }
     639             :   return "unknown relocation type";
     640             : }
     641             : 
     642             : void RelocInfo::Print(Isolate* isolate, std::ostream& os) {  // NOLINT
     643             :   os << static_cast<const void*>(pc_) << "  " << RelocModeName(rmode_);
     644             :   if (IsComment(rmode_)) {
     645             :     os << "  (" << reinterpret_cast<char*>(data_) << ")";
     646             :   } else if (rmode_ == DEOPT_SCRIPT_OFFSET || rmode_ == DEOPT_INLINING_ID) {
     647             :     os << "  (" << data() << ")";
     648             :   } else if (rmode_ == DEOPT_REASON) {
     649             :     os << "  ("
     650             :        << DeoptimizeReasonToString(static_cast<DeoptimizeReason>(data_)) << ")";
     651             :   } else if (rmode_ == EMBEDDED_OBJECT) {
     652             :     os << "  (" << Brief(target_object()) << ")";
     653             :   } else if (rmode_ == EXTERNAL_REFERENCE) {
     654             :     ExternalReferenceEncoder ref_encoder(isolate);
     655             :     os << " ("
     656             :        << ref_encoder.NameOfAddress(isolate, target_external_reference())
     657             :        << ")  (" << static_cast<const void*>(target_external_reference())
     658             :        << ")";
     659             :   } else if (IsCodeTarget(rmode_)) {
     660             :     Code* code = Code::GetCodeFromTargetAddress(target_address());
     661             :     os << " (" << Code::Kind2String(code->kind()) << ")  ("
     662             :        << static_cast<const void*>(target_address()) << ")";
     663             :   } else if (IsRuntimeEntry(rmode_) && isolate->deoptimizer_data() != nullptr) {
     664             :     // Depotimization bailouts are stored as runtime entries.
     665             :     int id = Deoptimizer::GetDeoptimizationId(
     666             :         isolate, target_address(), Deoptimizer::EAGER);
     667             :     if (id != Deoptimizer::kNotDeoptimizationEntry) {
     668             :       os << "  (deoptimization bailout " << id << ")";
     669             :     }
     670             :   } else if (IsConstPool(rmode_)) {
     671             :     os << " (size " << static_cast<int>(data_) << ")";
     672             :   }
     673             : 
     674             :   os << "\n";
     675             : }
     676             : #endif  // ENABLE_DISASSEMBLER
     677             : 
     678             : #ifdef VERIFY_HEAP
     679             : void RelocInfo::Verify(Isolate* isolate) {
     680             :   switch (rmode_) {
     681             :     case EMBEDDED_OBJECT:
     682             :       Object::VerifyPointer(target_object());
     683             :       break;
     684             :     case CODE_TARGET: {
     685             :       // convert inline target address to code object
     686             :       Address addr = target_address();
     687             :       CHECK_NOT_NULL(addr);
     688             :       // Check that we can find the right code object.
     689             :       Code* code = Code::GetCodeFromTargetAddress(addr);
     690             :       Object* found = isolate->FindCodeObject(addr);
     691             :       CHECK(found->IsCode());
     692             :       CHECK(code->address() == HeapObject::cast(found)->address());
     693             :       break;
     694             :     }
     695             :     case INTERNAL_REFERENCE:
     696             :     case INTERNAL_REFERENCE_ENCODED: {
     697             :       Address target = target_internal_reference();
     698             :       Address pc = target_internal_reference_address();
     699             :       Code* code = Code::cast(isolate->FindCodeObject(pc));
     700             :       CHECK(target >= code->instruction_start());
     701             :       CHECK(target <= code->instruction_end());
     702             :       break;
     703             :     }
     704             :     case RUNTIME_ENTRY:
     705             :     case COMMENT:
     706             :     case EXTERNAL_REFERENCE:
     707             :     case DEOPT_SCRIPT_OFFSET:
     708             :     case DEOPT_INLINING_ID:
     709             :     case DEOPT_REASON:
     710             :     case DEOPT_ID:
     711             :     case CONST_POOL:
     712             :     case VENEER_POOL:
     713             :     case WASM_CONTEXT_REFERENCE:
     714             :     case WASM_FUNCTION_TABLE_SIZE_REFERENCE:
     715             :     case WASM_GLOBAL_HANDLE:
     716             :     case WASM_PROTECTED_INSTRUCTION_LANDING:
     717             :     // TODO(eholk): make sure the protected instruction is in range.
     718             :     case NONE32:
     719             :     case NONE64:
     720             :       break;
     721             :     case NUMBER_OF_MODES:
     722             :     case PC_JUMP:
     723             :       UNREACHABLE();
     724             :       break;
     725             :   }
     726             : }
     727             : #endif  // VERIFY_HEAP
     728             : 
     729             : // Implementation of ExternalReference
     730             : 
     731    32290037 : static ExternalReference::Type BuiltinCallTypeForResultSize(int result_size) {
     732    32290037 :   switch (result_size) {
     733             :     case 1:
     734             :       return ExternalReference::BUILTIN_CALL;
     735             :     case 2:
     736       55703 :       return ExternalReference::BUILTIN_CALL_PAIR;
     737             :   }
     738           0 :   UNREACHABLE();
     739             : }
     740             : 
     741       53977 : void ExternalReference::SetUp() {
     742       53977 :   double_constants.min_int = kMinInt;
     743       53977 :   double_constants.one_half = 0.5;
     744       53977 :   double_constants.minus_one_half = -0.5;
     745       53977 :   double_constants.the_hole_nan = kHoleNanInt64;
     746       53977 :   double_constants.negative_infinity = -V8_INFINITY;
     747             :   double_constants.uint32_bias =
     748       53977 :     static_cast<double>(static_cast<uint32_t>(0xFFFFFFFF)) + 1;
     749       53977 : }
     750             : 
     751    12570562 : ExternalReference::ExternalReference(Address address, Isolate* isolate)
     752    12570562 :     : address_(Redirect(isolate, address)) {}
     753             : 
     754      169757 : ExternalReference::ExternalReference(
     755             :     ApiFunction* fun, Type type = ExternalReference::BUILTIN_CALL,
     756             :     Isolate* isolate = nullptr)
     757      169757 :     : address_(Redirect(isolate, fun->address(), type)) {}
     758             : 
     759    32288438 : ExternalReference::ExternalReference(Runtime::FunctionId id, Isolate* isolate)
     760    32288438 :     : ExternalReference(Runtime::FunctionForId(id), isolate) {}
     761             : 
     762    32290048 : ExternalReference::ExternalReference(const Runtime::Function* f,
     763             :                                      Isolate* isolate)
     764             :     : address_(Redirect(isolate, f->entry,
     765    64580096 :                         BuiltinCallTypeForResultSize(f->result_size))) {}
     766             : 
     767      583497 : ExternalReference ExternalReference::isolate_address(Isolate* isolate) {
     768      583497 :   return ExternalReference(isolate);
     769             : }
     770             : 
     771       55342 : ExternalReference ExternalReference::builtins_address(Isolate* isolate) {
     772       55342 :   return ExternalReference(isolate->builtins()->builtins_table_address());
     773             : }
     774             : 
     775       56241 : ExternalReference ExternalReference::interpreter_dispatch_table_address(
     776       56241 :     Isolate* isolate) {
     777       56241 :   return ExternalReference(isolate->interpreter()->dispatch_table_address());
     778             : }
     779             : 
     780           0 : ExternalReference ExternalReference::interpreter_dispatch_counters(
     781           0 :     Isolate* isolate) {
     782             :   return ExternalReference(
     783           0 :       isolate->interpreter()->bytecode_dispatch_counters_table());
     784             : }
     785             : 
     786       55373 : ExternalReference ExternalReference::bytecode_size_table_address(
     787             :     Isolate* isolate) {
     788             :   return ExternalReference(
     789       55373 :       interpreter::Bytecodes::bytecode_size_table_address());
     790             : }
     791             : 
     792           0 : ExternalReference::ExternalReference(StatsCounter* counter)
     793           0 :   : address_(reinterpret_cast<Address>(counter->GetInternalPointer())) {}
     794             : 
     795      194942 : ExternalReference::ExternalReference(IsolateAddressId id, Isolate* isolate)
     796      194942 :     : address_(isolate->get_address_from_id(id)) {}
     797             : 
     798         322 : ExternalReference::ExternalReference(const SCTableReference& table_ref)
     799         322 :   : address_(table_ref.address()) {}
     800             : 
     801       55342 : ExternalReference ExternalReference::
     802             :     incremental_marking_record_write_function(Isolate* isolate) {
     803             :   return ExternalReference(Redirect(
     804             :       isolate,
     805       55342 :       FUNCTION_ADDR(IncrementalMarking::RecordWriteFromCode)));
     806             : }
     807             : 
     808       55435 : ExternalReference ExternalReference::store_buffer_overflow_function(
     809             :     Isolate* isolate) {
     810             :   return ExternalReference(Redirect(
     811             :       isolate,
     812       55435 :       FUNCTION_ADDR(StoreBuffer::StoreBufferOverflow)));
     813             : }
     814             : 
     815       58822 : ExternalReference ExternalReference::delete_handle_scope_extensions(
     816             :     Isolate* isolate) {
     817             :   return ExternalReference(Redirect(
     818             :       isolate,
     819       58822 :       FUNCTION_ADDR(HandleScope::DeleteExtensions)));
     820             : }
     821             : 
     822       55838 : ExternalReference ExternalReference::get_date_field_function(
     823             :     Isolate* isolate) {
     824       55838 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(JSDate::GetField)));
     825             : }
     826             : 
     827       55528 : ExternalReference ExternalReference::date_cache_stamp(Isolate* isolate) {
     828       55528 :   return ExternalReference(isolate->date_cache()->stamp_address());
     829             : }
     830             : 
     831           0 : void ExternalReference::set_redirector(
     832             :     Isolate* isolate, ExternalReferenceRedirector* redirector) {
     833             :   // We can't stack them.
     834             :   DCHECK_NULL(isolate->external_reference_redirector());
     835             :   isolate->set_external_reference_redirector(
     836             :       reinterpret_cast<ExternalReferenceRedirectorPointer*>(redirector));
     837           0 : }
     838             : 
     839       55579 : ExternalReference ExternalReference::stress_deopt_count(Isolate* isolate) {
     840       55579 :   return ExternalReference(isolate->stress_deopt_count_address());
     841             : }
     842             : 
     843       93743 : ExternalReference ExternalReference::new_deoptimizer_function(
     844             :     Isolate* isolate) {
     845             :   return ExternalReference(
     846       93743 :       Redirect(isolate, FUNCTION_ADDR(Deoptimizer::New)));
     847             : }
     848             : 
     849       93743 : ExternalReference ExternalReference::compute_output_frames_function(
     850             :     Isolate* isolate) {
     851             :   return ExternalReference(
     852       93743 :       Redirect(isolate, FUNCTION_ADDR(Deoptimizer::ComputeOutputFrames)));
     853             : }
     854             : 
     855       55317 : ExternalReference ExternalReference::wasm_f32_trunc(Isolate* isolate) {
     856             :   return ExternalReference(
     857       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::f32_trunc_wrapper)));
     858             : }
     859       55317 : ExternalReference ExternalReference::wasm_f32_floor(Isolate* isolate) {
     860             :   return ExternalReference(
     861       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::f32_floor_wrapper)));
     862             : }
     863       55317 : ExternalReference ExternalReference::wasm_f32_ceil(Isolate* isolate) {
     864             :   return ExternalReference(
     865       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::f32_ceil_wrapper)));
     866             : }
     867       55317 : ExternalReference ExternalReference::wasm_f32_nearest_int(Isolate* isolate) {
     868             :   return ExternalReference(
     869       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::f32_nearest_int_wrapper)));
     870             : }
     871             : 
     872       55317 : ExternalReference ExternalReference::wasm_f64_trunc(Isolate* isolate) {
     873             :   return ExternalReference(
     874       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::f64_trunc_wrapper)));
     875             : }
     876             : 
     877       55317 : ExternalReference ExternalReference::wasm_f64_floor(Isolate* isolate) {
     878             :   return ExternalReference(
     879       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::f64_floor_wrapper)));
     880             : }
     881             : 
     882       55317 : ExternalReference ExternalReference::wasm_f64_ceil(Isolate* isolate) {
     883             :   return ExternalReference(
     884       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::f64_ceil_wrapper)));
     885             : }
     886             : 
     887       55317 : ExternalReference ExternalReference::wasm_f64_nearest_int(Isolate* isolate) {
     888             :   return ExternalReference(
     889       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::f64_nearest_int_wrapper)));
     890             : }
     891             : 
     892       55317 : ExternalReference ExternalReference::wasm_int64_to_float32(Isolate* isolate) {
     893             :   return ExternalReference(
     894       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::int64_to_float32_wrapper)));
     895             : }
     896             : 
     897       55317 : ExternalReference ExternalReference::wasm_uint64_to_float32(Isolate* isolate) {
     898             :   return ExternalReference(
     899       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::uint64_to_float32_wrapper)));
     900             : }
     901             : 
     902       55317 : ExternalReference ExternalReference::wasm_int64_to_float64(Isolate* isolate) {
     903             :   return ExternalReference(
     904       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::int64_to_float64_wrapper)));
     905             : }
     906             : 
     907       55317 : ExternalReference ExternalReference::wasm_uint64_to_float64(Isolate* isolate) {
     908             :   return ExternalReference(
     909       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::uint64_to_float64_wrapper)));
     910             : }
     911             : 
     912       55317 : ExternalReference ExternalReference::wasm_float32_to_int64(Isolate* isolate) {
     913             :   return ExternalReference(
     914       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::float32_to_int64_wrapper)));
     915             : }
     916             : 
     917       55317 : ExternalReference ExternalReference::wasm_float32_to_uint64(Isolate* isolate) {
     918             :   return ExternalReference(
     919       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::float32_to_uint64_wrapper)));
     920             : }
     921             : 
     922       55317 : ExternalReference ExternalReference::wasm_float64_to_int64(Isolate* isolate) {
     923             :   return ExternalReference(
     924       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::float64_to_int64_wrapper)));
     925             : }
     926             : 
     927       55317 : ExternalReference ExternalReference::wasm_float64_to_uint64(Isolate* isolate) {
     928             :   return ExternalReference(
     929       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::float64_to_uint64_wrapper)));
     930             : }
     931             : 
     932       55316 : ExternalReference ExternalReference::wasm_int64_div(Isolate* isolate) {
     933             :   return ExternalReference(
     934       55316 :       Redirect(isolate, FUNCTION_ADDR(wasm::int64_div_wrapper)));
     935             : }
     936             : 
     937       55316 : ExternalReference ExternalReference::wasm_int64_mod(Isolate* isolate) {
     938             :   return ExternalReference(
     939       55316 :       Redirect(isolate, FUNCTION_ADDR(wasm::int64_mod_wrapper)));
     940             : }
     941             : 
     942       55317 : ExternalReference ExternalReference::wasm_uint64_div(Isolate* isolate) {
     943             :   return ExternalReference(
     944       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::uint64_div_wrapper)));
     945             : }
     946             : 
     947       55317 : ExternalReference ExternalReference::wasm_uint64_mod(Isolate* isolate) {
     948             :   return ExternalReference(
     949       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::uint64_mod_wrapper)));
     950             : }
     951             : 
     952       55317 : ExternalReference ExternalReference::wasm_word32_ctz(Isolate* isolate) {
     953             :   return ExternalReference(
     954       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::word32_ctz_wrapper)));
     955             : }
     956             : 
     957       55317 : ExternalReference ExternalReference::wasm_word64_ctz(Isolate* isolate) {
     958             :   return ExternalReference(
     959       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::word64_ctz_wrapper)));
     960             : }
     961             : 
     962       55317 : ExternalReference ExternalReference::wasm_word32_popcnt(Isolate* isolate) {
     963             :   return ExternalReference(
     964       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::word32_popcnt_wrapper)));
     965             : }
     966             : 
     967       55317 : ExternalReference ExternalReference::wasm_word64_popcnt(Isolate* isolate) {
     968             :   return ExternalReference(
     969       55317 :       Redirect(isolate, FUNCTION_ADDR(wasm::word64_popcnt_wrapper)));
     970             : }
     971             : 
     972        6290 : static void f64_acos_wrapper(double* param) {
     973        6290 :   WriteDoubleValue(param, base::ieee754::acos(ReadDoubleValue(param)));
     974        6290 : }
     975             : 
     976       55329 : ExternalReference ExternalReference::f64_acos_wrapper_function(
     977             :     Isolate* isolate) {
     978       55329 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(f64_acos_wrapper)));
     979             : }
     980             : 
     981        6290 : static void f64_asin_wrapper(double* param) {
     982        6290 :   WriteDoubleValue(param, base::ieee754::asin(ReadDoubleValue(param)));
     983        6290 : }
     984             : 
     985       55330 : ExternalReference ExternalReference::f64_asin_wrapper_function(
     986             :     Isolate* isolate) {
     987       55330 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(f64_asin_wrapper)));
     988             : }
     989             : 
     990       55330 : ExternalReference ExternalReference::wasm_float64_pow(Isolate* isolate) {
     991             :   return ExternalReference(
     992       55330 :       Redirect(isolate, FUNCTION_ADDR(wasm::float64_pow_wrapper)));
     993             : }
     994             : 
     995       73203 : ExternalReference ExternalReference::wasm_set_thread_in_wasm_flag(
     996             :     Isolate* isolate) {
     997             :   return ExternalReference(
     998       73203 :       Redirect(isolate, FUNCTION_ADDR(wasm::set_thread_in_wasm_flag)));
     999             : }
    1000             : 
    1001       73202 : ExternalReference ExternalReference::wasm_clear_thread_in_wasm_flag(
    1002             :     Isolate* isolate) {
    1003             :   return ExternalReference(
    1004       73202 :       Redirect(isolate, FUNCTION_ADDR(wasm::clear_thread_in_wasm_flag)));
    1005             : }
    1006             : 
    1007          42 : static void f64_mod_wrapper(double* param0, double* param1) {
    1008             :   WriteDoubleValue(param0,
    1009             :                    Modulo(ReadDoubleValue(param0), ReadDoubleValue(param1)));
    1010          42 : }
    1011             : 
    1012       55341 : ExternalReference ExternalReference::f64_mod_wrapper_function(
    1013             :     Isolate* isolate) {
    1014       55341 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(f64_mod_wrapper)));
    1015             : }
    1016             : 
    1017       90238 : ExternalReference ExternalReference::wasm_call_trap_callback_for_testing(
    1018             :     Isolate* isolate) {
    1019             :   return ExternalReference(
    1020       90238 :       Redirect(isolate, FUNCTION_ADDR(wasm::call_trap_callback_for_testing)));
    1021             : }
    1022             : 
    1023       55310 : ExternalReference ExternalReference::log_enter_external_function(
    1024             :     Isolate* isolate) {
    1025             :   return ExternalReference(
    1026       55310 :       Redirect(isolate, FUNCTION_ADDR(Logger::EnterExternal)));
    1027             : }
    1028             : 
    1029       55310 : ExternalReference ExternalReference::log_leave_external_function(
    1030             :     Isolate* isolate) {
    1031             :   return ExternalReference(
    1032       55310 :       Redirect(isolate, FUNCTION_ADDR(Logger::LeaveExternal)));
    1033             : }
    1034             : 
    1035      299623 : ExternalReference ExternalReference::roots_array_start(Isolate* isolate) {
    1036      299623 :   return ExternalReference(isolate->heap()->roots_array_start());
    1037             : }
    1038             : 
    1039       55528 : ExternalReference ExternalReference::allocation_sites_list_address(
    1040             :     Isolate* isolate) {
    1041       55528 :   return ExternalReference(isolate->heap()->allocation_sites_list_address());
    1042             : }
    1043             : 
    1044     1715717 : ExternalReference ExternalReference::address_of_stack_limit(Isolate* isolate) {
    1045     1715717 :   return ExternalReference(isolate->stack_guard()->address_of_jslimit());
    1046             : }
    1047             : 
    1048       55321 : ExternalReference ExternalReference::address_of_real_stack_limit(
    1049             :     Isolate* isolate) {
    1050       55321 :   return ExternalReference(isolate->stack_guard()->address_of_real_jslimit());
    1051             : }
    1052             : 
    1053      686848 : ExternalReference ExternalReference::address_of_regexp_stack_limit(
    1054      686848 :     Isolate* isolate) {
    1055      686848 :   return ExternalReference(isolate->regexp_stack()->limit_address());
    1056             : }
    1057             : 
    1058       55435 : ExternalReference ExternalReference::address_of_regexp_dotall_flag(
    1059             :     Isolate* isolate) {
    1060       55435 :   return ExternalReference(&FLAG_harmony_regexp_dotall);
    1061             : }
    1062             : 
    1063       55373 : ExternalReference ExternalReference::store_buffer_top(Isolate* isolate) {
    1064       55373 :   return ExternalReference(isolate->heap()->store_buffer_top_address());
    1065             : }
    1066             : 
    1067       55342 : ExternalReference ExternalReference::heap_is_marking_flag_address(
    1068             :     Isolate* isolate) {
    1069       55342 :   return ExternalReference(isolate->heap()->IsMarkingFlagAddress());
    1070             : }
    1071             : 
    1072      227347 : ExternalReference ExternalReference::new_space_allocation_top_address(
    1073             :     Isolate* isolate) {
    1074      227347 :   return ExternalReference(isolate->heap()->NewSpaceAllocationTopAddress());
    1075             : }
    1076             : 
    1077      192861 : ExternalReference ExternalReference::new_space_allocation_limit_address(
    1078             :     Isolate* isolate) {
    1079      192861 :   return ExternalReference(isolate->heap()->NewSpaceAllocationLimitAddress());
    1080             : }
    1081             : 
    1082       56844 : ExternalReference ExternalReference::old_space_allocation_top_address(
    1083             :     Isolate* isolate) {
    1084       56844 :   return ExternalReference(isolate->heap()->OldSpaceAllocationTopAddress());
    1085             : }
    1086             : 
    1087       55511 : ExternalReference ExternalReference::old_space_allocation_limit_address(
    1088             :     Isolate* isolate) {
    1089       55511 :   return ExternalReference(isolate->heap()->OldSpaceAllocationLimitAddress());
    1090             : }
    1091             : 
    1092       58822 : ExternalReference ExternalReference::handle_scope_level_address(
    1093             :     Isolate* isolate) {
    1094       58822 :   return ExternalReference(HandleScope::current_level_address(isolate));
    1095             : }
    1096             : 
    1097       58822 : ExternalReference ExternalReference::handle_scope_next_address(
    1098             :     Isolate* isolate) {
    1099       58822 :   return ExternalReference(HandleScope::current_next_address(isolate));
    1100             : }
    1101             : 
    1102       58822 : ExternalReference ExternalReference::handle_scope_limit_address(
    1103             :     Isolate* isolate) {
    1104       58822 :   return ExternalReference(HandleScope::current_limit_address(isolate));
    1105             : }
    1106             : 
    1107       58822 : ExternalReference ExternalReference::scheduled_exception_address(
    1108             :     Isolate* isolate) {
    1109       58822 :   return ExternalReference(isolate->scheduled_exception_address());
    1110             : }
    1111             : 
    1112      107928 : ExternalReference ExternalReference::address_of_pending_message_obj(
    1113             :     Isolate* isolate) {
    1114      107928 :   return ExternalReference(isolate->pending_message_obj_address());
    1115             : }
    1116             : 
    1117       55335 : ExternalReference ExternalReference::address_of_min_int() {
    1118       55335 :   return ExternalReference(reinterpret_cast<void*>(&double_constants.min_int));
    1119             : }
    1120             : 
    1121       55335 : ExternalReference ExternalReference::address_of_one_half() {
    1122       55335 :   return ExternalReference(reinterpret_cast<void*>(&double_constants.one_half));
    1123             : }
    1124             : 
    1125       55311 : ExternalReference ExternalReference::address_of_minus_one_half() {
    1126             :   return ExternalReference(
    1127       55311 :       reinterpret_cast<void*>(&double_constants.minus_one_half));
    1128             : }
    1129             : 
    1130       55311 : ExternalReference ExternalReference::address_of_negative_infinity() {
    1131             :   return ExternalReference(
    1132       55311 :       reinterpret_cast<void*>(&double_constants.negative_infinity));
    1133             : }
    1134             : 
    1135       55317 : ExternalReference ExternalReference::address_of_the_hole_nan() {
    1136             :   return ExternalReference(
    1137       55317 :       reinterpret_cast<void*>(&double_constants.the_hole_nan));
    1138             : }
    1139             : 
    1140       55311 : ExternalReference ExternalReference::address_of_uint32_bias() {
    1141             :   return ExternalReference(
    1142       55311 :       reinterpret_cast<void*>(&double_constants.uint32_bias));
    1143             : }
    1144             : 
    1145       55316 : ExternalReference ExternalReference::address_of_float_abs_constant() {
    1146       55316 :   return ExternalReference(reinterpret_cast<void*>(&float_absolute_constant));
    1147             : }
    1148             : 
    1149       55317 : ExternalReference ExternalReference::address_of_float_neg_constant() {
    1150       55317 :   return ExternalReference(reinterpret_cast<void*>(&float_negate_constant));
    1151             : }
    1152             : 
    1153       55317 : ExternalReference ExternalReference::address_of_double_abs_constant() {
    1154       55317 :   return ExternalReference(reinterpret_cast<void*>(&double_absolute_constant));
    1155             : }
    1156             : 
    1157       55317 : ExternalReference ExternalReference::address_of_double_neg_constant() {
    1158       55317 :   return ExternalReference(reinterpret_cast<void*>(&double_negate_constant));
    1159             : }
    1160             : 
    1161       58822 : ExternalReference ExternalReference::is_profiling_address(Isolate* isolate) {
    1162       58822 :   return ExternalReference(isolate->is_profiling_address());
    1163             : }
    1164             : 
    1165       58791 : ExternalReference ExternalReference::invoke_function_callback(
    1166             :     Isolate* isolate) {
    1167             :   Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
    1168             :   ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
    1169             :   ApiFunction thunk_fun(thunk_address);
    1170       58791 :   return ExternalReference(&thunk_fun, thunk_type, isolate);
    1171             : }
    1172             : 
    1173       55342 : ExternalReference ExternalReference::invoke_accessor_getter_callback(
    1174             :     Isolate* isolate) {
    1175             :   Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
    1176             :   ExternalReference::Type thunk_type =
    1177             :       ExternalReference::PROFILING_GETTER_CALL;
    1178             :   ApiFunction thunk_fun(thunk_address);
    1179       55342 :   return ExternalReference(&thunk_fun, thunk_type, isolate);
    1180             : }
    1181             : 
    1182             : #ifndef V8_INTERPRETED_REGEXP
    1183             : 
    1184      242437 : ExternalReference ExternalReference::re_check_stack_guard_state(
    1185             :     Isolate* isolate) {
    1186             :   Address function;
    1187             : #if V8_TARGET_ARCH_X64
    1188             :   function = FUNCTION_ADDR(RegExpMacroAssemblerX64::CheckStackGuardState);
    1189             : #elif V8_TARGET_ARCH_IA32
    1190             :   function = FUNCTION_ADDR(RegExpMacroAssemblerIA32::CheckStackGuardState);
    1191             : #elif V8_TARGET_ARCH_ARM64
    1192             :   function = FUNCTION_ADDR(RegExpMacroAssemblerARM64::CheckStackGuardState);
    1193             : #elif V8_TARGET_ARCH_ARM
    1194             :   function = FUNCTION_ADDR(RegExpMacroAssemblerARM::CheckStackGuardState);
    1195             : #elif V8_TARGET_ARCH_PPC
    1196             :   function = FUNCTION_ADDR(RegExpMacroAssemblerPPC::CheckStackGuardState);
    1197             : #elif V8_TARGET_ARCH_MIPS
    1198             :   function = FUNCTION_ADDR(RegExpMacroAssemblerMIPS::CheckStackGuardState);
    1199             : #elif V8_TARGET_ARCH_MIPS64
    1200             :   function = FUNCTION_ADDR(RegExpMacroAssemblerMIPS::CheckStackGuardState);
    1201             : #elif V8_TARGET_ARCH_S390
    1202             :   function = FUNCTION_ADDR(RegExpMacroAssemblerS390::CheckStackGuardState);
    1203             : #else
    1204             :   UNREACHABLE();
    1205             : #endif
    1206      242437 :   return ExternalReference(Redirect(isolate, function));
    1207             : }
    1208             : 
    1209      148859 : ExternalReference ExternalReference::re_grow_stack(Isolate* isolate) {
    1210             :   return ExternalReference(
    1211      148859 :       Redirect(isolate, FUNCTION_ADDR(NativeRegExpMacroAssembler::GrowStack)));
    1212             : }
    1213             : 
    1214       55576 : ExternalReference ExternalReference::re_case_insensitive_compare_uc16(
    1215             :     Isolate* isolate) {
    1216             :   return ExternalReference(Redirect(
    1217             :       isolate,
    1218       55576 :       FUNCTION_ADDR(NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16)));
    1219             : }
    1220             : 
    1221       60358 : ExternalReference ExternalReference::re_word_character_map() {
    1222             :   return ExternalReference(
    1223       60358 :       NativeRegExpMacroAssembler::word_character_map_address());
    1224             : }
    1225             : 
    1226       55621 : ExternalReference ExternalReference::address_of_static_offsets_vector(
    1227             :     Isolate* isolate) {
    1228             :   return ExternalReference(
    1229       55621 :       reinterpret_cast<Address>(isolate->jsregexp_static_offsets_vector()));
    1230             : }
    1231             : 
    1232       55621 : ExternalReference ExternalReference::address_of_regexp_stack_memory_address(
    1233       55621 :     Isolate* isolate) {
    1234             :   return ExternalReference(
    1235       55621 :       isolate->regexp_stack()->memory_address());
    1236             : }
    1237             : 
    1238       55621 : ExternalReference ExternalReference::address_of_regexp_stack_memory_size(
    1239       55621 :     Isolate* isolate) {
    1240       55621 :   return ExternalReference(isolate->regexp_stack()->memory_size_address());
    1241             : }
    1242             : 
    1243             : #endif  // V8_INTERPRETED_REGEXP
    1244             : 
    1245       55379 : ExternalReference ExternalReference::ieee754_acos_function(Isolate* isolate) {
    1246             :   return ExternalReference(
    1247       55379 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::acos), BUILTIN_FP_CALL));
    1248             : }
    1249             : 
    1250       55378 : ExternalReference ExternalReference::ieee754_acosh_function(Isolate* isolate) {
    1251             :   return ExternalReference(Redirect(
    1252       55378 :       isolate, FUNCTION_ADDR(base::ieee754::acosh), BUILTIN_FP_FP_CALL));
    1253             : }
    1254             : 
    1255       55379 : ExternalReference ExternalReference::ieee754_asin_function(Isolate* isolate) {
    1256             :   return ExternalReference(
    1257       55379 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::asin), BUILTIN_FP_CALL));
    1258             : }
    1259             : 
    1260       55378 : ExternalReference ExternalReference::ieee754_asinh_function(Isolate* isolate) {
    1261             :   return ExternalReference(Redirect(
    1262       55378 :       isolate, FUNCTION_ADDR(base::ieee754::asinh), BUILTIN_FP_FP_CALL));
    1263             : }
    1264             : 
    1265       55392 : ExternalReference ExternalReference::ieee754_atan_function(Isolate* isolate) {
    1266             :   return ExternalReference(
    1267       55392 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::atan), BUILTIN_FP_CALL));
    1268             : }
    1269             : 
    1270       55378 : ExternalReference ExternalReference::ieee754_atanh_function(Isolate* isolate) {
    1271             :   return ExternalReference(Redirect(
    1272       55378 :       isolate, FUNCTION_ADDR(base::ieee754::atanh), BUILTIN_FP_FP_CALL));
    1273             : }
    1274             : 
    1275       55402 : ExternalReference ExternalReference::ieee754_atan2_function(Isolate* isolate) {
    1276             :   return ExternalReference(Redirect(
    1277       55402 :       isolate, FUNCTION_ADDR(base::ieee754::atan2), BUILTIN_FP_FP_CALL));
    1278             : }
    1279             : 
    1280       55378 : ExternalReference ExternalReference::ieee754_cbrt_function(Isolate* isolate) {
    1281             :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(base::ieee754::cbrt),
    1282       55378 :                                     BUILTIN_FP_FP_CALL));
    1283             : }
    1284             : 
    1285       55567 : ExternalReference ExternalReference::ieee754_cos_function(Isolate* isolate) {
    1286             :   return ExternalReference(
    1287       55567 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::cos), BUILTIN_FP_CALL));
    1288             : }
    1289             : 
    1290       55386 : ExternalReference ExternalReference::ieee754_cosh_function(Isolate* isolate) {
    1291             :   return ExternalReference(
    1292       55386 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::cosh), BUILTIN_FP_CALL));
    1293             : }
    1294             : 
    1295       55392 : ExternalReference ExternalReference::ieee754_exp_function(Isolate* isolate) {
    1296             :   return ExternalReference(
    1297       55392 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::exp), BUILTIN_FP_CALL));
    1298             : }
    1299             : 
    1300       55378 : ExternalReference ExternalReference::ieee754_expm1_function(Isolate* isolate) {
    1301             :   return ExternalReference(Redirect(
    1302       55378 :       isolate, FUNCTION_ADDR(base::ieee754::expm1), BUILTIN_FP_FP_CALL));
    1303             : }
    1304             : 
    1305       55543 : ExternalReference ExternalReference::ieee754_log_function(Isolate* isolate) {
    1306             :   return ExternalReference(
    1307       55543 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::log), BUILTIN_FP_CALL));
    1308             : }
    1309             : 
    1310       55378 : ExternalReference ExternalReference::ieee754_log1p_function(Isolate* isolate) {
    1311             :   return ExternalReference(
    1312       55378 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::log1p), BUILTIN_FP_CALL));
    1313             : }
    1314             : 
    1315       55378 : ExternalReference ExternalReference::ieee754_log10_function(Isolate* isolate) {
    1316             :   return ExternalReference(
    1317       55378 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::log10), BUILTIN_FP_CALL));
    1318             : }
    1319             : 
    1320       55378 : ExternalReference ExternalReference::ieee754_log2_function(Isolate* isolate) {
    1321             :   return ExternalReference(
    1322       55378 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::log2), BUILTIN_FP_CALL));
    1323             : }
    1324             : 
    1325       55567 : ExternalReference ExternalReference::ieee754_sin_function(Isolate* isolate) {
    1326             :   return ExternalReference(
    1327       55567 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::sin), BUILTIN_FP_CALL));
    1328             : }
    1329             : 
    1330       55386 : ExternalReference ExternalReference::ieee754_sinh_function(Isolate* isolate) {
    1331             :   return ExternalReference(
    1332       55386 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::sinh), BUILTIN_FP_CALL));
    1333             : }
    1334             : 
    1335       55392 : ExternalReference ExternalReference::ieee754_tan_function(Isolate* isolate) {
    1336             :   return ExternalReference(
    1337       55392 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::tan), BUILTIN_FP_CALL));
    1338             : }
    1339             : 
    1340       55386 : ExternalReference ExternalReference::ieee754_tanh_function(Isolate* isolate) {
    1341             :   return ExternalReference(
    1342       55386 :       Redirect(isolate, FUNCTION_ADDR(base::ieee754::tanh), BUILTIN_FP_CALL));
    1343             : }
    1344             : 
    1345     2338295 : void* libc_memchr(void* string, int character, size_t search_length) {
    1346     2338295 :   return memchr(string, character, search_length);
    1347             : }
    1348             : 
    1349       55403 : ExternalReference ExternalReference::libc_memchr_function(Isolate* isolate) {
    1350       55403 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(libc_memchr)));
    1351             : }
    1352             : 
    1353         957 : void* libc_memcpy(void* dest, const void* src, size_t n) {
    1354         957 :   return memcpy(dest, src, n);
    1355             : }
    1356             : 
    1357       55342 : ExternalReference ExternalReference::libc_memcpy_function(Isolate* isolate) {
    1358       55342 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(libc_memcpy)));
    1359             : }
    1360             : 
    1361         105 : void* libc_memmove(void* dest, const void* src, size_t n) {
    1362         105 :   return memmove(dest, src, n);
    1363             : }
    1364             : 
    1365       55342 : ExternalReference ExternalReference::libc_memmove_function(Isolate* isolate) {
    1366       55342 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(libc_memmove)));
    1367             : }
    1368             : 
    1369      167080 : void* libc_memset(void* dest, int byte, size_t n) {
    1370             :   DCHECK_EQ(static_cast<char>(byte), byte);
    1371      167080 :   return memset(dest, byte, n);
    1372             : }
    1373             : 
    1374       55341 : ExternalReference ExternalReference::libc_memset_function(Isolate* isolate) {
    1375       55341 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(libc_memset)));
    1376             : }
    1377             : 
    1378       55311 : ExternalReference ExternalReference::printf_function(Isolate* isolate) {
    1379       55311 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(std::printf)));
    1380             : }
    1381             : 
    1382             : template <typename SubjectChar, typename PatternChar>
    1383      221614 : ExternalReference ExternalReference::search_string_raw(Isolate* isolate) {
    1384             :   auto f = SearchStringRaw<SubjectChar, PatternChar>;
    1385      221614 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(f)));
    1386             : }
    1387             : 
    1388       56086 : ExternalReference ExternalReference::orderedhashmap_gethash_raw(
    1389             :     Isolate* isolate) {
    1390             :   auto f = OrderedHashMap::GetHash;
    1391       56086 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(f)));
    1392             : }
    1393             : 
    1394       55373 : ExternalReference ExternalReference::get_or_create_hash_raw(Isolate* isolate) {
    1395             :   typedef Smi* (*GetOrCreateHash)(Isolate * isolate, Object * key);
    1396             :   GetOrCreateHash f = Object::GetOrCreateHash;
    1397       55373 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(f)));
    1398             : }
    1399             : 
    1400       55537 : ExternalReference ExternalReference::try_internalize_string_function(
    1401             :     Isolate* isolate) {
    1402             :   return ExternalReference(Redirect(
    1403       55537 :       isolate, FUNCTION_ADDR(StringTable::LookupStringIfExists_NoAllocate)));
    1404             : }
    1405             : 
    1406       55311 : ExternalReference ExternalReference::check_object_type(Isolate* isolate) {
    1407       55311 :   return ExternalReference(Redirect(isolate, FUNCTION_ADDR(CheckObjectType)));
    1408             : }
    1409             : 
    1410             : #ifdef V8_INTL_SUPPORT
    1411       55341 : ExternalReference ExternalReference::intl_convert_one_byte_to_lower(
    1412             :     Isolate* isolate) {
    1413             :   return ExternalReference(
    1414       55341 :       Redirect(isolate, FUNCTION_ADDR(ConvertOneByteToLower)));
    1415             : }
    1416             : 
    1417       55341 : ExternalReference ExternalReference::intl_to_latin1_lower_table(
    1418             :     Isolate* isolate) {
    1419       55341 :   uint8_t* ptr = const_cast<uint8_t*>(ToLatin1LowerTable());
    1420       55341 :   return ExternalReference(reinterpret_cast<Address>(ptr));
    1421             : }
    1422             : #endif  // V8_INTL_SUPPORT
    1423             : 
    1424             : // Explicit instantiations for all combinations of 1- and 2-byte strings.
    1425             : template ExternalReference
    1426             : ExternalReference::search_string_raw<const uint8_t, const uint8_t>(Isolate*);
    1427             : template ExternalReference
    1428             : ExternalReference::search_string_raw<const uint8_t, const uc16>(Isolate*);
    1429             : template ExternalReference
    1430             : ExternalReference::search_string_raw<const uc16, const uint8_t>(Isolate*);
    1431             : template ExternalReference
    1432             : ExternalReference::search_string_raw<const uc16, const uc16>(Isolate*);
    1433             : 
    1434           0 : ExternalReference ExternalReference::page_flags(Page* page) {
    1435           0 :   return ExternalReference(reinterpret_cast<Address>(page) +
    1436           0 :                            MemoryChunk::kFlagsOffset);
    1437             : }
    1438             : 
    1439           0 : ExternalReference ExternalReference::ForDeoptEntry(Address entry) {
    1440           0 :   return ExternalReference(entry);
    1441             : }
    1442             : 
    1443       55311 : ExternalReference ExternalReference::cpu_features() {
    1444             :   DCHECK(CpuFeatures::initialized_);
    1445       55311 :   return ExternalReference(&CpuFeatures::supported_);
    1446             : }
    1447             : 
    1448       56952 : ExternalReference ExternalReference::promise_hook_or_debug_is_active_address(
    1449             :     Isolate* isolate) {
    1450       56952 :   return ExternalReference(isolate->promise_hook_or_debug_is_active_address());
    1451             : }
    1452             : 
    1453       56718 : ExternalReference ExternalReference::debug_is_active_address(
    1454       56718 :     Isolate* isolate) {
    1455       56718 :   return ExternalReference(isolate->debug()->is_active_address());
    1456             : }
    1457             : 
    1458       55590 : ExternalReference ExternalReference::debug_hook_on_function_call_address(
    1459       55590 :     Isolate* isolate) {
    1460       55590 :   return ExternalReference(isolate->debug()->hook_on_function_call_address());
    1461             : }
    1462             : 
    1463       55509 : ExternalReference ExternalReference::runtime_function_table_address(
    1464             :     Isolate* isolate) {
    1465             :   return ExternalReference(
    1466       55509 :       const_cast<Runtime::Function*>(Runtime::RuntimeFunctionTable(isolate)));
    1467             : }
    1468             : 
    1469           0 : double power_helper(Isolate* isolate, double x, double y) {
    1470           0 :   int y_int = static_cast<int>(y);
    1471           0 :   if (y == y_int) {
    1472           0 :     return power_double_int(x, y_int);  // Returns 1 if exponent is 0.
    1473             :   }
    1474           0 :   if (y == 0.5) {
    1475           0 :     lazily_initialize_fast_sqrt(isolate);
    1476             :     return (std::isinf(x)) ? V8_INFINITY
    1477           0 :                            : fast_sqrt(x + 0.0, isolate);  // Convert -0 to +0.
    1478             :   }
    1479           0 :   if (y == -0.5) {
    1480           0 :     lazily_initialize_fast_sqrt(isolate);
    1481             :     return (std::isinf(x)) ? 0 : 1.0 / fast_sqrt(x + 0.0,
    1482           0 :                                                  isolate);  // Convert -0 to +0.
    1483             :   }
    1484           0 :   return power_double_double(x, y);
    1485             : }
    1486             : 
    1487             : // Helper function to compute x^y, where y is known to be an
    1488             : // integer. Uses binary decomposition to limit the number of
    1489             : // multiplications; see the discussion in "Hacker's Delight" by Henry
    1490             : // S. Warren, Jr., figure 11-6, page 213.
    1491           0 : double power_double_int(double x, int y) {
    1492           0 :   double m = (y < 0) ? 1 / x : x;
    1493           0 :   unsigned n = (y < 0) ? -y : y;
    1494             :   double p = 1;
    1495           0 :   while (n != 0) {
    1496           0 :     if ((n & 1) != 0) p *= m;
    1497           0 :     m *= m;
    1498           0 :     if ((n & 2) != 0) p *= m;
    1499           0 :     m *= m;
    1500           0 :     n >>= 2;
    1501             :   }
    1502           0 :   return p;
    1503             : }
    1504             : 
    1505        2812 : double power_double_double(double x, double y) {
    1506             :   // The checks for special cases can be dropped in ia32 because it has already
    1507             :   // been done in generated code before bailing out here.
    1508        2965 :   if (std::isnan(y) || ((x == 1 || x == -1) && std::isinf(y))) {
    1509             :     return std::numeric_limits<double>::quiet_NaN();
    1510             :   }
    1511        2294 :   return Pow(x, y);
    1512             : }
    1513             : 
    1514           0 : double modulo_double_double(double x, double y) { return Modulo(x, y); }
    1515             : 
    1516       55342 : ExternalReference ExternalReference::power_double_double_function(
    1517             :     Isolate* isolate) {
    1518             :   return ExternalReference(Redirect(isolate,
    1519             :                                     FUNCTION_ADDR(power_double_double),
    1520       55342 :                                     BUILTIN_FP_FP_CALL));
    1521             : }
    1522             : 
    1523       55311 : ExternalReference ExternalReference::mod_two_doubles_operation(
    1524             :     Isolate* isolate) {
    1525             :   return ExternalReference(Redirect(
    1526       55311 :       isolate, FUNCTION_ADDR(modulo_double_double), BUILTIN_FP_FP_CALL));
    1527             : }
    1528             : 
    1529       55404 : ExternalReference ExternalReference::debug_last_step_action_address(
    1530       55404 :     Isolate* isolate) {
    1531       55404 :   return ExternalReference(isolate->debug()->last_step_action_address());
    1532             : }
    1533             : 
    1534       55342 : ExternalReference ExternalReference::debug_suspended_generator_address(
    1535       55342 :     Isolate* isolate) {
    1536       55342 :   return ExternalReference(isolate->debug()->suspended_generator_address());
    1537             : }
    1538             : 
    1539       55993 : ExternalReference ExternalReference::debug_restart_fp_address(
    1540       55993 :     Isolate* isolate) {
    1541       55993 :   return ExternalReference(isolate->debug()->restart_fp_address());
    1542             : }
    1543             : 
    1544         589 : ExternalReference ExternalReference::fixed_typed_array_base_data_offset() {
    1545             :   return ExternalReference(reinterpret_cast<void*>(
    1546         589 :       FixedTypedArrayBase::kDataOffset - kHeapObjectTag));
    1547             : }
    1548             : 
    1549      679340 : bool operator==(ExternalReference lhs, ExternalReference rhs) {
    1550      679340 :   return lhs.address() == rhs.address();
    1551             : }
    1552             : 
    1553           0 : bool operator!=(ExternalReference lhs, ExternalReference rhs) {
    1554           0 :   return !(lhs == rhs);
    1555             : }
    1556             : 
    1557     2600501 : size_t hash_value(ExternalReference reference) {
    1558     2600505 :   return base::hash<Address>()(reference.address());
    1559             : }
    1560             : 
    1561           0 : std::ostream& operator<<(std::ostream& os, ExternalReference reference) {
    1562             :   os << static_cast<const void*>(reference.address());
    1563           0 :   const Runtime::Function* fn = Runtime::FunctionForEntry(reference.address());
    1564           0 :   if (fn) os << "<" << fn->name << ".entry>";
    1565           0 :   return os;
    1566             : }
    1567             : 
    1568          36 : ConstantPoolBuilder::ConstantPoolBuilder(int ptr_reach_bits,
    1569         108 :                                          int double_reach_bits) {
    1570          36 :   info_[ConstantPoolEntry::INTPTR].entries.reserve(64);
    1571          36 :   info_[ConstantPoolEntry::INTPTR].regular_reach_bits = ptr_reach_bits;
    1572          36 :   info_[ConstantPoolEntry::DOUBLE].regular_reach_bits = double_reach_bits;
    1573          36 : }
    1574             : 
    1575         942 : ConstantPoolEntry::Access ConstantPoolBuilder::NextAccess(
    1576             :     ConstantPoolEntry::Type type) const {
    1577         942 :   const PerTypeEntryInfo& info = info_[type];
    1578             : 
    1579         942 :   if (info.overflow()) return ConstantPoolEntry::OVERFLOWED;
    1580             : 
    1581         822 :   int dbl_count = info_[ConstantPoolEntry::DOUBLE].regular_count;
    1582         822 :   int dbl_offset = dbl_count * kDoubleSize;
    1583         822 :   int ptr_count = info_[ConstantPoolEntry::INTPTR].regular_count;
    1584         822 :   int ptr_offset = ptr_count * kPointerSize + dbl_offset;
    1585             : 
    1586         822 :   if (type == ConstantPoolEntry::DOUBLE) {
    1587             :     // Double overflow detection must take into account the reach for both types
    1588         378 :     int ptr_reach_bits = info_[ConstantPoolEntry::INTPTR].regular_reach_bits;
    1589        1134 :     if (!is_uintn(dbl_offset, info.regular_reach_bits) ||
    1590         246 :         (ptr_count > 0 &&
    1591         246 :          !is_uintn(ptr_offset + kDoubleSize - kPointerSize, ptr_reach_bits))) {
    1592             :       return ConstantPoolEntry::OVERFLOWED;
    1593             :     }
    1594             :   } else {
    1595             :     DCHECK(type == ConstantPoolEntry::INTPTR);
    1596         888 :     if (!is_uintn(ptr_offset, info.regular_reach_bits)) {
    1597             :       return ConstantPoolEntry::OVERFLOWED;
    1598             :     }
    1599             :   }
    1600             : 
    1601         720 :   return ConstantPoolEntry::REGULAR;
    1602             : }
    1603             : 
    1604         684 : ConstantPoolEntry::Access ConstantPoolBuilder::AddEntry(
    1605        5064 :     ConstantPoolEntry& entry, ConstantPoolEntry::Type type) {
    1606             :   DCHECK(!emitted_label_.is_bound());
    1607         684 :   PerTypeEntryInfo& info = info_[type];
    1608             :   const int entry_size = ConstantPoolEntry::size(type);
    1609             :   bool merged = false;
    1610             : 
    1611         684 :   if (entry.sharing_ok()) {
    1612             :     // Try to merge entries
    1613         660 :     std::vector<ConstantPoolEntry>::iterator it = info.shared_entries.begin();
    1614         660 :     int end = static_cast<int>(info.shared_entries.size());
    1615        8568 :     for (int i = 0; i < end; i++, it++) {
    1616        3696 :       if ((entry_size == kPointerSize) ? entry.value() == it->value()
    1617             :                                        : entry.value64() == it->value64()) {
    1618             :         // Merge with found entry.
    1619             :         entry.set_merged_index(i);
    1620             :         merged = true;
    1621          72 :         break;
    1622             :       }
    1623             :     }
    1624             :   }
    1625             : 
    1626             :   // By definition, merged entries have regular access.
    1627             :   DCHECK(!merged || entry.merged_index() < info.regular_count);
    1628             :   ConstantPoolEntry::Access access =
    1629         684 :       (merged ? ConstantPoolEntry::REGULAR : NextAccess(type));
    1630             : 
    1631             :   // Enforce an upper bound on search time by limiting the search to
    1632             :   // unique sharable entries which fit in the regular section.
    1633         684 :   if (entry.sharing_ok() && !merged && access == ConstantPoolEntry::REGULAR) {
    1634         408 :     info.shared_entries.push_back(entry);
    1635             :   } else {
    1636         336 :     info.entries.push_back(entry);
    1637             :   }
    1638             : 
    1639             :   // We're done if we found a match or have already triggered the
    1640             :   // overflow state.
    1641        1296 :   if (merged || info.overflow()) return access;
    1642             : 
    1643         492 :   if (access == ConstantPoolEntry::REGULAR) {
    1644         432 :     info.regular_count++;
    1645             :   } else {
    1646          60 :     info.overflow_start = static_cast<int>(info.entries.size()) - 1;
    1647             :   }
    1648             : 
    1649             :   return access;
    1650             : }
    1651             : 
    1652           0 : void ConstantPoolBuilder::EmitSharedEntries(Assembler* assm,
    1653             :                                             ConstantPoolEntry::Type type) {
    1654           0 :   PerTypeEntryInfo& info = info_[type];
    1655           0 :   std::vector<ConstantPoolEntry>& shared_entries = info.shared_entries;
    1656             :   const int entry_size = ConstantPoolEntry::size(type);
    1657           0 :   int base = emitted_label_.pos();
    1658             :   DCHECK_GT(base, 0);
    1659           0 :   int shared_end = static_cast<int>(shared_entries.size());
    1660             :   std::vector<ConstantPoolEntry>::iterator shared_it = shared_entries.begin();
    1661           0 :   for (int i = 0; i < shared_end; i++, shared_it++) {
    1662           0 :     int offset = assm->pc_offset() - base;
    1663             :     shared_it->set_offset(offset);  // Save offset for merged entries.
    1664             :     if (entry_size == kPointerSize) {
    1665           0 :       assm->dp(shared_it->value());
    1666             :     } else {
    1667             :       assm->dq(shared_it->value64());
    1668             :     }
    1669             :     DCHECK(is_uintn(offset, info.regular_reach_bits));
    1670             : 
    1671             :     // Patch load sequence with correct offset.
    1672             :     assm->PatchConstantPoolAccessInstruction(shared_it->position(), offset,
    1673           0 :                                              ConstantPoolEntry::REGULAR, type);
    1674             :   }
    1675           0 : }
    1676             : 
    1677           0 : void ConstantPoolBuilder::EmitGroup(Assembler* assm,
    1678             :                                     ConstantPoolEntry::Access access,
    1679             :                                     ConstantPoolEntry::Type type) {
    1680           0 :   PerTypeEntryInfo& info = info_[type];
    1681             :   const bool overflow = info.overflow();
    1682           0 :   std::vector<ConstantPoolEntry>& entries = info.entries;
    1683             :   std::vector<ConstantPoolEntry>& shared_entries = info.shared_entries;
    1684             :   const int entry_size = ConstantPoolEntry::size(type);
    1685           0 :   int base = emitted_label_.pos();
    1686             :   DCHECK_GT(base, 0);
    1687             :   int begin;
    1688             :   int end;
    1689             : 
    1690           0 :   if (access == ConstantPoolEntry::REGULAR) {
    1691             :     // Emit any shared entries first
    1692           0 :     EmitSharedEntries(assm, type);
    1693             :   }
    1694             : 
    1695           0 :   if (access == ConstantPoolEntry::REGULAR) {
    1696             :     begin = 0;
    1697           0 :     end = overflow ? info.overflow_start : static_cast<int>(entries.size());
    1698             :   } else {
    1699             :     DCHECK(access == ConstantPoolEntry::OVERFLOWED);
    1700           0 :     if (!overflow) return;
    1701           0 :     begin = info.overflow_start;
    1702           0 :     end = static_cast<int>(entries.size());
    1703             :   }
    1704             : 
    1705             :   std::vector<ConstantPoolEntry>::iterator it = entries.begin();
    1706           0 :   if (begin > 0) std::advance(it, begin);
    1707           0 :   for (int i = begin; i < end; i++, it++) {
    1708             :     // Update constant pool if necessary and get the entry's offset.
    1709             :     int offset;
    1710             :     ConstantPoolEntry::Access entry_access;
    1711           0 :     if (!it->is_merged()) {
    1712             :       // Emit new entry
    1713             :       offset = assm->pc_offset() - base;
    1714             :       entry_access = access;
    1715             :       if (entry_size == kPointerSize) {
    1716           0 :         assm->dp(it->value());
    1717             :       } else {
    1718             :         assm->dq(it->value64());
    1719             :       }
    1720             :     } else {
    1721             :       // Retrieve offset from shared entry.
    1722             :       offset = shared_entries[it->merged_index()].offset();
    1723             :       entry_access = ConstantPoolEntry::REGULAR;
    1724             :     }
    1725             : 
    1726             :     DCHECK(entry_access == ConstantPoolEntry::OVERFLOWED ||
    1727             :            is_uintn(offset, info.regular_reach_bits));
    1728             : 
    1729             :     // Patch load sequence with correct offset.
    1730             :     assm->PatchConstantPoolAccessInstruction(it->position(), offset,
    1731           0 :                                              entry_access, type);
    1732             :   }
    1733             : }
    1734             : 
    1735             : // Emit and return position of pool.  Zero implies no constant pool.
    1736           0 : int ConstantPoolBuilder::Emit(Assembler* assm) {
    1737           0 :   bool emitted = emitted_label_.is_bound();
    1738             :   bool empty = IsEmpty();
    1739             : 
    1740           0 :   if (!emitted) {
    1741             :     // Mark start of constant pool.  Align if necessary.
    1742           0 :     if (!empty) assm->DataAlign(kDoubleSize);
    1743           0 :     assm->bind(&emitted_label_);
    1744           0 :     if (!empty) {
    1745             :       // Emit in groups based on access and type.
    1746             :       // Emit doubles first for alignment purposes.
    1747           0 :       EmitGroup(assm, ConstantPoolEntry::REGULAR, ConstantPoolEntry::DOUBLE);
    1748           0 :       EmitGroup(assm, ConstantPoolEntry::REGULAR, ConstantPoolEntry::INTPTR);
    1749           0 :       if (info_[ConstantPoolEntry::DOUBLE].overflow()) {
    1750           0 :         assm->DataAlign(kDoubleSize);
    1751             :         EmitGroup(assm, ConstantPoolEntry::OVERFLOWED,
    1752           0 :                   ConstantPoolEntry::DOUBLE);
    1753             :       }
    1754           0 :       if (info_[ConstantPoolEntry::INTPTR].overflow()) {
    1755             :         EmitGroup(assm, ConstantPoolEntry::OVERFLOWED,
    1756           0 :                   ConstantPoolEntry::INTPTR);
    1757             :       }
    1758             :     }
    1759             :   }
    1760             : 
    1761           0 :   return !empty ? emitted_label_.pos() : 0;
    1762             : }
    1763             : 
    1764       43091 : HeapObjectRequest::HeapObjectRequest(double heap_number, int offset)
    1765       43091 :     : kind_(kHeapNumber), offset_(offset) {
    1766       43091 :   value_.heap_number = heap_number;
    1767             :   DCHECK(!IsSmiDouble(value_.heap_number));
    1768       43091 : }
    1769             : 
    1770       45553 : HeapObjectRequest::HeapObjectRequest(CodeStub* code_stub, int offset)
    1771       45553 :     : kind_(kCodeStub), offset_(offset) {
    1772       45553 :   value_.code_stub = code_stub;
    1773             :   DCHECK_NOT_NULL(value_.code_stub);
    1774       45553 : }
    1775             : 
    1776             : // Platform specific but identical code for all the platforms.
    1777             : 
    1778      236610 : void Assembler::RecordDeoptReason(DeoptimizeReason reason,
    1779             :                                   SourcePosition position, int id) {
    1780             :   EnsureSpace ensure_space(this);
    1781      236610 :   RecordRelocInfo(RelocInfo::DEOPT_SCRIPT_OFFSET, position.ScriptOffset());
    1782      236610 :   RecordRelocInfo(RelocInfo::DEOPT_INLINING_ID, position.InliningId());
    1783      236611 :   RecordRelocInfo(RelocInfo::DEOPT_REASON, static_cast<int>(reason));
    1784      236611 :   RecordRelocInfo(RelocInfo::DEOPT_ID, id);
    1785      236611 : }
    1786             : 
    1787     1527904 : void Assembler::RecordComment(const char* msg) {
    1788     1527904 :   if (FLAG_code_comments) {
    1789             :     EnsureSpace ensure_space(this);
    1790           0 :     RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
    1791             :   }
    1792     1527904 : }
    1793             : 
    1794           0 : void Assembler::DataAlign(int m) {
    1795             :   DCHECK(m >= 2 && base::bits::IsPowerOfTwo(m));
    1796           0 :   while ((pc_offset() & (m - 1)) != 0) {
    1797           0 :     db(0);
    1798             :   }
    1799           0 : }
    1800             : 
    1801       88646 : void Assembler::RequestHeapObject(HeapObjectRequest request) {
    1802       88646 :   request.set_offset(pc_offset());
    1803             :   heap_object_requests_.push_front(request);
    1804       88654 : }
    1805             : 
    1806             : namespace {
    1807             : int caller_saved_codes[kNumJSCallerSaved];
    1808             : }
    1809             : 
    1810       53977 : void SetUpJSCallerSavedCodeData() {
    1811             :   int i = 0;
    1812      917609 :   for (int r = 0; r < kNumRegs; r++)
    1813      863632 :     if ((kJSCallerSaved & (1 << r)) != 0) caller_saved_codes[i++] = r;
    1814             : 
    1815             :   DCHECK_EQ(i, kNumJSCallerSaved);
    1816       53977 : }
    1817             : 
    1818           0 : int JSCallerSavedCode(int n) {
    1819             :   DCHECK(0 <= n && n < kNumJSCallerSaved);
    1820           0 :   return caller_saved_codes[n];
    1821             : }
    1822             : 
    1823             : }  // namespace internal
    1824             : }  // namespace v8

Generated by: LCOV version 1.10