Skip to content

Commit

Permalink
[vm] Multiple entrypoints: backend/assembler support.
Browse files Browse the repository at this point in the history
Test Plan:

Will be tested by following revisions which introduce optimizations that invoke the
new entrypoint.

Change-Id: I56d714bceb92c44a13c46d52457154b82577aa8c
Cq-Include-Trybots: luci.dart.try:vm-kernel-win-release-x64-try,vm-kernel-optcounter-threshold-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/67345
Commit-Queue: Samir Jindel <sjindel@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
  • Loading branch information
sjindel-google authored and commit-bot@chromium.org committed Aug 16, 2018
1 parent 821d724 commit d8a4a38
Show file tree
Hide file tree
Showing 39 changed files with 789 additions and 159 deletions.
9 changes: 9 additions & 0 deletions runtime/vm/clustered_snapshot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ class FunctionDeserializationCluster : public DeserializationCluster {

#if defined(DEBUG)
func->ptr()->entry_point_ = 0;
func->ptr()->unchecked_entry_point_ = 0;
#endif

#if !defined(DART_PRECOMPILED_RUNTIME)
Expand Down Expand Up @@ -686,6 +687,10 @@ class FunctionDeserializationCluster : public DeserializationCluster {
uword entry_point = func.raw()->ptr()->code_->ptr()->entry_point_;
ASSERT(entry_point != 0);
func.raw()->ptr()->entry_point_ = entry_point;
uword unchecked_entry_point =
func.raw()->ptr()->code_->ptr()->unchecked_entry_point_;
ASSERT(unchecked_entry_point != 0);
func.raw()->ptr()->unchecked_entry_point_ = unchecked_entry_point;
}
} else if (kind == Snapshot::kFullJIT) {
Function& func = Function::Handle(zone);
Expand Down Expand Up @@ -1774,6 +1779,8 @@ class CodeDeserializationCluster : public DeserializationCluster {
Instructions::MonomorphicEntryPoint(instr);
NOT_IN_PRECOMPILED(code->ptr()->active_instructions_ = instr);
code->ptr()->instructions_ = instr;
code->ptr()->unchecked_entry_point_ =
Instructions::UncheckedEntryPoint(instr);

#if !defined(DART_PRECOMPILED_RUNTIME)
if (d->kind() == Snapshot::kFullJIT) {
Expand All @@ -1782,6 +1789,8 @@ class CodeDeserializationCluster : public DeserializationCluster {
code->ptr()->entry_point_ = Instructions::EntryPoint(instr);
code->ptr()->monomorphic_entry_point_ =
Instructions::MonomorphicEntryPoint(instr);
code->ptr()->unchecked_entry_point_ =
Instructions::UncheckedEntryPoint(instr);
}
#endif // !DART_PRECOMPILED_RUNTIME

Expand Down
4 changes: 2 additions & 2 deletions runtime/vm/compiler/aot/precompiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2765,8 +2765,8 @@ void PrecompileParsedFunctionHelper::FinalizeCompilation(
deopt_info_array.Length() * sizeof(uword));
// Allocates instruction object. Since this occurs only at safepoint,
// there can be no concurrent access to the instruction page.
const Code& code =
Code::Handle(Code::FinalizeCode(function, assembler, optimized(), stats));
const Code& code = Code::Handle(Code::FinalizeCode(
function, graph_compiler, assembler, optimized(), stats));
code.set_is_optimized(optimized());
code.set_owner(function);
if (!function.IsOptimizable()) {
Expand Down
4 changes: 2 additions & 2 deletions runtime/vm/compiler/assembler/assembler_dbc_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ static void MakeDummyInstanceCall(Assembler* assembler, const Object& result) {
const char* dummy_function_name = "dummy_instance_function";
const Function& dummy_instance_function =
Function::Handle(CreateFunction(dummy_function_name));
Code& code =
Code::Handle(Code::FinalizeCode(dummy_instance_function, &_assembler_));
Code& code = Code::Handle(
Code::FinalizeCode(dummy_instance_function, nullptr, &_assembler_));
dummy_instance_function.AttachCode(code);

// Make a dummy ICData.
Expand Down
10 changes: 5 additions & 5 deletions runtime/vm/compiler/assembler/assembler_x64_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3903,7 +3903,7 @@ ASSEMBLER_TEST_RUN(PackedNegate, test) {
"push thr\n"
"movq r12,[rdi+0x8]\n"
"movq thr,rsi\n"
"movq pp,[r12+0x17]\n"
"movq pp,[r12+0x1f]\n"
"movl rax,0x........\n"
"movd xmm0,rax\n"
"shufps xmm0,xmm0 [0]\n"
Expand Down Expand Up @@ -3940,7 +3940,7 @@ ASSEMBLER_TEST_RUN(PackedAbsolute, test) {
"push thr\n"
"movq r12,[rdi+0x8]\n"
"movq thr,rsi\n"
"movq pp,[r12+0x17]\n"
"movq pp,[r12+0x1f]\n"
"movl rax,-0x........\n"
"movd xmm0,rax\n"
"shufps xmm0,xmm0 [0]\n"
Expand Down Expand Up @@ -3975,7 +3975,7 @@ ASSEMBLER_TEST_RUN(PackedSetWZero, test) {
"push thr\n"
"movq r12,[rdi+0x8]\n"
"movq thr,rsi\n"
"movq pp,[r12+0x17]\n"
"movq pp,[r12+0x1f]\n"
"movl rax,0x........\n"
"movd xmm0,rax\n"
"shufps xmm0,xmm0 [0]\n"
Expand Down Expand Up @@ -4820,7 +4820,7 @@ ASSEMBLER_TEST_RUN(TestObjectCompare, test) {
"push thr\n"
"movq r12,[rdi+0x8]\n"
"movq thr,rsi\n"
"movq pp,[r12+0x17]\n"
"movq pp,[r12+0x1f]\n"
"movq rax,[pp+0xf]\n"
"cmpq rax,[pp+0xf]\n"
"jnz 0x................\n"
Expand Down Expand Up @@ -5258,7 +5258,7 @@ ASSEMBLER_TEST_RUN(DoubleAbs, test) {
"push thr\n"
"movq r12,[rdi+0x8]\n"
"movq thr,rsi\n"
"movq pp,[r12+0x17]\n"
"movq pp,[r12+0x1f]\n"
"movq r11,[thr+0x...]\n"
"andpd xmm0,[r11]\n"
"pop thr\n"
Expand Down
10 changes: 9 additions & 1 deletion runtime/vm/compiler/assembler/disassembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ void Disassembler::DisassembleCodeHelper(const char* function_fullname,
PcDescriptors::Handle(zone, code.pc_descriptors());
THR_Print("%s}\n", descriptors.ToCString());

uword start = Instructions::Handle(zone, code.instructions()).PayloadStart();
const auto& instructions = Instructions::Handle(code.instructions());
const uword start = instructions.PayloadStart();

#if !defined(DART_PRECOMPILED_RUNTIME)
const Array& deopt_table = Array::Handle(zone, code.deopt_info_array());
Expand Down Expand Up @@ -322,6 +323,13 @@ void Disassembler::DisassembleCodeHelper(const char* function_fullname,
ExceptionHandlers::Handle(zone, code.exception_handlers());
THR_Print("%s}\n", handlers.ToCString());

if (instructions.unchecked_entrypoint_pc_offset() != 0) {
THR_Print("Unchecked entrypoint at offset 0x%" Px "\n",
Instructions::UncheckedEntryPoint(instructions.raw()));
} else {
THR_Print("No unchecked entrypoint.\n");
}

{
THR_Print("Static call target functions {\n");
const Array& table = Array::Handle(zone, code.static_calls_target_table());
Expand Down
7 changes: 7 additions & 0 deletions runtime/vm/compiler/backend/branch_optimizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,13 @@ void IfConverter::Simplify(FlowGraph* flow_graph) {
(pred1->PredecessorAt(0) == pred2->PredecessorAt(0))) {
BlockEntryInstr* pred = pred1->PredecessorAt(0);
BranchInstr* branch = pred->last_instruction()->AsBranch();

if (branch == nullptr) {
// There is no "B_pred" block.
ASSERT(pred->last_instruction()->IsGraphEntry());
continue;
}

ComparisonInstr* comparison = branch->comparison();

// Check if the platform supports efficient branchless IfThenElseInstr
Expand Down
4 changes: 3 additions & 1 deletion runtime/vm/compiler/backend/flow_graph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,9 @@ void FlowGraph::ComputeIsReceiver(PhiInstr* phi) const {
bool FlowGraph::IsReceiver(Definition* def) const {
def = def->OriginalDefinition(); // Could be redefined.
if (def->IsParameter()) return (def->AsParameter()->index() == 0);
if (!def->IsPhi() || graph_entry()->catch_entries().is_empty()) return false;
if (!def->IsPhi() || graph_entry()->HasSingleEntryPoint()) {
return false;
}
PhiInstr* phi = def->AsPhi();
if (phi->is_receiver() != PhiInstr::kUnknownReceiver) {
return (phi->is_receiver() == PhiInstr::kReceiver);
Expand Down
4 changes: 4 additions & 0 deletions runtime/vm/compiler/backend/flow_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ class FlowGraph : public ZoneAllocated {
return num_direct_parameters_ - variable->index().value();
}

bool IsEntryPoint(BlockEntryInstr* target) const {
return graph_entry()->IsEntryPoint(target);
}

// Flow graph orders.
const GrowableArray<BlockEntryInstr*>& preorder() const { return preorder_; }
const GrowableArray<BlockEntryInstr*>& postorder() const {
Expand Down
40 changes: 32 additions & 8 deletions runtime/vm/compiler/backend/flow_graph_compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,13 @@ bool FlowGraphCompiler::ForceSlowPathForStackOverflow() const {
return false;
}

static bool IsEmptyBlock(BlockEntryInstr* block) {
bool FlowGraphCompiler::IsEmptyBlock(BlockEntryInstr* block) const {
// Entry-points cannot be merged because they must have assembly
// prologue emitted which should not be included in any block they jump to.
return !block->IsCatchBlockEntry() && !block->HasNonRedundantParallelMove() &&
block->next()->IsGoto() &&
!block->next()->AsGoto()->HasNonRedundantParallelMove() &&
!block->IsIndirectEntry();
!block->IsIndirectEntry() && !flow_graph().IsEntryPoint(block);
}

void FlowGraphCompiler::CompactBlock(BlockEntryInstr* block) {
Expand Down Expand Up @@ -318,6 +320,26 @@ void FlowGraphCompiler::CompactBlocks() {
block_info->set_next_nonempty_label(nonempty_label);
}

intptr_t FlowGraphCompiler::UncheckedEntryOffset() const {
TargetEntryInstr* entry = flow_graph().graph_entry()->unchecked_entry();
if (entry == nullptr) {
entry = flow_graph().graph_entry()->normal_entry();
}
Label* target = GetJumpLabel(entry);

if (target->IsBound()) {
return target->Position();
}

// Intrinsification happened.
#ifdef DART_PRECOMPILER
if (parsed_function().function().IsDynamicFunction()) {
return Instructions::kUncheckedEntryOffset;
}
#endif
return 0;
}

void FlowGraphCompiler::EmitCatchEntryState(Environment* env,
intptr_t try_index) {
#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
Expand Down Expand Up @@ -865,7 +887,7 @@ Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id,
ICData::DeoptReasonId reason,
uint32_t flags) {
if (intrinsic_mode()) {
return &intrinsic_slow_path_label_;
return intrinsic_slow_path_label_;
}

// No deoptimization allowed when 'FLAG_precompiled_mode' is set.
Expand Down Expand Up @@ -1054,6 +1076,9 @@ void FlowGraphCompiler::FinalizeCodeSourceMap(const Code& code) {

// Returns 'true' if regular code generation should be skipped.
bool FlowGraphCompiler::TryIntrinsify() {
Label exit;
set_intrinsic_slow_path_label(&exit);

if (FLAG_intrinsify) {
// Intrinsification skips arguments checks, therefore disable if in checked
// mode or strong mode.
Expand Down Expand Up @@ -1106,8 +1131,8 @@ bool FlowGraphCompiler::TryIntrinsify() {
// (normal function body) starts.
// This means that there must not be any side-effects in intrinsic code
// before any deoptimization point.
ASSERT(!intrinsic_slow_path_label_.IsBound());
assembler()->Bind(&intrinsic_slow_path_label_);
assembler()->Bind(intrinsic_slow_path_label());
set_intrinsic_slow_path_label(nullptr);
return complete;
}

Expand Down Expand Up @@ -1276,9 +1301,8 @@ void FlowGraphCompiler::EmitComment(Instruction* instr) {
bool FlowGraphCompiler::NeedsEdgeCounter(TargetEntryInstr* block) {
// Only emit an edge counter if there is not goto at the end of the block,
// except for the entry block.
return (FLAG_reorder_basic_blocks &&
(!block->last_instruction()->IsGoto() ||
(block == flow_graph().graph_entry()->normal_entry())));
return FLAG_reorder_basic_blocks && (!block->last_instruction()->IsGoto() ||
flow_graph().IsEntryPoint(block));
}

// Allocate a register that is not explictly blocked.
Expand Down
19 changes: 17 additions & 2 deletions runtime/vm/compiler/backend/flow_graph_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,14 @@ class FlowGraphCompiler : public ValueObject {
void ExitIntrinsicMode();
bool intrinsic_mode() const { return intrinsic_mode_; }

Label* intrinsic_slow_path_label() { return &intrinsic_slow_path_label_; }
void set_intrinsic_slow_path_label(Label* label) {
ASSERT(intrinsic_slow_path_label_ == nullptr || label == nullptr);
intrinsic_slow_path_label_ = label;
}
Label* intrinsic_slow_path_label() const {
ASSERT(intrinsic_slow_path_label_ != nullptr);
return intrinsic_slow_path_label_;
}

bool ForceSlowPathForStackOverflow() const;

Expand Down Expand Up @@ -388,6 +395,8 @@ class FlowGraphCompiler : public ValueObject {

void CompileGraph();

void EmitPrologue();

void VisitBlocks();

// Bail out of the flow graph compiler. Does not return to the caller.
Expand Down Expand Up @@ -738,6 +747,12 @@ class FlowGraphCompiler : public ValueObject {
int bias,
bool jump_on_miss = true);

// Returns the offset (from the very beginning of the instructions) to the
// unchecked entry point (incl. prologue/frame setup, etc.).
intptr_t UncheckedEntryOffset() const;

bool IsEmptyBlock(BlockEntryInstr* block) const;

private:
friend class CheckStackOverflowSlowPath; // For pending_deoptimization_env_.
friend class CheckedSmiSlowPath; // Same.
Expand Down Expand Up @@ -938,7 +953,7 @@ class FlowGraphCompiler : public ValueObject {
bool may_reoptimize_;
// True while emitting intrinsic code.
bool intrinsic_mode_;
Label intrinsic_slow_path_label_;
Label* intrinsic_slow_path_label_ = nullptr;
CodeStatistics* stats_;

const Class& double_class_;
Expand Down
42 changes: 20 additions & 22 deletions runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -852,28 +852,7 @@ void FlowGraphCompiler::EmitFrameEntry() {
}
}

// Input parameters:
// LR: return address.
// SP: address of last argument.
// FP: caller's frame pointer.
// PP: caller's pool pointer.
// R4: arguments descriptor array.
void FlowGraphCompiler::CompileGraph() {
InitCompiler();
#ifdef DART_PRECOMPILER
const Function& function = parsed_function().function();
if (function.IsDynamicFunction()) {
SpecialStatsBegin(CombinedCodeStatistics::kTagCheckedEntry);
__ MonomorphicCheckedEntry();
SpecialStatsEnd(CombinedCodeStatistics::kTagCheckedEntry);
}
#endif // DART_PRECOMPILER

if (TryIntrinsify()) {
// Skip regular code generation.
return;
}

void FlowGraphCompiler::EmitPrologue() {
EmitFrameEntry();
ASSERT(assembler()->constant_pool_allowed());

Expand All @@ -898,6 +877,25 @@ void FlowGraphCompiler::CompileGraph() {
}

EndCodeSourceRange(TokenPosition::kDartCodePrologue);
}

// Input parameters:
// LR: return address.
// SP: address of last argument.
// FP: caller's frame pointer.
// PP: caller's pool pointer.
// R4: arguments descriptor array.
void FlowGraphCompiler::CompileGraph() {
InitCompiler();
#ifdef DART_PRECOMPILER
const Function& function = parsed_function().function();
if (function.IsDynamicFunction()) {
SpecialStatsBegin(CombinedCodeStatistics::kTagCheckedEntry);
__ MonomorphicCheckedEntry();
SpecialStatsEnd(CombinedCodeStatistics::kTagCheckedEntry);
}
#endif // DART_PRECOMPILER

VisitBlocks();

__ bkpt(0);
Expand Down
26 changes: 13 additions & 13 deletions runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -847,19 +847,8 @@ void FlowGraphCompiler::EmitFrameEntry() {
}
}

void FlowGraphCompiler::CompileGraph() {
InitCompiler();
#ifdef DART_PRECOMPILER
const Function& function = parsed_function().function();
if (function.IsDynamicFunction()) {
__ MonomorphicCheckedEntry();
}
#endif // DART_PRECOMPILER

if (TryIntrinsify()) {
// Skip regular code generation.
return;
}
void FlowGraphCompiler::EmitPrologue() {
BeginCodeSourceRange();

EmitFrameEntry();
ASSERT(assembler()->constant_pool_allowed());
Expand All @@ -885,6 +874,17 @@ void FlowGraphCompiler::CompileGraph() {
}

EndCodeSourceRange(TokenPosition::kDartCodePrologue);
}

void FlowGraphCompiler::CompileGraph() {
InitCompiler();
#ifdef DART_PRECOMPILER
const Function& function = parsed_function().function();
if (function.IsDynamicFunction()) {
__ MonomorphicCheckedEntry();
}
#endif // DART_PRECOMPILER

ASSERT(!block_order().is_empty());
VisitBlocks();

Expand Down
Loading

0 comments on commit d8a4a38

Please sign in to comment.