summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/graph-visualizer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/graph-visualizer.cc')
-rw-r--r--deps/v8/src/compiler/graph-visualizer.cc146
1 files changed, 72 insertions, 74 deletions
diff --git a/deps/v8/src/compiler/graph-visualizer.cc b/deps/v8/src/compiler/graph-visualizer.cc
index cbb7188993..76c5313329 100644
--- a/deps/v8/src/compiler/graph-visualizer.cc
+++ b/deps/v8/src/compiler/graph-visualizer.cc
@@ -8,8 +8,8 @@
#include <sstream>
#include <string>
-#include "src/code-stubs.h"
#include "src/compiler/all-nodes.h"
+#include "src/compiler/backend/register-allocator.h"
#include "src/compiler/compiler-source-position-table.h"
#include "src/compiler/graph.h"
#include "src/compiler/node-origin-table.h"
@@ -18,7 +18,6 @@
#include "src/compiler/opcodes.h"
#include "src/compiler/operator-properties.h"
#include "src/compiler/operator.h"
-#include "src/compiler/register-allocator.h"
#include "src/compiler/schedule.h"
#include "src/compiler/scheduler.h"
#include "src/interpreter/bytecodes.h"
@@ -63,6 +62,30 @@ std::ostream& operator<<(std::ostream& out, const NodeOriginAsJSON& asJSON) {
return out;
}
+class JSONEscaped {
+ public:
+ explicit JSONEscaped(const std::ostringstream& os) : str_(os.str()) {}
+
+ friend std::ostream& operator<<(std::ostream& os, const JSONEscaped& e) {
+ for (char c : e.str_) PipeCharacter(os, c);
+ return os;
+ }
+
+ private:
+ static std::ostream& PipeCharacter(std::ostream& os, char c) {
+ if (c == '"') return os << "\\\"";
+ if (c == '\\') return os << "\\\\";
+ if (c == '\b') return os << "\\b";
+ if (c == '\f') return os << "\\f";
+ if (c == '\n') return os << "\\n";
+ if (c == '\r') return os << "\\r";
+ if (c == '\t') return os << "\\t";
+ return os << c;
+ }
+
+ const std::string str_;
+};
+
void JsonPrintFunctionSource(std::ostream& os, int source_id,
std::unique_ptr<char[]> function_name,
Handle<Script> script, Isolate* isolate,
@@ -76,10 +99,12 @@ void JsonPrintFunctionSource(std::ostream& os, int source_id,
int start = 0;
int end = 0;
if (!script.is_null() && !script->IsUndefined(isolate) && !shared.is_null()) {
- Object* source_name = script->name();
+ Object source_name = script->name();
os << ", \"sourceName\": \"";
if (source_name->IsString()) {
- os << String::cast(source_name)->ToCString().get();
+ std::ostringstream escaped_name;
+ escaped_name << String::cast(source_name)->ToCString().get();
+ os << JSONEscaped(escaped_name);
}
os << "\"";
{
@@ -88,7 +113,8 @@ void JsonPrintFunctionSource(std::ostream& os, int source_id,
end = shared->EndPosition();
os << ", \"sourceText\": \"";
int len = shared->EndPosition() - start;
- String::SubStringRange source(String::cast(script->source()), start, len);
+ SubStringRange source(String::cast(script->source()), no_allocation,
+ start, len);
for (const auto& c : source) {
os << AsEscapedUC16ForJSON(c);
}
@@ -139,7 +165,8 @@ void JsonPrintAllSourceWithPositions(std::ostream& os,
AllowDeferredHandleDereference allow_deference_for_print_code;
os << "\"sources\" : {";
Handle<Script> script =
- (info->shared_info().is_null() || !info->shared_info()->script())
+ (info->shared_info().is_null() ||
+ info->shared_info()->script() == Object())
? Handle<Script>()
: handle(Script::cast(info->shared_info()->script()), isolate);
JsonPrintFunctionSource(os, -1,
@@ -189,9 +216,9 @@ std::unique_ptr<char[]> GetVisualizerLogFileName(OptimizedCompilationInfo* info,
bool source_available = false;
if (FLAG_trace_file_names && info->has_shared_info() &&
info->shared_info()->script()->IsScript()) {
- Object* source_name = Script::cast(info->shared_info()->script())->name();
+ Object source_name = Script::cast(info->shared_info()->script())->name();
if (source_name->IsString()) {
- String* str = String::cast(source_name);
+ String str = String::cast(source_name);
if (str->length() > 0) {
SNPrintF(source_file, "%s", str->ToCString().get());
std::replace(source_file.start(),
@@ -238,30 +265,6 @@ static const char* SafeMnemonic(Node* node) {
return node == nullptr ? "null" : node->op()->mnemonic();
}
-class JSONEscaped {
- public:
- explicit JSONEscaped(const std::ostringstream& os) : str_(os.str()) {}
-
- friend std::ostream& operator<<(std::ostream& os, const JSONEscaped& e) {
- for (char c : e.str_) PipeCharacter(os, c);
- return os;
- }
-
- private:
- static std::ostream& PipeCharacter(std::ostream& os, char c) {
- if (c == '"') return os << "\\\"";
- if (c == '\\') return os << "\\\\";
- if (c == '\b') return os << "\\b";
- if (c == '\f') return os << "\\f";
- if (c == '\n') return os << "\\n";
- if (c == '\r') return os << "\\r";
- if (c == '\t') return os << "\\t";
- return os << c;
- }
-
- const std::string str_;
-};
-
class JSONGraphNodeWriter {
public:
JSONGraphNodeWriter(std::ostream& os, Zone* zone, const Graph* graph,
@@ -699,9 +702,7 @@ void GraphC1Visualizer::PrintSchedule(const char* phase,
for (int j = instruction_block->first_instruction_index();
j <= instruction_block->last_instruction_index(); j++) {
PrintIndent();
- PrintableInstruction printable = {RegisterConfiguration::Default(),
- instructions->InstructionAt(j)};
- os_ << j << " " << printable << " <|@\n";
+ os_ << j << " " << *instructions->InstructionAt(j) << " <|@\n";
}
}
}
@@ -743,17 +744,13 @@ void GraphC1Visualizer::PrintLiveRange(const LiveRange* range, const char* type,
os_ << vreg << ":" << range->relative_id() << " " << type;
if (range->HasRegisterAssigned()) {
AllocatedOperand op = AllocatedOperand::cast(range->GetAssignedOperand());
- const auto config = RegisterConfiguration::Default();
if (op.IsRegister()) {
- os_ << " \"" << config->GetGeneralRegisterName(op.register_code())
- << "\"";
+ os_ << " \"" << Register::from_code(op.register_code()) << "\"";
} else if (op.IsDoubleRegister()) {
- os_ << " \"" << config->GetDoubleRegisterName(op.register_code())
- << "\"";
+ os_ << " \"" << DoubleRegister::from_code(op.register_code()) << "\"";
} else {
DCHECK(op.IsFloatRegister());
- os_ << " \"" << config->GetFloatRegisterName(op.register_code())
- << "\"";
+ os_ << " \"" << FloatRegister::from_code(op.register_code()) << "\"";
}
} else if (range->spilled()) {
const TopLevelLiveRange* top = range->TopLevel();
@@ -774,11 +771,18 @@ void GraphC1Visualizer::PrintLiveRange(const LiveRange* range, const char* type,
}
}
- // The toplevel range is always suffixed with :0. Use that as parent.
- os_ << " " << vreg << ":0";
+ // The toplevel range might be a splinter. Pre-resolve those here so that
+ // they have a proper parent.
+ const TopLevelLiveRange* parent = range->TopLevel();
+ if (parent->IsSplinter()) parent = parent->splintered_from();
+ os_ << " " << parent->vreg() << ":" << parent->relative_id();
// TODO(herhut) Find something useful to print for the hint field
- os_ << " unknown";
+ if (range->get_bundle() != nullptr) {
+ os_ << " B" << range->get_bundle()->id();
+ } else {
+ os_ << " unknown";
+ }
for (const UseInterval* interval = range->first_interval();
interval != nullptr; interval = interval->next()) {
@@ -964,7 +968,6 @@ std::ostream& operator<<(std::ostream& os, const AsScheduledGraph& scheduled) {
}
std::ostream& operator<<(std::ostream& os, const InstructionOperandAsJSON& o) {
- const RegisterConfiguration* conf = o.register_configuration_;
const InstructionOperand* op = o.op_;
const InstructionSequence* code = o.code_;
os << "{";
@@ -983,13 +986,12 @@ std::ostream& operator<<(std::ostream& os, const InstructionOperandAsJSON& o) {
break;
case UnallocatedOperand::FIXED_REGISTER: {
os << ",\"tooltip\": \"FIXED_REGISTER: "
- << conf->GetGeneralRegisterName(unalloc->fixed_register_index())
- << "\"";
+ << Register::from_code(unalloc->fixed_register_index()) << "\"";
break;
}
case UnallocatedOperand::FIXED_FP_REGISTER: {
os << ",\"tooltip\": \"FIXED_FP_REGISTER: "
- << conf->GetDoubleRegisterName(unalloc->fixed_register_index())
+ << DoubleRegister::from_code(unalloc->fixed_register_index())
<< "\"";
break;
}
@@ -1067,14 +1069,18 @@ std::ostream& operator<<(std::ostream& os, const InstructionOperandAsJSON& o) {
} else if (op->IsFPStackSlot()) {
os << "fp_stack:" << allocated->index();
} else if (op->IsRegister()) {
- os << conf->GetGeneralOrSpecialRegisterName(allocated->register_code());
+ if (allocated->register_code() < Register::kNumRegisters) {
+ os << Register::from_code(allocated->register_code());
+ } else {
+ os << Register::GetSpecialRegisterName(allocated->register_code());
+ }
} else if (op->IsDoubleRegister()) {
- os << conf->GetDoubleRegisterName(allocated->register_code());
+ os << DoubleRegister::from_code(allocated->register_code());
} else if (op->IsFloatRegister()) {
- os << conf->GetFloatRegisterName(allocated->register_code());
+ os << FloatRegister::from_code(allocated->register_code());
} else {
DCHECK(op->IsSimd128Register());
- os << conf->GetSimd128RegisterName(allocated->register_code());
+ os << Simd128Register::from_code(allocated->register_code());
}
os << "\",";
os << "\"tooltip\": \""
@@ -1088,13 +1094,11 @@ std::ostream& operator<<(std::ostream& os, const InstructionOperandAsJSON& o) {
return os;
}
-std::ostream& operator<<(std::ostream& os, const InstructionAsJSON& i) {
- const Instruction* instr = i.instr_;
- InstructionOperandAsJSON json_op = {i.register_configuration_, nullptr,
- i.code_};
+std::ostream& operator<<(std::ostream& os, const InstructionAsJSON& i_json) {
+ const Instruction* instr = i_json.instr_;
os << "{";
- os << "\"id\": " << i.index_ << ",";
+ os << "\"id\": " << i_json.index_ << ",";
os << "\"opcode\": \"" << ArchOpcodeField::decode(instr->opcode()) << "\",";
os << "\"flags\": \"";
FlagsMode fm = FlagsModeField::decode(instr->opcode());
@@ -1123,10 +1127,9 @@ std::ostream& operator<<(std::ostream& os, const InstructionAsJSON& i) {
if (move->IsEliminated()) continue;
if (!first) os << ",";
first = false;
- json_op.op_ = &move->destination();
- os << "[" << json_op << ",";
- json_op.op_ = &move->source();
- os << json_op << "]";
+ os << "[" << InstructionOperandAsJSON{&move->destination(), i_json.code_}
+ << "," << InstructionOperandAsJSON{&move->source(), i_json.code_}
+ << "]";
}
os << "]";
}
@@ -1137,8 +1140,7 @@ std::ostream& operator<<(std::ostream& os, const InstructionAsJSON& i) {
for (size_t i = 0; i < instr->OutputCount(); i++) {
if (need_comma) os << ",";
need_comma = true;
- json_op.op_ = instr->OutputAt(i);
- os << json_op;
+ os << InstructionOperandAsJSON{instr->OutputAt(i), i_json.code_};
}
os << "],";
@@ -1147,8 +1149,7 @@ std::ostream& operator<<(std::ostream& os, const InstructionAsJSON& i) {
for (size_t i = 0; i < instr->InputCount(); i++) {
if (need_comma) os << ",";
need_comma = true;
- json_op.op_ = instr->InputAt(i);
- os << json_op;
+ os << InstructionOperandAsJSON{instr->InputAt(i), i_json.code_};
}
os << "],";
@@ -1157,8 +1158,7 @@ std::ostream& operator<<(std::ostream& os, const InstructionAsJSON& i) {
for (size_t i = 0; i < instr->TempCount(); i++) {
if (need_comma) os << ",";
need_comma = true;
- json_op.op_ = instr->TempAt(i);
- os << json_op;
+ os << InstructionOperandAsJSON{instr->TempAt(i), i_json.code_};
}
os << "]";
os << "}";
@@ -1194,7 +1194,7 @@ std::ostream& operator<<(std::ostream& os, const InstructionBlockAsJSON& b) {
os << "],";
os << "\"phis\": [";
bool needs_comma = false;
- InstructionOperandAsJSON json_op = {b.register_configuration_, nullptr, code};
+ InstructionOperandAsJSON json_op = {nullptr, code};
for (const PhiInstruction* phi : block->phis()) {
if (needs_comma) os << ",";
needs_comma = true;
@@ -1212,7 +1212,7 @@ std::ostream& operator<<(std::ostream& os, const InstructionBlockAsJSON& b) {
os << "],";
os << "\"instructions\": [";
- InstructionAsJSON json_instr = {b.register_configuration_, -1, nullptr, code};
+ InstructionAsJSON json_instr = {-1, nullptr, code};
need_comma = false;
for (int j = block->first_instruction_index();
j <= block->last_instruction_index(); j++) {
@@ -1232,15 +1232,13 @@ std::ostream& operator<<(std::ostream& os, const InstructionSequenceAsJSON& s) {
const InstructionSequence* code = s.sequence_;
os << "\"blocks\": [";
- InstructionBlockAsJSON json_block = {s.register_configuration_, nullptr,
- code};
bool need_comma = false;
for (int i = 0; i < code->InstructionBlockCount(); i++) {
if (need_comma) os << ",";
need_comma = true;
- json_block.block_ = code->InstructionBlockAt(RpoNumber::FromInt(i));
- os << json_block;
+ os << InstructionBlockAsJSON{
+ code->InstructionBlockAt(RpoNumber::FromInt(i)), code};
}
os << "]";