aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-10-18 16:14:17 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-10-18 17:31:20 -0700
commit5a09572550870a5304b0a5d2e425e3f579cd1ed2 (patch)
treed549422beb58aedd749efc6992b16197df14dbd5
parent8f14b5c6400133e88c89060ce978114b2455d667 (diff)
avoid allocating huge lists for [BIGNUM x type] types
-rw-r--r--src/analyzer.js7
-rw-r--r--src/jsifier.js2
-rw-r--r--src/parseTools.js11
-rw-r--r--src/runtime.js5
4 files changed, 17 insertions, 8 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 43730755..2f6581b4 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -966,11 +966,10 @@ function analyzer(data, sidePass) {
var subType = check[2];
addTypeInternal(subType); // needed for anonymous structure definitions (see below)
- // Huge structural types are represented very inefficiently, both here and in generated JS. Best to avoid them - for example static char x[10*1024*1024]; is bad, while static char *x = malloc(10*1024*1024) is fine.
- if (num >= 10*1024*1024) warnOnce('warning: very large fixed-size structural type: ' + type + ' - can you reduce it? (compilation may be slow)');
+ var fields = [subType, subType]; // Two, so we get the flatFactor right. We care about the flatFactor, not the size here. see calculateStructAlignment
Types.types[nonPointing] = {
name_: nonPointing,
- fields: range(num).map(function() { return subType }),
+ fields: fields,
lineNum: '?'
};
newTypes[nonPointing] = 1;
@@ -979,7 +978,7 @@ function analyzer(data, sidePass) {
if (!Types.types[zerod]) {
Types.types[zerod] = {
name_: zerod,
- fields: [subType, subType], // Two, so we get the flatFactor right. We care about the flatFactor, not the size here
+ fields: fields,
lineNum: '?'
};
newTypes[zerod] = 1;
diff --git a/src/jsifier.js b/src/jsifier.js
index 70139d89..6da2b09f 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -153,7 +153,7 @@ function JSify(data, functionsOnly, givenFunctions) {
}
// Add current value(s)
var currValue = values[i];
- if (USE_TYPED_ARRAYS == 2 && typeData.fields[i] == 'i64') {
+ if (USE_TYPED_ARRAYS == 2 && (typeData.fields[i] == 'i64' || (typeData.flatFactor && typeData.fields[0] == 'i64'))) {
// 'flatten' out the 64-bit value into two 32-bit halves
var parts = parseI64Constant(currValue, true);
ret[index++] = parts[0];
diff --git a/src/parseTools.js b/src/parseTools.js
index bc5b3870..dae386f1 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1033,9 +1033,11 @@ function generateStructTypes(type) {
var ret = new Array(size);
var index = 0;
function add(typeData) {
+ var array = typeData.name_[0] === '['; // arrays just have 2 elements in their fields, see calculateStructAlignment
+ var num = array ? parseInt(typeData.name_.substr(1)) : typeData.fields.length;
var start = index;
- for (var i = 0; i < typeData.fields.length; i++) {
- var type = typeData.fields[i];
+ for (var i = 0; i < num; i++) {
+ var type = array ? typeData.fields[0] : typeData.fields[i];
if (!SAFE_HEAP && isPointerType(type)) type = '*'; // do not include unneeded type names without safe heap
if (Runtime.isNumberType(type) || isPointerType(type)) {
if (USE_TYPED_ARRAYS == 2 && type == 'i64') {
@@ -1058,7 +1060,10 @@ function generateStructTypes(type) {
}
add(Types.types[type]);
}
- var more = (i+1 < typeData.fields.length ? typeData.flatIndexes[i+1] : typeData.flatSize) - (index - start);
+ var more = array ? (i+1)*typeData.flatSize/num : (
+ (i+1 < typeData.fields.length ? typeData.flatIndexes[i+1] : typeData.flatSize)
+ );
+ more -= index - start;
for (var j = 0; j < more; j++) {
ret[index++] = 0;
}
diff --git a/src/runtime.js b/src/runtime.js
index 6839f556..fa127fe7 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -238,6 +238,11 @@ var Runtime = {
prev = curr;
return curr;
});
+ if (type.name_[0] === '[') {
+ // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
+ // allocating a potentially huge array for [999999 x i8] etc.
+ type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
+ }
type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
if (diffs.length == 0) {
type.flatFactor = type.flatSize;