1659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 59085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifndef V8_X64_ASSEMBLER_X64_INL_H_ 69085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define V8_X64_ASSEMBLER_X64_INL_H_ 79085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x64/assembler-x64.h" 9659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 105de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/cpu.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8memory.h" 13b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 1471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 169085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 17874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.orgbool CpuFeatures::SupportsCrankshaft() { return true; } 18874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org 199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 2071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org// ----------------------------------------------------------------------------- 2171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org// Implementation of Assembler 2271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 2371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 24e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgstatic const byte kCallOpcode = 0xE8; 254edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org// The length of pushq(rbp), movp(rbp, rsp), Push(rsi) and Push(rdi). 264edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.orgstatic const int kNoCodeAgeSequenceLength = kPointerSize == kInt64Size ? 6 : 17; 27e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 28e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 29755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgvoid Assembler::emitl(uint32_t x) { 30755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org Memory::uint32_at(pc_) = x; 31755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org pc_ += sizeof(uint32_t); 32755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 33755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 34755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 35fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgvoid Assembler::emitp(void* x, RelocInfo::Mode rmode) { 36fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org uintptr_t value = reinterpret_cast<uintptr_t>(x); 37fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Memory::uintptr_at(pc_) = value; 38fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (!RelocInfo::IsNone(rmode)) { 39fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org RecordRelocInfo(rmode, value); 40fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 41fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org pc_ += sizeof(uintptr_t); 42fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org} 43fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 44fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 45c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgvoid Assembler::emitq(uint64_t x) { 46755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org Memory::uint64_at(pc_) = x; 47e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org pc_ += sizeof(uint64_t); 48e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 49e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 50e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 51e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.orgvoid Assembler::emitw(uint16_t x) { 52e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org Memory::uint16_at(pc_) = x; 53e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org pc_ += sizeof(uint16_t); 54755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 55755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 56755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 578e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid Assembler::emit_code_target(Handle<Code> target, 588e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org RelocInfo::Mode rmode, 59471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId ast_id) { 60e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(RelocInfo::IsCodeTarget(rmode) || 61c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org rmode == RelocInfo::CODE_AGE_SEQUENCE); 62471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) { 63471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, ast_id.ToInt()); 648e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org } else { 658e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org RecordRelocInfo(rmode); 668e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org } 67c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org int current = code_targets_.length(); 68c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org if (current > 0 && code_targets_.last().is_identical_to(target)) { 69c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Optimization if we keep jumping to the same code target. 70c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org emitl(current - 1); 71c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org } else { 72c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org code_targets_.Add(target); 73c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org emitl(current); 74c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org } 75c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org} 76c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 77c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 786e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgvoid Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) { 79e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(RelocInfo::IsRuntimeEntry(rmode)); 806e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org RecordRelocInfo(rmode); 816e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org emitl(static_cast<uint32_t>(entry - isolate()->code_range()->start())); 826e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org} 836e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 846e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 8571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid Assembler::emit_rex_64(Register reg, Register rm_reg) { 865aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit()); 8771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 8871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 8971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 903e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgvoid Assembler::emit_rex_64(XMMRegister reg, Register rm_reg) { 913e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3); 923e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org} 933e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 943e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 95ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.orgvoid Assembler::emit_rex_64(Register reg, XMMRegister rm_reg) { 96ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3); 97ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org} 98ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 99ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 10071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid Assembler::emit_rex_64(Register reg, const Operand& op) { 1015aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org emit(0x48 | reg.high_bit() << 2 | op.rex_); 102755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 103755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 104755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 1053e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgvoid Assembler::emit_rex_64(XMMRegister reg, const Operand& op) { 1063e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_); 1073e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org} 1083e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 1093e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 110e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.orgvoid Assembler::emit_rex_64(Register rm_reg) { 111e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(rm_reg.code() & 0xf, rm_reg.code()); 1125aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org emit(0x48 | rm_reg.high_bit()); 113e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 114e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 115e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 116e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.orgvoid Assembler::emit_rex_64(const Operand& op) { 117e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org emit(0x48 | op.rex_); 118e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 119e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 120e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 121755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgvoid Assembler::emit_rex_32(Register reg, Register rm_reg) { 1225aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org emit(0x40 | reg.high_bit() << 2 | rm_reg.high_bit()); 123755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 124755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 125755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 126755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgvoid Assembler::emit_rex_32(Register reg, const Operand& op) { 1275aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org emit(0x40 | reg.high_bit() << 2 | op.rex_); 128755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 129755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 130755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 131e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.orgvoid Assembler::emit_rex_32(Register rm_reg) { 1325aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org emit(0x40 | rm_reg.high_bit()); 133e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 134e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 135e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 136e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.orgvoid Assembler::emit_rex_32(const Operand& op) { 137e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org emit(0x40 | op.rex_); 138e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 139e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 140e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 141755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgvoid Assembler::emit_optional_rex_32(Register reg, Register rm_reg) { 1425aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org byte rex_bits = reg.high_bit() << 2 | rm_reg.high_bit(); 143e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org if (rex_bits != 0) emit(0x40 | rex_bits); 144755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 145755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 146755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 147755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgvoid Assembler::emit_optional_rex_32(Register reg, const Operand& op) { 1485aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org byte rex_bits = reg.high_bit() << 2 | op.rex_; 149e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org if (rex_bits != 0) emit(0x40 | rex_bits); 15071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 15171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 15271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 1533e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgvoid Assembler::emit_optional_rex_32(XMMRegister reg, const Operand& op) { 1543e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org byte rex_bits = (reg.code() & 0x8) >> 1 | op.rex_; 1553e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org if (rex_bits != 0) emit(0x40 | rex_bits); 1563e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org} 1573e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 1583e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 1593e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgvoid Assembler::emit_optional_rex_32(XMMRegister reg, XMMRegister base) { 1603e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org byte rex_bits = (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3; 1613e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org if (rex_bits != 0) emit(0x40 | rex_bits); 1623e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org} 1633e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 1643e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 1653e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgvoid Assembler::emit_optional_rex_32(XMMRegister reg, Register base) { 1663e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org byte rex_bits = (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3; 1673e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org if (rex_bits != 0) emit(0x40 | rex_bits); 1683e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org} 1693e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 1703e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 171ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.orgvoid Assembler::emit_optional_rex_32(Register reg, XMMRegister base) { 172ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org byte rex_bits = (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3; 173ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org if (rex_bits != 0) emit(0x40 | rex_bits); 174ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org} 175ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 176ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 177e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.orgvoid Assembler::emit_optional_rex_32(Register rm_reg) { 1785aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org if (rm_reg.high_bit()) emit(0x41); 17971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 18071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 18171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 182e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.orgvoid Assembler::emit_optional_rex_32(const Operand& op) { 183e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org if (op.rex_ != 0) emit(0x40 | op.rex_); 184e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 185e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 186e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 18797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.orgAddress Assembler::target_address_at(Address pc, 18897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool) { 189c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org return Memory::int32_at(pc) + pc + 4; 190e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 191e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 192e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 19397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.orgvoid Assembler::set_target_address_at(Address pc, 19497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool, 1956a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Address target, 1966a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org ICacheFlushMode icache_flush_mode) { 197c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4); 1986a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 1995de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(pc, sizeof(int32_t)); 2006a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org } 20171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 20271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 20389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 20489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgAddress Assembler::target_address_from_return_address(Address pc) { 20589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org return pc - kCallTargetAddressOffset; 20689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org} 20789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 20889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org 2099d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgAddress Assembler::break_address_from_return_address(Address pc) { 2109d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org return pc - Assembler::kPatchDebugBreakSlotReturnOffset; 2119d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org} 2129d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2139d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 214c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgHandle<Object> Assembler::code_target_object_handle_at(Address pc) { 215c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org return code_targets_[Memory::int32_at(pc)]; 216c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org} 21771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 2186e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 2196e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgAddress Assembler::runtime_entry_at(Address pc) { 2206e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org return Memory::int32_at(pc) + isolate()->code_range()->start(); 2216e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org} 2226e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 22371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org// ----------------------------------------------------------------------------- 22471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org// Implementation of RelocInfo 22571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 226b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org// The modes possibly affected by apply must be in kApplyMask. 2276a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgvoid RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { 2286a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH; 2293e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org if (IsInternalReference(rmode_)) { 230b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org // absolute code pointer inside code object moves with the code object. 231c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org Memory::Address_at(pc_) += static_cast<int32_t>(delta); 2325de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org if (flush_icache) CpuFeatures::FlushICache(pc_, sizeof(Address)); 2336e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { 234c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org Memory::int32_at(pc_) -= static_cast<int32_t>(delta); 2355de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org if (flush_icache) CpuFeatures::FlushICache(pc_, sizeof(int32_t)); 236e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else if (rmode_ == CODE_AGE_SEQUENCE) { 237e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (*pc_ == kCallOpcode) { 238e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); 239e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org *p -= static_cast<int32_t>(delta); // Relocate entry. 2405de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); 241e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 242b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org } 243b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 244b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 245b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 2469085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgAddress RelocInfo::target_address() { 247e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); 24897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return Assembler::target_address_at(pc_, host_); 2499085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} 2509085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 2519085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 2529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgAddress RelocInfo::target_address_address() { 253e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) 25404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org || rmode_ == EMBEDDED_OBJECT 25504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org || rmode_ == EXTERNAL_REFERENCE); 2569085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return reinterpret_cast<Address>(pc_); 2579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} 2589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 2599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 260bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgAddress RelocInfo::constant_pool_entry_address() { 261bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org UNREACHABLE(); 262bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org return NULL; 263bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org} 264bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 265bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 2669155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgint RelocInfo::target_address_size() { 2679155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org if (IsCodedSpecially()) { 26888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org return Assembler::kSpecialTargetSize; 2699155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org } else { 27088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org return kPointerSize; 2719155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org } 2729155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org} 2739155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org 2749155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org 2756a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgvoid RelocInfo::set_target_address(Address target, 2766a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org WriteBarrierMode write_barrier_mode, 2776a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org ICacheFlushMode icache_flush_mode) { 278e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); 2796a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode); 2806a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL && 2816a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org IsCodeTarget(rmode_)) { 282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object* target_code = Code::GetCodeFromTargetAddress(target); 2836e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 2846e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org host(), this, HeapObject::cast(target_code)); 285c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org } 2869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} 287e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 288e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 289b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgObject* RelocInfo::target_object() { 290e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 291c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org return Memory::Object_at(pc_); 292c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org} 293c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 294c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 295f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comHandle<Object> RelocInfo::target_object_handle(Assembler* origin) { 296e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 297c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org if (rmode_ == EMBEDDED_OBJECT) { 298c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org return Memory::Object_Handle_at(pc_); 299c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org } else { 300c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org return origin->code_target_object_handle_at(pc_); 301c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org } 302b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 303b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 304b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 305057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgAddress RelocInfo::target_reference() { 306e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE); 307057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org return Memory::Address_at(pc_); 308b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 309b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 310b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 3116a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgvoid RelocInfo::set_target_object(Object* target, 3126a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org WriteBarrierMode write_barrier_mode, 3136a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org ICacheFlushMode icache_flush_mode) { 314e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Memory::Object_at(pc_) = target; 3166a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 3175de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(pc_, sizeof(Address)); 3186a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org } 3196a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org if (write_barrier_mode == UPDATE_WRITE_BARRIER && 320394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com host() != NULL && 321394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com target->IsHeapObject()) { 322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com host()->GetHeap()->incremental_marking()->RecordWrite( 323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com host(), &Memory::Object_at(pc_), HeapObject::cast(target)); 324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 325b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 326b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 327b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 3286e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgAddress RelocInfo::target_runtime_entry(Assembler* origin) { 329e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsRuntimeEntry(rmode_)); 3306e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org return origin->runtime_entry_at(pc_); 3316e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org} 3326e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 3336e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 3346e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgvoid RelocInfo::set_target_runtime_entry(Address target, 3356a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org WriteBarrierMode write_barrier_mode, 3366a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org ICacheFlushMode icache_flush_mode) { 337e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsRuntimeEntry(rmode_)); 3386a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org if (target_address() != target) { 3396a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org set_target_address(target, write_barrier_mode, icache_flush_mode); 3406a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org } 3416e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org} 3426e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 3436e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 34441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgHandle<Cell> RelocInfo::target_cell_handle() { 345e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(rmode_ == RelocInfo::CELL); 346a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Address address = Memory::Address_at(pc_); 34741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return Handle<Cell>(reinterpret_cast<Cell**>(address)); 348a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 35141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgCell* RelocInfo::target_cell() { 352e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(rmode_ == RelocInfo::CELL); 35341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return Cell::FromValueAddress(Memory::Address_at(pc_)); 354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3576a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgvoid RelocInfo::set_target_cell(Cell* cell, 3586a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org WriteBarrierMode write_barrier_mode, 3596a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org ICacheFlushMode icache_flush_mode) { 360e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(rmode_ == RelocInfo::CELL); 36141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Address address = cell->address() + Cell::kValueOffset; 362a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Memory::Address_at(pc_) = address; 3636a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 3645de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(pc_, sizeof(Address)); 3656a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org } 3666a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org if (write_barrier_mode == UPDATE_WRITE_BARRIER && 367394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com host() != NULL) { 368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // TODO(1550) We are passing NULL as a slot because cell can never be on 369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // evacuation candidate. 370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com host()->GetHeap()->incremental_marking()->RecordWrite( 371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com host(), NULL, cell); 372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 374a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 375a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 376057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid RelocInfo::WipeOut() { 377057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_)) { 378057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Memory::Address_at(pc_) = NULL; 379057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { 380057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org // Effectively write zero into the relocation. 38197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org Assembler::set_target_address_at(pc_, host_, pc_ + sizeof(int32_t)); 382057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org } else { 383057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org UNREACHABLE(); 384057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org } 385057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org} 386057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org 387057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org 3889d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.combool RelocInfo::IsPatchedReturnSequence() { 389911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // The recognized call sequence is: 390594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // movq(kScratchRegister, address); call(kScratchRegister); 391911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // It only needs to be distinguished from a return sequence 392911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // movq(rsp, rbp); pop(rbp); ret(n); int3 *6 393911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // The 11th byte is int3 (0xCC) in the return sequence and 394911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // REX.WB (0x48+register bit) for the call sequence. 395594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return pc_[Assembler::kMoveAddressIntoScratchRegisterInstructionLength] != 396594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 0xCC; 397b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 398b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 399b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 4002356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgbool RelocInfo::IsPatchedDebugBreakSlotSequence() { 4012356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org return !Assembler::IsNop(pc()); 4022356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org} 4032356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 4042356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 405c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgHandle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { 406e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 407e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(*pc_ == kCallOpcode); 408c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org return origin->code_target_object_handle_at(pc_ + 1); 409c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 410c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 411c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 412e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgCode* RelocInfo::code_age_stub() { 413e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 414e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(*pc_ == kCallOpcode); 415e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org return Code::GetCodeFromTargetAddress( 41697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org Assembler::target_address_at(pc_ + 1, host_)); 417e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 418e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 419e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4206a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.orgvoid RelocInfo::set_code_age_stub(Code* stub, 4216a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org ICacheFlushMode icache_flush_mode) { 422e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(*pc_ == kCallOpcode); 423e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 4246a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), 4256a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org icache_flush_mode); 426e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 427e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 428e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 429b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgAddress RelocInfo::call_address() { 430e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 431c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 432c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org return Memory::Address_at( 433c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org pc_ + Assembler::kRealPatchReturnSequenceAddressOffset); 434b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 435b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 436b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 437b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgvoid RelocInfo::set_call_address(Address target) { 438e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 439c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 440c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Memory::Address_at(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset) = 441c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org target; 4425de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache( 4435de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org pc_ + Assembler::kRealPatchReturnSequenceAddressOffset, sizeof(Address)); 444c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (host() != NULL) { 445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Object* target_code = Code::GetCodeFromTargetAddress(target); 446c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com host(), this, HeapObject::cast(target_code)); 448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 449b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 450b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 451b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 452b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgObject* RelocInfo::call_object() { 453b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org return *call_object_address(); 454b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 455b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 456b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 457b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgvoid RelocInfo::set_call_object(Object* target) { 458b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org *call_object_address() = target; 459b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 460b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 461b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 462b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgObject** RelocInfo::call_object_address() { 463e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 464c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 465911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return reinterpret_cast<Object**>( 466911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org pc_ + Assembler::kPatchReturnSequenceAddressOffset); 467b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 468b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 4699155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org 470e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.orgvoid RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { 4719155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org RelocInfo::Mode mode = rmode(); 4729155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org if (mode == RelocInfo::EMBEDDED_OBJECT) { 473b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org visitor->VisitEmbeddedPointer(this); 4745de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(pc_, sizeof(Address)); 4759155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org } else if (RelocInfo::IsCodeTarget(mode)) { 4769155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org visitor->VisitCodeTarget(this); 47741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } else if (mode == RelocInfo::CELL) { 47841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org visitor->VisitCell(this); 4799155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 48004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org visitor->VisitExternalReference(this); 4815de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(pc_, sizeof(Address)); 482e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else if (RelocInfo::IsCodeAgeSequence(mode)) { 483e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org visitor->VisitCodeAgeSequence(this); 484ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else if (((RelocInfo::IsJSReturn(mode) && 4852356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org IsPatchedReturnSequence()) || 4862356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org (RelocInfo::IsDebugBreakSlot(mode) && 487ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org IsPatchedDebugBreakSlotSequence())) && 488e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org isolate->debug()->has_break_points()) { 4899155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org visitor->VisitDebugTarget(this); 4906e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } else if (RelocInfo::IsRuntimeEntry(mode)) { 4919155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org visitor->VisitRuntimeEntry(this); 4929155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org } 4939155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org} 4949155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org 4959155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org 496ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgtemplate<typename StaticVisitor> 497ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid RelocInfo::Visit(Heap* heap) { 498ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org RelocInfo::Mode mode = rmode(); 499ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org if (mode == RelocInfo::EMBEDDED_OBJECT) { 500b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org StaticVisitor::VisitEmbeddedPointer(heap, this); 5015de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(pc_, sizeof(Address)); 502ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org } else if (RelocInfo::IsCodeTarget(mode)) { 503c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org StaticVisitor::VisitCodeTarget(heap, this); 50441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } else if (mode == RelocInfo::CELL) { 50541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org StaticVisitor::VisitCell(heap, this); 506ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 50704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org StaticVisitor::VisitExternalReference(this); 5085de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(pc_, sizeof(Address)); 509e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else if (RelocInfo::IsCodeAgeSequence(mode)) { 510e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org StaticVisitor::VisitCodeAgeSequence(heap, this); 511ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else if (heap->isolate()->debug()->has_break_points() && 512ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org ((RelocInfo::IsJSReturn(mode) && 513ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org IsPatchedReturnSequence()) || 514ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org (RelocInfo::IsDebugBreakSlot(mode) && 515ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org IsPatchedDebugBreakSlotSequence()))) { 516c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org StaticVisitor::VisitDebugTarget(heap, this); 5176e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } else if (RelocInfo::IsRuntimeEntry(mode)) { 518ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org StaticVisitor::VisitRuntimeEntry(this); 519ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org } 520ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org} 521ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 522ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 523755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// ----------------------------------------------------------------------------- 524755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// Implementation of Operand 525755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 5265aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid Operand::set_modrm(int mod, Register rm_reg) { 527e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_uint2(mod)); 5285aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org buf_[0] = mod << 6 | rm_reg.low_bits(); 52971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Set REX.B to the high bit of rm.code(). 5305aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org rex_ |= rm_reg.high_bit(); 53171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 53271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 53371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 53471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid Operand::set_sib(ScaleFactor scale, Register index, Register base) { 535e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(len_ == 1); 536e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_uint2(scale)); 537eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Use SIB with no index register only for base rsp or r12. Otherwise we 538eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // would skip the SIB byte entirely. 539e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!index.is(rsp) || base.is(rsp) || base.is(r12)); 5400ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org buf_[1] = (scale << 6) | (index.low_bits() << 3) | base.low_bits(); 5415aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org rex_ |= index.high_bit() << 1 | base.high_bit(); 54271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org len_ = 2; 54371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 54471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 545755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgvoid Operand::set_disp8(int disp) { 546e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_int8(disp)); 547e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(len_ == 1 || len_ == 2); 548755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org int8_t* p = reinterpret_cast<int8_t*>(&buf_[len_]); 549755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org *p = disp; 550755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org len_ += sizeof(int8_t); 551755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 55271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 553755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgvoid Operand::set_disp32(int disp) { 554e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(len_ == 1 || len_ == 2); 55571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); 55671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org *p = disp; 55771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org len_ += sizeof(int32_t); 55871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 55971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 56071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 5619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} } // namespace v8::internal 5629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 5639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif // V8_X64_ASSEMBLER_X64_INL_H_ 564