Skip to content

Commit

Permalink
[VM] Bare instructions - Part 4: Add --use-bare-instructions flag to …
Browse files Browse the repository at this point in the history
…AOT compiler & runtime

This is the final CL which adds a new --use-bare-instructions flag to
the VM.

If this flag is set during AOT compilation, we will:

  * Build one global object pool (abbr: GOP) which all code objects
    share. This gop will be stored in the object store.  The PP register
    is populated in the enter dart stub and it is restored when
    returning from native calls.

  * Gets rid of the CODE_REG/PP slots from the dart frames. Instead the
    compiled code uses the global object pool, which is always in PP.

  * Starts emitting pc-relative calls for calls between two dart
    functions or when invoking a stub.
    Limitation: We only emit pc-relative calls between two code objects
    in the same isolate (this is because the image writer is writing
    instruction objects for vm-isolate/main-isolate seperately)

  * We do compile-time relocation of those static calls after the
    precompiler has finished its work, but before writing the snapshot.
    This patches all the instruction objects with pc-relative calls to
    have the right .text distance.

  * We emit a sorted list of code objects in ObjectStore::reverse_code_table,
    which will be used by the AOT runtime to go back from PC to Code
    objects (where all metadata, e.g. stack maps, catch entry moves, pc
    descriptors are available).

Issue dart-lang#33274

Change-Id: I6c5dd2b1571e3a889b27e804a24c2986c71e03b6
Reviewed-on: https://dart-review.googlesource.com/c/85769
Commit-Queue: Martin Kustermann <[email protected]>
Reviewed-by: Ryan Macnak <[email protected]>
Reviewed-by: Vyacheslav Egorov <[email protected]>
  • Loading branch information
mkustermann authored and [email protected] committed Dec 14, 2018
1 parent 59e4760 commit 4fc2984
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 42 deletions.
53 changes: 53 additions & 0 deletions assembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,46 @@ intptr_t ObjIndexPair::Hashcode(Key key) {
// Unlikely.
return key.obj_->GetClassId();
}
void ObjectPoolWrapper::Reset() {
// Null out the handles we've accumulated.
for (intptr_t i = 0; i < object_pool_.length(); ++i) {
if (object_pool_[i].type() == ObjectPool::kTaggedObject) {
*const_cast<Object*>(object_pool_[i].obj_) = Object::null();
*const_cast<Object*>(object_pool_[i].equivalence_) = Object::null();
}
}

object_pool_.Clear();
object_pool_index_table_.Clear();
}

void ObjectPoolWrapper::InitializeFrom(const ObjectPool& other) {
ASSERT(object_pool_.length() == 0);

for (intptr_t i = 0; i < other.Length(); i++) {
auto type = other.TypeAt(i);
auto patchable = other.PatchableAt(i);
switch (type) {
case ObjectPool::kTaggedObject: {
ObjectPoolWrapperEntry entry(&Object::ZoneHandle(other.ObjectAt(i)),
patchable);
AddObject(entry);
break;
}
case ObjectPool::kImmediate:
case ObjectPool::kNativeFunction:
case ObjectPool::kNativeFunctionWrapper: {
ObjectPoolWrapperEntry entry(other.RawValueAt(i), type, patchable);
AddObject(entry);
break;
}
default:
UNREACHABLE();
}
}

ASSERT(CurrentLength() == other.Length());
}

