diff options
Diffstat (limited to 'js/src/jsatom.h')
-rw-r--r-- | js/src/jsatom.h | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/js/src/jsatom.h b/js/src/jsatom.h new file mode 100644 index 000000000..496dcbb4c --- /dev/null +++ b/js/src/jsatom.h @@ -0,0 +1,240 @@ +/* -*- 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 jsatom_h +#define jsatom_h + +#include "mozilla/HashFunctions.h" + +#include "jsalloc.h" + +#include "gc/Barrier.h" +#include "gc/Marking.h" +#include "gc/Rooting.h" +#include "js/GCAPI.h" +#include "js/GCHashTable.h" +#include "vm/CommonPropertyNames.h" + +class JSAtom; +class JSAutoByteString; + +namespace js { + +/* + * Return a printable, lossless char[] representation of a string-type atom. + * The lifetime of the result matches the lifetime of bytes. + */ +extern const char* +AtomToPrintableString(ExclusiveContext* cx, JSAtom* atom, JSAutoByteString* bytes); + +class AtomStateEntry +{ + uintptr_t bits; + + static const uintptr_t NO_TAG_MASK = uintptr_t(-1) - 1; + + public: + AtomStateEntry() : bits(0) {} + AtomStateEntry(const AtomStateEntry& other) : bits(other.bits) {} + AtomStateEntry(JSAtom* ptr, bool tagged) + : bits(uintptr_t(ptr) | uintptr_t(tagged)) + { + MOZ_ASSERT((uintptr_t(ptr) & 0x1) == 0); + } + + bool isPinned() const { + return bits & 0x1; + } + + /* + * Non-branching code sequence. Note that the const_cast is safe because + * the hash function doesn't consider the tag to be a portion of the key. + */ + void setPinned(bool pinned) const { + const_cast<AtomStateEntry*>(this)->bits |= uintptr_t(pinned); + } + + JSAtom* asPtr(ExclusiveContext* cx) const; + JSAtom* asPtrUnbarriered() const; + + bool needsSweep() { + JSAtom* atom = asPtrUnbarriered(); + return gc::IsAboutToBeFinalizedUnbarriered(&atom); + } +}; + +struct AtomHasher +{ + struct Lookup + { + union { + const JS::Latin1Char* latin1Chars; + const char16_t* twoByteChars; + }; + bool isLatin1; + size_t length; + const JSAtom* atom; /* Optional. */ + JS::AutoCheckCannotGC nogc; + + HashNumber hash; + + Lookup(const char16_t* chars, size_t length) + : twoByteChars(chars), isLatin1(false), length(length), atom(nullptr) + { + hash = mozilla::HashString(chars, length); + } + Lookup(const JS::Latin1Char* chars, size_t length) + : latin1Chars(chars), isLatin1(true), length(length), atom(nullptr) + { + hash = mozilla::HashString(chars, length); + } + inline explicit Lookup(const JSAtom* atom); + }; + + static HashNumber hash(const Lookup& l) { return l.hash; } + static inline bool match(const AtomStateEntry& entry, const Lookup& lookup); + static void rekey(AtomStateEntry& k, const AtomStateEntry& newKey) { k = newKey; } +}; + +using AtomSet = JS::GCHashSet<AtomStateEntry, AtomHasher, SystemAllocPolicy>; + +// This class is a wrapper for AtomSet that is used to ensure the AtomSet is +// not modified. It should only expose read-only methods from AtomSet. +// Note however that the atoms within the table can be marked during GC. +class FrozenAtomSet +{ + AtomSet* mSet; + +public: + // This constructor takes ownership of the passed-in AtomSet. + explicit FrozenAtomSet(AtomSet* set) { mSet = set; } + + ~FrozenAtomSet() { js_delete(mSet); } + + AtomSet::Ptr readonlyThreadsafeLookup(const AtomSet::Lookup& l) const; + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { + return mSet->sizeOfIncludingThis(mallocSizeOf); + } + + typedef AtomSet::Range Range; + + AtomSet::Range all() const { return mSet->all(); } +}; + +class PropertyName; + +} /* namespace js */ + +extern bool +AtomIsPinned(JSContext* cx, JSAtom* atom); + +/* Well-known predefined C strings. */ +#define DECLARE_PROTO_STR(name,code,init,clasp) extern const char js_##name##_str[]; +JS_FOR_EACH_PROTOTYPE(DECLARE_PROTO_STR) +#undef DECLARE_PROTO_STR + +#define DECLARE_CONST_CHAR_STR(idpart, id, text) extern const char js_##idpart##_str[]; +FOR_EACH_COMMON_PROPERTYNAME(DECLARE_CONST_CHAR_STR) +#undef DECLARE_CONST_CHAR_STR + +/* Constant strings that are not atomized. */ +extern const char js_break_str[]; +extern const char js_case_str[]; +extern const char js_catch_str[]; +extern const char js_class_str[]; +extern const char js_close_str[]; +extern const char js_const_str[]; +extern const char js_continue_str[]; +extern const char js_debugger_str[]; +extern const char js_default_str[]; +extern const char js_do_str[]; +extern const char js_else_str[]; +extern const char js_enum_str[]; +extern const char js_export_str[]; +extern const char js_extends_str[]; +extern const char js_finally_str[]; +extern const char js_for_str[]; +extern const char js_getter_str[]; +extern const char js_if_str[]; +extern const char js_implements_str[]; +extern const char js_import_str[]; +extern const char js_in_str[]; +extern const char js_instanceof_str[]; +extern const char js_interface_str[]; +extern const char js_package_str[]; +extern const char js_private_str[]; +extern const char js_protected_str[]; +extern const char js_public_str[]; +extern const char js_send_str[]; +extern const char js_setter_str[]; +extern const char js_static_str[]; +extern const char js_super_str[]; +extern const char js_switch_str[]; +extern const char js_this_str[]; +extern const char js_try_str[]; +extern const char js_typeof_str[]; +extern const char js_void_str[]; +extern const char js_while_str[]; +extern const char js_with_str[]; + +namespace js { + +class AutoLockForExclusiveAccess; + +/* + * Atom tracing and garbage collection hooks. + */ +void +MarkAtoms(JSTracer* trc, AutoLockForExclusiveAccess& lock); + +void +MarkPermanentAtoms(JSTracer* trc); + +void +MarkWellKnownSymbols(JSTracer* trc); + +/* N.B. must correspond to boolean tagging behavior. */ +enum PinningBehavior +{ + DoNotPinAtom = false, + PinAtom = true +}; + +extern JSAtom* +Atomize(ExclusiveContext* cx, const char* bytes, size_t length, + js::PinningBehavior pin = js::DoNotPinAtom); + +template <typename CharT> +extern JSAtom* +AtomizeChars(ExclusiveContext* cx, const CharT* chars, size_t length, + js::PinningBehavior pin = js::DoNotPinAtom); + +extern JSAtom* +AtomizeUTF8Chars(JSContext* cx, const char* utf8Chars, size_t utf8ByteLength); + +extern JSAtom* +AtomizeString(ExclusiveContext* cx, JSString* str, js::PinningBehavior pin = js::DoNotPinAtom); + +template <AllowGC allowGC> +extern JSAtom* +ToAtom(ExclusiveContext* cx, typename MaybeRooted<Value, allowGC>::HandleType v); + +enum XDRMode { + XDR_ENCODE, + XDR_DECODE +}; + +template <XDRMode mode> +class XDRState; + +template<XDRMode mode> +bool +XDRAtom(XDRState<mode>* xdr, js::MutableHandleAtom atomp); + +} /* namespace js */ + +#endif /* jsatom_h */ |