Index: src/x64/assembler-x64-inl.h |
=================================================================== |
--- src/x64/assembler-x64-inl.h (revision 13219) |
+++ src/x64/assembler-x64-inl.h (working copy) |
@@ -86,6 +86,20 @@ |
} |
+void Assembler::emit_deopt_entry(Address entry, RelocInfo::Mode rmode) { |
+ ASSERT(RelocInfo::IsDeoptEntry(rmode)); |
+ RecordRelocInfo(rmode); |
+ int current = deopt_entries_.length(); |
+ if (current > 0 && deopt_entries_.last() == entry) { |
+ // Optimization if we keep jumping to the same entry. |
+ emitl(current - 1); |
+ } else { |
+ deopt_entries_.Add(entry); |
+ emitl(current); |
+ } |
+} |
+ |
+ |
void Assembler::emit_rex_64(Register reg, Register rm_reg) { |
emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit()); |
} |
@@ -208,6 +222,11 @@ |
return code_targets_[Memory::int32_at(pc)]; |
} |
+ |
+Address Assembler::deopt_entry_at(Address pc) { |
+ return deopt_entries_[Memory::int32_at(pc)]; |
+} |
+ |
// ----------------------------------------------------------------------------- |
// Implementation of RelocInfo |
@@ -217,7 +236,7 @@ |
// absolute code pointer inside code object moves with the code object. |
Memory::Address_at(pc_) += static_cast<int32_t>(delta); |
CPU::FlushICache(pc_, sizeof(Address)); |
- } else if (IsCodeTarget(rmode_)) { |
+ } else if (IsCodeTarget(rmode_) || IsDeoptEntry(rmode_)) { |
Memory::int32_at(pc_) -= static_cast<int32_t>(delta); |
CPU::FlushICache(pc_, sizeof(int32_t)); |
} else if (rmode_ == CODE_AGE_SEQUENCE) { |
@@ -231,8 +250,9 @@ |
Address RelocInfo::target_address() { |
- ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); |
- if (IsCodeTarget(rmode_)) { |
+ ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY |
+ || IsDeoptEntry(rmode_)); |
+ if (IsCodeTarget(rmode_) || (IsDeoptEntry(rmode_))) { |
return Assembler::target_address_at(pc_); |
} else { |
return Memory::Address_at(pc_); |
@@ -242,6 +262,7 @@ |
Address RelocInfo::target_address_address() { |
ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY |
+ || IsDeoptEntry(rmode_) |
|| rmode_ == EMBEDDED_OBJECT |
|| rmode_ == EXTERNAL_REFERENCE); |
return reinterpret_cast<Address>(pc_); |
@@ -258,11 +279,13 @@ |
void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) { |
- ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); |
- if (IsCodeTarget(rmode_)) { |
+ ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY |
+ || IsDeoptEntry(rmode_)); |
+ if (IsCodeTarget(rmode_) || IsDeoptEntry(rmode_)) { |
Assembler::set_target_address_at(pc_, target); |
- Object* target_code = Code::GetCodeFromTargetAddress(target); |
- if (mode == UPDATE_WRITE_BARRIER && host() != NULL) { |
+ if (mode == UPDATE_WRITE_BARRIER && host() != NULL |
+ && IsCodeTarget(rmode_)) { |
+ Object* target_code = Code::GetCodeFromTargetAddress(target); |
host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
host(), this, HeapObject::cast(target_code)); |
} |
@@ -289,6 +312,12 @@ |
} |
+Address RelocInfo::target_deopt_entry(Assembler* origin) { |
+ ASSERT(IsDeoptEntry(rmode_)); |
+ return origin->deopt_entry_at(pc_); |
+} |
+ |
+ |
Object** RelocInfo::target_object_address() { |
ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
return reinterpret_cast<Object**>(pc_); |