/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sts=2 et sw=2 tw=80: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "jit/ShapeList.h" #include "gc/GC.h" #include "vm/List-inl.h" using namespace js; using namespace js::jit; const JSClass ShapeListObject::class_ = { "JIT ShapeList", 0, &classOps_, }; const JSClassOps ShapeListObject::classOps_ = { nullptr, // addProperty nullptr, // delProperty nullptr, // enumerate nullptr, // newEnumerate nullptr, // resolve nullptr, // mayResolve nullptr, // finalize nullptr, // call nullptr, // construct ShapeListObject::trace, // trace }; /* static */ ShapeListObject* ShapeListObject::create(JSContext* cx) { NativeObject* obj = NewTenuredObjectWithGivenProto(cx, &class_, nullptr); if (!obj) { return nullptr; } // Register this object so the GC can sweep its weak pointers. if (!cx->zone()->registerObjectWithWeakPointers(obj)) { ReportOutOfMemory(cx); return nullptr; } return &obj->as(); } Shape* ShapeListObject::get(uint32_t index) const { Shape* shape = getUnbarriered(index); gc::ReadBarrier(shape); return shape; } Shape* ShapeListObject::getUnbarriered(uint32_t index) const { Value value = ListObject::get(index); return static_cast(value.toPrivate()); } void ShapeListObject::trace(JSTracer* trc, JSObject* obj) { if (trc->traceWeakEdges()) { obj->as().traceWeak(trc); } } bool ShapeListObject::traceWeak(JSTracer* trc) { uint32_t length = getDenseInitializedLength(); if (length == 0) { return false; // Object may be uninitialized. } const HeapSlot* src = elements_; const HeapSlot* end = src + length; HeapSlot* dst = elements_; while (src != end) { Shape* shape = static_cast(src->toPrivate()); MOZ_ASSERT(shape->is()); if (TraceManuallyBarrieredWeakEdge(trc, &shape, "ShapeListObject shape")) { dst->unbarrieredSet(PrivateValue(shape)); dst++; } src++; } MOZ_ASSERT(dst <= end); uint32_t newLength = dst - elements_; setDenseInitializedLength(newLength); if (length != newLength) { JitSpew(JitSpew_StubFolding, "Cleared %u/%u shapes from %p", length - newLength, length, this); } return length != 0; }