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