[profview] Distinguish between parse/opt/unopt compile
Rather than lumping in parsing, bytecode compilation and optimized compilation all into the same VM "compile" state, seperate them out into individual states. Additionally, add support for these states to tickprocessor and profview. Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Change-Id: I5be943e23cae042e32e9ccb24415c67c18658b4b Reviewed-on: https://chromium-review.googlesource.com/608973 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Reviewed-by: Marja Hölttä <marja@chromium.org> Cr-Commit-Position: refs/heads/master@{#47283}
This commit is contained in:
parent
c35c54bb20
commit
dadbde038d
11
include/v8.h
11
include/v8.h
@ -1721,7 +1721,16 @@ class V8_EXPORT StackFrame {
|
||||
|
||||
|
||||
// A StateTag represents a possible state of the VM.
|
||||
enum StateTag { JS, GC, COMPILER, OTHER, EXTERNAL, IDLE };
|
||||
enum StateTag {
|
||||
JS,
|
||||
GC,
|
||||
PARSER,
|
||||
BYTECODE_COMPILER,
|
||||
COMPILER,
|
||||
OTHER,
|
||||
EXTERNAL,
|
||||
IDLE
|
||||
};
|
||||
|
||||
// A RegisterState represents the current state of registers used
|
||||
// by the sampling profiler API.
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/parsing/parser.h"
|
||||
#include "src/vm-state-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -26,6 +27,8 @@ BackgroundParsingTask::BackgroundParsingTask(
|
||||
options == ScriptCompiler::kProduceCodeCache ||
|
||||
options == ScriptCompiler::kNoCompileOptions);
|
||||
|
||||
VMState<PARSER> state(isolate);
|
||||
|
||||
// Prepare the data for the internalization phase and compilation phase, which
|
||||
// will happen in the main thread after parsing.
|
||||
ParseInfo* info = new ParseInfo(isolate->allocator());
|
||||
|
@ -498,7 +498,7 @@ MUST_USE_RESULT MaybeHandle<Code> CompileUnoptimizedFunction(
|
||||
Handle<SharedFunctionInfo> shared_info) {
|
||||
RuntimeCallTimerScope runtimeTimer(
|
||||
isolate, &RuntimeCallStats::CompileUnoptimizedFunction);
|
||||
VMState<COMPILER> state(isolate);
|
||||
VMState<BYTECODE_COMPILER> state(isolate);
|
||||
PostponeInterruptsScope postpone(isolate);
|
||||
|
||||
// Parse and update ParseInfo with the results.
|
||||
@ -896,7 +896,7 @@ Handle<SharedFunctionInfo> CompileToplevel(
|
||||
Handle<SharedFunctionInfo> result;
|
||||
|
||||
{
|
||||
VMState<COMPILER> state(isolate);
|
||||
VMState<BYTECODE_COMPILER> state(isolate);
|
||||
if (parse_info->literal() == nullptr &&
|
||||
!parsing::ParseProgram(parse_info, isolate)) {
|
||||
return Handle<SharedFunctionInfo>::null();
|
||||
@ -1508,7 +1508,7 @@ MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
|
||||
|
||||
CompilationJob* Compiler::PrepareUnoptimizedCompilationJob(
|
||||
ParseInfo* parse_info, Isolate* isolate) {
|
||||
VMState<COMPILER> state(isolate);
|
||||
VMState<BYTECODE_COMPILER> state(isolate);
|
||||
std::unique_ptr<CompilationJob> job(
|
||||
interpreter::Interpreter::NewCompilationJob(
|
||||
parse_info, parse_info->literal(), isolate));
|
||||
@ -1522,11 +1522,12 @@ bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) {
|
||||
// Take ownership of compilation job. Deleting job also tears down the zone.
|
||||
std::unique_ptr<CompilationJob> job(raw_job);
|
||||
|
||||
VMState<COMPILER> state(job->compilation_info()->isolate());
|
||||
if (job->compilation_info()->IsOptimizing()) {
|
||||
VMState<COMPILER> state(job->compilation_info()->isolate());
|
||||
return FinalizeOptimizedCompilationJob(job.get()) ==
|
||||
CompilationJob::SUCCEEDED;
|
||||
} else {
|
||||
VMState<BYTECODE_COMPILER> state(job->compilation_info()->isolate());
|
||||
return FinalizeUnoptimizedCompilationJob(job.get()) ==
|
||||
CompilationJob::SUCCEEDED;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/parsing/parse-info.h"
|
||||
#include "src/parsing/parser.h"
|
||||
#include "src/vm-state-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -19,6 +20,8 @@ bool ParseProgram(ParseInfo* info, Isolate* isolate) {
|
||||
DCHECK(info->is_toplevel());
|
||||
DCHECK_NULL(info->literal());
|
||||
|
||||
VMState<PARSER> state(isolate);
|
||||
|
||||
Parser parser(info);
|
||||
|
||||
FunctionLiteral* result = nullptr;
|
||||
@ -44,6 +47,8 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
|
||||
DCHECK(!shared_info.is_null());
|
||||
DCHECK_NULL(info->literal());
|
||||
|
||||
VMState<PARSER> state(isolate);
|
||||
|
||||
Parser parser(info);
|
||||
|
||||
FunctionLiteral* result = nullptr;
|
||||
|
@ -173,9 +173,15 @@ SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::AddStack() {
|
||||
case GC:
|
||||
name = "(GC)";
|
||||
break;
|
||||
case PARSER:
|
||||
name = "(PARSER)";
|
||||
break;
|
||||
case COMPILER:
|
||||
name = "(COMPILER)";
|
||||
break;
|
||||
case BYTECODE_COMPILER:
|
||||
name = "(BYTECODE_COMPILER)";
|
||||
break;
|
||||
case OTHER:
|
||||
name = "(V8 API)";
|
||||
break;
|
||||
|
@ -24,6 +24,10 @@ inline const char* StateToString(StateTag state) {
|
||||
return "JS";
|
||||
case GC:
|
||||
return "GC";
|
||||
case PARSER:
|
||||
return "PARSER";
|
||||
case BYTECODE_COMPILER:
|
||||
return "BYTECODE_COMPILER";
|
||||
case COMPILER:
|
||||
return "COMPILER";
|
||||
case OTHER:
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
let codeKinds = [
|
||||
"UNKNOWN",
|
||||
"CPPPARSE",
|
||||
"CPPCOMPBC",
|
||||
"CPPCOMP",
|
||||
"CPPGC",
|
||||
"CPPEXT",
|
||||
@ -64,8 +66,12 @@ function resolveCodeKindAndVmState(code, vmState) {
|
||||
if (vmState === 1) {
|
||||
kind = "CPPGC";
|
||||
} else if (vmState === 2) {
|
||||
kind = "CPPCOMP";
|
||||
kind = "CPPPARSE";
|
||||
} else if (vmState === 3) {
|
||||
kind = "CPPCOMPBC";
|
||||
} else if (vmState === 4) {
|
||||
kind = "CPPCOMP";
|
||||
} else if (vmState === 6) {
|
||||
kind = "CPPEXT";
|
||||
}
|
||||
}
|
||||
@ -85,10 +91,10 @@ function codeEquals(code1, code2, allowDifferentKinds = false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function createNodeFromStackEntry(code, codeId) {
|
||||
function createNodeFromStackEntry(code, codeId, vmState) {
|
||||
let name = code ? code.name : "UNKNOWN";
|
||||
|
||||
return { name, codeId, type : resolveCodeKind(code),
|
||||
return { name, codeId, type : resolveCodeKindAndVmState(code, vmState),
|
||||
children : [], ownTicks : 0, ticks : 0 };
|
||||
}
|
||||
|
||||
@ -143,6 +149,7 @@ function findNextFrame(file, stack, stackPos, step, filter) {
|
||||
|
||||
function addOrUpdateChildNode(parent, file, stackIndex, stackPos, ascending) {
|
||||
let stack = file.ticks[stackIndex].s;
|
||||
let vmState = file.ticks[stackIndex].vm;
|
||||
let codeId = stack[stackPos];
|
||||
let code = codeId >= 0 ? file.code[codeId] : undefined;
|
||||
if (stackPos === -1) {
|
||||
@ -157,7 +164,7 @@ function addOrUpdateChildNode(parent, file, stackIndex, stackPos, ascending) {
|
||||
let childId = childIdFromCode(codeId, code);
|
||||
let child = parent.children[childId];
|
||||
if (!child) {
|
||||
child = createNodeFromStackEntry(code, codeId);
|
||||
child = createNodeFromStackEntry(code, codeId, vmState);
|
||||
child.delayedExpansion = { frameList : [], ascending };
|
||||
parent.children[childId] = child;
|
||||
}
|
||||
@ -261,6 +268,8 @@ function buildCategoryTreeAndLookup() {
|
||||
addCategory("Other generated", [ "STUB", "BUILTIN" ]);
|
||||
addCategory("C++", [ "CPP", "LIB" ]);
|
||||
addCategory("C++/GC", [ "CPPGC" ]);
|
||||
addCategory("C++/Parser", [ "CPPPARSE" ]);
|
||||
addCategory("C++/Bytecode compiler", [ "CPPCOMPBC" ]);
|
||||
addCategory("C++/Compiler", [ "CPPCOMP" ]);
|
||||
addCategory("C++/External", [ "CPPEXT" ]);
|
||||
addCategory("Unknown", [ "UNKNOWN" ]);
|
||||
@ -345,7 +354,7 @@ class FunctionListTree {
|
||||
}
|
||||
child = tree.children[childId];
|
||||
if (!child) {
|
||||
child = createNodeFromStackEntry(code, codeId);
|
||||
child = createNodeFromStackEntry(code, codeId, vmState);
|
||||
child.children[0] = createEmptyNode("Top-down tree");
|
||||
child.children[0].delayedExpansion =
|
||||
{ frameList : [], ascending : false };
|
||||
|
@ -213,6 +213,14 @@ let bucketDescriptors =
|
||||
color : "#8080ff",
|
||||
backgroundColor : "#e0e0ff",
|
||||
text : "C++/external" },
|
||||
{ kinds : [ "CPPPARSE" ],
|
||||
color : "#b890f7",
|
||||
backgroundColor : "#ebdeff",
|
||||
text : "C++/Parser" },
|
||||
{ kinds : [ "CPPCOMPBC" ],
|
||||
color : "#52b0ce",
|
||||
backgroundColor : "#a5c8d4",
|
||||
text : "C++/Bytecode compiler" },
|
||||
{ kinds : [ "CPPCOMP" ],
|
||||
color : "#00ffff",
|
||||
backgroundColor : "#c0ffff",
|
||||
@ -251,6 +259,10 @@ function codeTypeToText(type) {
|
||||
switch (type) {
|
||||
case "UNKNOWN":
|
||||
return "Unknown";
|
||||
case "CPPPARSE":
|
||||
return "C++ (parser)";
|
||||
case "CPPCOMPBC":
|
||||
return "C++ (bytecode compiler)";
|
||||
case "CPPCOMP":
|
||||
return "C++ (compiler)";
|
||||
case "CPPGC":
|
||||
|
@ -216,10 +216,12 @@ inherits(TickProcessor, LogReader);
|
||||
TickProcessor.VmStates = {
|
||||
JS: 0,
|
||||
GC: 1,
|
||||
COMPILER: 2,
|
||||
OTHER: 3,
|
||||
EXTERNAL: 4,
|
||||
IDLE: 5
|
||||
PARSER: 2,
|
||||
BYTECODE_COMPILER: 3,
|
||||
COMPILER: 4,
|
||||
OTHER: 5,
|
||||
EXTERNAL: 6,
|
||||
IDLE: 7,
|
||||
};
|
||||
|
||||
|
||||
@ -853,6 +855,10 @@ function ArgumentsProcessor(args) {
|
||||
'Show only ticks from JS VM state'],
|
||||
'-g': ['stateFilter', TickProcessor.VmStates.GC,
|
||||
'Show only ticks from GC VM state'],
|
||||
'-p': ['stateFilter', TickProcessor.VmStates.PARSER,
|
||||
'Show only ticks from PARSER VM state'],
|
||||
'-b': ['stateFilter', TickProcessor.VmStates.BYTECODE_COMPILER,
|
||||
'Show only ticks from BYTECODE_COMPILER VM state'],
|
||||
'-c': ['stateFilter', TickProcessor.VmStates.COMPILER,
|
||||
'Show only ticks from COMPILER VM state'],
|
||||
'-o': ['stateFilter', TickProcessor.VmStates.OTHER,
|
||||
|
Loading…
Reference in New Issue
Block a user