Home | History | Annotate | Download | only in turbolizer
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 var DEFAULT_NODE_WIDTH = 240;
      6 var DEFAULT_NODE_HEIGHT = 40;
      7 var TYPE_HEIGHT = 25;
      8 var DEFAULT_NODE_BUBBLE_RADIUS = 4;
      9 var NODE_INPUT_WIDTH = 20;
     10 var MINIMUM_NODE_INPUT_APPROACH = 20;
     11 var MINIMUM_NODE_OUTPUT_APPROACH = 15;
     12 
     13 function isNodeInitiallyVisible(node) {
     14   return node.cfg;
     15 }
     16 
     17 var Node = {
     18   isControl: function() {
     19     return this.control;
     20   },
     21   isInput: function() {
     22     return this.opcode == 'Parameter' || this.opcode.endsWith('Constant');
     23   },
     24   isJavaScript: function() {
     25     return this.opcode.startsWith('JS');
     26   },
     27   isSimplified: function() {
     28     if (this.isJavaScript) return false;
     29     return this.opcode.endsWith('Phi') ||
     30       this.opcode.startsWith('Boolean') ||
     31       this.opcode.startsWith('Number') ||
     32       this.opcode.startsWith('String') ||
     33       this.opcode.startsWith('Change') ||
     34       this.opcode.startsWith('Object') ||
     35       this.opcode.startsWith('Reference') ||
     36       this.opcode.startsWith('Any') ||
     37       this.opcode.endsWith('ToNumber') ||
     38       (this.opcode == 'AnyToBoolean') ||
     39       (this.opcode.startsWith('Load') && this.opcode.length > 4) ||
     40       (this.opcode.startsWith('Store') && this.opcode.length > 5);
     41   },
     42   isMachine: function() {
     43     return !(this.isControl() || this.isInput() ||
     44              this.isJavaScript() || this.isSimplified());
     45   },
     46   getTotalNodeWidth: function() {
     47     var inputWidth = this.inputs.length * NODE_INPUT_WIDTH;
     48     return Math.max(inputWidth, this.width);
     49   },
     50   getLabel: function() {
     51     return this.label;
     52   },
     53   getDisplayLabel: function() {
     54     var result = this.id + ":" + this.label;
     55     if (result.length > 30) {
     56       return this.id + ":" + this.opcode;
     57     } else  {
     58       return result;
     59     }
     60   },
     61   getType: function() {
     62     return this.type;
     63   },
     64   getDisplayType: function() {
     65     var type_string = this.type;
     66     if (type_string == undefined) return "";
     67     if (type_string.length > 24) {
     68       type_string = type_string.substr(0, 25) + "...";
     69     }
     70     return type_string;
     71   },
     72   deepestInputRank: function() {
     73     var deepestRank = 0;
     74     this.inputs.forEach(function(e) {
     75       if (e.isVisible() && !e.isBackEdge()) {
     76         if (e.source.rank > deepestRank) {
     77           deepestRank = e.source.rank;
     78         }
     79       }
     80     });
     81     return deepestRank;
     82   },
     83   areAnyOutputsVisible: function() {
     84     var visibleCount = 0;
     85     this.outputs.forEach(function(e) { if (e.isVisible()) ++visibleCount; });
     86     if (this.outputs.length == visibleCount) return 2;
     87     if (visibleCount != 0) return 1;
     88     return 0;
     89   },
     90   setOutputVisibility: function(v) {
     91     var result = false;
     92     this.outputs.forEach(function(e) {
     93       e.visible = v;
     94       if (v) {
     95         if (!e.target.visible) {
     96           e.target.visible = true;
     97           result = true;
     98         }
     99       }
    100     });
    101     return result;
    102   },
    103   setInputVisibility: function(i, v) {
    104     var edge = this.inputs[i];
    105     edge.visible = v;
    106     if (v) {
    107       if (!edge.source.visible) {
    108         edge.source.visible = true;
    109         return true;
    110       }
    111     }
    112     return false;
    113   },
    114   getInputApproach: function(index) {
    115     return this.y - MINIMUM_NODE_INPUT_APPROACH -
    116       (index % 4) * MINIMUM_EDGE_SEPARATION - DEFAULT_NODE_BUBBLE_RADIUS
    117   },
    118   getOutputApproach: function(graph, index) {
    119     return this.y + this.outputApproach + graph.getNodeHeight() +
    120       + DEFAULT_NODE_BUBBLE_RADIUS;
    121   },
    122   getInputX: function(index) {
    123     var result = this.getTotalNodeWidth() - (NODE_INPUT_WIDTH / 2) +
    124         (index - this.inputs.length + 1) * NODE_INPUT_WIDTH;
    125     return result;
    126   },
    127   getOutputX: function() {
    128     return this.getTotalNodeWidth() - (NODE_INPUT_WIDTH / 2);
    129   },
    130   getFunctionRelativeSourcePosition: function(graph) {
    131     return this.pos - graph.sourcePosition;
    132   },
    133   hasBackEdges: function() {
    134     return (this.opcode == "Loop") ||
    135       ((this.opcode == "Phi" || this.opcode == "EffectPhi") &&
    136        this.inputs[this.inputs.length - 1].source.opcode == "Loop");
    137   }
    138 };
    139