mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 20:44:37 +03:00
Reduced the size of instruction names array by 2kB by merging shorter names into longer names.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,10 @@
|
|||||||
// by a linker to make all pointers the binary application/library uses valid.
|
// by a linker to make all pointers the binary application/library uses valid.
|
||||||
// This approach decreases the final size of AsmJit binary and relocation data.
|
// This approach decreases the final size of AsmJit binary and relocation data.
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
|
var hasOwn = Object.prototype.hasOwnProperty;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// [Utilities]
|
// [Utilities]
|
||||||
@@ -42,73 +45,182 @@ function inject(s, start, end, code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// [Database]
|
// [IndexedString]
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
var Database = (function() {
|
var IndexedString = function() {
|
||||||
// `IndexedString` class.
|
|
||||||
var IndexedString = function() {
|
|
||||||
this.array = [];
|
|
||||||
this.index = 0;
|
|
||||||
this.map = {};
|
this.map = {};
|
||||||
};
|
this.size = -1;
|
||||||
|
this.array = [];
|
||||||
|
};
|
||||||
|
|
||||||
IndexedString.prototype.add = function(s) {
|
IndexedString.prototype.add = function(s) {
|
||||||
var index = this.map[s];
|
this.map[s] = -1;
|
||||||
|
};
|
||||||
|
|
||||||
if (typeof index === "number")
|
IndexedString.prototype.index = function() {
|
||||||
return index;
|
var map = this.map;
|
||||||
|
var array = this.array;
|
||||||
|
|
||||||
index = this.index;
|
var partialMap = {};
|
||||||
this.array.push(s);
|
var k, kp;
|
||||||
this.index += s.length + 1;
|
var i, len;
|
||||||
this.map[s] = index;
|
|
||||||
return index;
|
|
||||||
};
|
|
||||||
|
|
||||||
IndexedString.prototype.get = function(s) {
|
// Create a map that will contain all keys and partial keys.
|
||||||
return this.map[s];
|
for (k in map) {
|
||||||
};
|
if (!k) {
|
||||||
|
partialMap[k] = k;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (i = 0, len = k.length; i < len; i++) {
|
||||||
|
var kp = k.substr(i);
|
||||||
|
if (!hasOwn.call(partialMap, kp) || partialMap[kp].length < len)
|
||||||
|
partialMap[kp] = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an array that will only contain keys that are needed.
|
||||||
|
for (k in map) {
|
||||||
|
if (partialMap[k] === k)
|
||||||
|
array.push(k);
|
||||||
|
}
|
||||||
|
array.sort();
|
||||||
|
|
||||||
|
// Create valid offsets to the `array`.
|
||||||
|
var offMap = {};
|
||||||
|
var offset = 0;
|
||||||
|
|
||||||
|
for (i = 0, len = array.length; i < len; i++) {
|
||||||
|
k = array[i];
|
||||||
|
|
||||||
|
offMap[k] = offset;
|
||||||
|
offset += k.length + 1;
|
||||||
|
}
|
||||||
|
this.size = offset;
|
||||||
|
|
||||||
|
// Assign valid offsets to `map`.
|
||||||
|
for (kp in map) {
|
||||||
|
k = partialMap[kp];
|
||||||
|
map[kp] = offMap[k] + k.length - kp.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
(function() {
|
||||||
|
// Testing code to experiment with eliminating suffixes from instruction names.
|
||||||
|
var suffixList = [
|
||||||
|
"ss", "ps", "sd", "pd",
|
||||||
|
"bw", "bd", "bq",
|
||||||
|
"ww", "wd", "wq",
|
||||||
|
"dq", "b", "w", "d", "q"
|
||||||
|
];
|
||||||
|
var reducedMap = {};
|
||||||
|
var reducedSize = 0;
|
||||||
|
|
||||||
|
var xMap = {};
|
||||||
|
var xArr = [];
|
||||||
|
|
||||||
|
for (i = 0, len = array.length; i < len; i++) {
|
||||||
|
k = array[i];
|
||||||
|
|
||||||
|
var suffix = null;
|
||||||
|
var after = k;
|
||||||
|
|
||||||
|
for (var j = 0; j < suffixList.length; j++) {
|
||||||
|
suffix = suffixList[j];
|
||||||
|
if (k.lastIndexOf(suffix) === k.length - suffix.length) {
|
||||||
|
after = k.substr(0, k.length - suffix.length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reducedMap[after] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing code to get which suffixes are the most used.
|
||||||
|
for (k in map) {
|
||||||
|
for (i = 1; i < k.length; i++) {
|
||||||
|
var xKey = k.substr(i);
|
||||||
|
if (hasOwn.call(xMap, xKey)) {
|
||||||
|
xMap[xKey]++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xMap[xKey] = 1;
|
||||||
|
xArr.push(xKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xArr.sort(function(a, b) {
|
||||||
|
return xMap[a] - xMap[b];
|
||||||
|
});
|
||||||
|
for (i = 0; i < xArr.length; i++) {
|
||||||
|
console.log(xArr[i] + " " + xMap[xArr[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k in reducedMap)
|
||||||
|
reducedSize += k.length + 1;
|
||||||
|
console.log("ReducedSize=" + reducedSize);
|
||||||
|
})();
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
IndexedString.prototype.format = function(indent) {
|
||||||
|
if (this.size === -1)
|
||||||
|
throw new Error("IndexedString not indexed yet, call index()");
|
||||||
|
|
||||||
IndexedString.prototype.format = function(indent) {
|
|
||||||
var s = "";
|
var s = "";
|
||||||
var array = this.array;
|
var array = this.array;
|
||||||
|
|
||||||
for (var i = 0; i < array.length; i++) {
|
for (var i = 0; i < array.length; i++) {
|
||||||
s += indent + "\"" + array[i] + "\\0\"";
|
s += indent + "\"" + array[i];
|
||||||
if (i === array.length - 1)
|
s += (i !== array.length - 1) ? "\\0\"" : "\";";
|
||||||
s += ";";
|
|
||||||
s += "\n";
|
s += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
};
|
};
|
||||||
|
|
||||||
IndexedString.prototype.getSize = function() {
|
IndexedString.prototype.getSize = function() {
|
||||||
return this.index;
|
if (this.size === -1)
|
||||||
};
|
throw new Error("IndexedString not indexed yet, call index()");
|
||||||
|
return this.size;
|
||||||
|
};
|
||||||
|
|
||||||
// `Database` class.
|
IndexedString.prototype.getIndex = function(k) {
|
||||||
var Database = function() {
|
if (this.size === -1)
|
||||||
|
throw new Error("IndexedString not indexed yet, call index()");
|
||||||
|
|
||||||
|
if (!hasOwn.call(this.map, k))
|
||||||
|
throw new Error("Key '" + k + "' not found in IndexedString.");
|
||||||
|
|
||||||
|
return this.map[k];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// [Database]
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
var Database = function() {
|
||||||
this.instMap = {};
|
this.instMap = {};
|
||||||
this.instNames = new IndexedString();
|
this.instNames = new IndexedString();
|
||||||
this.instAlpha = new Array(26);
|
this.instAlpha = new Array(26);
|
||||||
|
|
||||||
this.extendedData = [];
|
this.extendedData = [];
|
||||||
this.extendedMap = {};
|
this.extendedMap = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
Database.prototype.add = function(name, id, extendedData) {
|
Database.prototype.add = function(name, id, extendedData) {
|
||||||
this.instMap[name] = {
|
this.instMap[name] = {
|
||||||
id : id, // Instruction ID.
|
id : id, // Instruction ID.
|
||||||
nameIndex : 0, // Instruction name-index, used directly by AsmJit.
|
nameIndex : -1, // Instruction name-index.
|
||||||
vPrefix : 0, // Instruction starts with 'v', not used at this point.
|
|
||||||
extendedData : extendedData,
|
extendedData : extendedData,
|
||||||
extendedIndex : ""
|
extendedIndex : ""
|
||||||
};
|
};
|
||||||
};
|
this.instNames.add(name);
|
||||||
|
};
|
||||||
|
|
||||||
Database.prototype.index = function() {
|
Database.prototype.index = function() {
|
||||||
var instMap = this.instMap;
|
var instMap = this.instMap;
|
||||||
var instNames = this.instNames;
|
var instNames = this.instNames;
|
||||||
var instAlpha = this.instAlpha;
|
var instAlpha = this.instAlpha;
|
||||||
@@ -116,10 +228,12 @@ var Database = (function() {
|
|||||||
var extendedData = this.extendedData;
|
var extendedData = this.extendedData;
|
||||||
var extendedMap = this.extendedMap;
|
var extendedMap = this.extendedMap;
|
||||||
|
|
||||||
|
instNames.index();
|
||||||
|
|
||||||
for (var name in instMap) {
|
for (var name in instMap) {
|
||||||
var inst = instMap[name];
|
var inst = instMap[name];
|
||||||
|
|
||||||
var nameIndex = instNames.add(name);
|
var nameIndex = instNames.getIndex(name);
|
||||||
var extendedIndex = extendedMap[inst.extendedData];
|
var extendedIndex = extendedMap[inst.extendedData];
|
||||||
|
|
||||||
if (typeof extendedIndex !== "number") {
|
if (typeof extendedIndex !== "number") {
|
||||||
@@ -137,15 +251,8 @@ var Database = (function() {
|
|||||||
|
|
||||||
if (instAlpha[aIndex] === undefined)
|
if (instAlpha[aIndex] === undefined)
|
||||||
instAlpha[aIndex] = inst.id;
|
instAlpha[aIndex] = inst.id;
|
||||||
|
|
||||||
if (name.indexOf("v") === 0) {
|
|
||||||
inst.vPrefix = 1;
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
return Database;
|
|
||||||
})();
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// [Generate]
|
// [Generate]
|
||||||
@@ -271,15 +378,11 @@ var generate = function(fileName, arch) {
|
|||||||
code += disclaimer;
|
code += disclaimer;
|
||||||
code += "#if !defined(ASMJIT_DISABLE_NAMES)\n";
|
code += "#if !defined(ASMJIT_DISABLE_NAMES)\n";
|
||||||
code += "const char _" + arch + "InstName[] =\n";
|
code += "const char _" + arch + "InstName[] =\n";
|
||||||
for (k in db.instMap) {
|
code += db.instNames.format(" ") + "\n";
|
||||||
var inst = db.instMap[k];
|
|
||||||
code += " \"" + k + "\\0\"\n";
|
|
||||||
}
|
|
||||||
code = code.substr(code, code.length - 1) + ";\n\n";
|
|
||||||
|
|
||||||
// Generate AlphaIndex.
|
// Generate AlphaIndex.
|
||||||
code += disclaimer;
|
code += disclaimer;
|
||||||
code += "enum k" + Arch + "InstAlphaIndex {\n";
|
code += "enum " + Arch + "InstAlphaIndex {\n";
|
||||||
code += " k" + Arch + "InstAlphaIndexFirst = 'a',\n";
|
code += " k" + Arch + "InstAlphaIndexFirst = 'a',\n";
|
||||||
code += " k" + Arch + "InstAlphaIndexLast = 'z',\n";
|
code += " k" + Arch + "InstAlphaIndexLast = 'z',\n";
|
||||||
code += " k" + Arch + "InstAlphaIndexInvalid = 0xFFFF\n";
|
code += " k" + Arch + "InstAlphaIndexInvalid = 0xFFFF\n";
|
||||||
@@ -299,7 +402,7 @@ var generate = function(fileName, arch) {
|
|||||||
|
|
||||||
// Generate NameIndex.
|
// Generate NameIndex.
|
||||||
code += disclaimer;
|
code += disclaimer;
|
||||||
code += "enum k" + Arch + "InstData_NameIndex {\n";
|
code += "enum " + Arch + "InstData_NameIndex {\n";
|
||||||
for (k in db.instMap) {
|
for (k in db.instMap) {
|
||||||
var inst = db.instMap[k];
|
var inst = db.instMap[k];
|
||||||
code += " " + inst.id + "_NameIndex = " + inst.nameIndex + ",\n";
|
code += " " + inst.id + "_NameIndex = " + inst.nameIndex + ",\n";
|
||||||
@@ -321,7 +424,7 @@ var generate = function(fileName, arch) {
|
|||||||
code += "\n";
|
code += "\n";
|
||||||
|
|
||||||
code += disclaimer;
|
code += disclaimer;
|
||||||
code += "enum k" + Arch + "InstData_ExtendedIndex {\n";
|
code += "enum " + Arch + "InstData_ExtendedIndex {\n";
|
||||||
for (k in db.instMap) {
|
for (k in db.instMap) {
|
||||||
var inst = db.instMap[k];
|
var inst = db.instMap[k];
|
||||||
code += " " + inst.id + "_ExtendedIndex = " + inst.extendedIndex + ",\n";
|
code += " " + inst.id + "_ExtendedIndex = " + inst.extendedIndex + ",\n";
|
||||||
|
|||||||
Reference in New Issue
Block a user