LCOV - code coverage report
Current view: top level - js/src/vm - Symbol.h (source / functions) Hit Total Coverage
Test: output.info Lines: 10 24 41.7 %
Date: 2017-07-14 16:53:18 Functions: 7 13 53.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_Symbol_h
       8             : #define vm_Symbol_h
       9             : 
      10             : #include "mozilla/Attributes.h"
      11             : 
      12             : #include <stdio.h>
      13             : 
      14             : #include "jsalloc.h"
      15             : #include "jsapi.h"
      16             : 
      17             : #include "gc/Barrier.h"
      18             : #include "gc/Marking.h"
      19             : #include "js/GCHashTable.h"
      20             : #include "js/RootingAPI.h"
      21             : #include "js/TypeDecls.h"
      22             : #include "js/Utility.h"
      23             : #include "vm/String.h"
      24             : 
      25             : namespace js {
      26             : class AutoLockForExclusiveAccess;
      27             : } // namespace js
      28             : 
      29             : namespace JS {
      30             : 
      31             : class Symbol : public js::gc::TenuredCell
      32             : {
      33             :   private:
      34             :     SymbolCode code_;
      35             : 
      36             :     // Each Symbol gets its own hash code so that we don't have to use
      37             :     // addresses as hash codes (a security hazard).
      38             :     js::HashNumber hash_;
      39             : 
      40             :     JSAtom* description_;
      41             : 
      42             :     // The minimum allocation size is sizeof(JSString): 16 bytes on 32-bit
      43             :     // architectures and 24 bytes on 64-bit.  A size_t of padding makes Symbol
      44             :     // the minimum size on both.
      45             :     size_t unused_;
      46             : 
      47          56 :     Symbol(SymbolCode code, js::HashNumber hash, JSAtom* desc)
      48          56 :         : code_(code), hash_(hash), description_(desc)
      49             :     {
      50             :         // Silence warnings about unused_ being... unused.
      51             :         (void)unused_;
      52          56 :     }
      53             : 
      54             :     Symbol(const Symbol&) = delete;
      55             :     void operator=(const Symbol&) = delete;
      56             : 
      57             :     static Symbol*
      58             :     newInternal(JSContext* cx, SymbolCode code, js::HashNumber hash,
      59             :                 JSAtom* description, js::AutoLockForExclusiveAccess& lock);
      60             : 
      61             :   public:
      62             :     static Symbol* new_(JSContext* cx, SymbolCode code, JSString* description);
      63             :     static Symbol* for_(JSContext* cx, js::HandleString description);
      64             : 
      65        2335 :     JSAtom* description() const { return description_; }
      66          86 :     SymbolCode code() const { return code_; }
      67        8768 :     js::HashNumber hash() const { return hash_; }
      68             : 
      69        6164 :     bool isWellKnownSymbol() const { return uint32_t(code_) < WellKnownSymbolLimit; }
      70             : 
      71             :     // An "interesting symbol" is a well-known symbol, like @@toStringTag,
      72             :     // that's often looked up on random objects but is usually not present. We
      73             :     // optimize this by setting a flag on the object's BaseShape when such
      74             :     // symbol properties are added, so we can optimize lookups on objects that
      75             :     // don't have the BaseShape flag.
      76        4350 :     bool isInterestingSymbol() const {
      77        4350 :         return code_ == SymbolCode::toStringTag || code_ == SymbolCode::toPrimitive;
      78             :     }
      79             : 
      80             :     static const JS::TraceKind TraceKind = JS::TraceKind::Symbol;
      81           0 :     inline void traceChildren(JSTracer* trc) {
      82           0 :         if (description_)
      83           0 :             js::TraceManuallyBarrieredEdge(trc, &description_, "description");
      84           0 :     }
      85           0 :     inline void finalize(js::FreeOp*) {}
      86             : 
      87           0 :     static MOZ_ALWAYS_INLINE void writeBarrierPre(Symbol* thing) {
      88           0 :         if (thing && !thing->isWellKnownSymbol())
      89           0 :             thing->asTenured().writeBarrierPre(thing);
      90           0 :     }
      91             : 
      92             :     size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
      93             :         return mallocSizeOf(this);
      94             :     }
      95             : 
      96             : #ifdef DEBUG
      97             :     void dump(FILE* fp = stderr);
      98             : #endif
      99             : };
     100             : 
     101             : } /* namespace JS */
     102             : 
     103             : namespace js {
     104             : 
     105             : /* Hash policy used by the SymbolRegistry. */
     106             : struct HashSymbolsByDescription
     107             : {
     108             :     typedef JS::Symbol* Key;
     109             :     typedef JSAtom* Lookup;
     110             : 
     111           0 :     static HashNumber hash(Lookup l) {
     112           0 :         return HashNumber(l->hash());
     113             :     }
     114           0 :     static bool match(Key sym, Lookup l) {
     115           0 :         return sym->description() == l;
     116             :     }
     117             : };
     118             : 
     119             : /*
     120             :  * The runtime-wide symbol registry, used to implement Symbol.for().
     121             :  *
     122             :  * ES6 draft rev 25 (2014 May 22) calls this the GlobalSymbolRegistry List. In
     123             :  * our implementation, it is not global. There is one per JSRuntime. The
     124             :  * symbols in the symbol registry, like all symbols, are allocated in the atoms
     125             :  * compartment and can be directly referenced from any compartment. They are
     126             :  * never shared across runtimes.
     127             :  *
     128             :  * The memory management strategy here is modeled after js::AtomSet. It's like
     129             :  * a WeakSet. The registry itself does not keep any symbols alive; when a
     130             :  * symbol in the registry is collected, the registry entry is removed. No GC
     131             :  * nondeterminism is exposed to scripts, because there is no API for
     132             :  * enumerating the symbol registry, querying its size, etc.
     133             :  */
     134           0 : class SymbolRegistry : public GCHashSet<ReadBarrieredSymbol,
     135             :                                         HashSymbolsByDescription,
     136             :                                         SystemAllocPolicy>
     137             : {
     138             :   public:
     139           4 :     SymbolRegistry() {}
     140             : };
     141             : 
     142             : } /* namespace js */
     143             : 
     144             : namespace js {
     145             : 
     146             : // ES6 rev 27 (2014 Aug 24) 19.4.3.3
     147             : bool
     148             : SymbolDescriptiveString(JSContext* cx, JS::Symbol* sym, JS::MutableHandleValue result);
     149             : 
     150             : bool
     151             : IsSymbolOrSymbolWrapper(const JS::Value& v);
     152             : 
     153             : JS::Symbol*
     154             : ToSymbolPrimitive(const JS::Value& v);
     155             : 
     156             : } /* namespace js */
     157             : 
     158             : #endif /* vm_Symbol_h */

Generated by: LCOV version 1.13