13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_X64_ASSEMBLER_X64_INL_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_X64_ASSEMBLER_X64_INL_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "x64/assembler-x64.h"
323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "cpu.h"
34f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#include "debug.h"
3544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "v8memory.h"
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of Assembler
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emitl(uint32_t x) {
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Memory::uint32_at(pc_) = x;
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  pc_ += sizeof(uint32_t);
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emitq(uint64_t x, RelocInfo::Mode rmode) {
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Memory::uint64_at(pc_) = x;
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rmode != RelocInfo::NONE) {
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RecordRelocInfo(rmode, x);
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  pc_ += sizeof(uint64_t);
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emitw(uint16_t x) {
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Memory::uint16_at(pc_) = x;
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  pc_ += sizeof(uint16_t);
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
66257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Assembler::emit_code_target(Handle<Code> target,
67257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                 RelocInfo::Mode rmode,
68257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                 unsigned ast_id) {
693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  ASSERT(RelocInfo::IsCodeTarget(rmode));
70257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (rmode == RelocInfo::CODE_TARGET && ast_id != kNoASTId) {
71257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, ast_id);
72257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
73257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    RecordRelocInfo(rmode);
74257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  int current = code_targets_.length();
763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (current > 0 && code_targets_.last().is_identical_to(target)) {
773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    // Optimization if we keep jumping to the same code target.
783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    emitl(current - 1);
793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    code_targets_.Add(target);
813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    emitl(current);
823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(Register reg, Register rm_reg) {
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit());
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(XMMRegister reg, Register rm_reg) {
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
966ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::emit_rex_64(Register reg, XMMRegister rm_reg) {
976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(Register reg, const Operand& op) {
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x48 | reg.high_bit() << 2 | op.rex_);
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(XMMRegister reg, const Operand& op) {
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_);
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(Register rm_reg) {
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT_EQ(rm_reg.code() & 0xf, rm_reg.code());
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x48 | rm_reg.high_bit());
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(const Operand& op) {
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x48 | op.rex_);
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_32(Register reg, Register rm_reg) {
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x40 | reg.high_bit() << 2 | rm_reg.high_bit());
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_32(Register reg, const Operand& op) {
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x40 | reg.high_bit() << 2  | op.rex_);
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_32(Register rm_reg) {
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x40 | rm_reg.high_bit());
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_32(const Operand& op) {
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x40 | op.rex_);
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(Register reg, Register rm_reg) {
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte rex_bits = reg.high_bit() << 2 | rm_reg.high_bit();
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rex_bits != 0) emit(0x40 | rex_bits);
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(Register reg, const Operand& op) {
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte rex_bits =  reg.high_bit() << 2 | op.rex_;
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rex_bits != 0) emit(0x40 | rex_bits);
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(XMMRegister reg, const Operand& op) {
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte rex_bits =  (reg.code() & 0x8) >> 1 | op.rex_;
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rex_bits != 0) emit(0x40 | rex_bits);
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(XMMRegister reg, XMMRegister base) {
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte rex_bits =  (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3;
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rex_bits != 0) emit(0x40 | rex_bits);
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(XMMRegister reg, Register base) {
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte rex_bits =  (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3;
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rex_bits != 0) emit(0x40 | rex_bits);
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1726ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::emit_optional_rex_32(Register reg, XMMRegister base) {
1736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  byte rex_bits =  (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3;
1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (rex_bits != 0) emit(0x40 | rex_bits);
1756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
1766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(Register rm_reg) {
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rm_reg.high_bit()) emit(0x41);
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(const Operand& op) {
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (op.rex_ != 0) emit(0x40 | op.rex_);
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress Assembler::target_address_at(Address pc) {
1893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return Memory::int32_at(pc) + pc + 4;
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::set_target_address_at(Address pc, Address target) {
194d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4);
1953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  CPU::FlushICache(pc, sizeof(int32_t));
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockHandle<Object> Assembler::code_target_object_handle_at(Address pc) {
1993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return code_targets_[Memory::int32_at(pc)];
2003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of RelocInfo
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The modes possibly affected by apply must be in kApplyMask.
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::apply(intptr_t delta) {
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IsInternalReference(rmode_)) {
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // absolute code pointer inside code object moves with the code object.
209d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Memory::Address_at(pc_) += static_cast<int32_t>(delta);
2101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
2113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else if (IsCodeTarget(rmode_)) {
212d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Memory::int32_at(pc_) -= static_cast<int32_t>(delta);
2131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(int32_t));
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address() {
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
2203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (IsCodeTarget(rmode_)) {
2213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    return Assembler::target_address_at(pc_);
2223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
2233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    return Memory::Address_at(pc_);
2243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address_address() {
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              || rmode_ == EMBEDDED_OBJECT
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              || rmode_ == EXTERNAL_REFERENCE);
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reinterpret_cast<Address>(pc_);
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
236f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeint RelocInfo::target_address_size() {
237f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  if (IsCodedSpecially()) {
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return Assembler::kSpecialTargetSize;
239f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else {
2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return kPointerSize;
241f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
242f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
243f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
244f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
2473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (IsCodeTarget(rmode_)) {
2483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Assembler::set_target_address_at(pc_, target);
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* target_code = Code::GetCodeFromTargetAddress(target);
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (mode == UPDATE_WRITE_BARRIER && host() != NULL) {
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          host(), this, HeapObject::cast(target_code));
2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
2553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Memory::Address_at(pc_) = target;
2561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
2573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::target_object() {
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
2633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return Memory::Object_at(pc_);
2643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
2653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
2663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Object> RelocInfo::target_object_handle(Assembler* origin) {
2683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
2693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (rmode_ == EMBEDDED_OBJECT) {
2703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    return Memory::Object_Handle_at(pc_);
2713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
2723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    return origin->code_target_object_handle_at(pc_);
2733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** RelocInfo::target_object_address() {
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reinterpret_cast<Object**>(pc_);
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress* RelocInfo::target_reference_address() {
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reinterpret_cast<Address*>(pc_);
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) {
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Memory::Object_at(pc_) = target;
2921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  CPU::FlushICache(pc_, sizeof(Address));
2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (mode == UPDATE_WRITE_BARRIER &&
2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      host() != NULL &&
2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      target->IsHeapObject()) {
2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWrite(
2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        host(), &Memory::Object_at(pc_), HeapObject::cast(target));
2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHandle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Address address = Memory::Address_at(pc_);
305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return Handle<JSGlobalPropertyCell>(
306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      reinterpret_cast<JSGlobalPropertyCell**>(address));
307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochJSGlobalPropertyCell* RelocInfo::target_cell() {
311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Address address = Memory::Address_at(pc_);
313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Object* object = HeapObject::FromAddress(
314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      address - JSGlobalPropertyCell::kValueOffset);
315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return reinterpret_cast<JSGlobalPropertyCell*>(object);
316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_cell(JSGlobalPropertyCell* cell,
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                WriteBarrierMode mode) {
321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Address address = cell->address() + JSGlobalPropertyCell::kValueOffset;
323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Memory::Address_at(pc_) = address;
3241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  CPU::FlushICache(pc_, sizeof(Address));
3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (mode == UPDATE_WRITE_BARRIER &&
3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      host() != NULL) {
3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // TODO(1550) We are passing NULL as a slot because cell can never be on
3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // evacuation candidate.
3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWrite(
3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        host(), NULL, cell);
3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool RelocInfo::IsPatchedReturnSequence() {
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The recognized call sequence is:
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //  movq(kScratchRegister, immediate64); call(kScratchRegister);
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // It only needs to be distinguished from a return sequence
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //  movq(rsp, rbp); pop(rbp); ret(n); int3 *6
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The 11th byte is int3 (0xCC) in the return sequence and
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.WB (0x48+register bit) for the call sequence.
3423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#ifdef ENABLE_DEBUGGER_SUPPORT
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return pc_[10] != 0xCC;
3443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#else
3453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return false;
3463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbool RelocInfo::IsPatchedDebugBreakSlotSequence() {
3517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return !Assembler::IsNop(pc());
3527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
3537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
3547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::call_address() {
356bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
357bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
3583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return Memory::Address_at(
3593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block      pc_ + Assembler::kRealPatchReturnSequenceAddressOffset);
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_call_address(Address target) {
364bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
365bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
3663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Memory::Address_at(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset) =
3673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block      target;
3681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  CPU::FlushICache(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset,
3691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                   sizeof(Address));
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (host() != NULL) {
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* target_code = Code::GetCodeFromTargetAddress(target);
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        host(), this, HeapObject::cast(target_code));
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::call_object() {
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return *call_object_address();
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_call_object(Object* target) {
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *call_object_address() = target;
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** RelocInfo::call_object_address() {
389bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
390bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reinterpret_cast<Object**>(
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      pc_ + Assembler::kPatchReturnSequenceAddressOffset);
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
395f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
396f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid RelocInfo::Visit(ObjectVisitor* visitor) {
397f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  RelocInfo::Mode mode = rmode();
398f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  if (mode == RelocInfo::EMBEDDED_OBJECT) {
3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    visitor->VisitEmbeddedPointer(this);
4001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
401f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else if (RelocInfo::IsCodeTarget(mode)) {
402f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitCodeTarget(this);
4031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
4041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    visitor->VisitGlobalPropertyCell(this);
405f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    visitor->VisitExternalReference(this);
4071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
408f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT
40944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // TODO(isolates): Get a cached isolate below.
41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (((RelocInfo::IsJSReturn(mode) &&
4117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch              IsPatchedReturnSequence()) ||
4127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch             (RelocInfo::IsDebugBreakSlot(mode) &&
41344f0eee88ff00398ff7f715fab053374d808c90dSteve Block              IsPatchedDebugBreakSlotSequence())) &&
41444f0eee88ff00398ff7f715fab053374d808c90dSteve Block             Isolate::Current()->debug()->has_break_points()) {
415f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitDebugTarget(this);
416f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif
417f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else if (mode == RelocInfo::RUNTIME_ENTRY) {
418f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitRuntimeEntry(this);
419f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
420f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
421f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
422f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
423756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merricktemplate<typename StaticVisitor>
42444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RelocInfo::Visit(Heap* heap) {
425756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  RelocInfo::Mode mode = rmode();
426756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  if (mode == RelocInfo::EMBEDDED_OBJECT) {
4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    StaticVisitor::VisitEmbeddedPointer(heap, this);
4281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
429756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  } else if (RelocInfo::IsCodeTarget(mode)) {
4308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    StaticVisitor::VisitCodeTarget(heap, this);
4311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
4328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    StaticVisitor::VisitGlobalPropertyCell(heap, this);
433756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    StaticVisitor::VisitExternalReference(this);
4351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
436756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#ifdef ENABLE_DEBUGGER_SUPPORT
43744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (heap->isolate()->debug()->has_break_points() &&
438756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick             ((RelocInfo::IsJSReturn(mode) &&
439756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick              IsPatchedReturnSequence()) ||
440756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick             (RelocInfo::IsDebugBreakSlot(mode) &&
441756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick              IsPatchedDebugBreakSlotSequence()))) {
4428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    StaticVisitor::VisitDebugTarget(heap, this);
443756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#endif
444756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  } else if (mode == RelocInfo::RUNTIME_ENTRY) {
445756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    StaticVisitor::VisitRuntimeEntry(this);
446756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
447756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
448756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
449756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of Operand
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_modrm(int mod, Register rm_reg) {
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(is_uint2(mod));
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  buf_[0] = mod << 6 | rm_reg.low_bits();
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set REX.B to the high bit of rm.code().
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rex_ |= rm_reg.high_bit();
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_sib(ScaleFactor scale, Register index, Register base) {
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(len_ == 1);
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(is_uint2(scale));
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Use SIB with no index register only for base rsp or r12. Otherwise we
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // would skip the SIB byte entirely.
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!index.is(rsp) || base.is(rsp) || base.is(r12));
4671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  buf_[1] = (scale << 6) | (index.low_bits() << 3) | base.low_bits();
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rex_ |= index.high_bit() << 1 | base.high_bit();
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  len_ = 2;
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_disp8(int disp) {
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(is_int8(disp));
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(len_ == 1 || len_ == 2);
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int8_t* p = reinterpret_cast<int8_t*>(&buf_[len_]);
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *p = disp;
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  len_ += sizeof(int8_t);
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_disp32(int disp) {
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(len_ == 1 || len_ == 2);
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]);
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *p = disp;
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  len_ += sizeof(int32_t);
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_X64_ASSEMBLER_X64_INL_H_
491