intptr_t ObjectPoolWrapper::AddObject(const Object& obj,
ObjectPool::Patchability patchable) {
Expand All @@ -267,6 +307,19 @@ intptr_t ObjectPoolWrapper::AddObject(ObjectPoolWrapperEntry entry) {
(entry.obj_->IsNotTemporaryScopedHandle() &&
(entry.equivalence_ == NULL ||
entry.equivalence_->IsNotTemporaryScopedHandle())));

if (entry.type() == ObjectPool::kTaggedObject) {
// If the owner of the object pool wrapper specified a specific zone we
// shoulld use we'll do so.
if (zone_ != NULL) {
entry.obj_ = &Object::ZoneHandle(zone_, entry.obj_->raw());
if (entry.equivalence_ != NULL) {
entry.equivalence_ =
&Object::ZoneHandle(zone_, entry.equivalence_->raw());
}
}
}

object_pool_.Add(entry);
if (entry.patchable() == ObjectPool::kNotPatchable) {
// The object isn't patchable. Record the index for fast lookup.
Expand Down
38 changes: 38 additions & 0 deletions assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -370,10 +370,40 @@ class ObjIndexPair {

class ObjectPoolWrapper : public ValueObject {
public:
ObjectPoolWrapper() : zone_(nullptr) {}
~ObjectPoolWrapper() {
if (zone_ != nullptr) {
Reset();
zone_ = nullptr;
}
}

// Clears all existing entries in this object pool builder.
//
// Note: Any code which has been compiled via this builder might use offsets
// into the pool which are not correct anymore.
void Reset();

// Initializes this object pool builder from [other].
//
// All entries from [other] will be populated, including their
// kind/patchability bits.
void InitializeFrom(const ObjectPool& other);

// Initialize this object pool builder with a [zone].
//
// Any objects added later on will be referenced using handles from [zone].
void InitializeWithZone(Zone* zone) {
ASSERT(object_pool_.length() == 0);
ASSERT(zone_ == nullptr && zone != nullptr);
zone_ = zone;
}

intptr_t AddObject(
const Object& obj,
ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
intptr_t AddImmediate(uword imm);

intptr_t FindObject(
const Object& obj,
ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
Expand All @@ -386,6 +416,9 @@ class ObjectPoolWrapper : public ValueObject {

RawObjectPool* MakeObjectPool();

intptr_t CurrentLength() { return object_pool_.length(); }
ObjectPoolWrapperEntry& EntryAt(intptr_t i) { return object_pool_[i]; }

private:
intptr_t AddObject(ObjectPoolWrapperEntry entry);
intptr_t FindObject(ObjectPoolWrapperEntry entry);
Expand All @@ -395,6 +428,11 @@ class ObjectPoolWrapper : public ValueObject {

// Hashmap for fast lookup in object pool.
DirectChainedHashMap<ObjIndexPair> object_pool_index_table_;

// The zone used for allocating the handles we keep in the map and array (or
// NULL, in which case allocations happen using the zone active at the point
// of insertion).
Zone* zone_;
};

enum RestorePP { kRestoreCallerPP, kKeepCalleePP };
Expand Down
25 changes: 18 additions & 7 deletions assembler_arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace dart {

DECLARE_FLAG(bool, check_code_pointer);
DECLARE_FLAG(bool, inline_alloc);
DECLARE_FLAG(bool, precompiled_mode);

uint32_t Address::encoding3() const {
if (kind_ == Immediate) {
Expand Down Expand Up @@ -3162,10 +3163,16 @@ void Assembler::EnterDartFrame(intptr_t frame_size) {
COMPILE_ASSERT(PP < CODE_REG);
COMPILE_ASSERT(CODE_REG < FP);
COMPILE_ASSERT(FP < LR);
EnterFrame((1 << PP) | (1 << CODE_REG) | (1 << FP) | (1 << LR), 0);

// Setup pool pointer for this dart function.
LoadPoolPointer();
if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
EnterFrame((1 << PP) | (1 << CODE_REG) | (1 << FP) | (1 << LR), 0);

// Setup pool pointer for this dart function.
LoadPoolPointer();
} else {
EnterFrame((1 << FP) | (1 << LR), 0);
}
set_constant_pool_allowed(true);

// Reserve space for locals.
AddImmediate(SP, -frame_size);
Expand All @@ -3186,8 +3193,10 @@ void Assembler::EnterOsrFrame(intptr_t extra_size) {
}

void Assembler::LeaveDartFrame() {
ldr(PP,
Address(FP, compiler_frame_layout.saved_caller_pp_from_fp * kWordSize));
if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
ldr(PP,
Address(FP, compiler_frame_layout.saved_caller_pp_from_fp * kWordSize));
}
set_constant_pool_allowed(false);

// This will implicitly drop saved PP, PC marker due to restoring SP from FP
Expand All @@ -3196,8 +3205,10 @@ void Assembler::LeaveDartFrame() {
}

void Assembler::LeaveDartFrameAndReturn() {
ldr(PP,
Address(FP, compiler_frame_layout.saved_caller_pp_from_fp * kWordSize));
if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
ldr(PP,
Address(FP, compiler_frame_layout.saved_caller_pp_from_fp * kWordSize));
}
set_constant_pool_allowed(false);

// This will implicitly drop saved PP, PC marker due to restoring SP from FP
Expand Down
35 changes: 21 additions & 14 deletions assembler_arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace dart {

DECLARE_FLAG(bool, check_code_pointer);
DECLARE_FLAG(bool, inline_alloc);
DECLARE_FLAG(bool, precompiled_mode);

DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches");

Expand Down Expand Up @@ -1250,15 +1251,18 @@ void Assembler::EnterDartFrame(intptr_t frame_size, Register new_pp) {
ASSERT(!constant_pool_allowed());
// Setup the frame.
EnterFrame(0);
TagAndPushPPAndPcMarker(); // Save PP and PC marker.

// Load the pool pointer.
if (new_pp == kNoRegister) {
LoadPoolPointer();
} else {
mov(PP, new_pp);
set_constant_pool_allowed(true);
if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
TagAndPushPPAndPcMarker(); // Save PP and PC marker.

// Load the pool pointer.
if (new_pp == kNoRegister) {
LoadPoolPointer();
} else {
mov(PP, new_pp);
}
}
set_constant_pool_allowed(true);

// Reserve space.
if (frame_size > 0) {
Expand All @@ -1283,13 +1287,15 @@ void Assembler::EnterOsrFrame(intptr_t extra_size, Register new_pp) {
}

void Assembler::LeaveDartFrame(RestorePP restore_pp) {
if (restore_pp == kRestoreCallerPP) {
set_constant_pool_allowed(false);
// Restore and untag PP.
LoadFromOffset(PP, FP,
compiler_frame_layout.saved_caller_pp_from_fp * kWordSize);
sub(PP, PP, Operand(kHeapObjectTag));
if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
if (restore_pp == kRestoreCallerPP) {
// Restore and untag PP.
LoadFromOffset(PP, FP,
compiler_frame_layout.saved_caller_pp_from_fp * kWordSize);
sub(PP, PP, Operand(kHeapObjectTag));
}
}
set_constant_pool_allowed(false);
LeaveFrame();
}

Expand Down Expand Up @@ -1325,7 +1331,8 @@ void Assembler::LeaveCallRuntimeFrame() {
const intptr_t kPushedRegistersSize =
kDartVolatileCpuRegCount * kWordSize +
kDartVolatileFpuRegCount * kWordSize +
2 * kWordSize; // PP and pc marker from EnterStubFrame.
(compiler_frame_layout.dart_fixed_frame_size - 2) *
kWordSize; // From EnterStubFrame (excluding PC / FP)
AddImmediate(SP, FP, -kPushedRegistersSize);
for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) {
const Register reg = static_cast<Register>(i);
Expand Down
29 changes: 18 additions & 11 deletions assembler_x64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace dart {

DECLARE_FLAG(bool, check_code_pointer);
DECLARE_FLAG(bool, inline_alloc);
DECLARE_FLAG(bool, precompiled_mode);

Assembler::Assembler(ObjectPoolWrapper* object_pool_wrapper,
bool use_far_branches)
Expand Down Expand Up @@ -1531,7 +1532,9 @@ void Assembler::LeaveCallRuntimeFrame() {
const intptr_t kPushedRegistersSize =
kPushedCpuRegistersCount * kWordSize +
kPushedXmmRegistersCount * kFpuRegisterSize +
2 * kWordSize; // PP, pc marker from EnterStubFrame
(compiler_frame_layout.dart_fixed_frame_size - 2) *
kWordSize; // From EnterStubFrame (excluding PC / FP)

leaq(RSP, Address(RBP, -kPushedRegistersSize));

// TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
Expand Down Expand Up @@ -1568,12 +1571,14 @@ void Assembler::LoadPoolPointer(Register pp) {
void Assembler::EnterDartFrame(intptr_t frame_size, Register new_pp) {
ASSERT(!constant_pool_allowed());
EnterFrame(0);
pushq(CODE_REG);
pushq(PP);
if (new_pp == kNoRegister) {
LoadPoolPointer(PP);
} else {
movq(PP, new_pp);
if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
pushq(CODE_REG);
pushq(PP);
if (new_pp == kNoRegister) {
LoadPoolPointer(PP);
} else {
movq(PP, new_pp);
}
}
set_constant_pool_allowed(true);
if (frame_size != 0) {
Expand All @@ -1583,11 +1588,13 @@ void Assembler::EnterDartFrame(intptr_t frame_size, Register new_pp) {

void Assembler::LeaveDartFrame(RestorePP restore_pp) {
// Restore caller's PP register that was pushed in EnterDartFrame.
if (restore_pp == kRestoreCallerPP) {
movq(PP, Address(RBP, (compiler_frame_layout.saved_caller_pp_from_fp *
kWordSize)));
set_constant_pool_allowed(false);
if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
if (restore_pp == kRestoreCallerPP) {
movq(PP, Address(RBP, (compiler_frame_layout.saved_caller_pp_from_fp *
kWordSize)));
}
}
set_constant_pool_allowed(false);
LeaveFrame();
}

Expand Down
31 changes: 21 additions & 10 deletions disassembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -329,19 +329,23 @@ void Disassembler::DisassembleCodeHelper(const char* function_fullname,
THR_Print("Static call target functions {\n");
const auto& table = Array::Handle(zone, code.static_calls_target_table());
auto& cls = Class::Handle(zone);
auto& kind_and_offset = Smi::Handle(zone);
auto& kind_type_and_offset = Smi::Handle(zone);
auto& function = Function::Handle(zone);
auto& code = Code::Handle(zone);
if (!table.IsNull()) {
StaticCallsTable static_calls(table);
for (auto& call : static_calls) {
kind_and_offset = call.Get<Code::kSCallTableKindAndOffset>();
kind_type_and_offset = call.Get<Code::kSCallTableKindAndOffset>();
function = call.Get<Code::kSCallTableFunctionTarget>();
code = call.Get<Code::kSCallTableCodeTarget>();

auto kind = Code::KindField::decode(kind_and_offset.Value());
auto offset = Code::OffsetField::decode(kind_and_offset.Value());
auto kind = Code::KindField::decode(kind_type_and_offset.Value());
auto offset = Code::OffsetField::decode(kind_type_and_offset.Value());
auto entry_point =
Code::EntryPointField::decode(kind_type_and_offset.Value());

const char* s_entry_point =
entry_point == Code::kUncheckedEntry ? " <unchecked-entry>" : "";
const char* skind = nullptr;
switch (kind) {
case Code::kPcRelativeCall:
Expand All @@ -359,15 +363,17 @@ void Disassembler::DisassembleCodeHelper(const char* function_fullname,
if (function.IsNull()) {
cls ^= code.owner();
if (cls.IsNull()) {
THR_Print(" 0x%" Px ": %s, %p (%s)\n", start + offset,
code.QualifiedName(), code.raw(), skind);
THR_Print(" 0x%" Px ": %s, %p (%s)%s\n", start + offset,
code.QualifiedName(), code.raw(), skind, s_entry_point);
} else {
THR_Print(" 0x%" Px ": allocation stub for %s, %p (%s)\n",
start + offset, cls.ToCString(), code.raw(), skind);
THR_Print(" 0x%" Px ": allocation stub for %s, %p (%s)%s\n",
start + offset, cls.ToCString(), code.raw(), skind,
s_entry_point);
}
} else {
THR_Print(" 0x%" Px ": %s, %p (%s)\n", start + offset,
function.ToFullyQualifiedCString(), code.raw(), skind);
THR_Print(" 0x%" Px ": %s, %p (%s)%s\n", start + offset,
function.ToFullyQualifiedCString(), code.raw(), skind,
s_entry_point);
}
}
}
Expand All @@ -389,6 +395,11 @@ void Disassembler::DisassembleCode(const Function& function,
DisassembleCodeHelper(function_fullname, code, optimized);
}

#else // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)

void Disassembler::DisassembleCode(const Function& function,
const Code& code,
bool optimized) {}
#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)

} // namespace dart

0 comments on commit 4fc2984

Please sign in to comment.