Bug 1867190 - Add prefs for PHC probablities r=glandium
[gecko.git] / js / src / vm / SymbolType.cpp
blobca7ab7df6708f29d576cc934158405e7c306706c
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"
12 #include "vm/Realm.h"
14 #include "vm/Realm-inl.h"
16 using JS::Symbol;
17 using namespace js;
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);
29 if (description) {
30 atom = AtomizeString(cx, description);
31 if (!atom) {
32 return nullptr;
36 Symbol* sym = newInternal(cx, code, cx->runtime()->randomHashCode(), atom);
37 if (sym) {
38 cx->markAtom(sym);
40 return sym;
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));
50 if (!atom) {
51 return nullptr;
54 SymbolRegistry& registry = cx->symbolRegistry();
55 DependentAddPtr<SymbolRegistry> p(cx, registry, atom);
56 if (p) {
57 cx->markAtom(*p);
58 return *p;
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);
65 if (!sym) {
66 return nullptr;
69 if (!p.add(cx, registry, atom, sym)) {
70 return nullptr;
73 cx->markAtom(sym);
74 return sym;
77 #if defined(DEBUG) || defined(JS_JITSPEW)
78 void Symbol::dump() {
79 js::Fprinter out(stderr);
80 dump(out);
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("
90 : "Symbol(");
92 if (description()) {
93 description()->dumpCharsNoNewline(out);
94 } else {
95 out.printf("undefined");
98 out.putChar(')');
100 if (code_ == SymbolCode::UniqueSymbol) {
101 out.printf("@%p", (void*)this);
103 } else if (code_ == SymbolCode::PrivateNameSymbol) {
104 MOZ_ASSERT(description());
105 out.putChar('#');
106 description()->dumpCharsNoNewline(out);
107 out.printf("@%p", (void*)this);
108 } else {
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) {
116 // steps 2-5
117 JSStringBuilder sb(cx);
118 if (!sb.append("Symbol(")) {
119 return false;
121 if (JSAtom* desc = sym->description()) {
122 if (!sb.append(desc)) {
123 return false;
126 if (!sb.append(')')) {
127 return false;
130 // step 6
131 JSString* str = sb.finishString();
132 if (!str) {
133 return false;
135 result.setString(str);
136 return true;
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
142 // this method.
143 MOZ_ASSERT(get().isTenured());
144 return js::gc::Arena::thingSize(get().asTenured().getAllocKind());