100e12b6cd
When creating new instructions that inherit a token position that represents a source location from another instruction, the inheriting instruction must also have the same inlining ID in order for the source position represented by the token position to be looked up in the correct script. Force this by wrapping both in a single InstructionSource struct which is taken by instructions which take token positions instead of just a token position. That way, it's more work to manually transfer the token position separately from the inlining ID of the instruction than doing the right thing of transfering both at once. To ensure this information is kept consistent, we pass InstructionSource structs through the FlowGraphCompiler all the way down to the CodeSourceMapBuilder. This CL also makes the following changes: * Cache the upper bound of source positions in scripts and use it to add a check for if a given real token position is valid for the script without iterating over the line starts data for each token position. * Start inlining intervals appropriately when adding descriptor and null check information to the code source map. Code size changes are minimal on Flutter gallery in release mode (<0.05% decrease). TEST=Existing tests on trybots, with manual checking with --check-token-positions that previous errors are now removed. Bug: https://github.com/dart-lang/sdk/issues/44436 Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try Change-Id: I23ced262cb4e9fe9d81356f409e7e8d220d63ee0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/173967 Reviewed-by: Régis Crelier <regis@google.com>
82 lines
3.2 KiB
C++
82 lines
3.2 KiB
C++
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#ifndef RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_CHECKER_H_
|
|
#define RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_CHECKER_H_
|
|
|
|
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
#error "AOT runtime should not use compiler sources (including header files)"
|
|
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
#if defined(DEBUG)
|
|
|
|
#include "vm/compiler/backend/flow_graph.h"
|
|
#include "vm/compiler/backend/il.h"
|
|
|
|
namespace dart {
|
|
|
|
// Class responsible for performing sanity checks on the flow graph.
|
|
// The intended use is running the checks after each compiler pass
|
|
// in debug mode in order to detect graph inconsistencies as soon
|
|
// as possible. This way, culprit passes are more easily identified.
|
|
//
|
|
// All important assumptions on the flow graph structure that can be
|
|
// verified in reasonable time should be made explicit in this pass
|
|
// so that we no longer rely on asserts that are dispersed throughout
|
|
// the passes or, worse, unwritten assumptions once agreed upon but
|
|
// so easily forgotten. Since the graph checker runs only in debug
|
|
// mode, it is acceptable to perform slightly elaborate tests.
|
|
class FlowGraphChecker : public FlowGraphVisitor {
|
|
public:
|
|
// Constructs graph checker. The checker uses some custom-made
|
|
// visitation to perform additional checks, and uses the
|
|
// FlowGraphVisitor structure for anything else.
|
|
FlowGraphChecker(FlowGraph* flow_graph,
|
|
const GrowableArray<const Function*>& inline_id_to_function)
|
|
: FlowGraphVisitor(flow_graph->preorder()),
|
|
flow_graph_(flow_graph),
|
|
inline_id_to_function_(inline_id_to_function),
|
|
script_(Script::Handle(flow_graph_->zone())),
|
|
current_block_(nullptr) {}
|
|
|
|
// Performs a sanity check on the flow graph.
|
|
void Check(const char* pass_name);
|
|
|
|
private:
|
|
// Custom-made visitors.
|
|
void VisitBlocks() override;
|
|
void VisitInstructions(BlockEntryInstr* block);
|
|
void VisitInstruction(Instruction* instruction);
|
|
void VisitDefinition(Definition* def);
|
|
void VisitUseDef(Instruction* instruction,
|
|
Value* use,
|
|
intptr_t index,
|
|
bool is_env);
|
|
void VisitDefUse(Definition* def, Value* use, Value* prev, bool is_env);
|
|
|
|
// Instruction visitors.
|
|
void VisitConstant(ConstantInstr* constant) override;
|
|
void VisitPhi(PhiInstr* phi) override;
|
|
void VisitGoto(GotoInstr* jmp) override;
|
|
void VisitIndirectGoto(IndirectGotoInstr* jmp) override;
|
|
void VisitBranch(BranchInstr* branch) override;
|
|
void VisitRedefinition(RedefinitionInstr* def) override;
|
|
void VisitClosureCall(ClosureCallInstr* call) override;
|
|
void VisitStaticCall(StaticCallInstr* call) override;
|
|
void VisitInstanceCall(InstanceCallInstr* call) override;
|
|
void VisitPolymorphicInstanceCall(
|
|
PolymorphicInstanceCallInstr* call) override;
|
|
|
|
FlowGraph* const flow_graph_;
|
|
const GrowableArray<const Function*>& inline_id_to_function_;
|
|
Script& script_;
|
|
BlockEntryInstr* current_block_;
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // defined(DEBUG)
|
|
|
|
#endif // RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_CHECKER_H_
|