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