LCOV - code coverage report
Current view: top level - js/src/vm - TaggedProto.h (source / functions) Hit Total Coverage
Test: output.info Lines: 38 49 77.6 %
Date: 2017-07-14 16:53:18 Functions: 28 39 71.8 %
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 vm_TaggedProto_h
       8             : #define vm_TaggedProto_h
       9             : 
      10             : #include "gc/Tracer.h"
      11             : 
      12             : namespace js {
      13             : 
      14             : // Information about an object prototype, which can be either a particular
      15             : // object, null, or a lazily generated object. The latter is only used by
      16             : // certain kinds of proxies.
      17             : class TaggedProto
      18             : {
      19             :   public:
      20             :     static JSObject * const LazyProto;
      21             : 
      22      114333 :     TaggedProto() : proto(nullptr) {}
      23     2487373 :     TaggedProto(const TaggedProto& other) : proto(other.proto) {}
      24       79395 :     explicit TaggedProto(JSObject* proto) : proto(proto) {}
      25             : 
      26             :     uintptr_t toWord() const { return uintptr_t(proto); }
      27             : 
      28     1091621 :     bool isDynamic() const {
      29     1091621 :         return proto == LazyProto;
      30             :     }
      31     3540055 :     bool isObject() const {
      32             :         /* Skip nullptr and LazyProto. */
      33     3540055 :         return uintptr_t(proto) > uintptr_t(TaggedProto::LazyProto);
      34             :     }
      35     1397589 :     JSObject* toObject() const {
      36     1397589 :         MOZ_ASSERT(isObject());
      37     1397577 :         return proto;
      38             :     }
      39      353806 :     JSObject* toObjectOrNull() const {
      40      353806 :         MOZ_ASSERT(!proto || isObject());
      41      353806 :         return proto;
      42             :     }
      43        5132 :     JSObject* raw() const { return proto; }
      44             : 
      45      170179 :     bool operator ==(const TaggedProto& other) const { return proto == other.proto; }
      46           0 :     bool operator !=(const TaggedProto& other) const { return proto != other.proto; }
      47             : 
      48             :     HashNumber hashCode() const;
      49             : 
      50           0 :     void trace(JSTracer* trc) {
      51           0 :         if (isObject())
      52           0 :             TraceManuallyBarrieredEdge(trc, &proto, "TaggedProto");
      53           0 :     }
      54             : 
      55             :   private:
      56             :     JSObject* proto;
      57             : };
      58             : 
      59             : template <>
      60             : struct MovableCellHasher<TaggedProto>
      61             : {
      62             :     using Key = TaggedProto;
      63             :     using Lookup = TaggedProto;
      64             : 
      65         915 :     static bool hasHash(const Lookup& l) {
      66         915 :         return !l.isObject() || MovableCellHasher<JSObject*>::hasHash(l.toObject());
      67             :     }
      68      114782 :     static bool ensureHash(const Lookup& l) {
      69      114782 :         return !l.isObject() || MovableCellHasher<JSObject*>::ensureHash(l.toObject());
      70             :     }
      71      274302 :     static HashNumber hash(const Lookup& l) {
      72      274302 :         if (l.isDynamic())
      73         622 :             return uint64_t(1);
      74      273681 :         if (!l.isObject())
      75       34752 :             return uint64_t(0);
      76      238930 :         return MovableCellHasher<JSObject*>::hash(l.toObject());
      77             :     }
      78      238860 :     static bool match(const Key& k, const Lookup& l) {
      79      477721 :         return k.isDynamic() == l.isDynamic() &&
      80      955439 :                k.isObject() == l.isObject() &&
      81      871335 :                (!k.isObject() ||
      82      871335 :                 MovableCellHasher<JSObject*>::match(k.toObject(), l.toObject()));
      83             :     }
      84             : };
      85             : 
      86             : template <>
      87             : struct InternalBarrierMethods<TaggedProto>
      88             : {
      89             :     static void preBarrier(TaggedProto& proto);
      90             : 
      91             :     static void postBarrier(TaggedProto* vp, TaggedProto prev, TaggedProto next);
      92             : 
      93             :     static void readBarrier(const TaggedProto& proto);
      94             : 
      95           0 :     static bool isMarkable(const TaggedProto& proto) {
      96           0 :         return proto.isObject();
      97             :     }
      98             : };
      99             : 
     100             : template <class Wrapper>
     101      348535 : class WrappedPtrOperations<TaggedProto, Wrapper>
     102             : {
     103      217090 :     const TaggedProto& value() const {
     104      217090 :         return static_cast<const Wrapper*>(this)->get();
     105             :     }
     106             : 
     107             :   public:
     108             :     uintptr_t toWord() const { return value().toWord(); }
     109             :     inline bool isDynamic() const { return value().isDynamic(); }
     110      118112 :     inline bool isObject() const { return value().isObject(); }
     111       98900 :     inline JSObject* toObject() const { return value().toObject(); }
     112          69 :     inline JSObject* toObjectOrNull() const { return value().toObjectOrNull(); }
     113             :     JSObject* raw() const { return value().raw(); }
     114             :     HashNumber hashCode() const { return value().hashCode(); }
     115             :     uint64_t uniqueId() const { return value().uniqueId(); }
     116             : };
     117             : 
     118             : // If the TaggedProto is a JSObject pointer, convert to that type and call |f|
     119             : // with the pointer. If the TaggedProto is lazy, calls F::defaultValue.
     120             : template <typename F, typename... Args>
     121             : auto
     122           0 : DispatchTyped(F f, const TaggedProto& proto, Args&&... args)
     123             :   -> decltype(f(static_cast<JSObject*>(nullptr), mozilla::Forward<Args>(args)...))
     124             : {
     125           0 :     if (proto.isObject())
     126           0 :         return f(proto.toObject(), mozilla::Forward<Args>(args)...);
     127           0 :     return F::defaultValue(proto);
     128             : }
     129             : 
     130             : // Since JSObject pointers are either nullptr or a valid object and since the
     131             : // object layout of TaggedProto is identical to a bare object pointer, we can
     132             : // safely treat a pointer to an already-rooted object (e.g. HandleObject) as a
     133             : // pointer to a TaggedProto.
     134             : inline Handle<TaggedProto>
     135      124656 : AsTaggedProto(HandleObject obj)
     136             : {
     137             :     static_assert(sizeof(JSObject*) == sizeof(TaggedProto),
     138             :                   "TaggedProto must be binary compatible with JSObject");
     139             :     return Handle<TaggedProto>::fromMarkedLocation(
     140      124656 :             reinterpret_cast<TaggedProto const*>(obj.address()));
     141             : }
     142             : 
     143             : } // namespace js
     144             : 
     145             : #endif // vm_TaggedProto_h

Generated by: LCOV version 1.13