From caf0d5b33426bfd43d6b37738f884e58205af146 Mon Sep 17 00:00:00 2001 From: Ryota Shioya Date: Wed, 14 Aug 2019 21:47:47 +0900 Subject: [PATCH] Add an X86-Gem5 mode for stats --- konata.js | 25 ++++++++++++++++++--- stats.js | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/konata.js b/konata.js index 040264c..6e12c6a 100644 --- a/konata.js +++ b/konata.js @@ -1,6 +1,6 @@ // JSDoc のタイプチェックに型を認識させるため let Op = require("./op").Op; // eslint-disable-line -let Stats = require("./stats").GenericStats; // eslint-disable-line +let CreateStats = require("./stats").CreateStats; // eslint-disable-line class Konata{ constructor(){ @@ -119,12 +119,14 @@ class Konata{ } // パイプライン中の統計を計算し,終わったら finish に渡す - async stats(update, finish){ + async statsBody_(update, finish, statsList){ let lastID = this.lastID; - let stats = new Stats(this); let sleepTimer = 0; let SLEEP_INTERVAL = 50000; + let GIVE_UP_TIME = 1000; + + let stats = statsList.shift(); for (let i = 0; i < lastID; i++) { let op = this.getOp(i); @@ -133,6 +135,12 @@ class Konata{ } stats.update(op); + if (!stats.isDetected && i > GIVE_UP_TIME) { + console.log(`Gave up analyzing this file (${stats.name})`); + this.statsBody_(update, finish, statsList); + return; + } + // 一定時間毎に setTimeout でその他の処理への切り替えを入れる if (sleepTimer > SLEEP_INTERVAL) { sleepTimer = 0; @@ -145,9 +153,20 @@ class Konata{ sleepTimer++; } + if (!stats.isDetected) { + console.log(`Gave up analyzing this file (${stats.name})`); + this.statsBody_(update, finish, statsList); + return; + } + + console.log(`Finished stats processing ('${stats.name}')`); stats.finish(); finish(stats.stats); } + async stats(update, finish){ + let statsList = CreateStats(this); + this.statsBody_(update, finish, statsList); + } } diff --git a/stats.js b/stats.js index 9d1c7b1..c74c8b4 100644 --- a/stats.js +++ b/stats.js @@ -48,6 +48,12 @@ class GenericStats{ this.inBrFlush_ = false; this.inJumpFlush_ = false; this.inMemFlush_ = false; + + this.isDetected_ = true; // 常に true + } + + get name(){ + return "GenericStats"; } get stats() {return this.stats_;} @@ -153,6 +159,64 @@ class GenericStats{ isStore_(text){ return text.match(/[\s](st)|(sw)|(sh)|(sb)[^\s]*[\s]*/); } + + get isDetected() {return this.isDetected_;} +} + +class X86_Gem5_Stats extends GenericStats{ + /** @param {Konata} konata */ + constructor(konata){ + super(konata); + this.isDetected_ = false; + } + + get name(){ + return "X86_Gem5_Stats"; + } + + update(op){ + super.update(op); + + if (!this.isDetected_ ) { + let text = op.labelName; + if (text.match(/[eErR][aAbBcCdD][xX][^,]*,[^,]*[eErR][aAbBcCdD][xX]/)) { + this.isDetected_ = true; + } + if (text.match(/[xXyY][mM][mM][^,]*,[^,]*[xXyY][mM][mM]/)) { + this.isDetected_ = true; + } + if (this.isDetected_) { + console.log(`Detected X86-Gem5 from '${text}' in X86_Gem5_Stats`); + } + } + } + + + // J で始まり JMP ではなく,wrip に分解される命令は条件分岐 + isBranch_(text){ + return text.match(/[\s]*[jJ][^mM][^:]+:\s*wrip/); + } + + // jmX, call, ret で wrip はジャンプ + isJump_(text){ + return text.match(/([\s]*([jJ][mM])|([cC][aA][lL][lL])|([rR][eE][tT]))[^:]+:\s*wrip/); + } + + // : st はストア + isStore_(text){ + return text.match(/[\s]*[^:]+:\s*st/); + } +} + +/** + * @param {Konata} konata + * @returns {GenericStats[]} */ +function CreateStats(konata){ + return [ + new X86_Gem5_Stats(konata), + new GenericStats(konata), + ]; } -module.exports.GenericStats = GenericStats; +//module.exports.GenericStats = GenericStats; +module.exports.CreateStats = CreateStats;