LCOV - code coverage report
Current view: top level - js/src/vm - Symbol.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 21 74 28.4 %
Date: 2017-07-14 16:53:18 Functions: 4 8 50.0 %
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             : #include "vm/Symbol.h"
       8             : 
       9             : #include "jscntxt.h"
      10             : #include "jscompartment.h"
      11             : 
      12             : #include "builtin/SymbolObject.h"
      13             : #include "gc/Allocator.h"
      14             : #include "gc/Rooting.h"
      15             : #include "vm/StringBuffer.h"
      16             : 
      17             : #include "jscompartmentinlines.h"
      18             : 
      19             : using JS::Symbol;
      20             : using namespace js;
      21             : 
      22             : Symbol*
      23          56 : Symbol::newInternal(JSContext* cx, JS::SymbolCode code, uint32_t hash, JSAtom* description,
      24             :                     AutoLockForExclusiveAccess& lock)
      25             : {
      26          56 :     MOZ_ASSERT(cx->compartment() == cx->atomsCompartment(lock));
      27             : 
      28             :     // Following js::AtomizeString, we grudgingly forgo last-ditch GC here.
      29          56 :     Symbol* p = Allocate<JS::Symbol, NoGC>(cx);
      30          56 :     if (!p) {
      31           0 :         ReportOutOfMemory(cx);
      32           0 :         return nullptr;
      33             :     }
      34          56 :     return new (p) Symbol(code, hash, description);
      35             : }
      36             : 
      37             : Symbol*
      38          56 : Symbol::new_(JSContext* cx, JS::SymbolCode code, JSString* description)
      39             : {
      40          56 :     JSAtom* atom = nullptr;
      41          56 :     if (description) {
      42          56 :         atom = AtomizeString(cx, description);
      43          56 :         if (!atom)
      44           0 :             return nullptr;
      45             :     }
      46             : 
      47             :     // Lock to allocate. If symbol allocation becomes a bottleneck, this can
      48             :     // probably be replaced with an assertion that we're on the active thread.
      49         112 :     AutoLockForExclusiveAccess lock(cx);
      50             :     Symbol* sym;
      51             :     {
      52         112 :         AutoAtomsCompartment ac(cx, lock);
      53          56 :         sym = newInternal(cx, code, cx->compartment()->randomHashCode(), atom, lock);
      54             :     }
      55          56 :     if (sym)
      56          56 :         cx->markAtom(sym);
      57          56 :     return sym;
      58             : }
      59             : 
      60             : Symbol*
      61           0 : Symbol::for_(JSContext* cx, HandleString description)
      62             : {
      63           0 :     JSAtom* atom = AtomizeString(cx, description);
      64           0 :     if (!atom)
      65           0 :         return nullptr;
      66             : 
      67           0 :     AutoLockForExclusiveAccess lock(cx);
      68             : 
      69           0 :     SymbolRegistry& registry = cx->symbolRegistry(lock);
      70           0 :     SymbolRegistry::AddPtr p = registry.lookupForAdd(atom);
      71           0 :     if (p) {
      72           0 :         cx->markAtom(*p);
      73           0 :         return *p;
      74             :     }
      75             : 
      76             :     Symbol* sym;
      77             :     {
      78           0 :         AutoAtomsCompartment ac(cx, lock);
      79           0 :         sym = newInternal(cx, SymbolCode::InSymbolRegistry, atom->hash(), atom, lock);
      80           0 :         if (!sym)
      81           0 :             return nullptr;
      82             : 
      83             :         // p is still valid here because we have held the lock since the
      84             :         // lookupForAdd call, and newInternal can't GC.
      85           0 :         if (!registry.add(p, sym)) {
      86             :             // SystemAllocPolicy does not report OOM.
      87           0 :             ReportOutOfMemory(cx);
      88           0 :             return nullptr;
      89             :         }
      90             :     }
      91           0 :     cx->markAtom(sym);
      92           0 :     return sym;
      93             : }
      94             : 
      95             : #ifdef DEBUG
      96             : void
      97           0 : Symbol::dump(FILE* fp)
      98             : {
      99           0 :     if (isWellKnownSymbol()) {
     100             :         // All the well-known symbol names are ASCII.
     101           0 :         description_->dumpCharsNoNewline(fp);
     102           0 :     } else if (code_ == SymbolCode::InSymbolRegistry || code_ == SymbolCode::UniqueSymbol) {
     103           0 :         fputs(code_ == SymbolCode::InSymbolRegistry ? "Symbol.for(" : "Symbol(", fp);
     104             : 
     105           0 :         if (description_)
     106           0 :             description_->dumpCharsNoNewline(fp);
     107             :         else
     108           0 :             fputs("undefined", fp);
     109             : 
     110           0 :         fputc(')', fp);
     111             : 
     112           0 :         if (code_ == SymbolCode::UniqueSymbol)
     113           0 :             fprintf(fp, "@%p", (void*) this);
     114             :     } else {
     115           0 :         fprintf(fp, "<Invalid Symbol code=%u>", unsigned(code_));
     116             :     }
     117           0 : }
     118             : #endif  // DEBUG
     119             : 
     120             : bool
     121           0 : js::SymbolDescriptiveString(JSContext* cx, Symbol* sym, MutableHandleValue result)
     122             : {
     123             :     // steps 2-5
     124           0 :     StringBuffer sb(cx);
     125           0 :     if (!sb.append("Symbol("))
     126           0 :         return false;
     127           0 :     RootedString str(cx, sym->description());
     128           0 :     if (str) {
     129           0 :         if (!sb.append(str))
     130           0 :             return false;
     131             :     }
     132           0 :     if (!sb.append(')'))
     133           0 :         return false;
     134             : 
     135             :     // step 6
     136           0 :     str = sb.finishString();
     137           0 :     if (!str)
     138           0 :         return false;
     139           0 :     result.setString(str);
     140           0 :     return true;
     141             : }
     142             : 
     143             : bool
     144        2513 : js::IsSymbolOrSymbolWrapper(const Value& v)
     145             : {
     146        2513 :     return v.isSymbol() || (v.isObject() && v.toObject().is<SymbolObject>());
     147             : }
     148             : 
     149             : JS::Symbol*
     150        1252 : js::ToSymbolPrimitive(const Value& v)
     151             : {
     152        1252 :     MOZ_ASSERT(IsSymbolOrSymbolWrapper(v));
     153        1252 :     return v.isSymbol() ? v.toSymbol() : v.toObject().as<SymbolObject>().unbox();
     154             : }
     155             : 
     156             : 
     157             : JS::ubi::Node::Size
     158           0 : JS::ubi::Concrete<JS::Symbol>::size(mozilla::MallocSizeOf mallocSizeOf) const
     159             : {
     160             :     // If we start allocating symbols in the nursery, we will need to update
     161             :     // this method.
     162           0 :     MOZ_ASSERT(get().isTenured());
     163           0 :     return js::gc::Arena::thingSize(get().asTenured().getAllocKind());
     164             : }

Generated by: LCOV version 1.13