LCOV - code coverage report
Current view: top level - src/x64 - assembler-x64-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 175 187 93.6 %
Date: 2017-04-26 Functions: 24 25 96.0 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_X64_ASSEMBLER_X64_INL_H_
       6             : #define V8_X64_ASSEMBLER_X64_INL_H_
       7             : 
       8             : #include "src/x64/assembler-x64.h"
       9             : 
      10             : #include "src/base/cpu.h"
      11             : #include "src/debug/debug.h"
      12             : #include "src/objects-inl.h"
      13             : #include "src/v8memory.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : 
      18             : bool CpuFeatures::SupportsCrankshaft() { return true; }
      19             : 
      20             : bool CpuFeatures::SupportsWasmSimd128() { return IsSupported(SSE4_1); }
      21             : 
      22             : // -----------------------------------------------------------------------------
      23             : // Implementation of Assembler
      24             : 
      25             : 
      26             : static const byte kCallOpcode = 0xE8;
      27             : 
      28             : 
      29             : void Assembler::emitl(uint32_t x) {
      30    84929151 :   Memory::uint32_at(pc_) = x;
      31    84929151 :   pc_ += sizeof(uint32_t);
      32             : }
      33             : 
      34             : 
      35    37378780 : void Assembler::emitp(void* x, RelocInfo::Mode rmode) {
      36    37378780 :   uintptr_t value = reinterpret_cast<uintptr_t>(x);
      37    37378780 :   Memory::uintptr_at(pc_) = value;
      38    37378780 :   if (!RelocInfo::IsNone(rmode)) {
      39    21872279 :     RecordRelocInfo(rmode, value);
      40             :   }
      41    37378771 :   pc_ += sizeof(uintptr_t);
      42    37378771 : }
      43             : 
      44             : 
      45             : void Assembler::emitq(uint64_t x) {
      46      789158 :   Memory::uint64_at(pc_) = x;
      47      789158 :   pc_ += sizeof(uint64_t);
      48             : }
      49             : 
      50             : 
      51             : void Assembler::emitw(uint16_t x) {
      52      138507 :   Memory::uint16_at(pc_) = x;
      53      138507 :   pc_ += sizeof(uint16_t);
      54             : }
      55             : 
      56             : 
      57    17880250 : void Assembler::emit_code_target(Handle<Code> target,
      58             :                                  RelocInfo::Mode rmode,
      59             :                                  TypeFeedbackId ast_id) {
      60             :   DCHECK(RelocInfo::IsCodeTarget(rmode) ||
      61             :       rmode == RelocInfo::CODE_AGE_SEQUENCE);
      62    17880250 :   if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) {
      63     1530903 :     RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, ast_id.ToInt());
      64             :   } else {
      65    16349347 :     RecordRelocInfo(rmode);
      66             :   }
      67    17880264 :   int current = code_targets_.length();
      68    33608680 :   if (current > 0 && code_targets_.last().address() == target.address()) {
      69             :     // Optimization if we keep jumping to the same code target.
      70     1503582 :     emitl(current - 1);
      71             :   } else {
      72    16376682 :     code_targets_.Add(target);
      73    16376682 :     emitl(current);
      74             :   }
      75    17880264 : }
      76             : 
      77             : 
      78             : void Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) {
      79             :   DCHECK(RelocInfo::IsRuntimeEntry(rmode));
      80      889889 :   RecordRelocInfo(rmode);
      81     1779778 :   emitl(static_cast<uint32_t>(entry - isolate_data().code_range_start_));
      82             : }
      83             : 
      84    12080008 : void Assembler::emit(Immediate x) {
      85    12080008 :   if (!RelocInfo::IsNone(x.rmode_)) {
      86      246868 :     RecordRelocInfo(x.rmode_);
      87             :   }
      88    12080008 :   emitl(x.value_);
      89    12080008 : }
      90             : 
      91             : void Assembler::emit_rex_64(Register reg, Register rm_reg) {
      92    45653128 :   emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit());
      93             : }
      94             : 
      95             : 
      96             : void Assembler::emit_rex_64(XMMRegister reg, Register rm_reg) {
      97         396 :   emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
      98             : }
      99             : 
     100             : 
     101             : void Assembler::emit_rex_64(Register reg, XMMRegister rm_reg) {
     102         132 :   emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
     103             : }
     104             : 
     105             : 
     106             : void Assembler::emit_rex_64(Register reg, const Operand& op) {
     107    59023755 :   emit(0x48 | reg.high_bit() << 2 | op.rex_);
     108             : }
     109             : 
     110             : 
     111             : void Assembler::emit_rex_64(XMMRegister reg, const Operand& op) {
     112         544 :   emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_);
     113             : }
     114             : 
     115             : 
     116             : void Assembler::emit_rex_64(Register rm_reg) {
     117             :   DCHECK_EQ(rm_reg.code() & 0xf, rm_reg.code());
     118    50581727 :   emit(0x48 | rm_reg.high_bit());
     119             : }
     120             : 
     121             : 
     122             : void Assembler::emit_rex_64(const Operand& op) {
     123      310862 :   emit(0x48 | op.rex_);
     124             : }
     125             : 
     126             : 
     127             : void Assembler::emit_rex_32(Register reg, Register rm_reg) {
     128       21114 :   emit(0x40 | reg.high_bit() << 2 | rm_reg.high_bit());
     129             : }
     130             : 
     131             : 
     132             : void Assembler::emit_rex_32(Register reg, const Operand& op) {
     133        5999 :   emit(0x40 | reg.high_bit() << 2  | op.rex_);
     134             : }
     135             : 
     136             : 
     137             : void Assembler::emit_rex_32(Register rm_reg) {
     138      428541 :   emit(0x40 | rm_reg.high_bit());
     139             : }
     140             : 
     141             : 
     142             : void Assembler::emit_rex_32(const Operand& op) {
     143             :   emit(0x40 | op.rex_);
     144             : }
     145             : 
     146             : 
     147             : void Assembler::emit_optional_rex_32(Register reg, Register rm_reg) {
     148     7213474 :   byte rex_bits = reg.high_bit() << 2 | rm_reg.high_bit();
     149     3606737 :   if (rex_bits != 0) emit(0x40 | rex_bits);
     150             : }
     151             : 
     152             : 
     153             : void Assembler::emit_optional_rex_32(Register reg, const Operand& op) {
     154     9039808 :   byte rex_bits =  reg.high_bit() << 2 | op.rex_;
     155     9039808 :   if (rex_bits != 0) emit(0x40 | rex_bits);
     156             : }
     157             : 
     158             : 
     159             : void Assembler::emit_optional_rex_32(XMMRegister reg, const Operand& op) {
     160       34668 :   byte rex_bits =  (reg.code() & 0x8) >> 1 | op.rex_;
     161       34668 :   if (rex_bits != 0) emit(0x40 | rex_bits);
     162             : }
     163             : 
     164             : 
     165             : void Assembler::emit_optional_rex_32(XMMRegister reg, XMMRegister base) {
     166        6301 :   byte rex_bits =  (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3;
     167        6301 :   if (rex_bits != 0) emit(0x40 | rex_bits);
     168             : }
     169             : 
     170             : 
     171             : void Assembler::emit_optional_rex_32(XMMRegister reg, Register base) {
     172       18441 :   byte rex_bits =  (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3;
     173       18441 :   if (rex_bits != 0) emit(0x40 | rex_bits);
     174             : }
     175             : 
     176             : 
     177             : void Assembler::emit_optional_rex_32(Register reg, XMMRegister base) {
     178         122 :   byte rex_bits =  (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3;
     179         122 :   if (rex_bits != 0) emit(0x40 | rex_bits);
     180             : }
     181             : 
     182             : 
     183             : void Assembler::emit_optional_rex_32(Register rm_reg) {
     184    52598234 :   if (rm_reg.high_bit()) emit(0x41);
     185             : }
     186             : 
     187             : void Assembler::emit_optional_rex_32(XMMRegister rm_reg) {
     188         169 :   if (rm_reg.high_bit()) emit(0x41);
     189             : }
     190             : 
     191             : void Assembler::emit_optional_rex_32(const Operand& op) {
     192    15070887 :   if (op.rex_ != 0) emit(0x40 | op.rex_);
     193             : }
     194             : 
     195             : 
     196             : // byte 1 of 3-byte VEX
     197             : void Assembler::emit_vex3_byte1(XMMRegister reg, XMMRegister rm,
     198             :                                 LeadingOpcode m) {
     199      720547 :   byte rxb = ~((reg.high_bit() << 2) | rm.high_bit()) << 5;
     200      720547 :   emit(rxb | m);
     201             : }
     202             : 
     203             : 
     204             : // byte 1 of 3-byte VEX
     205             : void Assembler::emit_vex3_byte1(XMMRegister reg, const Operand& rm,
     206             :                                 LeadingOpcode m) {
     207       49157 :   byte rxb = ~((reg.high_bit() << 2) | rm.rex_) << 5;
     208       49157 :   emit(rxb | m);
     209             : }
     210             : 
     211             : 
     212             : // byte 1 of 2-byte VEX
     213             : void Assembler::emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l,
     214             :                                 SIMDPrefix pp) {
     215     8770198 :   byte rv = ~((reg.high_bit() << 4) | v.code()) << 3;
     216     8770198 :   emit(rv | l | pp);
     217             : }
     218             : 
     219             : 
     220             : // byte 2 of 3-byte VEX
     221             : void Assembler::emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l,
     222             :                                 SIMDPrefix pp) {
     223      769704 :   emit(w | ((~v.code() & 0xf) << 3) | l | pp);
     224             : }
     225             : 
     226             : 
     227     2371271 : void Assembler::emit_vex_prefix(XMMRegister reg, XMMRegister vreg,
     228             :                                 XMMRegister rm, VectorLength l, SIMDPrefix pp,
     229             :                                 LeadingOpcode mm, VexW w) {
     230     2371271 :   if (rm.high_bit() || mm != k0F || w != kW0) {
     231             :     emit_vex3_byte0();
     232             :     emit_vex3_byte1(reg, rm, mm);
     233             :     emit_vex3_byte2(w, vreg, l, pp);
     234             :   } else {
     235             :     emit_vex2_byte0();
     236             :     emit_vex2_byte1(reg, vreg, l, pp);
     237             :   }
     238     2371271 : }
     239             : 
     240             : 
     241             : void Assembler::emit_vex_prefix(Register reg, Register vreg, Register rm,
     242             :                                 VectorLength l, SIMDPrefix pp, LeadingOpcode mm,
     243             :                                 VexW w) {
     244         364 :   XMMRegister ireg = {reg.code()};
     245         364 :   XMMRegister ivreg = {vreg.code()};
     246         364 :   XMMRegister irm = {rm.code()};
     247         364 :   emit_vex_prefix(ireg, ivreg, irm, l, pp, mm, w);
     248             : }
     249             : 
     250             : 
     251     7168631 : void Assembler::emit_vex_prefix(XMMRegister reg, XMMRegister vreg,
     252       49157 :                                 const Operand& rm, VectorLength l,
     253             :                                 SIMDPrefix pp, LeadingOpcode mm, VexW w) {
     254     7168631 :   if (rm.rex_ || mm != k0F || w != kW0) {
     255             :     emit_vex3_byte0();
     256             :     emit_vex3_byte1(reg, rm, mm);
     257             :     emit_vex3_byte2(w, vreg, l, pp);
     258             :   } else {
     259             :     emit_vex2_byte0();
     260             :     emit_vex2_byte1(reg, vreg, l, pp);
     261             :   }
     262     7168631 : }
     263             : 
     264             : 
     265             : void Assembler::emit_vex_prefix(Register reg, Register vreg, const Operand& rm,
     266             :                                 VectorLength l, SIMDPrefix pp, LeadingOpcode mm,
     267             :                                 VexW w) {
     268         364 :   XMMRegister ireg = {reg.code()};
     269         364 :   XMMRegister ivreg = {vreg.code()};
     270         364 :   emit_vex_prefix(ireg, ivreg, rm, l, pp, mm, w);
     271             : }
     272             : 
     273             : 
     274             : Address Assembler::target_address_at(Address pc, Address constant_pool) {
     275   349888323 :   return Memory::int32_at(pc) + pc + 4;
     276             : }
     277             : 
     278             : 
     279             : void Assembler::set_target_address_at(Isolate* isolate, Address pc,
     280             :                                       Address constant_pool, Address target,
     281             :                                       ICacheFlushMode icache_flush_mode) {
     282             :   DCHECK_IMPLIES(isolate == nullptr, icache_flush_mode == SKIP_ICACHE_FLUSH);
     283   347747970 :   Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4);
     284    19008269 :   if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
     285   328745100 :     Assembler::FlushICache(isolate, pc, sizeof(int32_t));
     286             :   }
     287             : }
     288             : 
     289   347370148 : Address Assembler::target_address_at(Address pc, Code* code) {
     290             :   Address constant_pool = code ? code->constant_pool() : NULL;
     291   347370148 :   return target_address_at(pc, constant_pool);
     292             : }
     293             : 
     294        5413 : void Assembler::set_target_address_at(Isolate* isolate, Address pc, Code* code,
     295             :                                       Address target,
     296             :                                       ICacheFlushMode icache_flush_mode) {
     297             :   Address constant_pool = code ? code->constant_pool() : NULL;
     298             :   set_target_address_at(isolate, pc, constant_pool, target, icache_flush_mode);
     299        5413 : }
     300             : 
     301             : void Assembler::deserialization_set_target_internal_reference_at(
     302             :     Isolate* isolate, Address pc, Address target, RelocInfo::Mode mode) {
     303    90135114 :   Memory::Address_at(pc) = target;
     304             : }
     305             : 
     306             : 
     307             : Address Assembler::target_address_from_return_address(Address pc) {
     308             :   return pc - kCallTargetAddressOffset;
     309             : }
     310             : 
     311             : void Assembler::deserialization_set_special_target_at(
     312             :     Isolate* isolate, Address instruction_payload, Code* code, Address target) {
     313             :   set_target_address_at(isolate, instruction_payload, code, target);
     314             : }
     315             : 
     316    17875886 : Handle<Code> Assembler::code_target_object_handle_at(Address pc) {
     317    35751772 :   return code_targets_[Memory::int32_at(pc)];
     318             : }
     319             : 
     320             : 
     321      889879 : Address Assembler::runtime_entry_at(Address pc) {
     322      889879 :   return Memory::int32_at(pc) + isolate_data().code_range_start_;
     323             : }
     324             : 
     325             : // -----------------------------------------------------------------------------
     326             : // Implementation of RelocInfo
     327             : 
     328             : // The modes possibly affected by apply must be in kApplyMask.
     329             : void RelocInfo::apply(intptr_t delta) {
     330      635777 :   if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) {
     331      505609 :     Memory::int32_at(pc_) -= static_cast<int32_t>(delta);
     332      130168 :   } else if (IsCodeAgeSequence(rmode_)) {
     333        5257 :     if (*pc_ == kCallOpcode) {
     334             :       int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
     335        5257 :       *p -= static_cast<int32_t>(delta);  // Relocate entry.
     336             :     }
     337      124910 :   } else if (IsInternalReference(rmode_)) {
     338             :     // absolute code pointer inside code object moves with the code object.
     339      124910 :     Memory::Address_at(pc_) += delta;
     340             :   }
     341             : }
     342             : 
     343             : 
     344             : Address RelocInfo::target_address() {
     345             :   DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
     346   347370119 :   return Assembler::target_address_at(pc_, host_);
     347             : }
     348             : 
     349             : Address RelocInfo::target_address_address() {
     350             :   DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
     351             :                               || rmode_ == EMBEDDED_OBJECT
     352             :                               || rmode_ == EXTERNAL_REFERENCE);
     353             :   return reinterpret_cast<Address>(pc_);
     354             : }
     355             : 
     356             : 
     357             : Address RelocInfo::constant_pool_entry_address() {
     358           0 :   UNREACHABLE();
     359             :   return NULL;
     360             : }
     361             : 
     362             : 
     363             : int RelocInfo::target_address_size() {
     364     1843733 :   if (IsCodedSpecially()) {
     365             :     return Assembler::kSpecialTargetSize;
     366             :   } else {
     367             :     return kPointerSize;
     368             :   }
     369             : }
     370             : 
     371             : HeapObject* RelocInfo::target_object() {
     372             :   DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
     373    42847671 :   return HeapObject::cast(Memory::Object_at(pc_));
     374             : }
     375             : 
     376             : Handle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
     377             :   DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
     378    34072331 :   if (rmode_ == EMBEDDED_OBJECT) {
     379    16196461 :     return Handle<HeapObject>::cast(Memory::Object_Handle_at(pc_));
     380             :   } else {
     381    17875870 :     return origin->code_target_object_handle_at(pc_);
     382             :   }
     383             : }
     384             : 
     385             : 
     386             : Address RelocInfo::target_external_reference() {
     387             :   DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
     388      990758 :   return Memory::Address_at(pc_);
     389             : }
     390             : 
     391             : 
     392             : Address RelocInfo::target_internal_reference() {
     393             :   DCHECK(rmode_ == INTERNAL_REFERENCE);
     394      224084 :   return Memory::Address_at(pc_);
     395             : }
     396             : 
     397             : 
     398             : Address RelocInfo::target_internal_reference_address() {
     399             :   DCHECK(rmode_ == INTERNAL_REFERENCE);
     400             :   return reinterpret_cast<Address>(pc_);
     401             : }
     402             : 
     403             : void RelocInfo::set_target_object(HeapObject* target,
     404             :                                   WriteBarrierMode write_barrier_mode,
     405    33329837 :                                   ICacheFlushMode icache_flush_mode) {
     406             :   DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
     407    21588736 :   Memory::Object_at(pc_) = target;
     408        4852 :   if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
     409     5387702 :     Assembler::FlushICache(target->GetIsolate(), pc_, sizeof(Address));
     410             :   }
     411    17081684 :   if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) {
     412             :     host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this,
     413    16248155 :                                                                   target);
     414    16248153 :     host()->GetHeap()->RecordWriteIntoCode(host(), this, target);
     415             :   }
     416             : }
     417             : 
     418             : 
     419             : Address RelocInfo::target_runtime_entry(Assembler* origin) {
     420             :   DCHECK(IsRuntimeEntry(rmode_));
     421      889879 :   return origin->runtime_entry_at(pc_);
     422             : }
     423             : 
     424             : void RelocInfo::set_target_runtime_entry(Isolate* isolate, Address target,
     425             :                                          WriteBarrierMode write_barrier_mode,
     426             :                                          ICacheFlushMode icache_flush_mode) {
     427             :   DCHECK(IsRuntimeEntry(rmode_));
     428      889879 :   if (target_address() != target) {
     429      889879 :     set_target_address(isolate, target, write_barrier_mode, icache_flush_mode);
     430             :   }
     431             : }
     432             : 
     433             : 
     434             : Handle<Cell> RelocInfo::target_cell_handle() {
     435             :   DCHECK(rmode_ == RelocInfo::CELL);
     436       38676 :   Address address = Memory::Address_at(pc_);
     437             :   return Handle<Cell>(reinterpret_cast<Cell**>(address));
     438             : }
     439             : 
     440             : 
     441             : Cell* RelocInfo::target_cell() {
     442             :   DCHECK(rmode_ == RelocInfo::CELL);
     443       65501 :   return Cell::FromValueAddress(Memory::Address_at(pc_));
     444             : }
     445             : 
     446             : 
     447             : void RelocInfo::set_target_cell(Cell* cell,
     448             :                                 WriteBarrierMode write_barrier_mode,
     449       38975 :                                 ICacheFlushMode icache_flush_mode) {
     450             :   DCHECK(rmode_ == RelocInfo::CELL);
     451       38975 :   Address address = cell->address() + Cell::kValueOffset;
     452       38975 :   Memory::Address_at(pc_) = address;
     453             :   if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
     454         299 :     Assembler::FlushICache(cell->GetIsolate(), pc_, sizeof(Address));
     455             :   }
     456       38975 :   if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
     457       38975 :       host() != NULL) {
     458             :     host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this,
     459       38676 :                                                                   cell);
     460             :   }
     461             : }
     462             : 
     463             : void RelocInfo::WipeOut(Isolate* isolate) {
     464       20494 :   if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) ||
     465        6883 :       IsInternalReference(rmode_)) {
     466        8212 :     Memory::Address_at(pc_) = NULL;
     467        5399 :   } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) {
     468             :     // Effectively write zero into the relocation.
     469             :     Assembler::set_target_address_at(isolate, pc_, host_,
     470        5399 :                                      pc_ + sizeof(int32_t));
     471             :   } else {
     472           0 :     UNREACHABLE();
     473             :   }
     474             : }
     475             : 
     476             : Handle<Code> RelocInfo::code_age_stub_handle(Assembler* origin) {
     477             :   DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
     478             :   DCHECK(*pc_ == kCallOpcode);
     479          14 :   return origin->code_target_object_handle_at(pc_ + 1);
     480             : }
     481             : 
     482             : 
     483             : Code* RelocInfo::code_age_stub() {
     484             :   DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
     485             :   DCHECK(*pc_ == kCallOpcode);
     486             :   return Code::GetCodeFromTargetAddress(
     487           0 :       Assembler::target_address_at(pc_ + 1, host_));
     488             : }
     489             : 
     490             : 
     491             : void RelocInfo::set_code_age_stub(Code* stub,
     492             :                                   ICacheFlushMode icache_flush_mode) {
     493             :   DCHECK(*pc_ == kCallOpcode);
     494             :   DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
     495             :   Assembler::set_target_address_at(stub->GetIsolate(), pc_ + 1, host_,
     496             :                                    stub->instruction_start(),
     497          14 :                                    icache_flush_mode);
     498             : }
     499             : 
     500             : 
     501             : Address RelocInfo::debug_call_address() {
     502             :   DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence());
     503       12039 :   return Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset);
     504             : }
     505             : 
     506           0 : void RelocInfo::set_debug_call_address(Isolate* isolate, Address target) {
     507             :   DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence());
     508           0 :   Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset) =
     509           0 :       target;
     510             :   Assembler::FlushICache(isolate,
     511           0 :                          pc_ + Assembler::kPatchDebugBreakSlotAddressOffset,
     512           0 :                          sizeof(Address));
     513           0 :   if (host() != NULL) {
     514           0 :     Code* target_code = Code::GetCodeFromTargetAddress(target);
     515             :     host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this,
     516           0 :                                                                   target_code);
     517             :   }
     518             : }
     519             : 
     520             : template <typename ObjectVisitor>
     521    73685002 : void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
     522             :   RelocInfo::Mode mode = rmode();
     523    36875787 :   if (mode == RelocInfo::EMBEDDED_OBJECT) {
     524     4464800 :     visitor->VisitEmbeddedPointer(host(), this);
     525     2232400 :     Assembler::FlushICache(isolate, pc_, sizeof(Address));
     526    34643387 :   } else if (RelocInfo::IsCodeTarget(mode)) {
     527    30498642 :     visitor->VisitCodeTarget(host(), this);
     528    19394066 :   } else if (mode == RelocInfo::CELL) {
     529        7304 :     visitor->VisitCellPointer(host(), this);
     530    19390414 :   } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
     531    31439622 :     visitor->VisitExternalReference(host(), this);
     532     3642569 :   } else if (mode == RelocInfo::INTERNAL_REFERENCE) {
     533     7090360 :     visitor->VisitInternalReference(host(), this);
     534       97389 :   } else if (RelocInfo::IsCodeAgeSequence(mode)) {
     535           0 :     visitor->VisitCodeAgeSequence(host(), this);
     536      120365 :   } else if (RelocInfo::IsDebugBreakSlot(mode) &&
     537       22976 :              IsPatchedDebugBreakSlotSequence()) {
     538          24 :     visitor->VisitDebugTarget(host(), this);
     539       81803 :   } else if (RelocInfo::IsRuntimeEntry(mode)) {
     540      117678 :     visitor->VisitRuntimeEntry(host(), this);
     541             :   }
     542    36875787 : }
     543             : 
     544             : 
     545             : template<typename StaticVisitor>
     546   776988535 : void RelocInfo::Visit(Heap* heap) {
     547             :   RelocInfo::Mode mode = rmode();
     548   776988535 :   if (mode == RelocInfo::EMBEDDED_OBJECT) {
     549             :     StaticVisitor::VisitEmbeddedPointer(heap, this);
     550    61635708 :     Assembler::FlushICache(heap->isolate(), pc_, sizeof(Address));
     551   746170682 :   } else if (RelocInfo::IsCodeTarget(mode)) {
     552             :     StaticVisitor::VisitCodeTarget(heap, this);
     553   431821434 :   } else if (mode == RelocInfo::CELL) {
     554             :     StaticVisitor::VisitCell(heap, this);
     555   431759884 :   } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
     556             :     StaticVisitor::VisitExternalReference(this);
     557    80509921 :   } else if (mode == RelocInfo::INTERNAL_REFERENCE) {
     558             :     StaticVisitor::VisitInternalReference(this);
     559     1264282 :   } else if (RelocInfo::IsCodeAgeSequence(mode)) {
     560             :     StaticVisitor::VisitCodeAgeSequence(heap, this);
     561     1328782 :   } else if (RelocInfo::IsDebugBreakSlot(mode) &&
     562       64500 :              IsPatchedDebugBreakSlotSequence()) {
     563             :     StaticVisitor::VisitDebugTarget(heap, this);
     564             :   } else if (RelocInfo::IsRuntimeEntry(mode)) {
     565             :     StaticVisitor::VisitRuntimeEntry(this);
     566             :   }
     567   776987928 : }
     568             : 
     569             : 
     570             : // -----------------------------------------------------------------------------
     571             : // Implementation of Operand
     572             : 
     573             : void Operand::set_modrm(int mod, Register rm_reg) {
     574             :   DCHECK(is_uint2(mod));
     575    90292425 :   buf_[0] = mod << 6 | rm_reg.low_bits();
     576             :   // Set REX.B to the high bit of rm.code().
     577    90235514 :   rex_ |= rm_reg.high_bit();
     578             : }
     579             : 
     580             : 
     581             : void Operand::set_sib(ScaleFactor scale, Register index, Register base) {
     582             :   DCHECK(len_ == 1);
     583             :   DCHECK(is_uint2(scale));
     584             :   // Use SIB with no index register only for base rsp or r12. Otherwise we
     585             :   // would skip the SIB byte entirely.
     586             :   DCHECK(!index.is(rsp) || base.is(rsp) || base.is(r12));
     587    21108281 :   buf_[1] = (scale << 6) | (index.low_bits() << 3) | base.low_bits();
     588    18490301 :   rex_ |= index.high_bit() << 1 | base.high_bit();
     589    15923146 :   len_ = 2;
     590             : }
     591             : 
     592             : void Operand::set_disp8(int disp) {
     593             :   DCHECK(is_int8(disp));
     594             :   DCHECK(len_ == 1 || len_ == 2);
     595    67420229 :   int8_t* p = reinterpret_cast<int8_t*>(&buf_[len_]);
     596    67420229 :   *p = disp;
     597    67420229 :   len_ += sizeof(int8_t);
     598             : }
     599             : 
     600             : void Operand::set_disp32(int disp) {
     601             :   DCHECK(len_ == 1 || len_ == 2);
     602    14299495 :   int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]);
     603    14299495 :   *p = disp;
     604    14299495 :   len_ += sizeof(int32_t);
     605             : }
     606             : 
     607             : void Operand::set_disp64(int64_t disp) {
     608             :   DCHECK_EQ(1, len_);
     609        6086 :   int64_t* p = reinterpret_cast<int64_t*>(&buf_[len_]);
     610        6086 :   *p = disp;
     611        6086 :   len_ += sizeof(disp);
     612             : }
     613             : }  // namespace internal
     614             : }  // namespace v8
     615             : 
     616             : #endif  // V8_X64_ASSEMBLER_X64_INL_H_

Generated by: LCOV version 1.10