tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ShapeList.cpp (5598B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      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 #include "jit/ShapeList.h"
      8 
      9 #include "gc/GC.h"
     10 
     11 #include "vm/List-inl.h"
     12 
     13 using namespace js;
     14 using namespace js::jit;
     15 
     16 const JSClass ShapeListObject::class_ = {
     17    "JIT ShapeList",
     18    0,
     19    &classOps_,
     20 };
     21 
     22 const JSClassOps ShapeListObject::classOps_ = {
     23    nullptr,                 // addProperty
     24    nullptr,                 // delProperty
     25    nullptr,                 // enumerate
     26    nullptr,                 // newEnumerate
     27    nullptr,                 // resolve
     28    nullptr,                 // mayResolve
     29    nullptr,                 // finalize
     30    nullptr,                 // call
     31    nullptr,                 // construct
     32    ShapeListObject::trace,  // trace
     33 };
     34 
     35 /* static */ ShapeListObject* ShapeListObject::create(JSContext* cx) {
     36  NativeObject* obj = NewTenuredObjectWithGivenProto(cx, &class_, nullptr);
     37  if (!obj) {
     38    return nullptr;
     39  }
     40 
     41  // Register this object so the GC can sweep its weak pointers.
     42  if (!cx->zone()->registerObjectWithWeakPointers(obj)) {
     43    ReportOutOfMemory(cx);
     44    return nullptr;
     45  }
     46 
     47  return &obj->as<ShapeListObject>();
     48 }
     49 
     50 Shape* ShapeListObject::get(uint32_t index) const {
     51  Shape* shape = getUnbarriered(index);
     52  gc::ReadBarrier(shape);
     53  return shape;
     54 }
     55 
     56 Shape* ShapeListObject::getUnbarriered(uint32_t index) const {
     57  Value value = ListObject::get(index);
     58  return static_cast<Shape*>(value.toPrivate());
     59 }
     60 
     61 void ShapeListObject::trace(JSTracer* trc, JSObject* obj) {
     62  if (trc->traceWeakEdges()) {
     63    obj->as<ShapeListObject>().traceWeak(trc);
     64  }
     65 }
     66 
     67 bool ShapeListObject::traceWeak(JSTracer* trc) {
     68  uint32_t length = getDenseInitializedLength();
     69  if (length == 0) {
     70    return false;  // Object may be uninitialized.
     71  }
     72 
     73  const HeapSlot* src = elements_;
     74  const HeapSlot* end = src + length;
     75  HeapSlot* dst = elements_;
     76  while (src != end) {
     77    Shape* shape = static_cast<Shape*>(src->toPrivate());
     78    MOZ_ASSERT(shape->is<Shape>());
     79    if (TraceManuallyBarrieredWeakEdge(trc, &shape, "ShapeListObject shape")) {
     80      dst->unbarrieredSet(PrivateValue(shape));
     81      dst++;
     82    }
     83    src++;
     84  }
     85 
     86  MOZ_ASSERT(dst <= end);
     87  uint32_t newLength = dst - elements_;
     88  setDenseInitializedLength(newLength);
     89 
     90  if (length != newLength) {
     91    JitSpew(JitSpew_StubFolding, "Cleared %u/%u shapes from %p",
     92            length - newLength, length, this);
     93  }
     94 
     95  return length != 0;
     96 }
     97 
     98 const JSClass ShapeListWithOffsetsObject::class_ = {
     99    "JIT ShapeList",
    100    0,
    101    &classOps_,
    102 };
    103 
    104 const JSClassOps ShapeListWithOffsetsObject::classOps_ = {
    105    nullptr,                            // addProperty
    106    nullptr,                            // delProperty
    107    nullptr,                            // enumerate
    108    nullptr,                            // newEnumerate
    109    nullptr,                            // resolve
    110    nullptr,                            // mayResolve
    111    nullptr,                            // finalize
    112    nullptr,                            // call
    113    nullptr,                            // construct
    114    ShapeListWithOffsetsObject::trace,  // trace
    115 };
    116 
    117 /* static */ ShapeListWithOffsetsObject* ShapeListWithOffsetsObject::create(
    118    JSContext* cx) {
    119  NativeObject* obj = NewTenuredObjectWithGivenProto(cx, &class_, nullptr);
    120  if (!obj) {
    121    return nullptr;
    122  }
    123 
    124  // Register this object so the GC can sweep its weak pointers.
    125  if (!cx->zone()->registerObjectWithWeakPointers(obj)) {
    126    ReportOutOfMemory(cx);
    127    return nullptr;
    128  }
    129 
    130  return &obj->as<ShapeListWithOffsetsObject>();
    131 }
    132 
    133 Shape* ShapeListWithOffsetsObject::getShape(uint32_t index) const {
    134  Shape* shape = getShapeUnbarriered(index);
    135  gc::ReadBarrier(shape);
    136  return shape;
    137 }
    138 
    139 Shape* ShapeListWithOffsetsObject::getShapeUnbarriered(uint32_t index) const {
    140  Value value = ListObject::get(index * 2);
    141  return static_cast<Shape*>(value.toPrivate());
    142 }
    143 
    144 uint32_t ShapeListWithOffsetsObject::getOffset(uint32_t index) const {
    145  Value value = ListObject::get(index * 2 + 1);
    146  return value.toPrivateUint32();
    147 }
    148 
    149 uint32_t ShapeListWithOffsetsObject::numShapes() const {
    150  MOZ_ASSERT(length() % 2 == 0);
    151  return length() / 2;
    152 };
    153 
    154 void ShapeListWithOffsetsObject::trace(JSTracer* trc, JSObject* obj) {
    155  if (trc->traceWeakEdges()) {
    156    obj->as<ShapeListWithOffsetsObject>().traceWeak(trc);
    157  }
    158 }
    159 
    160 bool ShapeListWithOffsetsObject::traceWeak(JSTracer* trc) {
    161  uint32_t length = getDenseInitializedLength();
    162  if (length == 0) {
    163    return false;  // Object may be uninitialized.
    164  }
    165 
    166  const HeapSlot* src = elements_;
    167  const HeapSlot* end = src + length;
    168  HeapSlot* dst = elements_;
    169  while (src != end) {
    170    Shape* shape = static_cast<Shape*>(src[0].toPrivate());
    171    uint32_t offset = src[1].toPrivateUint32();
    172    MOZ_ASSERT(shape->is<Shape>());
    173    if (TraceManuallyBarrieredWeakEdge(trc, &shape,
    174                                       "ShapeListWithOffsetsObject shape")) {
    175      dst[0].unbarrieredSet(PrivateValue(shape));
    176      dst[1].unbarrieredSet(PrivateUint32Value(offset));
    177      dst += 2;
    178    }
    179    src += 2;
    180  }
    181 
    182  MOZ_ASSERT(dst <= end);
    183  uint32_t newLength = dst - elements_;
    184  setDenseInitializedLength(newLength);
    185 
    186  if (length != newLength) {
    187    JitSpew(JitSpew_StubFolding, "Cleared %u/%u shapes from %p",
    188            (length - newLength) / 2, (length) / 2, this);
    189  }
    190 
    191  return length != 0;
    192 }