aboutsummaryrefslogtreecommitdiff
path: root/src/experimental
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-05-05 12:04:03 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-05-05 12:04:03 -0700
commit04b9ead6af75bdb4ede91dd7f7be6895df92371c (patch)
tree50a1186be21ff3747aec84846f08eb3fcac912d6 /src/experimental
parent11f749648a1246af4be025e94d17bea6e6e62b2c (diff)
string cache diff
Diffstat (limited to 'src/experimental')
-rw-r--r--src/experimental/stringCache.diff147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/experimental/stringCache.diff b/src/experimental/stringCache.diff
new file mode 100644
index 00000000..26cbc68c
--- /dev/null
+++ b/src/experimental/stringCache.diff
@@ -0,0 +1,147 @@
+diff --git a/src/library_gl.js b/src/library_gl.js
+index 7471578..9228964 100644
+--- a/src/library_gl.js
++++ b/src/library_gl.js
+@@ -1256,28 +1256,28 @@ var LibraryGL = {
+
+ setClientAttribute: function(name, size, type, stride, pointer) {
+ var attrib = this.clientAttributes[GL.immediate.ATTRIBUTE_BY_NAME[name]];
+ attrib.size = size;
+ attrib.type = type;
+ attrib.stride = stride;
+ attrib.pointer = pointer;
+- attrib.name = name + size;
++ attrib.name = Runtime.getStringConcat(name, size);
+ },
+
+ // Renderers
+ addRendererComponent: function(component) {
+ if (this.rendererComponents[component]) return;
+ this.rendererComponents[component] = 1;
+- this.renderer += component;
++ this.renderer = Runtime.getStringConcat(this.renderer, component);
+ },
+
+ setRenderer: function(renderer) {
+ var name = renderer;
+ if (GL.currProgram && renderer[0] != 'U') {
+- name = 'UD' + GL.currProgram + '|' + renderer; // user-defined program renderer
++ name = Runtime.getStringConcat(Runtime.getStringConcat('UD', GL.currProgram), Runtime.getStringConcat('|', renderer)); // user-defined program renderer
+ }
+ this.renderer = name;
+ if (this.renderers[name]) return this.renderers[name];
+ this.renderers[name] = this.createRenderer(renderer);
+ return this.renderers[name];
+ },
+
+@@ -1300,15 +1300,18 @@ var LibraryGL = {
+ }
+ vertexSize += size * 4; // XXX assuming float
+ } else if (which == 'N') {
+ vertexSize += 4; // 1 char, + alignment
+ } else if (which == 'C') {
+ vertexSize += 4; // Up to 4 chars, + alignment
+ } else {
+- console.log('Warning: Ignoring renderer attribute ' + which);
++#if ASSERTIONS
++ console.log('Warning: Ignoring renderer attribute');
++ console.log(which);
++#endif
+ size = parseInt(renderer[i+1]);
+ vertexSize += size * 4; // XXX assuming float
+ }
+ }
+ assert(positionSize > 0);
+ // TODO: verify vertexSize is equal to the stride in enabled client arrays
+ var useCurrProgram = !!GL.currProgram;
+@@ -1465,30 +1468,30 @@ var LibraryGL = {
+ var renderer = '', bytes = 0;
+ for (var i = 0; i < attributes.length; i++) {
+ var attribute = attributes[i];
+ if (!attribute) break;
+ attribute.offset = attribute.pointer - start;
+ if (attribute.offset > bytes) { // ensure we start where we should
+ assert((attribute.offset - bytes)%4 == 0); // XXX assuming 4-alignment
+- renderer += '?' + ((attribute.offset - bytes)/4);
++ renderer = Runtime.getStringConcat(renderer, Runtime.getStringConcat('?', ((attribute.offset - bytes)/4)));
+ bytes += attribute.offset - bytes;
+ }
+- renderer += attribute.name;
++ renderer = Runtime.getStringConcat(renderer, attribute.name);
+ bytes += attribute.size * GL.immediate.byteSizeByType[attribute.type];
+ if (bytes % 4 != 0) bytes += 4 - (bytes % 4); // XXX assuming 4-alignment
+ #if ASSERTIONS
+ assert(0 <= attribute.offset && attribute.offset < stride); // must all be in the same buffer
+ #endif
+ }
+
+ assert(stride == 0 || bytes <= stride);
+
+ if (bytes < stride) { // ensure the size is that of the stride
+ assert((stride - bytes)%4 == 0); // assuming float
+- renderer += '?' + ((stride-bytes)/4);
++ renderer = Runtime.getStringConcat(renderer, Runtime.getStringConcat('?', ((stride-bytes)/4)));
+ bytes = stride;
+ }
+
+ bytes *= count;
+ if (!GL.currArrayBuffer) {
+ GL.immediate.vertexData = {{{ makeHEAPView('F32', 'start', 'start + bytes') }}}; // XXX assuming float
+ }
+@@ -1671,15 +1674,15 @@ var LibraryGL = {
+ },
+
+ glVertexPointer__deps: ['$GLEmulation'], // if any pointers are used, glVertexPointer must be, and if it is, then we need emulation
+ glVertexPointer: function(size, type, stride, pointer) {
+ GL.immediate.setClientAttribute('V', size, type, stride, pointer);
+ },
+ glTexCoordPointer: function(size, type, stride, pointer) {
+- GL.immediate.setClientAttribute('T' + GL.immediate.clientActiveTexture, size, type, stride, pointer);
++ GL.immediate.setClientAttribute(Runtime.getStringConcat('T', GL.immediate.clientActiveTexture), size, type, stride, pointer);
+ },
+ glNormalPointer: function(type, stride, pointer) {
+ GL.immediate.setClientAttribute('N', 1, type, stride, pointer);
+ },
+ glColorPointer: function(size, type, stride, pointer) {
+ GL.immediate.setClientAttribute('C', size, type, stride, pointer);
+ },
+diff --git a/src/runtime.js b/src/runtime.js
+index 6a251c4..012a66d 100644
+--- a/src/runtime.js
++++ b/src/runtime.js
+@@ -319,25 +319,34 @@ var Runtime = {
+ if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
+ if (!Runtime.warnOnce.shown[text]) {
+ Runtime.warnOnce.shown[text] = 1;
+ Module.printErr(text);
+ }
+ },
+
++ // Cache for JS function wrappers for C functions in FUNCTION_TABLE
+ funcWrappers: {},
+-
+ getFuncWrapper: function(func) {
+ if (!Runtime.funcWrappers[func]) {
+ Runtime.funcWrappers[func] = function() {
+ FUNCTION_TABLE[func].apply(null, arguments);
+ };
+ }
+ return Runtime.funcWrappers[func];
+ },
+
++ // Cache for small recurring strings generated by concatenating other
++ // strings, use this to avoid needless allocation and collection
++ stringCache: {},
++ getStringConcat: function(a, b) {
++ var cacheItem = Runtime.stringCache[a];
++ if (!cacheItem) cacheItem = Runtime.stringCache[a] = {};
++ return cacheItem[b] || (cacheItem[b] = a + b);
++ },
++
+ #if RUNTIME_DEBUG
+ debug: true, // Switch to false at runtime to disable logging at the right times
+
+ printObjectList: [],
+
+ prettyPrint: function(arg) {
+ if (typeof arg == 'undefined') return '!UNDEFINED!';