Commit d616baed authored by danno@chromium.org's avatar danno@chromium.org

Use direct jump and call instruction for X64 when the deoptimization entries are in the code range.

Review URL: https://codereview.chromium.org/11574027

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13901 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9be937e6
...@@ -178,6 +178,19 @@ Address* RelocInfo::target_reference_address() { ...@@ -178,6 +178,19 @@ Address* RelocInfo::target_reference_address() {
} }
Address RelocInfo::target_runtime_entry(Assembler* origin) {
ASSERT(IsRuntimeEntry(rmode_));
return target_address();
}
void RelocInfo::set_target_runtime_entry(Address target,
WriteBarrierMode mode) {
ASSERT(IsRuntimeEntry(rmode_));
if (target_address() != target) set_target_address(target, mode);
}
Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() { Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
Address address = Memory::Address_at(pc_); Address address = Memory::Address_at(pc_);
......
...@@ -316,6 +316,9 @@ class RelocInfo BASE_EMBEDDED { ...@@ -316,6 +316,9 @@ class RelocInfo BASE_EMBEDDED {
static inline bool IsEmbeddedObject(Mode mode) { static inline bool IsEmbeddedObject(Mode mode) {
return mode == EMBEDDED_OBJECT; return mode == EMBEDDED_OBJECT;
} }
static inline bool IsRuntimeEntry(Mode mode) {
return mode == RUNTIME_ENTRY;
}
// Is the relocation mode affected by GC? // Is the relocation mode affected by GC?
static inline bool IsGCRelocMode(Mode mode) { static inline bool IsGCRelocMode(Mode mode) {
return mode <= LAST_GCED_ENUM; return mode <= LAST_GCED_ENUM;
...@@ -379,6 +382,10 @@ class RelocInfo BASE_EMBEDDED { ...@@ -379,6 +382,10 @@ class RelocInfo BASE_EMBEDDED {
INLINE(Object** target_object_address()); INLINE(Object** target_object_address());
INLINE(void set_target_object(Object* target, INLINE(void set_target_object(Object* target,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER)); WriteBarrierMode mode = UPDATE_WRITE_BARRIER));
INLINE(Address target_runtime_entry(Assembler* origin));
INLINE(void set_target_runtime_entry(Address target,
WriteBarrierMode mode =
UPDATE_WRITE_BARRIER));
INLINE(JSGlobalPropertyCell* target_cell()); INLINE(JSGlobalPropertyCell* target_cell());
INLINE(Handle<JSGlobalPropertyCell> target_cell_handle()); INLINE(Handle<JSGlobalPropertyCell> target_cell_handle());
INLINE(void set_target_cell(JSGlobalPropertyCell* cell, INLINE(void set_target_cell(JSGlobalPropertyCell* cell,
......
...@@ -51,7 +51,7 @@ static const byte kCallOpcode = 0xE8; ...@@ -51,7 +51,7 @@ static const byte kCallOpcode = 0xE8;
// The modes possibly affected by apply must be in kApplyMask. // The modes possibly affected by apply must be in kApplyMask.
void RelocInfo::apply(intptr_t delta) { void RelocInfo::apply(intptr_t delta) {
if (rmode_ == RUNTIME_ENTRY || IsCodeTarget(rmode_)) { if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) {
int32_t* p = reinterpret_cast<int32_t*>(pc_); int32_t* p = reinterpret_cast<int32_t*>(pc_);
*p -= delta; // Relocate entry. *p -= delta; // Relocate entry.
CPU::FlushICache(p, sizeof(uint32_t)); CPU::FlushICache(p, sizeof(uint32_t));
...@@ -83,13 +83,13 @@ void RelocInfo::apply(intptr_t delta) { ...@@ -83,13 +83,13 @@ void RelocInfo::apply(intptr_t delta) {
Address RelocInfo::target_address() { Address RelocInfo::target_address() {
ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
return Assembler::target_address_at(pc_); return Assembler::target_address_at(pc_);
} }
Address RelocInfo::target_address_address() { Address RelocInfo::target_address_address() {
ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
|| rmode_ == EMBEDDED_OBJECT || rmode_ == EMBEDDED_OBJECT
|| rmode_ == EXTERNAL_REFERENCE); || rmode_ == EXTERNAL_REFERENCE);
return reinterpret_cast<Address>(pc_); return reinterpret_cast<Address>(pc_);
...@@ -103,7 +103,7 @@ int RelocInfo::target_address_size() { ...@@ -103,7 +103,7 @@ int RelocInfo::target_address_size() {
void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) { void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
Assembler::set_target_address_at(pc_, target); Assembler::set_target_address_at(pc_, target);
ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) { if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) {
Object* target_code = Code::GetCodeFromTargetAddress(target); Object* target_code = Code::GetCodeFromTargetAddress(target);
host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
...@@ -149,6 +149,19 @@ Address* RelocInfo::target_reference_address() { ...@@ -149,6 +149,19 @@ Address* RelocInfo::target_reference_address() {
} }
Address RelocInfo::target_runtime_entry(Assembler* origin) {
ASSERT(IsRuntimeEntry(rmode_));
return reinterpret_cast<Address>(*reinterpret_cast<int32_t*>(pc_));
}
void RelocInfo::set_target_runtime_entry(Address target,
WriteBarrierMode mode) {
ASSERT(IsRuntimeEntry(rmode_));
if (target_address() != target) set_target_address(target, mode);
}
Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() { Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
Address address = Memory::Address_at(pc_); Address address = Memory::Address_at(pc_);
...@@ -262,7 +275,7 @@ void RelocInfo::Visit(ObjectVisitor* visitor) { ...@@ -262,7 +275,7 @@ void RelocInfo::Visit(ObjectVisitor* visitor) {
Isolate::Current()->debug()->has_break_points()) { Isolate::Current()->debug()->has_break_points()) {
visitor->VisitDebugTarget(this); visitor->VisitDebugTarget(this);
#endif #endif
} else if (mode == RelocInfo::RUNTIME_ENTRY) { } else if (IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this); visitor->VisitRuntimeEntry(this);
} }
} }
...@@ -291,7 +304,7 @@ void RelocInfo::Visit(Heap* heap) { ...@@ -291,7 +304,7 @@ void RelocInfo::Visit(Heap* heap) {
IsPatchedDebugBreakSlotSequence()))) { IsPatchedDebugBreakSlotSequence()))) {
StaticVisitor::VisitDebugTarget(heap, this); StaticVisitor::VisitDebugTarget(heap, this);
#endif #endif
} else if (mode == RelocInfo::RUNTIME_ENTRY) { } else if (IsRuntimeEntry(mode)) {
StaticVisitor::VisitRuntimeEntry(this); StaticVisitor::VisitRuntimeEntry(this);
} }
} }
......
...@@ -1425,7 +1425,11 @@ void Assembler::call(byte* entry, RelocInfo::Mode rmode) { ...@@ -1425,7 +1425,11 @@ void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
ASSERT(!RelocInfo::IsCodeTarget(rmode)); ASSERT(!RelocInfo::IsCodeTarget(rmode));
EMIT(0xE8); EMIT(0xE8);
if (RelocInfo::IsRuntimeEntry(rmode)) {
emit(reinterpret_cast<uint32_t>(entry), rmode);
} else {
emit(entry - (pc_ + sizeof(int32_t)), rmode); emit(entry - (pc_ + sizeof(int32_t)), rmode);
}
} }
...@@ -1490,7 +1494,11 @@ void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) { ...@@ -1490,7 +1494,11 @@ void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
ASSERT(!RelocInfo::IsCodeTarget(rmode)); ASSERT(!RelocInfo::IsCodeTarget(rmode));
EMIT(0xE9); EMIT(0xE9);
if (RelocInfo::IsRuntimeEntry(rmode)) {
emit(reinterpret_cast<uint32_t>(entry), rmode);
} else {
emit(entry - (pc_ + sizeof(int32_t)), rmode); emit(entry - (pc_ + sizeof(int32_t)), rmode);
}
} }
...@@ -1547,7 +1555,11 @@ void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) { ...@@ -1547,7 +1555,11 @@ void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
// 0000 1111 1000 tttn #32-bit disp. // 0000 1111 1000 tttn #32-bit disp.
EMIT(0x0F); EMIT(0x0F);
EMIT(0x80 | cc); EMIT(0x80 | cc);
if (RelocInfo::IsRuntimeEntry(rmode)) {
emit(reinterpret_cast<uint32_t>(entry), rmode);
} else {
emit(entry - (pc_ + sizeof(int32_t)), rmode); emit(entry - (pc_ + sizeof(int32_t)), rmode);
}
} }
...@@ -2564,10 +2576,7 @@ void Assembler::GrowBuffer() { ...@@ -2564,10 +2576,7 @@ void Assembler::GrowBuffer() {
// Relocate runtime entries. // Relocate runtime entries.
for (RelocIterator it(desc); !it.done(); it.next()) { for (RelocIterator it(desc); !it.done(); it.next()) {
RelocInfo::Mode rmode = it.rinfo()->rmode(); RelocInfo::Mode rmode = it.rinfo()->rmode();
if (rmode == RelocInfo::RUNTIME_ENTRY) { if (rmode == RelocInfo::INTERNAL_REFERENCE) {
int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
*p -= pc_delta; // relocate entry
} else if (rmode == RelocInfo::INTERNAL_REFERENCE) {
int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc()); int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
if (*p != 0) { // 0 means uninitialized. if (*p != 0) { // 0 means uninitialized.
*p += pc_delta; *p += pc_delta;
......
...@@ -231,6 +231,19 @@ Address* RelocInfo::target_reference_address() { ...@@ -231,6 +231,19 @@ Address* RelocInfo::target_reference_address() {
} }
Address RelocInfo::target_runtime_entry(Assembler* origin) {
ASSERT(IsRuntimeEntry(rmode_));
return target_address();
}
void RelocInfo::set_target_runtime_entry(Address target,
WriteBarrierMode mode) {
ASSERT(IsRuntimeEntry(rmode_));
if (target_address() != target) set_target_address(target, mode);
}
Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() { Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
Address address = Memory::Address_at(pc_); Address address = Memory::Address_at(pc_);
......
...@@ -8793,8 +8793,10 @@ void Code::CopyFrom(const CodeDesc& desc) { ...@@ -8793,8 +8793,10 @@ void Code::CopyFrom(const CodeDesc& desc) {
int mode_mask = RelocInfo::kCodeTargetMask | int mode_mask = RelocInfo::kCodeTargetMask |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) | RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) |
RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
RelocInfo::kApplyMask; RelocInfo::kApplyMask;
Assembler* origin = desc.origin; // Needed to find target_object on X64. // Needed to find target_object and runtime_entry on X64
Assembler* origin = desc.origin;
for (RelocIterator it(this, mode_mask); !it.done(); it.next()) { for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
RelocInfo::Mode mode = it.rinfo()->rmode(); RelocInfo::Mode mode = it.rinfo()->rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) { if (mode == RelocInfo::EMBEDDED_OBJECT) {
...@@ -8810,6 +8812,9 @@ void Code::CopyFrom(const CodeDesc& desc) { ...@@ -8810,6 +8812,9 @@ void Code::CopyFrom(const CodeDesc& desc) {
Code* code = Code::cast(*p); Code* code = Code::cast(*p);
it.rinfo()->set_target_address(code->instruction_start(), it.rinfo()->set_target_address(code->instruction_start(),
SKIP_WRITE_BARRIER); SKIP_WRITE_BARRIER);
} else if (RelocInfo::IsRuntimeEntry(mode)) {
Address p = it.rinfo()->target_runtime_entry(origin);
it.rinfo()->set_target_runtime_entry(p, SKIP_WRITE_BARRIER);
} else { } else {
it.rinfo()->apply(delta); it.rinfo()->apply(delta);
} }
......
...@@ -894,6 +894,10 @@ class CodeRange { ...@@ -894,6 +894,10 @@ class CodeRange {
void TearDown(); void TearDown();
bool exists() { return this != NULL && code_range_ != NULL; } bool exists() { return this != NULL && code_range_ != NULL; }
Address start() {
if (this == NULL || code_range_ == NULL) return NULL;
return static_cast<Address>(code_range_->address());
}
bool contains(Address address) { bool contains(Address address) {
if (this == NULL || code_range_ == NULL) return false; if (this == NULL || code_range_ == NULL) return false;
Address start = static_cast<Address>(code_range_->address()); Address start = static_cast<Address>(code_range_->address());
......
...@@ -86,6 +86,14 @@ void Assembler::emit_code_target(Handle<Code> target, ...@@ -86,6 +86,14 @@ void Assembler::emit_code_target(Handle<Code> target,
} }
void Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) {
ASSERT(RelocInfo::IsRuntimeEntry(rmode));
ASSERT(isolate()->code_range()->exists());
RecordRelocInfo(rmode);
emitl(static_cast<uint32_t>(entry - isolate()->code_range()->start()));
}
void Assembler::emit_rex_64(Register reg, Register rm_reg) { void Assembler::emit_rex_64(Register reg, Register rm_reg) {
emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit()); emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit());
} }
...@@ -208,6 +216,12 @@ Handle<Object> Assembler::code_target_object_handle_at(Address pc) { ...@@ -208,6 +216,12 @@ Handle<Object> Assembler::code_target_object_handle_at(Address pc) {
return code_targets_[Memory::int32_at(pc)]; return code_targets_[Memory::int32_at(pc)];
} }
Address Assembler::runtime_entry_at(Address pc) {
ASSERT(isolate()->code_range()->exists());
return Memory::int32_at(pc) + isolate()->code_range()->start();
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Implementation of RelocInfo // Implementation of RelocInfo
...@@ -217,7 +231,7 @@ void RelocInfo::apply(intptr_t delta) { ...@@ -217,7 +231,7 @@ void RelocInfo::apply(intptr_t delta) {
// absolute code pointer inside code object moves with the code object. // absolute code pointer inside code object moves with the code object.
Memory::Address_at(pc_) += static_cast<int32_t>(delta); Memory::Address_at(pc_) += static_cast<int32_t>(delta);
CPU::FlushICache(pc_, sizeof(Address)); CPU::FlushICache(pc_, sizeof(Address));
} else if (IsCodeTarget(rmode_)) { } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) {
Memory::int32_at(pc_) -= static_cast<int32_t>(delta); Memory::int32_at(pc_) -= static_cast<int32_t>(delta);
CPU::FlushICache(pc_, sizeof(int32_t)); CPU::FlushICache(pc_, sizeof(int32_t));
} else if (rmode_ == CODE_AGE_SEQUENCE) { } else if (rmode_ == CODE_AGE_SEQUENCE) {
...@@ -231,17 +245,13 @@ void RelocInfo::apply(intptr_t delta) { ...@@ -231,17 +245,13 @@ void RelocInfo::apply(intptr_t delta) {
Address RelocInfo::target_address() { Address RelocInfo::target_address() {
ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
if (IsCodeTarget(rmode_)) {
return Assembler::target_address_at(pc_); return Assembler::target_address_at(pc_);
} else {
return Memory::Address_at(pc_);
}
} }
Address RelocInfo::target_address_address() { Address RelocInfo::target_address_address() {
ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
|| rmode_ == EMBEDDED_OBJECT || rmode_ == EMBEDDED_OBJECT
|| rmode_ == EXTERNAL_REFERENCE); || rmode_ == EXTERNAL_REFERENCE);
return reinterpret_cast<Address>(pc_); return reinterpret_cast<Address>(pc_);
...@@ -258,18 +268,13 @@ int RelocInfo::target_address_size() { ...@@ -258,18 +268,13 @@ int RelocInfo::target_address_size() {
void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) { void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
if (IsCodeTarget(rmode_)) {
Assembler::set_target_address_at(pc_, target); Assembler::set_target_address_at(pc_, target);
if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) {
Object* target_code = Code::GetCodeFromTargetAddress(target); Object* target_code = Code::GetCodeFromTargetAddress(target);
if (mode == UPDATE_WRITE_BARRIER && host() != NULL) {
host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
host(), this, HeapObject::cast(target_code)); host(), this, HeapObject::cast(target_code));
} }
} else {
Memory::Address_at(pc_) = target;
CPU::FlushICache(pc_, sizeof(Address));
}
} }
...@@ -314,6 +319,19 @@ void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) { ...@@ -314,6 +319,19 @@ void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) {
} }
Address RelocInfo::target_runtime_entry(Assembler* origin) {
ASSERT(IsRuntimeEntry(rmode_));
return origin->runtime_entry_at(pc_);
}
void RelocInfo::set_target_runtime_entry(Address target,
WriteBarrierMode mode) {
ASSERT(IsRuntimeEntry(rmode_));
if (target_address() != target) set_target_address(target, mode);
}
Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() { Handle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
Address address = Memory::Address_at(pc_); Address address = Memory::Address_at(pc_);
...@@ -443,7 +461,7 @@ void RelocInfo::Visit(ObjectVisitor* visitor) { ...@@ -443,7 +461,7 @@ void RelocInfo::Visit(ObjectVisitor* visitor) {
Isolate::Current()->debug()->has_break_points()) { Isolate::Current()->debug()->has_break_points()) {
visitor->VisitDebugTarget(this); visitor->VisitDebugTarget(this);
#endif #endif
} else if (mode == RelocInfo::RUNTIME_ENTRY) { } else if (RelocInfo::IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this); visitor->VisitRuntimeEntry(this);
} }
} }
...@@ -472,7 +490,7 @@ void RelocInfo::Visit(Heap* heap) { ...@@ -472,7 +490,7 @@ void RelocInfo::Visit(Heap* heap) {
IsPatchedDebugBreakSlotSequence()))) { IsPatchedDebugBreakSlotSequence()))) {
StaticVisitor::VisitDebugTarget(heap, this); StaticVisitor::VisitDebugTarget(heap, this);
#endif #endif
} else if (mode == RelocInfo::RUNTIME_ENTRY) { } else if (RelocInfo::IsRuntimeEntry(mode)) {
StaticVisitor::VisitRuntimeEntry(this); StaticVisitor::VisitRuntimeEntry(this);
} }
} }
......
...@@ -841,6 +841,16 @@ void Assembler::call(Label* L) { ...@@ -841,6 +841,16 @@ void Assembler::call(Label* L) {
} }
void Assembler::call(Address entry, RelocInfo::Mode rmode) {
ASSERT(RelocInfo::IsRuntimeEntry(rmode));
positions_recorder()->WriteRecordedPositions();
EnsureSpace ensure_space(this);
// 1110 1000 #32-bit disp.
emit(0xE8);
emit_runtime_entry(entry, rmode);
}
void Assembler::call(Handle<Code> target, void Assembler::call(Handle<Code> target,
RelocInfo::Mode rmode, RelocInfo::Mode rmode,
TypeFeedbackId ast_id) { TypeFeedbackId ast_id) {
...@@ -1247,6 +1257,16 @@ void Assembler::j(Condition cc, Label* L, Label::Distance distance) { ...@@ -1247,6 +1257,16 @@ void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
} }
void Assembler::j(Condition cc, Address entry, RelocInfo::Mode rmode) {
ASSERT(RelocInfo::IsRuntimeEntry(rmode));
EnsureSpace ensure_space(this);
ASSERT(is_uint4(cc));
emit(0x0F);
emit(0x80 | cc);
emit_runtime_entry(entry, rmode);
}
void Assembler::j(Condition cc, void Assembler::j(Condition cc,
Handle<Code> target, Handle<Code> target,
RelocInfo::Mode rmode) { RelocInfo::Mode rmode) {
...@@ -1309,6 +1329,15 @@ void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) { ...@@ -1309,6 +1329,15 @@ void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
} }
void Assembler::jmp(Address entry, RelocInfo::Mode rmode) {
ASSERT(RelocInfo::IsRuntimeEntry(rmode));
EnsureSpace ensure_space(this);
ASSERT(RelocInfo::IsRuntimeEntry(rmode));
emit(0xE9);
emit_runtime_entry(entry, rmode);
}
void Assembler::jmp(Register target) { void Assembler::jmp(Register target) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
// Opcode FF/4 r64. // Opcode FF/4 r64.
...@@ -3049,6 +3078,7 @@ void Assembler::RecordComment(const char* msg, bool force) { ...@@ -3049,6 +3078,7 @@ void Assembler::RecordComment(const char* msg, bool force) {
const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
1 << RelocInfo::RUNTIME_ENTRY |
1 << RelocInfo::INTERNAL_REFERENCE | 1 << RelocInfo::INTERNAL_REFERENCE |
1 << RelocInfo::CODE_AGE_SEQUENCE; 1 << RelocInfo::CODE_AGE_SEQUENCE;
......
...@@ -561,6 +561,7 @@ class Assembler : public AssemblerBase { ...@@ -561,6 +561,7 @@ class Assembler : public AssemblerBase {
} }
inline Handle<Object> code_target_object_handle_at(Address pc); inline Handle<Object> code_target_object_handle_at(Address pc);
inline Address runtime_entry_at(Address pc);
// Number of bytes taken up by the branch target in the code. // Number of bytes taken up by the branch target in the code.
static const int kSpecialTargetSize = 4; // Use 32-bit displacement. static const int kSpecialTargetSize = 4; // Use 32-bit displacement.
// Distance between the address of the code target in the call instruction // Distance between the address of the code target in the call instruction
...@@ -1180,6 +1181,7 @@ class Assembler : public AssemblerBase { ...@@ -1180,6 +1181,7 @@ class Assembler : public AssemblerBase {
// Calls // Calls
// Call near relative 32-bit displacement, relative to next instruction. // Call near relative 32-bit displacement, relative to next instruction.
void call(Label* L); void call(Label* L);
void call(Address entry, RelocInfo::Mode rmode);
void call(Handle<Code> target, void call(Handle<Code> target,
RelocInfo::Mode rmode = RelocInfo::CODE_TARGET, RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
TypeFeedbackId ast_id = TypeFeedbackId::None()); TypeFeedbackId ast_id = TypeFeedbackId::None());
...@@ -1201,6 +1203,7 @@ class Assembler : public AssemblerBase { ...@@ -1201,6 +1203,7 @@ class Assembler : public AssemblerBase {
// Use a 32-bit signed displacement. // Use a 32-bit signed displacement.
// Unconditional jump to L // Unconditional jump to L
void jmp(Label* L, Label::Distance distance = Label::kFar); void jmp(Label* L, Label::Distance distance = Label::kFar);
void jmp(Address entry, RelocInfo::Mode rmode);
void jmp(Handle<Code> target, RelocInfo::Mode rmode); void jmp(Handle<Code> target, RelocInfo::Mode rmode);
// Jump near absolute indirect (r64) // Jump near absolute indirect (r64)
...@@ -1213,6 +1216,7 @@ class Assembler : public AssemblerBase { ...@@ -1213,6 +1216,7 @@ class Assembler : public AssemblerBase {
void j(Condition cc, void j(Condition cc,
Label* L, Label* L,
Label::Distance distance = Label::kFar); Label::Distance distance = Label::kFar);
void j(Condition cc, Address entry, RelocInfo::Mode rmode);
void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode); void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
// Floating-point operations // Floating-point operations
...@@ -1430,6 +1434,7 @@ class Assembler : public AssemblerBase { ...@@ -1430,6 +1434,7 @@ class Assembler : public AssemblerBase {
inline void emit_code_target(Handle<Code> target, inline void emit_code_target(Handle<Code> target,
RelocInfo::Mode rmode, RelocInfo::Mode rmode,
TypeFeedbackId ast_id = TypeFeedbackId::None()); TypeFeedbackId ast_id = TypeFeedbackId::None());
inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode);
void emit(Immediate x) { emitl(x.value_); } void emit(Immediate x) { emitl(x.value_); }
// Emits a REX prefix that encodes a 64-bit operand size and // Emits a REX prefix that encodes a 64-bit operand size and
......
...@@ -353,9 +353,9 @@ bool LCodeGen::GenerateJumpTable() { ...@@ -353,9 +353,9 @@ bool LCodeGen::GenerateJumpTable() {
} }
} else { } else {
if (is_lazy_deopt) { if (is_lazy_deopt) {
__ Call(entry, RelocInfo::RUNTIME_ENTRY); __ call(entry, RelocInfo::RUNTIME_ENTRY);
} else { } else {
__ Jump(entry, RelocInfo::RUNTIME_ENTRY); __ jmp(entry, RelocInfo::RUNTIME_ENTRY);
} }
} }
} }
...@@ -754,9 +754,9 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) { ...@@ -754,9 +754,9 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
bool needs_lazy_deopt = info()->IsStub(); bool needs_lazy_deopt = info()->IsStub();
if (cc == no_condition && frame_is_built_) { if (cc == no_condition && frame_is_built_) {
if (needs_lazy_deopt) { if (needs_lazy_deopt) {
__ Call(entry, RelocInfo::RUNTIME_ENTRY); __ call(entry, RelocInfo::RUNTIME_ENTRY);
} else { } else {
__ Jump(entry, RelocInfo::RUNTIME_ENTRY); __ jmp(entry, RelocInfo::RUNTIME_ENTRY);
} }
} else { } else {
// We often have several deopts to the same entry, reuse the last // We often have several deopts to the same entry, reuse the last
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment