[VM] Reland "[VM] Extract common code from Assembler to new AssemblerBase base class"

This reverts commit 04381d7571.

Closes https://github.com/dart-lang/sdk/issues/34973

Change-Id: I843c3fe4cc8265fb43b6b09623e7509837a878f0
Reviewed-on: https://dart-review.googlesource.com/c/82041
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
This commit is contained in:
Martin Kustermann
2018-10-30 12:00:22 +00:00
committed by commit-bot@chromium.org
parent a09ec46da6
commit 70abec503d
11 changed files with 96 additions and 312 deletions
+6 -6
View File
@@ -173,7 +173,7 @@ void AssemblerBuffer::EmitObject(const Object& object) {
}
// Shared macros are implemented here.
void Assembler::Unimplemented(const char* message) {
void AssemblerBase::Unimplemented(const char* message) {
const char* format = "Unimplemented: %s";
const intptr_t len = Utils::SNPrint(NULL, 0, format, message);
char* buffer = reinterpret_cast<char*>(malloc(len + 1));
@@ -181,7 +181,7 @@ void Assembler::Unimplemented(const char* message) {
Stop(buffer);
}
void Assembler::Untested(const char* message) {
void AssemblerBase::Untested(const char* message) {
const char* format = "Untested: %s";
const intptr_t len = Utils::SNPrint(NULL, 0, format, message);
char* buffer = reinterpret_cast<char*>(malloc(len + 1));
@@ -189,7 +189,7 @@ void Assembler::Untested(const char* message) {
Stop(buffer);
}
void Assembler::Unreachable(const char* message) {
void AssemblerBase::Unreachable(const char* message) {
const char* format = "Unreachable: %s";
const intptr_t len = Utils::SNPrint(NULL, 0, format, message);
char* buffer = reinterpret_cast<char*>(malloc(len + 1));
@@ -197,7 +197,7 @@ void Assembler::Unreachable(const char* message) {
Stop(buffer);
}
void Assembler::Comment(const char* format, ...) {
void AssemblerBase::Comment(const char* format, ...) {
if (EmittingComments()) {
char buffer[1024];
@@ -212,11 +212,11 @@ void Assembler::Comment(const char* format, ...) {
}
}
bool Assembler::EmittingComments() {
bool AssemblerBase::EmittingComments() {
return FLAG_code_comments || FLAG_disassemble || FLAG_disassemble_optimized;
}
const Code::Comments& Assembler::GetCodeComments() const {
const Code::Comments& AssemblerBase::GetCodeComments() const {
Code::Comments& comments = Code::Comments::New(comments_.length());
for (intptr_t i = 0; i < comments_.length(); i++) {
+71
View File
@@ -412,6 +412,77 @@ class ObjectPoolWrapper : public ValueObject {
enum RestorePP { kRestoreCallerPP, kKeepCalleePP };
class AssemblerBase : public ValueObject {
public:
explicit AssemblerBase(ObjectPoolWrapper* object_pool_wrapper)
: prologue_offset_(-1),
has_single_entry_point_(true),
object_pool_wrapper_(object_pool_wrapper) {}
virtual ~AssemblerBase() {}
intptr_t CodeSize() const { return buffer_.Size(); }
uword CodeAddress(intptr_t offset) { return buffer_.Address(offset); }
ObjectPoolWrapper& object_pool_wrapper() { return *object_pool_wrapper_; }
intptr_t prologue_offset() const { return prologue_offset_; }
bool has_single_entry_point() const { return has_single_entry_point_; }
void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
static bool EmittingComments();
const Code::Comments& GetCodeComments() const;
void Unimplemented(const char* message);
void Untested(const char* message);
void Unreachable(const char* message);
virtual void Stop(const char* message) = 0;
void FinalizeInstructions(const MemoryRegion& region) {
buffer_.FinalizeInstructions(region);
}
// Count the fixups that produce a pointer offset, without processing
// the fixups.
intptr_t CountPointerOffsets() const { return buffer_.CountPointerOffsets(); }
const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const {
return buffer_.pointer_offsets();
}
RawObjectPool* MakeObjectPool() {
if (object_pool_wrapper_ != nullptr) {
return object_pool_wrapper_->MakeObjectPool();
}
return nullptr;
}
protected:
AssemblerBuffer buffer_; // Contains position independent code.
int32_t prologue_offset_;
bool has_single_entry_point_;
private:
class CodeComment : public ZoneAllocated {
public:
CodeComment(intptr_t pc_offset, const String& comment)
: pc_offset_(pc_offset), comment_(comment) {}
intptr_t pc_offset() const { return pc_offset_; }
const String& comment() const { return comment_; }
private:
intptr_t pc_offset_;
const String& comment_;
DISALLOW_COPY_AND_ASSIGN(CodeComment);
};
GrowableArray<CodeComment*> comments_;
ObjectPoolWrapper* object_pool_wrapper_;
};
} // namespace dart
#if defined(TARGET_ARCH_IA32)
+3 -59
View File
@@ -336,16 +336,12 @@ class FieldAddress : public Address {
}
};
class Assembler : public ValueObject {
class Assembler : public AssemblerBase {
public:
explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
bool use_far_branches = false)
: buffer_(),
object_pool_wrapper_(object_pool_wrapper),
prologue_offset_(-1),
has_single_entry_point_(true),
: AssemblerBase(object_pool_wrapper),
use_far_branches_(use_far_branches),
comments_(),
constant_pool_allowed_(false) {}
~Assembler() {}
@@ -364,25 +360,6 @@ class Assembler : public ValueObject {
}
// Misc. functionality
intptr_t CodeSize() const { return buffer_.Size(); }
intptr_t prologue_offset() const { return prologue_offset_; }
bool has_single_entry_point() const { return has_single_entry_point_; }
// Count the fixups that produce a pointer offset, without processing
// the fixups. On ARM there are no pointers in code.
intptr_t CountPointerOffsets() const { return 0; }
const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const {
ASSERT(buffer_.pointer_offsets().length() == 0); // No pointers in code.
return buffer_.pointer_offsets();
}
ObjectPoolWrapper& object_pool_wrapper() { return *object_pool_wrapper_; }
RawObjectPool* MakeObjectPool() {
return object_pool_wrapper_->MakeObjectPool();
}
bool use_far_branches() const {
return FLAG_use_far_branches || use_far_branches_;
}
@@ -393,24 +370,12 @@ class Assembler : public ValueObject {
void set_use_far_branches(bool b) { use_far_branches_ = b; }
#endif // TESTING || DEBUG
void FinalizeInstructions(const MemoryRegion& region) {
buffer_.FinalizeInstructions(region);
}
// Debugging and bringup support.
void Breakpoint() { bkpt(0); }
void Stop(const char* message);
void Unimplemented(const char* message);
void Untested(const char* message);
void Unreachable(const char* message);
void Stop(const char* message) override;
static void InitializeMemoryWithBreakpoints(uword data, intptr_t length);
void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
static bool EmittingComments();
const Code::Comments& GetCodeComments() const;
static const char* RegisterName(Register reg);
static const char* FpuRegisterName(FpuRegister reg);
@@ -1160,10 +1125,6 @@ class Assembler : public ValueObject {
static int32_t DecodeBranchOffset(int32_t inst);
private:
AssemblerBuffer buffer_; // Contains position independent code.
ObjectPoolWrapper* object_pool_wrapper_;
int32_t prologue_offset_;
bool has_single_entry_point_;
bool use_far_branches_;
// If you are thinking of using one or both of these instructions directly,
@@ -1176,23 +1137,6 @@ class Assembler : public ValueObject {
void BranchLink(const ExternalLabel* label);
class CodeComment : public ZoneAllocated {
public:
CodeComment(intptr_t pc_offset, const String& comment)
: pc_offset_(pc_offset), comment_(comment) {}
intptr_t pc_offset() const { return pc_offset_; }
const String& comment() const { return comment_; }
private:
intptr_t pc_offset_;
const String& comment_;
DISALLOW_COPY_AND_ASSIGN(CodeComment);
};
GrowableArray<CodeComment*> comments_;
bool constant_pool_allowed_;
void LoadObjectHelper(Register rd,
@@ -23,12 +23,8 @@ DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches");
Assembler::Assembler(ObjectPoolWrapper* object_pool_wrapper,
bool use_far_branches)
: buffer_(),
object_pool_wrapper_(object_pool_wrapper),
prologue_offset_(-1),
has_single_entry_point_(true),
: AssemblerBase(object_pool_wrapper),
use_far_branches_(use_far_branches),
comments_(),
constant_pool_allowed_(false) {}
void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) {
@@ -423,7 +423,7 @@ class Operand : public ValueObject {
friend class Assembler;
};
class Assembler : public ValueObject {
class Assembler : public AssemblerBase {
public:
explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
bool use_far_branches = false);
@@ -458,50 +458,18 @@ class Assembler : public ValueObject {
cmp(value, Operand(TMP));
}
// Misc. functionality
intptr_t CodeSize() const { return buffer_.Size(); }
intptr_t prologue_offset() const { return prologue_offset_; }
bool has_single_entry_point() const { return has_single_entry_point_; }
// Count the fixups that produce a pointer offset, without processing
// the fixups. On ARM64 there are no pointers in code.
intptr_t CountPointerOffsets() const { return 0; }
const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const {
ASSERT(buffer_.pointer_offsets().length() == 0); // No pointers in code.
return buffer_.pointer_offsets();
}
ObjectPoolWrapper& object_pool_wrapper() { return *object_pool_wrapper_; }
RawObjectPool* MakeObjectPool() {
return object_pool_wrapper_->MakeObjectPool();
}
bool use_far_branches() const {
return FLAG_use_far_branches || use_far_branches_;
}
void set_use_far_branches(bool b) { use_far_branches_ = b; }
void FinalizeInstructions(const MemoryRegion& region) {
buffer_.FinalizeInstructions(region);
}
// Debugging and bringup support.
void Breakpoint() { brk(0); }
void Stop(const char* message);
void Unimplemented(const char* message);
void Untested(const char* message);
void Unreachable(const char* message);
void Stop(const char* message) override;
static void InitializeMemoryWithBreakpoints(uword data, intptr_t length);
void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
static bool EmittingComments();
const Code::Comments& GetCodeComments() const;
static const char* RegisterName(Register reg);
static const char* FpuRegisterName(FpuRegister reg);
@@ -1625,29 +1593,8 @@ class Assembler : public ValueObject {
OperandSize sz);
private:
AssemblerBuffer buffer_; // Contains position independent code.
ObjectPoolWrapper* object_pool_wrapper_;
int32_t prologue_offset_;
bool has_single_entry_point_;
bool use_far_branches_;
class CodeComment : public ZoneAllocated {
public:
CodeComment(intptr_t pc_offset, const String& comment)
: pc_offset_(pc_offset), comment_(comment) {}
intptr_t pc_offset() const { return pc_offset_; }
const String& comment() const { return comment_; }
private:
intptr_t pc_offset_;
const String& comment_;
DISALLOW_COPY_AND_ASSIGN(CodeComment);
};
GrowableArray<CodeComment*> comments_;
bool constant_pool_allowed_;
void LoadWordFromPoolOffsetFixed(Register dst, uint32_t offset);
+3 -53
View File
@@ -25,54 +25,24 @@ class Address : public ValueObject {
Address();
};
class Assembler : public ValueObject {
class Assembler : public AssemblerBase {
public:
explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
bool use_far_branches = false)
: buffer_(), object_pool_wrapper_(object_pool_wrapper), comments_() {}
: AssemblerBase(object_pool_wrapper) {}
~Assembler() {}
void Bind(Label* label);
void Jump(Label* label);
// Misc. functionality
intptr_t CodeSize() const { return buffer_.Size(); }
intptr_t prologue_offset() const { return 0; }
bool has_single_entry_point() const { return true; }
// Count the fixups that produce a pointer offset, without processing
// the fixups.
intptr_t CountPointerOffsets() const { return 0; }
const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const {
ASSERT(buffer_.pointer_offsets().length() == 0); // No pointers in code.
return buffer_.pointer_offsets();
}
ObjectPoolWrapper& object_pool_wrapper() { return *object_pool_wrapper_; }
RawObjectPool* MakeObjectPool() {
return object_pool_wrapper_->MakeObjectPool();
}
void FinalizeInstructions(const MemoryRegion& region) {
buffer_.FinalizeInstructions(region);
}
// Debugging and bringup support.
void Stop(const char* message);
void Unimplemented(const char* message);
void Untested(const char* message);
void Unreachable(const char* message);
void Stop(const char* message) override;
static void InitializeMemoryWithBreakpoints(uword data, intptr_t length);
void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
static bool EmittingComments();
const Code::Comments& GetCodeComments() const;
static const char* RegisterName(Register reg);
static const char* FpuRegisterName(FpuRegister reg) { return "?"; }
@@ -125,26 +95,6 @@ class Assembler : public ValueObject {
void Nop(intptr_t d) { Nop(0, d); }
private:
AssemblerBuffer buffer_; // Contains position independent code.
ObjectPoolWrapper* object_pool_wrapper_;
class CodeComment : public ZoneAllocated {
public:
CodeComment(intptr_t pc_offset, const String& comment)
: pc_offset_(pc_offset), comment_(comment) {}
intptr_t pc_offset() const { return pc_offset_; }
const String& comment() const { return comment_; }
private:
intptr_t pc_offset_;
const String& comment_;
DISALLOW_COPY_AND_ASSIGN(CodeComment);
};
GrowableArray<CodeComment*> comments_;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(Assembler);
};
+3 -57
View File
@@ -221,18 +221,13 @@ class FieldAddress : public Address {
}
};
class Assembler : public ValueObject {
class Assembler : public AssemblerBase {
public:
explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
bool use_far_branches = false)
: buffer_(),
prologue_offset_(-1),
: AssemblerBase(object_pool_wrapper),
jit_cookie_(0),
comments_(),
code_(Code::ZoneHandle()) {
// On ia32 we don't use object pools.
USE(object_pool_wrapper);
// This mode is only needed and implemented for ARM.
ASSERT(!use_far_branches);
}
@@ -715,30 +710,8 @@ class Assembler : public ValueObject {
void Bind(Label* label);
void Jump(Label* label) { jmp(label); }
// Address of code at offset.
uword CodeAddress(intptr_t offset) { return buffer_.Address(offset); }
intptr_t CodeSize() const { return buffer_.Size(); }
intptr_t prologue_offset() const { return prologue_offset_; }
bool has_single_entry_point() const { return true; }
// Count the fixups that produce a pointer offset, without processing
// the fixups.
intptr_t CountPointerOffsets() const { return buffer_.CountPointerOffsets(); }
const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const {
return buffer_.pointer_offsets();
}
ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; }
RawObjectPool* MakeObjectPool() {
return object_pool_wrapper_.MakeObjectPool();
}
void FinalizeInstructions(const MemoryRegion& region) {
buffer_.FinalizeInstructions(region);
}
// Set up a Dart frame on entry with a frame pointer and PC information to
// enable easy access to the RawInstruction object of code corresponding
// to this frame.
@@ -831,18 +804,10 @@ class Assembler : public ValueObject {
// Debugging and bringup support.
void Breakpoint() { int3(); }
void Stop(const char* message);
void Unimplemented(const char* message);
void Untested(const char* message);
void Unreachable(const char* message);
void Stop(const char* message) override;
static void InitializeMemoryWithBreakpoints(uword data, intptr_t length);
void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
static bool EmittingComments();
const Code::Comments& GetCodeComments() const;
static const char* RegisterName(Register reg);
static const char* FpuRegisterName(FpuRegister reg);
@@ -873,21 +838,6 @@ class Assembler : public ValueObject {
void PushCodeObject();
private:
class CodeComment : public ZoneAllocated {
public:
CodeComment(intptr_t pc_offset, const String& comment)
: pc_offset_(pc_offset), comment_(comment) {}
intptr_t pc_offset() const { return pc_offset_; }
const String& comment() const { return comment_; }
private:
intptr_t pc_offset_;
const String& comment_;
DISALLOW_COPY_AND_ASSIGN(CodeComment);
};
void Alu(int bytes, uint8_t opcode, Register dst, Register src);
void Alu(uint8_t modrm_opcode, Register dst, const Immediate& imm);
void Alu(int bytes, uint8_t opcode, Register dst, const Address& src);
@@ -931,11 +881,7 @@ class Assembler : public ValueObject {
int32_t jit_cookie();
AssemblerBuffer buffer_;
ObjectPoolWrapper object_pool_wrapper_;
intptr_t prologue_offset_;
int32_t jit_cookie_;
GrowableArray<CodeComment*> comments_;
Code& code_;
DISALLOW_ALLOCATION();
+3 -15
View File
@@ -24,12 +24,7 @@ DECLARE_FLAG(bool, inline_alloc);
Assembler::Assembler(ObjectPoolWrapper* object_pool_wrapper,
bool use_far_branches)
: buffer_(),
object_pool_wrapper_(object_pool_wrapper),
prologue_offset_(-1),
has_single_entry_point_(true),
comments_(),
constant_pool_allowed_(false) {
: AssemblerBase(object_pool_wrapper), constant_pool_allowed_(false) {
// Far branching mode is only needed and implemented for ARM.
ASSERT(!use_far_branches);
}
@@ -1369,19 +1364,12 @@ void Assembler::IncrementSmiField(const Address& dest, int64_t increment) {
addq(dest, inc_imm);
}
void Assembler::Stop(const char* message, bool fixed_length_encoding) {
void Assembler::Stop(const char* message) {
if (FLAG_print_stop_message) {
int64_t message_address = reinterpret_cast<int64_t>(message);
pushq(TMP); // Preserve TMP register.
pushq(RDI); // Preserve RDI register.
if (fixed_length_encoding) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitRegisterREX(RDI, REX_W);
EmitUint8(0xB8 | (RDI & 7));
EmitInt64(message_address);
} else {
LoadImmediate(RDI, Immediate(message_address));
}
LoadImmediate(RDI, Immediate(message_address));
call(&StubCode::PrintStopMessage_entry()->label());
popq(RDI); // Restore RDI register.
popq(TMP); // Restore TMP register.
+2 -58
View File
@@ -275,7 +275,7 @@ class FieldAddress : public Address {
}
};
class Assembler : public ValueObject {
class Assembler : public AssemblerBase {
public:
explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
bool use_far_branches = false);
@@ -818,36 +818,6 @@ class Assembler : public ValueObject {
cmpq(value, address);
}
void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
static bool EmittingComments();
const Code::Comments& GetCodeComments() const;
// Address of code at offset.
uword CodeAddress(intptr_t offset) { return buffer_.Address(offset); }
intptr_t CodeSize() const { return buffer_.Size(); }
intptr_t prologue_offset() const { return prologue_offset_; }
bool has_single_entry_point() const { return has_single_entry_point_; }
// Count the fixups that produce a pointer offset, without processing
// the fixups.
intptr_t CountPointerOffsets() const { return buffer_.CountPointerOffsets(); }
const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const {
return buffer_.pointer_offsets();
}
ObjectPoolWrapper& object_pool_wrapper() { return *object_pool_wrapper_; }
RawObjectPool* MakeObjectPool() {
return object_pool_wrapper_->MakeObjectPool();
}
void FinalizeInstructions(const MemoryRegion& region) {
buffer_.FinalizeInstructions(region);
}
void RestoreCodePointer();
void LoadPoolPointer(Register pp = PP);
@@ -929,10 +899,7 @@ class Assembler : public ValueObject {
// Debugging and bringup support.
void Breakpoint() { int3(); }
void Stop(const char* message, bool fixed_length_encoding = false);
void Unimplemented(const char* message);
void Untested(const char* message);
void Unreachable(const char* message);
void Stop(const char* message) override;
static void InitializeMemoryWithBreakpoints(uword data, intptr_t length);
@@ -961,29 +928,6 @@ class Assembler : public ValueObject {
static bool IsSafeSmi(const Object& object) { return object.IsSmi(); }
private:
AssemblerBuffer buffer_;
ObjectPoolWrapper* object_pool_wrapper_;
intptr_t prologue_offset_;
bool has_single_entry_point_;
class CodeComment : public ZoneAllocated {
public:
CodeComment(intptr_t pc_offset, const String& comment)
: pc_offset_(pc_offset), comment_(comment) {}
intptr_t pc_offset() const { return pc_offset_; }
const String& comment() const { return comment_; }
private:
intptr_t pc_offset_;
const String& comment_;
DISALLOW_COPY_AND_ASSIGN(CodeComment);
};
GrowableArray<CodeComment*> comments_;
bool constant_pool_allowed_;
intptr_t FindImmediate(int64_t imm);
+1 -2
View File
@@ -14733,8 +14733,7 @@ RawCode* Code::FinalizeCode(const char* name,
}
ASSERT(assembler != NULL);
const ObjectPool& object_pool =
ObjectPool::Handle(assembler->object_pool_wrapper().MakeObjectPool());
const auto& object_pool = ObjectPool::Handle(assembler->MakeObjectPool());
// Allocate the Code and Instructions objects. Code is allocated first
// because a GC during allocation of the code will leave the instruction
+1 -2
View File
@@ -345,8 +345,7 @@ RawInstructions* TypeTestingStubGenerator::BuildCodeForType(const Type& type) {
ASSERT(!type_class.IsNull());
// To use the already-defined __ Macro !
ObjectPoolWrapper object_pool_wrapper;
Assembler assembler(&object_pool_wrapper);
Assembler assembler(nullptr);
BuildOptimizedTypeTestStub(&assembler, hi, type, type_class);
const char* name = namer_.StubNameForType(type);