docs: function MaliParser(importer) {
      Parser.call(this, importer);
  
      // kernel DVFS events
      importer.registerEventHandler('mali_dvfs_event',
          MaliParser.prototype.dvfsEventEvent.bind(this));
      importer.registerEventHandler('mali_dvfs_set_clock',
          MaliParser.prototype.dvfsSetClockEvent.bind(this));
      importer.registerEventHandler('mali_dvfs_set_voltage',
          MaliParser.prototype.dvfsSetVoltageEvent.bind(this));
  
      // kernel Mali hw counter events
      this.addJMCounter('mali_hwc_MESSAGES_SENT', 'Messages Sent');
      this.addJMCounter('mali_hwc_MESSAGES_RECEIVED', 'Messages Received');
      this.addJMCycles('mali_hwc_GPU_ACTIVE', 'GPU Active');
      this.addJMCycles('mali_hwc_IRQ_ACTIVE', 'IRQ Active');
  
      for (var i = 0; i < 7; i++) {
        var jobStr = 'JS' + i;
        var jobHWCStr = 'mali_hwc_' + jobStr;
        this.addJMCounter(jobHWCStr + '_JOBS', jobStr + ' Jobs');
        this.addJMCounter(jobHWCStr + '_TASKS', jobStr + ' Tasks');
        this.addJMCycles(jobHWCStr + '_ACTIVE', jobStr + ' Active');
        this.addJMCycles(jobHWCStr + '_WAIT_READ', jobStr + ' Wait Read');
        this.addJMCycles(jobHWCStr + '_WAIT_ISSUE', jobStr + ' Wait Issue');
        this.addJMCycles(jobHWCStr + '_WAIT_DEPEND', jobStr + ' Wait Depend');
        this.addJMCycles(jobHWCStr + '_WAIT_FINISH', jobStr + ' Wait Finish');
      }
  
      this.addTilerCounter('mali_hwc_TRIANGLES', 'Triangles');
      this.addTilerCounter('mali_hwc_QUADS', 'Quads');
      this.addTilerCounter('mali_hwc_POLYGONS', 'Polygons');
      this.addTilerCounter('mali_hwc_POINTS', 'Points');
      this.addTilerCounter('mali_hwc_LINES', 'Lines');
      this.addTilerCounter('mali_hwc_VCACHE_HIT', 'VCache Hit');
      this.addTilerCounter('mali_hwc_VCACHE_MISS', 'VCache Miss');
      this.addTilerCounter('mali_hwc_FRONT_FACING', 'Front Facing');
      this.addTilerCounter('mali_hwc_BACK_FACING', 'Back Facing');
      this.addTilerCounter('mali_hwc_PRIM_VISIBLE', 'Prim Visible');
      this.addTilerCounter('mali_hwc_PRIM_CULLED', 'Prim Culled');
      this.addTilerCounter('mali_hwc_PRIM_CLIPPED', 'Prim Clipped');
  
      this.addTilerCounter('mali_hwc_WRBUF_HIT', 'Wrbuf Hit');
      this.addTilerCounter('mali_hwc_WRBUF_MISS', 'Wrbuf Miss');
      this.addTilerCounter('mali_hwc_WRBUF_LINE', 'Wrbuf Line');
      this.addTilerCounter('mali_hwc_WRBUF_PARTIAL', 'Wrbuf Partial');
      this.addTilerCounter('mali_hwc_WRBUF_STALL', 'Wrbuf Stall');
  
      this.addTilerCycles('mali_hwc_ACTIVE', 'Tiler Active');
      this.addTilerCycles('mali_hwc_INDEX_WAIT', 'Index Wait');
      this.addTilerCycles('mali_hwc_INDEX_RANGE_WAIT', 'Index Range Wait');
      this.addTilerCycles('mali_hwc_VERTEX_WAIT', 'Vertex Wait');
      this.addTilerCycles('mali_hwc_PCACHE_WAIT', 'Pcache Wait');
      this.addTilerCycles('mali_hwc_WRBUF_WAIT', 'Wrbuf Wait');
      this.addTilerCycles('mali_hwc_BUS_READ', 'Bus Read');
      this.addTilerCycles('mali_hwc_BUS_WRITE', 'Bus Write');
  
      this.addTilerCycles('mali_hwc_TILER_UTLB_STALL', 'Tiler UTLB Stall');
      this.addTilerCycles('mali_hwc_TILER_UTLB_HIT', 'Tiler UTLB Hit');
  
      this.addFragCycles('mali_hwc_FRAG_ACTIVE', 'Active');
      /* NB: don't propagate spelling mistakes to labels */
      this.addFragCounter('mali_hwc_FRAG_PRIMATIVES', 'Primitives');
      this.addFragCounter('mali_hwc_FRAG_PRIMATIVES_DROPPED',
          'Primitives Dropped');
      this.addFragCycles('mali_hwc_FRAG_CYCLE_DESC', 'Descriptor Processing');
      this.addFragCycles('mali_hwc_FRAG_CYCLES_PLR', 'PLR Processing??');
      this.addFragCycles('mali_hwc_FRAG_CYCLES_VERT', 'Vertex Processing');
      this.addFragCycles('mali_hwc_FRAG_CYCLES_TRISETUP', 'Triangle Setup');
      this.addFragCycles('mali_hwc_FRAG_CYCLES_RAST', 'Rasterization???');
      this.addFragCounter('mali_hwc_FRAG_THREADS', 'Threads');
      this.addFragCounter('mali_hwc_FRAG_DUMMY_THREADS', 'Dummy Threads');
      this.addFragCounter('mali_hwc_FRAG_QUADS_RAST', 'Quads Rast');
      this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_TEST', 'Quads EZS Test');
      this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_KILLED', 'Quads EZS Killed');
      this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_TEST', 'Quads LZS Test');
      this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_KILLED', 'Quads LZS Killed');
      this.addFragCycles('mali_hwc_FRAG_CYCLE_NO_TILE', 'No Tiles');
      this.addFragCounter('mali_hwc_FRAG_NUM_TILES', 'Tiles');
      this.addFragCounter('mali_hwc_FRAG_TRANS_ELIM', 'Transactions Eliminated');
  
      this.addComputeCycles('mali_hwc_COMPUTE_ACTIVE', 'Active');
      this.addComputeCounter('mali_hwc_COMPUTE_TASKS', 'Tasks');
      this.addComputeCounter('mali_hwc_COMPUTE_THREADS', 'Threads Started');
      this.addComputeCycles('mali_hwc_COMPUTE_CYCLES_DESC',
          'Waiting for Descriptors');
  
      this.addTripipeCycles('mali_hwc_TRIPIPE_ACTIVE', 'Active');
  
      this.addArithCounter('mali_hwc_ARITH_WORDS', 'Instructions (/Pipes)');
      this.addArithCycles('mali_hwc_ARITH_CYCLES_REG',
          'Reg scheduling stalls (/Pipes)');
      this.addArithCycles('mali_hwc_ARITH_CYCLES_L0',
          'L0 cache miss stalls (/Pipes)');
      this.addArithCounter('mali_hwc_ARITH_FRAG_DEPEND',
          'Frag dep check failures (/Pipes)');
  
      this.addLSCounter('mali_hwc_LS_WORDS', 'Instruction Words Completed');
      this.addLSCounter('mali_hwc_LS_ISSUES', 'Full Pipeline Issues');
      this.addLSCounter('mali_hwc_LS_RESTARTS', 'Restarts (unpairable insts)');
      this.addLSCounter('mali_hwc_LS_REISSUES_MISS',
          'Pipeline reissue (cache miss/uTLB)');
      this.addLSCounter('mali_hwc_LS_REISSUES_VD',
          'Pipeline reissue (varying data)');
      /* TODO(sleffler) fix kernel event typo */
      this.addLSCounter('mali_hwc_LS_REISSUE_ATTRIB_MISS',
          'Pipeline reissue (attribute cache miss)');
      this.addLSCounter('mali_hwc_LS_REISSUE_NO_WB', 'Writeback not used');
  
      this.addTexCounter('mali_hwc_TEX_WORDS', 'Words');
      this.addTexCounter('mali_hwc_TEX_BUBBLES', 'Bubbles');
      this.addTexCounter('mali_hwc_TEX_WORDS_L0', 'Words L0');
      this.addTexCounter('mali_hwc_TEX_WORDS_DESC', 'Words Desc');
      this.addTexCounter('mali_hwc_TEX_THREADS', 'Threads');
      this.addTexCounter('mali_hwc_TEX_RECIRC_FMISS', 'Recirc due to Full Miss');
      this.addTexCounter('mali_hwc_TEX_RECIRC_DESC', 'Recirc due to Desc Miss');
      this.addTexCounter('mali_hwc_TEX_RECIRC_MULTI', 'Recirc due to Multipass');
      this.addTexCounter('mali_hwc_TEX_RECIRC_PMISS',
          'Recirc due to Partial Cache Miss');
      this.addTexCounter('mali_hwc_TEX_RECIRC_CONF',
          'Recirc due to Cache Conflict');
  
      this.addLSCCounter('mali_hwc_LSC_READ_HITS', 'Read Hits');
      this.addLSCCounter('mali_hwc_LSC_READ_MISSES', 'Read Misses');
      this.addLSCCounter('mali_hwc_LSC_WRITE_HITS', 'Write Hits');
      this.addLSCCounter('mali_hwc_LSC_WRITE_MISSES', 'Write Misses');
      this.addLSCCounter('mali_hwc_LSC_ATOMIC_HITS', 'Atomic Hits');
      this.addLSCCounter('mali_hwc_LSC_ATOMIC_MISSES', 'Atomic Misses');
      this.addLSCCounter('mali_hwc_LSC_LINE_FETCHES', 'Line Fetches');
      this.addLSCCounter('mali_hwc_LSC_DIRTY_LINE', 'Dirty Lines');
      this.addLSCCounter('mali_hwc_LSC_SNOOPS', 'Snoops');
  
      this.addAXICounter('mali_hwc_AXI_TLB_STALL', 'Address channel stall');
      this.addAXICounter('mali_hwc_AXI_TLB_MISS', 'Cache Miss');
      this.addAXICounter('mali_hwc_AXI_TLB_TRANSACTION', 'Transactions');
      this.addAXICounter('mali_hwc_LS_TLB_MISS', 'LS Cache Miss');
      this.addAXICounter('mali_hwc_LS_TLB_HIT', 'LS Cache Hit');
      this.addAXICounter('mali_hwc_AXI_BEATS_READ', 'Read Beats');
      this.addAXICounter('mali_hwc_AXI_BEATS_WRITE', 'Write Beats');
  
      this.addMMUCounter('mali_hwc_MMU_TABLE_WALK', 'Page Table Walks');
      this.addMMUCounter('mali_hwc_MMU_REPLAY_MISS',
          'Cache Miss from Replay Buffer');
      this.addMMUCounter('mali_hwc_MMU_REPLAY_FULL', 'Replay Buffer Full');
      this.addMMUCounter('mali_hwc_MMU_NEW_MISS', 'Cache Miss on New Request');
      this.addMMUCounter('mali_hwc_MMU_HIT', 'Cache Hit');
  
      this.addMMUCycles('mali_hwc_UTLB_STALL', 'UTLB Stalled');
      this.addMMUCycles('mali_hwc_UTLB_REPLAY_MISS', 'UTLB Replay Miss');
      this.addMMUCycles('mali_hwc_UTLB_REPLAY_FULL', 'UTLB Replay Full');
      this.addMMUCycles('mali_hwc_UTLB_NEW_MISS', 'UTLB New Miss');
      this.addMMUCycles('mali_hwc_UTLB_HIT', 'UTLB Hit');
  
      this.addL2Counter('mali_hwc_L2_READ_BEATS', 'Read Beats');
      this.addL2Counter('mali_hwc_L2_WRITE_BEATS', 'Write Beats');
      this.addL2Counter('mali_hwc_L2_ANY_LOOKUP', 'Any Lookup');
      this.addL2Counter('mali_hwc_L2_READ_LOOKUP', 'Read Lookup');
      this.addL2Counter('mali_hwc_L2_SREAD_LOOKUP', 'Shareable Read Lookup');
      this.addL2Counter('mali_hwc_L2_READ_REPLAY', 'Read Replayed');
      this.addL2Counter('mali_hwc_L2_READ_SNOOP', 'Read Snoop');
      this.addL2Counter('mali_hwc_L2_READ_HIT', 'Read Cache Hit');
      this.addL2Counter('mali_hwc_L2_CLEAN_MISS', 'CleanUnique Miss');
      this.addL2Counter('mali_hwc_L2_WRITE_LOOKUP', 'Write Lookup');
      this.addL2Counter('mali_hwc_L2_SWRITE_LOOKUP', 'Shareable Write Lookup');
      this.addL2Counter('mali_hwc_L2_WRITE_REPLAY', 'Write Replayed');
      this.addL2Counter('mali_hwc_L2_WRITE_SNOOP', 'Write Snoop');
      this.addL2Counter('mali_hwc_L2_WRITE_HIT', 'Write Cache Hit');
      this.addL2Counter('mali_hwc_L2_EXT_READ_FULL', 'ExtRD with BIU Full');
      this.addL2Counter('mali_hwc_L2_EXT_READ_HALF', 'ExtRD with BIU >1/2 Full');
      this.addL2Counter('mali_hwc_L2_EXT_WRITE_FULL', 'ExtWR with BIU Full');
      this.addL2Counter('mali_hwc_L2_EXT_WRITE_HALF', 'ExtWR with BIU >1/2 Full');
  
      this.addL2Counter('mali_hwc_L2_EXT_READ', 'External Read (ExtRD)');
      this.addL2Counter('mali_hwc_L2_EXT_READ_LINE', 'ExtRD (linefill)');
      this.addL2Counter('mali_hwc_L2_EXT_WRITE', 'External Write (ExtWR)');
      this.addL2Counter('mali_hwc_L2_EXT_WRITE_LINE', 'ExtWR (linefill)');
      this.addL2Counter('mali_hwc_L2_EXT_WRITE_SMALL', 'ExtWR (burst size <64B)');
      this.addL2Counter('mali_hwc_L2_EXT_BARRIER', 'External Barrier');
      this.addL2Counter('mali_hwc_L2_EXT_AR_STALL', 'Address Read stalls');
      this.addL2Counter('mali_hwc_L2_EXT_R_BUF_FULL',
          'Response Buffer full stalls');
      this.addL2Counter('mali_hwc_L2_EXT_RD_BUF_FULL',
          'Read Data Buffer full stalls');
      this.addL2Counter('mali_hwc_L2_EXT_R_RAW', 'RAW hazard stalls');
      this.addL2Counter('mali_hwc_L2_EXT_W_STALL', 'Write Data stalls');
      this.addL2Counter('mali_hwc_L2_EXT_W_BUF_FULL', 'Write Data Buffer full');
      this.addL2Counter('mali_hwc_L2_EXT_R_W_HAZARD', 'WAW or WAR hazard stalls');
      this.addL2Counter('mali_hwc_L2_TAG_HAZARD', 'Tag hazard replays');
      this.addL2Cycles('mali_hwc_L2_SNOOP_FULL', 'Snoop buffer full');
      this.addL2Cycles('mali_hwc_L2_REPLAY_FULL', 'Replay buffer full');
  
      // DDK events (from X server)
      importer.registerEventHandler('tracing_mark_write:mali_driver',
          MaliParser.prototype.maliDDKEvent.bind(this));
  
      this.model_ = importer.model_;
    }