diff options
Diffstat (limited to 'js/src/vm/Symbol.h')
-rw-r--r-- | js/src/vm/Symbol.h | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/js/src/vm/Symbol.h b/js/src/vm/Symbol.h new file mode 100644 index 000000000..2872fa3c6 --- /dev/null +++ b/js/src/vm/Symbol.h @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * 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/. */ + +#ifndef vm_Symbol_h +#define vm_Symbol_h + +#include "mozilla/Attributes.h" + +#include <stdio.h> + +#include "jsalloc.h" +#include "jsapi.h" + +#include "gc/Barrier.h" +#include "gc/Marking.h" +#include "js/GCHashTable.h" +#include "js/RootingAPI.h" +#include "js/TypeDecls.h" +#include "js/Utility.h" +#include "vm/String.h" + +namespace js { +class AutoLockForExclusiveAccess; +} // namespace js + +namespace JS { + +class Symbol : public js::gc::TenuredCell +{ + private: + SymbolCode code_; + + // Each Symbol gets its own hash code so that we don't have to use + // addresses as hash codes (a security hazard). + js::HashNumber hash_; + + JSAtom* description_; + + // The minimum allocation size is sizeof(JSString): 16 bytes on 32-bit + // architectures and 24 bytes on 64-bit. A size_t of padding makes Symbol + // the minimum size on both. + size_t unused_; + + Symbol(SymbolCode code, js::HashNumber hash, JSAtom* desc) + : code_(code), hash_(hash), description_(desc) + { + // Silence warnings about unused_ being... unused. + (void)unused_; + } + + Symbol(const Symbol&) = delete; + void operator=(const Symbol&) = delete; + + static Symbol* + newInternal(js::ExclusiveContext* cx, SymbolCode code, js::HashNumber hash, + JSAtom* description, js::AutoLockForExclusiveAccess& lock); + + public: + static Symbol* new_(js::ExclusiveContext* cx, SymbolCode code, JSString* description); + static Symbol* for_(js::ExclusiveContext* cx, js::HandleString description); + + JSAtom* description() const { return description_; } + SymbolCode code() const { return code_; } + js::HashNumber hash() const { return hash_; } + + bool isWellKnownSymbol() const { return uint32_t(code_) < WellKnownSymbolLimit; } + + static const JS::TraceKind TraceKind = JS::TraceKind::Symbol; + inline void traceChildren(JSTracer* trc) { + if (description_) + js::TraceManuallyBarrieredEdge(trc, &description_, "description"); + } + inline void finalize(js::FreeOp*) {} + + static MOZ_ALWAYS_INLINE void writeBarrierPre(Symbol* thing) { + if (thing && !thing->isWellKnownSymbol()) + thing->asTenured().writeBarrierPre(thing); + } + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { + return mallocSizeOf(this); + } + +#ifdef DEBUG + void dump(FILE* fp = stderr); +#endif +}; + +} /* namespace JS */ + +namespace js { + +/* Hash policy used by the SymbolRegistry. */ +struct HashSymbolsByDescription +{ + typedef JS::Symbol* Key; + typedef JSAtom* Lookup; + + static HashNumber hash(Lookup l) { + return HashNumber(l->hash()); + } + static bool match(Key sym, Lookup l) { + return sym->description() == l; + } +}; + +/* + * The runtime-wide symbol registry, used to implement Symbol.for(). + * + * ES6 draft rev 25 (2014 May 22) calls this the GlobalSymbolRegistry List. In + * our implementation, it is not global. There is one per JSRuntime. The + * symbols in the symbol registry, like all symbols, are allocated in the atoms + * compartment and can be directly referenced from any compartment. They are + * never shared across runtimes. + * + * The memory management strategy here is modeled after js::AtomSet. It's like + * a WeakSet. The registry itself does not keep any symbols alive; when a + * symbol in the registry is collected, the registry entry is removed. No GC + * nondeterminism is exposed to scripts, because there is no API for + * enumerating the symbol registry, querying its size, etc. + */ +class SymbolRegistry : public GCHashSet<ReadBarrieredSymbol, + HashSymbolsByDescription, + SystemAllocPolicy> +{ + public: + SymbolRegistry() {} +}; + +} /* namespace js */ + +namespace js { + +// ES6 rev 27 (2014 Aug 24) 19.4.3.3 +bool +SymbolDescriptiveString(JSContext* cx, JS::Symbol* sym, JS::MutableHandleValue result); + +bool +IsSymbolOrSymbolWrapper(const JS::Value& v); + +JS::Symbol* +ToSymbolPrimitive(const JS::Value& v); + +} /* namespace js */ + +#endif /* vm_Symbol_h */ |