A.Olokhtonov
5 months ago
commit
432fd08944
6 changed files with 238 additions and 0 deletions
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
html, body { |
||||
margin: 0; |
||||
padding: 0; |
||||
width: 100%; |
||||
height: 100%; |
||||
overflow: hidden; |
||||
} |
||||
|
||||
body .main { |
||||
height: 100%; |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<meta charset="utf-8"> |
||||
<title>Nitka</title> |
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> |
||||
|
||||
<link rel="shortcut icon" href="icons/favicon.svg" id="favicon"> |
||||
<link rel="stylesheet" type="text/css" href="default.css"> |
||||
|
||||
<!-- <link rel="preload" href="icons/picker.svg" as="image" type="image/svg+xml" /> --> |
||||
|
||||
<script type="text/javascript" src="index.js"></script> |
||||
<script type="text/javascript" src="parse.js"></script> |
||||
<script type="text/javascript" src="render.js"></script> |
||||
<script type="text/javascript" src="input.js"></script> |
||||
</head> |
||||
<body> |
||||
<div class="main"> |
||||
</div> |
||||
</body> |
||||
</html> |
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
document.addEventListener('DOMContentLoaded', main); |
||||
|
||||
function main() { |
||||
init_listeners(); |
||||
} |
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
function init_listeners() { |
||||
document.querySelector('.main').addEventListener('dragover', cancel); |
||||
document.querySelector('.main').addEventListener('drop', drop); |
||||
} |
||||
|
||||
function cancel(e) { |
||||
e.preventDefault(); |
||||
e.stopPropagation(); |
||||
} |
||||
|
||||
function drop(e) { |
||||
e.preventDefault(); |
||||
|
||||
if (e.dataTransfer.files.length !== 1) { |
||||
console.error('Only one file at once, please!'); |
||||
return false; |
||||
} |
||||
|
||||
const file = e.dataTransfer.files[0]; |
||||
const fr = new FileReader(); |
||||
|
||||
const upload_failed = () => { |
||||
console.error('Upload failed'); |
||||
}; |
||||
|
||||
const upload_started = () => { |
||||
console.log('Upload started'); |
||||
}; |
||||
|
||||
const upload_finished = () => { |
||||
const text = fr.result; |
||||
console.log('Finished. String length:', text.length); |
||||
parse(text); |
||||
}; |
||||
|
||||
const upload_progress = (e) => { |
||||
if (e.lengthComputable) { |
||||
const percent = Math.floor(e.loaded / e.total * 100); |
||||
console.log(`Progress: ${percent}%`); |
||||
} else { |
||||
console.log('Progress: unknown'); |
||||
} |
||||
}; |
||||
|
||||
fr.addEventListener('abort', upload_failed); |
||||
fr.addEventListener('error', upload_failed); |
||||
fr.addEventListener('load', upload_finished); |
||||
fr.addEventListener('loadstart', upload_started); |
||||
fr.addEventListener('progress', upload_progress); |
||||
|
||||
fr.readAsText(file); |
||||
} |
@ -0,0 +1,147 @@
@@ -0,0 +1,147 @@
|
||||
function parse(text) { |
||||
// https://github.com/shioyadan/Konata/blob/master/docs/kanata-log-format.md
|
||||
|
||||
const before = performance.now(); |
||||
|
||||
let line_start = 0; |
||||
let line_index = 0; |
||||
|
||||
//console.log(text);
|
||||
|
||||
for (let i = 0; i < text.length; ++i) { |
||||
const c = text[i]; |
||||
|
||||
if (c === '\n') { |
||||
// TODO: speed
|
||||
const line_copy = text.substring(line_start, i); |
||||
const line_parts = line_copy.split(/\s+/); |
||||
|
||||
if (line_parts.length === 0) { |
||||
console.error('Parser error: empty line'); |
||||
return false; |
||||
} |
||||
|
||||
const command = line_parts[0]; |
||||
switch (command) { |
||||
case 'Kanata': { |
||||
if (!assert_arglen(line_parts, 1, 'Kanata')) return false; |
||||
|
||||
const version = Number(line_parts[1]); |
||||
if (version !== 4) { |
||||
console.error('Parser error: only Kanata traces version 4 are supported'); |
||||
return false; |
||||
} |
||||
|
||||
break; |
||||
} |
||||
|
||||
case 'C=': { |
||||
if (!assert_arglen(line_parts, 1, 'C=')) return false; |
||||
|
||||
const cycles = Number(line_parts[1]); |
||||
|
||||
break; |
||||
} |
||||
|
||||
case 'C': { |
||||
if (!assert_arglen(line_parts, 1, 'C')) return false; |
||||
|
||||
const cycles = Number(line_parts[1]); |
||||
|
||||
break; |
||||
} |
||||
|
||||
case 'I': { |
||||
if (!assert_arglen(line_parts, 3, 'I')) return false; |
||||
|
||||
const insn_id_in_file = Number(line_parts[1]); |
||||
const insn_id_in_sim = Number(line_parts[2]); |
||||
const thread_id = Number(line_parts[3]); |
||||
|
||||
break; |
||||
} |
||||
|
||||
case 'L': { |
||||
if (!assert_arglenmin(line_parts, 3, 'L')) return false; |
||||
|
||||
const id = Number(line_parts[1]); |
||||
const type = Number(line_parts[2]); |
||||
const text = line_parts.slice(3).join(' '); // TODO: preserve spacing, newlines
|
||||
|
||||
break; |
||||
} |
||||
|
||||
case 'S': { |
||||
if (!assert_arglen(line_parts, 3, 'S')) return false; |
||||
|
||||
const id = Number(line_parts[1]); |
||||
const lane = Number(line_parts[2]); |
||||
const stage = line_parts[3]; |
||||
|
||||
break; |
||||
} |
||||
|
||||
case 'E': { |
||||
if (!assert_arglen(line_parts, 3, 'E')) return false; |
||||
|
||||
const id = Number(line_parts[1]); |
||||
const lane = Number(line_parts[2]); |
||||
const stage = line_parts[3]; |
||||
|
||||
break; |
||||
} |
||||
|
||||
case 'R': { |
||||
if (!assert_arglen(line_parts, 3, 'R')) return false; |
||||
|
||||
const id = Number(line_parts[1]); |
||||
const retire_id = Number(line_parts[2]); |
||||
const type = Number(line_parts[3]); |
||||
|
||||
break; |
||||
} |
||||
|
||||
case 'W': { |
||||
if (!assert_arglen(line_parts, 3, 'W')) return false; |
||||
|
||||
const consumer_id = Number(line_parts[1]); |
||||
const producer_id = Number(line_parts[2]); |
||||
const type = Number(line_parts[3]); |
||||
|
||||
break; |
||||
} |
||||
|
||||
default: { |
||||
console.error('Parser error: unexpected command', command); |
||||
return false; |
||||
} |
||||
} |
||||
//console.log(command);
|
||||
|
||||
line_start = i + 1; |
||||
line_index += 1; |
||||
} |
||||
} |
||||
|
||||
const after = performance.now(); |
||||
|
||||
console.log(`Parsed in ${Math.round(after - before)}ms`); |
||||
} |
||||
|
||||
function assert_arglen(args, arglen, command) { |
||||
if (args.length !== arglen + 1) { |
||||
console.error(`Parser error: command ${command} requires ${arglen} argument(s)`); |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
function assert_arglenmin(args, arglen, command) { |
||||
if (args.length < arglen + 1) { |
||||
console.error(`Parser error: command ${command} requires at least ${arglen} argument(s)`); |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
Loading…
Reference in new issue