1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
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/. */
7 #include "vm/SymbolType.h"
9 #include "gc/HashUtil.h"
10 #include "util/StringBuffer.h"
11 #include "vm/JSContext.h"
14 #include "vm/Realm-inl.h"
19 Symbol
* Symbol::newInternal(JSContext
* cx
, JS::SymbolCode code
, uint32_t hash
,
20 Handle
<JSAtom
*> description
) {
21 MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx
->runtime()));
22 AutoAllocInAtomsZone
az(cx
);
23 return cx
->newCell
<Symbol
>(code
, hash
, description
);
26 Symbol
* Symbol::new_(JSContext
* cx
, JS::SymbolCode code
,
27 HandleString description
) {
28 Rooted
<JSAtom
*> atom(cx
);
30 atom
= AtomizeString(cx
, description
);
36 Symbol
* sym
= newInternal(cx
, code
, cx
->runtime()->randomHashCode(), atom
);
43 Symbol
* Symbol::newWellKnown(JSContext
* cx
, JS::SymbolCode code
,
44 Handle
<PropertyName
*> description
) {
45 return newInternal(cx
, code
, cx
->runtime()->randomHashCode(), description
);
48 Symbol
* Symbol::for_(JSContext
* cx
, HandleString description
) {
49 Rooted
<JSAtom
*> atom(cx
, AtomizeString(cx
, description
));
54 SymbolRegistry
& registry
= cx
->symbolRegistry();
55 DependentAddPtr
<SymbolRegistry
> p(cx
, registry
, atom
);
61 // Rehash the hash of the atom to give the corresponding symbol a hash
62 // that is different than the hash of the corresponding atom.
63 HashNumber hash
= mozilla::HashGeneric(atom
->hash());
64 Symbol
* sym
= newInternal(cx
, SymbolCode::InSymbolRegistry
, hash
, atom
);
69 if (!p
.add(cx
, registry
, atom
, sym
)) {
77 #if defined(DEBUG) || defined(JS_JITSPEW)
79 js::Fprinter
out(stderr
);
83 void Symbol::dump(js::GenericPrinter
& out
) {
84 if (isWellKnownSymbol()) {
85 // All the well-known symbol names are ASCII.
86 description()->dumpCharsNoNewline(out
);
87 } else if (code_
== SymbolCode::InSymbolRegistry
||
88 code_
== SymbolCode::UniqueSymbol
) {
89 out
.printf(code_
== SymbolCode::InSymbolRegistry
? "Symbol.for("
93 description()->dumpCharsNoNewline(out
);
95 out
.printf("undefined");
100 if (code_
== SymbolCode::UniqueSymbol
) {
101 out
.printf("@%p", (void*)this);
103 } else if (code_
== SymbolCode::PrivateNameSymbol
) {
104 MOZ_ASSERT(description());
106 description()->dumpCharsNoNewline(out
);
107 out
.printf("@%p", (void*)this);
109 out
.printf("<Invalid Symbol code=%u>", unsigned(code_
));
112 #endif // defined(DEBUG) || defined(JS_JITSPEW)
114 bool js::SymbolDescriptiveString(JSContext
* cx
, Symbol
* sym
,
115 MutableHandleValue result
) {
117 JSStringBuilder
sb(cx
);
118 if (!sb
.append("Symbol(")) {
121 if (JSAtom
* desc
= sym
->description()) {
122 if (!sb
.append(desc
)) {
126 if (!sb
.append(')')) {
131 JSString
* str
= sb
.finishString();
135 result
.setString(str
);
139 JS::ubi::Node::Size
JS::ubi::Concrete
<JS::Symbol
>::size(
140 mozilla::MallocSizeOf mallocSizeOf
) const {
141 // If we start allocating symbols in the nursery, we will need to update
143 MOZ_ASSERT(get().isTenured());
144 return js::gc::Arena::thingSize(get().asTenured().getAllocKind());