LCOV - code coverage report
Current view: top level - js/src/jit - CompactBuffer.h (source / functions) Hit Total Coverage
Test: output.info Lines: 96 116 82.8 %
Date: 2017-07-14 16:53:18 Functions: 22 26 84.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef jit_Compactbuffer_h
       8             : #define jit_Compactbuffer_h
       9             : 
      10             : #include "jsalloc.h"
      11             : 
      12             : #include "jit/IonTypes.h"
      13             : #include "js/Vector.h"
      14             : 
      15             : namespace js {
      16             : namespace jit {
      17             : 
      18             : class CompactBufferWriter;
      19             : 
      20             : // CompactBuffers are byte streams designed for compressable integers. It has
      21             : // helper functions for writing bytes, fixed-size integers, and variable-sized
      22             : // integers. Variable sized integers are encoded in 1-5 bytes, each byte
      23             : // containing 7 bits of the integer and a bit which specifies whether the next
      24             : // byte is also part of the integer.
      25             : //
      26             : // Fixed-width integers are also available, in case the actual value will not
      27             : // be known until later.
      28             : 
      29             : class CompactBufferReader
      30             : {
      31             :     const uint8_t* buffer_;
      32             :     const uint8_t* end_;
      33             : 
      34       21254 :     uint32_t readVariableLength() {
      35       21254 :         uint32_t val = 0;
      36       21254 :         uint32_t shift = 0;
      37             :         uint8_t byte;
      38        3747 :         while (true) {
      39       25001 :             MOZ_ASSERT(shift < 32);
      40       25001 :             byte = readByte();
      41       25001 :             val |= (uint32_t(byte) >> 1) << shift;
      42       25001 :             shift += 7;
      43       25001 :             if (!(byte & 1))
      44       42508 :                 return val;
      45             :         }
      46             :     }
      47             : 
      48             :   public:
      49       26717 :     CompactBufferReader(const uint8_t* start, const uint8_t* end)
      50       26717 :       : buffer_(start),
      51       26717 :         end_(end)
      52       26717 :     { }
      53             :     inline explicit CompactBufferReader(const CompactBufferWriter& writer);
      54       40128 :     uint8_t readByte() {
      55       40128 :         MOZ_ASSERT(buffer_ < end_);
      56       40128 :         return *buffer_++;
      57             :     }
      58          14 :     uint32_t readFixedUint32_t() {
      59          14 :         uint32_t b0 = readByte();
      60          14 :         uint32_t b1 = readByte();
      61          14 :         uint32_t b2 = readByte();
      62          14 :         uint32_t b3 = readByte();
      63          14 :         return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
      64             :     }
      65           0 :     uint16_t readFixedUint16_t() {
      66           0 :         uint32_t b0 = readByte();
      67           0 :         uint32_t b1 = readByte();
      68           0 :         return b0 | (b1 << 8);
      69             :     }
      70             :     uint32_t readNativeEndianUint32_t() {
      71             :         // Must be at 4-byte boundary
      72             :         MOZ_ASSERT(uintptr_t(buffer_) % sizeof(uint32_t) == 0);
      73             :         return *reinterpret_cast<const uint32_t*>(buffer_);
      74             :     }
      75       21254 :     uint32_t readUnsigned() {
      76       21254 :         return readVariableLength();
      77             :     }
      78           1 :     int32_t readSigned() {
      79           1 :         uint8_t b = readByte();
      80           1 :         bool isNegative = !!(b & (1 << 0));
      81           1 :         bool more = !!(b & (1 << 1));
      82           1 :         int32_t result = b >> 2;
      83           1 :         if (more)
      84           0 :             result |= readUnsigned() << 6;
      85           1 :         if (isNegative)
      86           0 :             return -result;
      87           1 :         return result;
      88             :     }
      89             : 
      90           1 :     void* readRawPointer() {
      91           1 :         uintptr_t ptrWord = 0;
      92           9 :         for (unsigned i = 0; i < sizeof(uintptr_t); i++) {
      93           8 :             ptrWord |= static_cast<uintptr_t>(readByte()) << (i*8);
      94             :         }
      95           1 :         return reinterpret_cast<void*>(ptrWord);
      96             :     }
      97             : 
      98       11848 :     bool more() const {
      99       11848 :         MOZ_ASSERT(buffer_ <= end_);
     100       11848 :         return buffer_ < end_;
     101             :     }
     102             : 
     103         366 :     void seek(const uint8_t* start, uint32_t offset) {
     104         366 :         buffer_ = start + offset;
     105         366 :         MOZ_ASSERT(start < end_);
     106         366 :         MOZ_ASSERT(buffer_ < end_);
     107         366 :     }
     108             : 
     109        2259 :     const uint8_t* currentPosition() const {
     110        2259 :         return buffer_;
     111             :     }
     112             : };
     113             : 
     114       29039 : class CompactBufferWriter
     115             : {
     116             :     js::Vector<uint8_t, 32, SystemAllocPolicy> buffer_;
     117             :     bool enoughMemory_;
     118             : 
     119             :   public:
     120       29037 :     CompactBufferWriter()
     121       29037 :       : enoughMemory_(true)
     122       29036 :     { }
     123             : 
     124           0 :     void setOOM() {
     125           0 :         enoughMemory_ = false;
     126           0 :     }
     127             : 
     128             :     // Note: writeByte() takes uint32 to catch implicit casts with a runtime
     129             :     // assert.
     130      272667 :     void writeByte(uint32_t byte) {
     131      272667 :         MOZ_ASSERT(byte <= 0xFF);
     132      272667 :         enoughMemory_ &= buffer_.append(byte);
     133      272624 :     }
     134             :     void writeByteAt(uint32_t pos, uint32_t byte) {
     135             :         MOZ_ASSERT(byte <= 0xFF);
     136             :         if (!oom())
     137             :             buffer_[pos] = byte;
     138             :     }
     139       94339 :     void writeUnsigned(uint32_t value) {
     140       15321 :         do {
     141       94339 :             uint8_t byte = ((value & 0x7F) << 1) | (value > 0x7F);
     142       94339 :             writeByte(byte);
     143       94331 :             value >>= 7;
     144       94331 :         } while (value);
     145       79010 :     }
     146             :     void writeUnsignedAt(uint32_t pos, uint32_t value, uint32_t original) {
     147             :         MOZ_ASSERT(value <= original);
     148             :         do {
     149             :             uint8_t byte = ((value & 0x7F) << 1) | (original > 0x7F);
     150             :             writeByteAt(pos++, byte);
     151             :             value >>= 7;
     152             :             original >>= 7;
     153             :         } while (original);
     154             :     }
     155        4805 :     void writeSigned(int32_t v) {
     156        4805 :         bool isNegative = v < 0;
     157        4805 :         uint32_t value = isNegative ? -v : v;
     158        4805 :         uint8_t byte = ((value & 0x3F) << 2) | ((value > 0x3F) << 1) | uint32_t(isNegative);
     159        4805 :         writeByte(byte);
     160             : 
     161             :         // Write out the rest of the bytes, if needed.
     162        4805 :         value >>= 6;
     163        4805 :         if (value == 0)
     164        2389 :             return;
     165        2416 :         writeUnsigned(value);
     166             :     }
     167        2879 :     void writeFixedUint32_t(uint32_t value) {
     168        2879 :         writeByte(value & 0xFF);
     169        2879 :         writeByte((value >> 8) & 0xFF);
     170        2879 :         writeByte((value >> 16) & 0xFF);
     171        2879 :         writeByte((value >> 24) & 0xFF);
     172        2879 :     }
     173             :     void writeFixedUint16_t(uint16_t value) {
     174             :         writeByte(value & 0xFF);
     175             :         writeByte(value >> 8);
     176             :     }
     177           0 :     void writeNativeEndianUint32_t(uint32_t value) {
     178             :         // Must be at 4-byte boundary
     179           0 :         MOZ_ASSERT_IF(!oom(), length() % sizeof(uint32_t) == 0);
     180           0 :         writeFixedUint32_t(0);
     181           0 :         if (oom())
     182           0 :             return;
     183           0 :         uint8_t* endPtr = buffer() + length();
     184           0 :         reinterpret_cast<uint32_t*>(endPtr)[-1] = value;
     185             :     }
     186           1 :     void writeRawPointer(void* ptr) {
     187           1 :         uintptr_t ptrWord = reinterpret_cast<uintptr_t>(ptr);
     188           9 :         for (unsigned i = 0; i < sizeof(uintptr_t); i++) {
     189           8 :             writeByte((ptrWord >> (i*8)) & 0xFF);
     190             :         }
     191           1 :     }
     192      133055 :     size_t length() const {
     193      133055 :         return buffer_.length();
     194             :     }
     195       28663 :     uint8_t* buffer() {
     196       28663 :         MOZ_ASSERT(!oom());
     197       28663 :         return &buffer_[0];
     198             :     }
     199        7811 :     const uint8_t* buffer() const {
     200        7811 :         MOZ_ASSERT(!oom());
     201        7811 :         return &buffer_[0];
     202             :     }
     203      179653 :     bool oom() const {
     204      179653 :         return !enoughMemory_;
     205             :     }
     206       30583 :     void propagateOOM(bool success) {
     207       30583 :         enoughMemory_ &= success;
     208       30583 :     }
     209             : };
     210             : 
     211           0 : CompactBufferReader::CompactBufferReader(const CompactBufferWriter& writer)
     212           0 :   : buffer_(writer.buffer()),
     213           0 :     end_(writer.buffer() + writer.length())
     214             : {
     215           0 : }
     216             : 
     217             : } // namespace jit
     218             : } // namespace js
     219             : 
     220             : #endif /* jit_Compactbuffer_h */

Generated by: LCOV version 1.13