diff options
Diffstat (limited to 'src/framework.js')
| -rw-r--r-- | src/framework.js | 257 | 
1 files changed, 0 insertions, 257 deletions
| diff --git a/src/framework.js b/src/framework.js deleted file mode 100644 index 1a98ca16..00000000 --- a/src/framework.js +++ /dev/null @@ -1,257 +0,0 @@ -//"use strict"; - -// -// A framework to make building Emscripten easier. Lets you write modular -// code to handle specific issues. -// -// Actor - Some code that processes items. -// Item - Some data that is processed by actors. -// Substrate - A 'world' with some actors and some items. -// -// The idea is to create a substrate, fill it with the proper items -// and actors, and then run it to completion. Actors will process -// the items they are given, and forward the results to other actors, -// until we are finished. Some of the results are then the final -// output of the entire calculation done in the substrate. -// - -var DEBUG = 0; -var DEBUG_MEMORY = 0; - -var MemoryDebugger = { -  clear: function() { -    MemoryDebugger.time = Date.now(); -    MemoryDebugger.datas = {}; -    var info = MemoryDebugger.doGC(); -    MemoryDebugger.last = info[2]; -    MemoryDebugger.max = 0; -    MemoryDebugger.tick('--clear--'); -  }, - -  doGC: function() { -    var raw = gc().replace('\n', ''); -    print('zz raw gc info: ' + raw); -    return /before (\d+), after (\d+),.*/.exec(raw); -  }, - -  tick: function(name) { -    var now = Date.now(); -    if (now - this.time > 1000) { -      // .. -      this.time = now; -    } - -    // assume |name| exists from now on - -    var raw = gc().replace('\n', ''); -    var info = MemoryDebugger.doGC(); -    var before = info[1]; -    var after = info[2]; -    MemoryDebugger.max = Math.max(MemoryDebugger.max, before, after); -    // A GC not called by us may have done some work 'silently' -    var garbage = before - after; -    var real = after - MemoryDebugger.last; -    print('zz gc stats changes: ' + [name, real, garbage]); -    MemoryDebugger.last = after; - -    if (Math.abs(garbage) + Math.abs(real) > 0) { -      var data = MemoryDebugger.datas[name]; -      if (!data) { -        data = MemoryDebugger.datas[name] = { -          name: name, -          count: 0, -          garbage: 0, -          real: 0 -        }; -      } -      data.garbage += garbage; -      data.real += real; -      data.count++; -    } - -    MemoryDebugger.dump(); -  }, - -  dump: function() { -    var vals = values(MemoryDebugger.datas); -    print('zz max: ' + (MemoryDebugger.max/(1024*1024)).toFixed(3)); -    print('zz real:'); -    vals.sort(function(x, y) { return y.real - x.real }); -    vals.forEach(function(v) { if (Math.abs(v.real) > 1024*1024) print('zz    ' + v.name + ' real = ' + (v.real/(1024*1024)).toFixed(3) + ' mb'); }); -    print('zz garbage:'); -    vals.sort(function(x, y) { return y.garbage - x.garbage }); -    vals.forEach(function(v) { if (Math.abs(v.garbage) > 1024*1024) print('zz    ' + v.name + ' garbage = ' + (v.garbage/(1024*1024)).toFixed(3) + ' mb'); }); -  } -} - -if (DEBUG_MEMORY) MemoryDebugger.clear(); - -function Substrate(name_) { -  this.name_ = name_; -  this.actors = {}; -  this.currUid = 1; -}; - -Substrate.prototype = { -  addItem: function(item, targetActor) { -    if (targetActor == '/dev/null') return; -    if (targetActor == '/dev/stdout') { -      this.results.push(item); -      return; -    } -    this.actors[targetActor].inbox.push(item); -  }, - -  addItems: function(items, targetActor) { -    if (targetActor == '/dev/null') return; -    if (targetActor == '/dev/stdout') { -      this.results = this.results.concat(items); -      return; -    } -    this.actors[targetActor].inbox = this.actors[targetActor].inbox.concat(items); -  }, - -  checkInbox: function(actor) { -    var items = actor.inbox; -    for (var i = 0; i < items.length; i++) { -      var item = items[i]; -      if (!item.__uid__) { -        item.__uid__ = this.currUid; -        this.currUid ++; -      } -    } -    var MAX_INCOMING = Infinity; -    if (MAX_INCOMING == Infinity) { -      actor.inbox = []; -      actor.items = actor.items.concat(items); -    } else { -      throw 'Warning: Enter this code at your own risk. It can save memory, but often regresses speed.'; -      actor.inbox = items.slice(MAX_INCOMING); -      actor.items = actor.items.concat(items.slice(0, MAX_INCOMING)); -    } -  }, - -  addActor: function(name_, actor) { -    assert(name_ && actor); -    actor.name_ = name_; -    actor.items = []; -    actor.inbox = []; -    actor.forwardItem  = bind(this, this.addItem); -    actor.forwardItems = bind(this, this.addItems); -    this.actors[name_] = actor; -    if (!actor.process) actor.process = Actor.prototype.process; -    return actor; -  }, - -  solve: function() { -    dprint('framework', "// Solving " + this.name_ + "..."); - -    if (DEBUG_MEMORY) MemoryDebugger.tick('pre-run substrate ' + this.name_ + ' (priors may be cleaned)'); - -    var startTime = Date.now(); -    var midTime = startTime; -    var that = this; -    function midComment() { -      var curr = Date.now(); -      if (curr - midTime > 500) { -        dprint('framework', '// Working on ' + that.name_ + ', so far ' + ((curr-startTime)/1000).toString().substr(0,10) + ' seconds.'); -        midTime = curr; -      } -    } -    function finalComment() { -      dprint('framework', '// Completed ' + that.name_ + ' in ' + ((Date.now() - startTime)/1000).toString().substr(0,10) + ' seconds.'); -    } - -    var ret = null; -    var finalResult = null; -    this.results = []; -    var finished = false; -    var onResult = this.onResult; -    var actors = values(this.actors); // Assumes actors are not constantly added -    while (!finished) { -      dprint('framework', "Cycle start, items: ");// + values(this.actors).map(function(actor) actor.items).reduce(function(x,y) x+y, 0)); -      var hadProcessing = false; -      for (var i = 0; i < actors.length; i++) { -        var actor = actors[i]; -        if (actor.inbox.length == 0 && actor.items.length == 0) continue; - -        midComment(); - -        this.checkInbox(actor); -        var outputs; -        var currResultCount = this.results.length; -        dprint('framework', 'Processing using ' + actor.name_ + ': ' + actor.items.length); -        outputs = actor.process(actor.items); -        actor.items = []; -        if (DEBUG_MEMORY) MemoryDebugger.tick('actor ' + actor.name_); -        dprint('framework', 'New results: ' + (outputs.length + this.results.length - currResultCount) + ' out of ' + (this.results.length + outputs.length)); -        hadProcessing = true; - -        if (outputs && outputs.length > 0) { -          if (outputs.length === 1 && outputs[0].__finalResult__) { -            if (DEBUG) print("Solving complete: __finalResult__"); -            delete outputs[0].__finalResult__; // Might recycle this -            delete outputs[0].__uid__; -            finalComment(); -            finished = true; -            finalResult = outputs[0]; -          } else { -            this.results = this.results.concat(outputs); -          } -        } -      } -      if (!hadProcessing) { -        if (DEBUG) print("Solving complete: no remaining items"); -        finalComment(); -        this.results.forEach(function(result) { -          delete result.__uid__; // Might recycle these -          if (onResult) onResult(result); -        }); -        ret = this.results; -        this.results = null; // No need to hold on to them any more -        break; -      } -      if (finalResult) { -        ret = finalResult; -        break; -      } -      midComment(); -    } - -    // Clear the actors. Do not forget about the actors, though, to make this substrate reusable. -    actors.forEach(function(actor) { -      actor.items = null; -      actor.inbox = null; -    }); - -    if (DEBUG_MEMORY) MemoryDebugger.tick('finished ' + this.name_); - -    return ret; -  } -}; - -// Global access to the currently-being processed item. -// Note that if you overload process in Actor, this will need to be set if you rely on it. -var Framework = { -  currItem: null -}; - -function Actor() { }; -Actor.prototype = { -  process: function(items) { -    var ret = []; -    for (var i = 0; i < items.length; i++) { -      var item = items[i]; -      items[i] = null; // items may be very very large. Allow GCing to occur in the loop by releasing refs here -      dprint('frameworkLines', 'Processing item for llvm line ' + item.lineNum); -      Framework.currItem = item; -      var outputs = this.processItem(item); -      Framework.currItem = null; -      if (outputs) { -        ret = ret.concat(outputs); -      } -    } -    return ret; -  } -}; - | 
