Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
More tweaks
  • Loading branch information
mraleph committed Jan 21, 2021
1 parent b1c27ac commit 6612e52
Show file tree
Hide file tree
Showing 15 changed files with 270 additions and 69 deletions.
4 changes: 2 additions & 2 deletions runtime/vm/code_comments.cc
Expand Up @@ -8,7 +8,7 @@

namespace dart {

const Code::Comments& CreateCommentsFrom(compiler::Assembler* assembler) {
const CodeComments* CreateCommentsFrom(compiler::Assembler* assembler) {
const auto& comments = assembler->comments();
Code::Comments& result = Code::Comments::New(comments.length());

Expand All @@ -17,7 +17,7 @@ const Code::Comments& CreateCommentsFrom(compiler::Assembler* assembler) {
result.SetCommentAt(i, comments[i]->comment());
}

return result;
return new CodeCommentsWrapper(result);
}

} // namespace dart
Expand Down
6 changes: 4 additions & 2 deletions runtime/vm/code_comments.h
Expand Up @@ -14,7 +14,7 @@

namespace dart {

class CodeCommentsWrapper final : public CodeComments {
class CodeCommentsWrapper final : public ZoneAllocated, public CodeComments {
public:
explicit CodeCommentsWrapper(const Code::Comments& comments)
: comments_(comments), string_(String::Handle()) {}
Expand All @@ -30,12 +30,14 @@ class CodeCommentsWrapper final : public CodeComments {
return string_.ToCString();
}

const Code::Comments& Unwrap() const { return comments_; }

private:
const Code::Comments& comments_;
String& string_;
};

const Code::Comments& CreateCommentsFrom(compiler::Assembler* assembler);
const CodeComments* CreateCommentsFrom(compiler::Assembler* assembler);


} // namespace dart
Expand Down
2 changes: 1 addition & 1 deletion runtime/vm/code_observers.h
Expand Up @@ -16,7 +16,7 @@ namespace dart {

// An abstract representation of comments associated with the given code
// object. We assume that comments are sorted by PCOffset.
class CodeComments : public ValueObject {
class CodeComments {
public:
CodeComments() = default;
virtual ~CodeComments() = default;
Expand Down
7 changes: 4 additions & 3 deletions runtime/vm/compiler/assembler/disassembler.cc
Expand Up @@ -6,6 +6,7 @@

#include "platform/text_buffer.h"
#include "platform/unaligned.h"
#include "vm/code_comments.h"
#include "vm/code_patcher.h"
#include "vm/dart_entry.h"
#include "vm/deopt_instructions.h"
Expand Down Expand Up @@ -161,9 +162,9 @@ void Disassembler::Disassemble(uword start,
uword end,
DisassemblyFormatter* formatter,
const Code& code,
const Code::Comments* comments) {
const CodeComments* comments) {
if (comments == nullptr) {
comments = code.IsNull() ? &Code::Comments::New(0) : &code.comments();
comments = code.IsNull() ? new CodeCommentsWrapper(Code::Comments::New(0)) : code.comments();
}
ASSERT(formatter != NULL);
char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form.
Expand All @@ -179,7 +180,7 @@ void Disassembler::Disassemble(uword start,
comments->PCOffsetAt(comment_finger) <= offset) {
formatter->Print(
" ;; %s\n",
String::Handle(comments->CommentAt(comment_finger)).ToCString());
comments->CommentAt(comment_finger));
comment_finger++;
}
if (old_comment_finger != comment_finger && !code.IsNull()) {
Expand Down
7 changes: 4 additions & 3 deletions runtime/vm/compiler/assembler/disassembler.h
Expand Up @@ -17,8 +17,9 @@
namespace dart {

// Forward declaration.
class MemoryRegion;
class CodeComments;
class JSONArray;
class MemoryRegion;

// Disassembly formatter interface, which consumes the
// disassembled instructions in any desired form.
Expand Down Expand Up @@ -122,7 +123,7 @@ class Disassembler : public AllStatic {
uword end,
DisassemblyFormatter* formatter,
const Code& code,
const Code::Comments* comments = nullptr);
const CodeComments* comments = nullptr);

static void Disassemble(uword start,
uword end,
Expand All @@ -133,7 +134,7 @@ class Disassembler : public AllStatic {
static void Disassemble(uword start,
uword end,
DisassemblyFormatter* formatter,
const Code::Comments* comments) {
const CodeComments* comments) {
Disassemble(start, end, formatter, Code::Handle(), comments);
}

Expand Down
12 changes: 9 additions & 3 deletions runtime/vm/compiler/backend/flow_graph.cc
Expand Up @@ -1904,6 +1904,15 @@ void FlowGraph::InsertConversionsFor(Definition* def) {
static void UnboxPhi(PhiInstr* phi) {
Representation unboxed = phi->representation();

#if defined(TARGET_ARCH_IS_64_BIT)
if (phi->Type()->IsInt()) {
unboxed =
RangeUtils::Fits(phi->range(), RangeBoundary::kRangeBoundaryInt32)
? kUnboxedInt32
: kUnboxedInt64;
}
#endif

switch (phi->Type()->ToCid()) {
case kDoubleCid:
if (CanUnboxDouble()) {
Expand Down Expand Up @@ -1968,9 +1977,6 @@ static void UnboxPhi(PhiInstr* phi) {
Definition* input = phi->InputAt(i)->definition();
if (input->IsBox()) {
should_unbox = true;
} else if (!input->IsConstant()) {
should_unbox = false;
break;
}
}

Expand Down
4 changes: 4 additions & 0 deletions runtime/vm/compiler/backend/il.h
Expand Up @@ -3520,6 +3520,10 @@ class ReachabilityFenceInstr : public TemplateInstruction<1, NoThrow> {
virtual bool ComputeCanDeoptimize() const { return false; }
virtual bool HasUnknownSideEffects() const { return false; }

virtual Representation RequiredInputRepresentation(intptr_t idx) const {
return kNoRepresentation;
}

PRINT_OPERANDS_TO_SUPPORT

private:
Expand Down
12 changes: 12 additions & 0 deletions runtime/vm/compiler/backend/redundancy_elimination.cc
Expand Up @@ -4224,7 +4224,14 @@ void DeadCodeElimination::EliminateDeadCode(FlowGraph* flow_graph) {
}
}

static bool IsNoInterrupts(const Function& function) {
Object& options = Object::Handle();
return Library::FindPragma(dart::Thread::Current(), /*only_core=*/false,
function, Symbols::vm_no_interrupts(), &options);
}

void CheckStackOverflowElimination::EliminateStackOverflow(FlowGraph* graph) {
const bool remove_all = IsNoInterrupts(graph->function());
CheckStackOverflowInstr* first_stack_overflow_instr = NULL;
for (BlockIterator block_it = graph->reverse_postorder_iterator();
!block_it.Done(); block_it.Advance()) {
Expand All @@ -4234,6 +4241,11 @@ void CheckStackOverflowElimination::EliminateStackOverflow(FlowGraph* graph) {
Instruction* current = it.Current();

if (CheckStackOverflowInstr* instr = current->AsCheckStackOverflow()) {
if (remove_all) {
it.RemoveCurrentFromGraph();
continue;
}

if (first_stack_overflow_instr == NULL) {
first_stack_overflow_instr = instr;
ASSERT(!first_stack_overflow_instr->in_loop());
Expand Down
157 changes: 157 additions & 0 deletions runtime/vm/dwarf.cc
Expand Up @@ -4,6 +4,7 @@

#include "vm/dwarf.h"

#include "vm/code_comments.h"
#include "vm/code_descriptors.h"
#include "vm/elf.h"
#include "vm/image_snapshot.h"
Expand All @@ -13,6 +14,11 @@ namespace dart {

#if defined(DART_PRECOMPILER)

DEFINE_FLAG(charp,
write_code_comments_as_synthetic_source_to,
nullptr,
"Print comments associated with instructions into the given file");

class DwarfPosition {
public:
DwarfPosition(int32_t line, int32_t column) : line_(line), column_(column) {
Expand Down Expand Up @@ -506,7 +512,158 @@ void Dwarf::WriteInliningNode(DwarfWriteStream* stream,
stream->uleb128(0); // End of children.
}

void Dwarf::WriteSyntheticLineNumberProgram(DwarfWriteStream* stream) {
auto file_open = Dart::file_open_callback();
auto file_write = Dart::file_write_callback();
auto file_close = Dart::file_close_callback();
if ((file_open == nullptr) || (file_write == nullptr) ||
(file_close == nullptr)) {
return;
}

TextBuffer comments_buffer(128 * KB);

auto comments_file = file_open(FLAG_write_code_comments_as_synthetic_source_to, /*write=*/true);
if (comments_file == nullptr) {
OS::PrintErr("Failed to open file %s\n", FLAG_write_code_comments_as_synthetic_source_to);
return;
}

// 6.2.4 The Line Number Program Header

// 1. unit_length. This encoding implies 32-bit DWARF.
auto const line_prefix = "line";
intptr_t line_start;
intptr_t line_size_fixup = stream->ReserveSize(line_prefix, &line_start);

stream->u2(2); // 2. DWARF version 2

// 3. header_length
auto const lineheader_prefix = "lineheader";
intptr_t lineheader_start;
intptr_t lineheader_size_fixup =
stream->ReserveSize(lineheader_prefix, &lineheader_start);

stream->u1(1); // 4. minimum_instruction_length
stream->u1(1); // 5. default_is_stmt (true for compatibility with dsymutil).
stream->u1(0); // 6. line_base
stream->u1(1); // 7. line_range
stream->u1(13); // 8. opcode_base (12 standard opcodes in Dwarf 2)

// 9. standard_opcode_lengths
stream->u1(0); // DW_LNS_copy, 0 operands
stream->u1(1); // DW_LNS_advance_pc, 1 operands
stream->u1(1); // DW_LNS_advance_list, 1 operands
stream->u1(1); // DW_LNS_set_file, 1 operands
stream->u1(1); // DW_LNS_set_column, 1 operands
stream->u1(0); // DW_LNS_negate_stmt, 0 operands
stream->u1(0); // DW_LNS_set_basic_block, 0 operands
stream->u1(0); // DW_LNS_const_add_pc, 0 operands
stream->u1(1); // DW_LNS_fixed_advance_pc, 1 operands
stream->u1(0); // DW_LNS_set_prolog_end, 0 operands
stream->u1(0); // DW_LNS_set_epligoue_begin, 0 operands
stream->u1(1); // DW_LNS_set_isa, 1 operands

// 10. include_directories (sequence of path names)
// We don't emit any because we use full paths below.
stream->u1(0);

// 11. file_names (sequence of file entries)
stream->string(FLAG_write_code_comments_as_synthetic_source_to); // NOLINT
stream->uleb128(0); // Include directory index.
stream->uleb128(0); // File modification time.
stream->uleb128(0); // File length.
stream->u1(0); // End of file names.
stream->SetSize(lineheader_size_fixup, lineheader_prefix, lineheader_start);

// 6.2.5 The Line Number Program

// The initial values for the line number program state machine registers
// according to the DWARF standard.
intptr_t previous_pc_offset = 0;
intptr_t previous_line = 1;
// Other info not stored in the state machine registers.
const char* previous_asm_name = nullptr;

intptr_t current_line = 0;

for (intptr_t i = 0; i < codes_.length(); i++) {
const Code& code = *(codes_[i]);
auto const asm_name = code_to_name_.LookupValue(&code);
ASSERT(asm_name != nullptr);

auto comments = code.comments();
if (comments == nullptr) {
continue;
}

for (intptr_t i = 0, len = comments->Length(); i < len;) {
intptr_t current_pc_offset = comments->PCOffsetAt(i);
while (i < len && current_pc_offset == comments->PCOffsetAt(i)) {
comments_buffer.AddString(comments->CommentAt(i));
comments_buffer.AddChar('\n');
current_line++;
i++;
}

if (current_line != previous_line) {
stream->u1(DW_LNS_advance_line);
stream->sleb128(current_line - previous_line);
previous_line = current_line;
}

if (previous_asm_name == nullptr) {
auto const instr_size = 1 + compiler::target::kWordSize;
stream->u1(0); // This is an extended opcode
stream->u1(instr_size); // that is 5 or 9 bytes long
stream->u1(DW_LNE_set_address);
stream->OffsetFromSymbol(asm_name, current_pc_offset);
} else {
stream->u1(DW_LNS_advance_pc);
stream->DistanceBetweenSymbolOffsets(asm_name, current_pc_offset,
previous_asm_name,
previous_pc_offset);
}
stream->u1(DW_LNS_copy);
previous_asm_name = asm_name;
previous_pc_offset = current_pc_offset;
}
}

// Advance pc to end of the compilation unit if not already there.
if (codes_.length() != 0) {
const intptr_t last_code_index = codes_.length() - 1;
const Code& last_code = *(codes_[last_code_index]);
const intptr_t last_pc_offset = last_code.Size();
const char* last_asm_name = code_to_name_.LookupValue(&last_code);
ASSERT(last_asm_name != nullptr);

stream->u1(DW_LNS_advance_pc);
if (previous_asm_name != nullptr) {
stream->DistanceBetweenSymbolOffsets(
last_asm_name, last_pc_offset, previous_asm_name, previous_pc_offset);
} else {
// No LNP entries (e.g., only stub code).
ASSERT(previous_pc_offset == 0);
stream->uleb128(last_pc_offset);
}
}

// End of contiguous machine code.
stream->u1(0); // This is an extended opcode
stream->u1(1); // that is 1 byte long
stream->u1(DW_LNE_end_sequence);
stream->SetSize(line_size_fixup, line_prefix, line_start);

file_write(comments_buffer.buffer(), comments_buffer.length(), comments_file);
file_close(comments_file);
}

void Dwarf::WriteLineNumberProgram(DwarfWriteStream* stream) {
if (FLAG_write_code_comments_as_synthetic_source_to != nullptr) {
WriteSyntheticLineNumberProgram(stream);
return;
}
// 6.2.4 The Line Number Program Header

// 1. unit_length. This encoding implies 32-bit DWARF.
Expand Down
2 changes: 2 additions & 0 deletions runtime/vm/dwarf.h
Expand Up @@ -307,6 +307,8 @@ class Dwarf : public ZoneAllocated {
const char* root_code_name,
const Script& parent_script);

void WriteSyntheticLineNumberProgram(DwarfWriteStream* stream);

const char* Deobfuscate(const char* cstr);
static Trie<const char>* CreateReverseObfuscationTrie(Zone* zone);

Expand Down
9 changes: 4 additions & 5 deletions runtime/vm/ffi_callback_trampolines.cc
Expand Up @@ -72,14 +72,13 @@ void NativeCallbackTrampolines::AllocateTrampoline() {
const char* name = "FfiJitCallbackTrampolines";
ASSERT(!Thread::Current()->IsAtSafepoint());
if (CodeObservers::AreActive()) {
const auto& comments = CreateCommentsFrom(&assembler);
CodeCommentsWrapper wrapper(comments);
const auto comments = CreateCommentsFrom(&assembler);
CodeObservers::NotifyAll(name,
/*base=*/memory->start(),
/*prologue_offset=*/0,
/*size=*/assembler.CodeSize(),
/*optimized=*/false, // not really relevant
&wrapper);
comments);
}
#endif
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
Expand All @@ -90,10 +89,10 @@ void NativeCallbackTrampolines::AllocateTrampoline() {
"[%" Pd " -> %" Pd "]: {\n",
next_callback_id_,
next_callback_id_ + NumCallbackTrampolinesPerPage() - 1);
const auto& comments = CreateCommentsFrom(&assembler);
const auto comments = CreateCommentsFrom(&assembler);
Disassembler::Disassemble(memory->start(),
memory->start() + assembler.CodeSize(),
&formatter, &comments);
&formatter, comments);
}
#endif

Expand Down

0 comments on commit 6612e52

Please sign in to comment.