js/src/jit/CompactBuffer.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     7 #ifndef jit_Compactbuffer_h
     8 #define jit_Compactbuffer_h
    10 #include "jsalloc.h"
    12 #include "jit/IonTypes.h"
    13 #include "js/Vector.h"
    15 namespace js {
    16 namespace jit {
    18 class CompactBufferWriter;
    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.
    29 class CompactBufferReader
    30 {
    31     const uint8_t *buffer_;
    32     const uint8_t *end_;
    34     uint32_t readVariableLength() {
    35         uint32_t val = 0;
    36         uint32_t shift = 0;
    37         uint8_t byte;
    38         while (true) {
    39             JS_ASSERT(shift < 32);
    40             byte = readByte();
    41             val |= (uint32_t(byte) >> 1) << shift;
    42             shift += 7;
    43             if (!(byte & 1))
    44                 return val;
    45         }
    46         MOZ_ASSUME_UNREACHABLE("unreachable");
    47     }
    49   public:
    50     CompactBufferReader(const uint8_t *start, const uint8_t *end)
    51       : buffer_(start),
    52         end_(end)
    53     { }
    54     inline CompactBufferReader(const CompactBufferWriter &writer);
    55     uint8_t readByte() {
    56         JS_ASSERT(buffer_ < end_);
    57         return *buffer_++;
    58     }
    59     uint32_t readFixedUint32_t() {
    60         uint32_t b0 = readByte();
    61         uint32_t b1 = readByte();
    62         uint32_t b2 = readByte();
    63         uint32_t b3 = readByte();
    64         return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
    65     }
    66     uint16_t readFixedUint16_t() {
    67         uint32_t b0 = readByte();
    68         uint32_t b1 = readByte();
    69         return b0 | (b1 << 8);
    70     }
    71     uint32_t readUnsigned() {
    72         return readVariableLength();
    73     }
    74     int32_t readSigned() {
    75         uint8_t b = readByte();
    76         bool isNegative = !!(b & (1 << 0));
    77         bool more = !!(b & (1 << 1));
    78         int32_t result = b >> 2;
    79         if (more)
    80             result |= readUnsigned() << 6;
    81         if (isNegative)
    82             return -result;
    83         return result;
    84     }
    86     bool more() const {
    87         JS_ASSERT(buffer_ <= end_);
    88         return buffer_ < end_;
    89     }
    91     void seek(const uint8_t *start, uint32_t offset) {
    92         buffer_ = start + offset;
    93         MOZ_ASSERT(start < end_);
    94         MOZ_ASSERT(buffer_ < end_);
    95     }
    96 };
    98 class CompactBufferWriter
    99 {
   100     js::Vector<uint8_t, 32, SystemAllocPolicy> buffer_;
   101     bool enoughMemory_;
   103   public:
   104     CompactBufferWriter()
   105       : enoughMemory_(true)
   106     { }
   108     // Note: writeByte() takes uint32 to catch implicit casts with a runtime
   109     // assert.
   110     void writeByte(uint32_t byte) {
   111         JS_ASSERT(byte <= 0xFF);
   112         enoughMemory_ &= buffer_.append(byte);
   113     }
   114     void writeUnsigned(uint32_t value) {
   115         do {
   116             uint8_t byte = ((value & 0x7F) << 1) | (value > 0x7F);
   117             writeByte(byte);
   118             value >>= 7;
   119         } while (value);
   120     }
   121     void writeSigned(int32_t v) {
   122         bool isNegative = v < 0;
   123         uint32_t value = isNegative ? -v : v;
   124         uint8_t byte = ((value & 0x3F) << 2) | ((value > 0x3F) << 1) | uint32_t(isNegative);
   125         writeByte(byte);
   127         // Write out the rest of the bytes, if needed.
   128         value >>= 6;
   129         if (value == 0)
   130             return;
   131         writeUnsigned(value);
   132     }
   133     void writeFixedUint32_t(uint32_t value) {
   134         writeByte(value & 0xFF);
   135         writeByte((value >> 8) & 0xFF);
   136         writeByte((value >> 16) & 0xFF);
   137         writeByte((value >> 24) & 0xFF);
   138     }
   139     void writeFixedUint16_t(uint16_t value) {
   140         writeByte(value & 0xFF);
   141         writeByte(value >> 8);
   142     }
   143     size_t length() const {
   144         return buffer_.length();
   145     }
   146     uint8_t *buffer() {
   147         return &buffer_[0];
   148     }
   149     const uint8_t *buffer() const {
   150         return &buffer_[0];
   151     }
   152     bool oom() const {
   153         return !enoughMemory_;
   154     }
   155 };
   157 CompactBufferReader::CompactBufferReader(const CompactBufferWriter &writer)
   158   : buffer_(writer.buffer()),
   159     end_(writer.buffer() + writer.length())
   160 {
   161 }
   163 } // namespace jit
   164 } // namespace js
   166 #endif /* jit_Compactbuffer_h */

mercurial