VM: Emit compacter code for x64 branches to external labels.

Use jmp [PP + 0xiiii] instead of

movq TMP, [PP + 0xiiii]
jmp TMP

Also, remove some unused code from x64 assembler.

R=zra@google.com

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

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@43094 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
fschneider@google.com
2015-01-23 10:28:23 +00:00
parent bdba8f356b
commit 340299bc13
6 changed files with 35 additions and 63 deletions
+17 -5
View File
@@ -8,6 +8,7 @@
#include "vm/assembler.h"
#include "vm/cpu.h"
#include "vm/heap.h"
#include "vm/instructions.h"
#include "vm/locations.h"
#include "vm/memory_region.h"
#include "vm/runtime_entry.h"
@@ -2558,6 +2559,14 @@ void Assembler::jmp(Register reg) {
}
void Assembler::jmp(const Address& dst) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitOperandREX(4, dst, REX_NONE);
EmitUint8(0xFF);
EmitOperand(4, dst);
}
void Assembler::jmp(Label* label, bool near) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
if (VerifiedMemory::enabled()) {
@@ -2599,15 +2608,18 @@ void Assembler::jmp(const ExternalLabel* label) {
void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) {
ASSERT(allow_constant_pool());
intptr_t call_start = buffer_.GetPosition();
LoadExternalLabel(TMP, label, kPatchable, pp);
jmp(TMP);
ASSERT((buffer_.GetPosition() - call_start) == kJmpExternalLabelSize);
const int32_t offset =
Array::element_offset(FindExternalLabel(label, kPatchable));
// Patchable jumps always use a 32-bit immediate encoding.
jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag));
ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes);
}
void Assembler::Jmp(const ExternalLabel* label, Register pp) {
LoadExternalLabel(TMP, label, kNotPatchable, pp);
jmp(TMP);
const int32_t offset =
Array::element_offset(FindExternalLabel(label, kNotPatchable));
jmp(Address(pp, offset - kHeapObjectTag));
}
+1 -1
View File
@@ -353,7 +353,6 @@ class Assembler : public ValueObject {
void call(const ExternalLabel* label);
static const intptr_t kCallExternalLabelSize = 7;
static const intptr_t kJmpExternalLabelSize = 10;
void pushq(Register reg);
void pushq(const Address& address);
@@ -669,6 +668,7 @@ class Assembler : public ValueObject {
void j(Condition condition, const ExternalLabel* label);
void jmp(Register reg);
void jmp(const Address& address);
// Note: verified_mem mode forces far jumps.
void jmp(Label* label, bool near = kFarJump);
void jmp(const ExternalLabel* label);
+14
View File
@@ -1808,6 +1808,20 @@ ASSEMBLER_TEST_RUN(JumpSimpleLeaf, test) {
}
ASSEMBLER_TEST_GENERATE(JumpIndirect, assembler) {
ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42));
__ movq(Address(CallingConventions::kArg1Reg, 0), Immediate(call1.address()));
__ jmp(Address(CallingConventions::kArg1Reg, 0));
}
ASSEMBLER_TEST_RUN(JumpIndirect, test) {
uword temp = 0;
typedef int (*JumpIndirect)(uword*);
EXPECT_EQ(42, reinterpret_cast<JumpIndirect>(test->entry())(&temp));
}
ASSEMBLER_TEST_GENERATE(SingleFPMoves, assembler) {
__ movq(RAX, Immediate(bit_cast<int32_t, float>(234.0f)));
__ movd(XMM0, RAX);
+2 -25
View File
@@ -37,28 +37,6 @@ bool InstructionPattern::TestBytesWith(const int* data, int num_bytes) const {
}
uword CallPattern::TargetAddress() const {
ASSERT(IsValid());
return *reinterpret_cast<uword*>(start() + 2);
}
void CallPattern::SetTargetAddress(uword target) const {
ASSERT(IsValid());
*reinterpret_cast<uword*>(start() + 2) = target;
CPU::FlushICache(start() + 2, kWordSize);
}
const int* CallPattern::pattern() const {
// movq $target, TMP
// callq *TMP
static const int kCallPattern[kLengthInBytes] =
{0x49, 0xBB, -1, -1, -1, -1, -1, -1, -1, -1, 0x41, 0xFF, 0xD3};
return kCallPattern;
}
uword JumpPattern::TargetAddress() const {
ASSERT(IsValid());
int index = InstructionPattern::IndexFromPPLoad(start() + 3);
@@ -76,10 +54,9 @@ void JumpPattern::SetTargetAddress(uword target) const {
const int* JumpPattern::pattern() const {
// 00: 4d 8b 9d imm32 mov R11, [R13 + off]
// 07: 41 ff e3 jmpq R11
// 07: 41 ff a7 imm32 jmpq [reg + off]
static const int kJumpPattern[kLengthInBytes] =
{0x4D, 0x8B, -1, -1, -1, -1, -1, 0x41, 0xFF, 0xE3};
{0x41, 0xFF, -1, -1, -1, -1, -1};
return kJumpPattern;
}
+1 -24
View File
@@ -56,29 +56,6 @@ class InstructionPattern : public ValueObject {
};
class CallPattern : public InstructionPattern {
public:
CallPattern(uword pc, const Code& code)
: InstructionPattern(pc),
code_(code) {}
static int InstructionLength() {
return kLengthInBytes;
}
uword TargetAddress() const;
void SetTargetAddress(uword new_target) const;
virtual int pattern_length_in_bytes() const {
return kLengthInBytes;
}
private:
static const int kLengthInBytes = 13;
virtual const int* pattern() const;
const Code& code_;
DISALLOW_COPY_AND_ASSIGN(CallPattern);
};
class JumpPattern : public InstructionPattern {
public:
JumpPattern(uword pc, const Code& code)
@@ -93,8 +70,8 @@ class JumpPattern : public InstructionPattern {
return kLengthInBytes;
}
static const int kLengthInBytes = 7;
private:
static const int kLengthInBytes = 10;
virtual const int* pattern() const;
const Array& object_pool_;
-8
View File
@@ -21,14 +21,6 @@ ASSEMBLER_TEST_GENERATE(Call, assembler) {
}
ASSEMBLER_TEST_RUN(Call, test) {
StubCode* stub_code = Isolate::Current()->stub_code();
CallPattern call(test->entry(), test->code());
EXPECT_EQ(stub_code->InvokeDartCodeLabel().address(),
call.TargetAddress());
}
static intptr_t prologue_code_size = -1;