diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/runtime/Identifier.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/runtime/Identifier.cpp')
-rw-r--r-- | Source/JavaScriptCore/runtime/Identifier.cpp | 126 |
1 files changed, 103 insertions, 23 deletions
diff --git a/Source/JavaScriptCore/runtime/Identifier.cpp b/Source/JavaScriptCore/runtime/Identifier.cpp index d26d9567c..3658d8772 100644 --- a/Source/JavaScriptCore/runtime/Identifier.cpp +++ b/Source/JavaScriptCore/runtime/Identifier.cpp @@ -25,7 +25,7 @@ #include "JSObject.h" #include "JSScope.h" #include "NumericStrings.h" -#include "JSCInlines.h" +#include "Operations.h" #include <new> #include <string.h> #include <wtf/Assertions.h> @@ -38,33 +38,121 @@ using WTF::ThreadSpecific; namespace JSC { -Ref<StringImpl> Identifier::add(VM* vm, const char* c) +IdentifierTable* createIdentifierTable() +{ + return new IdentifierTable; +} + +void deleteIdentifierTable(IdentifierTable* table) +{ + delete table; +} + +struct IdentifierASCIIStringTranslator { + static unsigned hash(const LChar* c) + { + return StringHasher::computeHashAndMaskTop8Bits(c); + } + + static bool equal(StringImpl* r, const LChar* s) + { + return Identifier::equal(r, s); + } + + static void translate(StringImpl*& location, const LChar* c, unsigned hash) + { + size_t length = strlen(reinterpret_cast<const char*>(c)); + location = &StringImpl::createFromLiteral(reinterpret_cast<const char*>(c), length).leakRef(); + location->setHash(hash); + } +}; + +struct IdentifierLCharFromUCharTranslator { + static unsigned hash(const CharBuffer<UChar>& buf) + { + return StringHasher::computeHashAndMaskTop8Bits(buf.s, buf.length); + } + + static bool equal(StringImpl* str, const CharBuffer<UChar>& buf) + { + return Identifier::equal(str, buf.s, buf.length); + } + + static void translate(StringImpl*& location, const CharBuffer<UChar>& buf, unsigned hash) + { + LChar* d; + StringImpl& r = StringImpl::createUninitialized(buf.length, d).leakRef(); + WTF::copyLCharsFromUCharSource(d, buf.s, buf.length); + r.setHash(hash); + location = &r; + } +}; + +PassRefPtr<StringImpl> Identifier::add(VM* vm, const char* c) { ASSERT(c); ASSERT(c[0]); if (!c[1]) - return *vm->smallStrings.singleCharacterStringRep(c[0]); + return add(vm, vm->smallStrings.singleCharacterStringRep(c[0])); + + IdentifierTable& identifierTable = *vm->identifierTable; + + HashSet<StringImpl*>::AddResult addResult = identifierTable.add<const LChar*, IdentifierASCIIStringTranslator>(reinterpret_cast<const LChar*>(c)); + + // If the string is newly-translated, then we need to adopt it. + // The boolean in the pair tells us if that is so. + RefPtr<StringImpl> addedString = addResult.isNewEntry ? adoptRef(*addResult.iterator) : *addResult.iterator; - return *AtomicStringImpl::add(c); + return addedString.release(); } -Ref<StringImpl> Identifier::add(ExecState* exec, const char* c) +PassRefPtr<StringImpl> Identifier::add(ExecState* exec, const char* c) { return add(&exec->vm(), c); } -Ref<StringImpl> Identifier::add8(VM* vm, const UChar* s, int length) +PassRefPtr<StringImpl> Identifier::add8(VM* vm, const UChar* s, int length) { if (length == 1) { UChar c = s[0]; ASSERT(c <= 0xff); if (canUseSingleCharacterString(c)) - return *vm->smallStrings.singleCharacterStringRep(c); + return add(vm, vm->smallStrings.singleCharacterStringRep(c)); } + if (!length) - return *StringImpl::empty(); + return StringImpl::empty(); + CharBuffer<UChar> buf = { s, static_cast<unsigned>(length) }; + HashSet<StringImpl*>::AddResult addResult = vm->identifierTable->add<CharBuffer<UChar>, IdentifierLCharFromUCharTranslator >(buf); + + // If the string is newly-translated, then we need to adopt it. + // The boolean in the pair tells us if that is so. + return addResult.isNewEntry ? adoptRef(*addResult.iterator) : *addResult.iterator; +} + +PassRefPtr<StringImpl> Identifier::addSlowCase(VM* vm, StringImpl* r) +{ + if (r->isEmptyUnique()) + return r; + ASSERT(!r->isIdentifier()); + // The empty & null strings are static singletons, and static strings are handled + // in ::add() in the header, so we should never get here with a zero length string. + ASSERT(r->length()); + + if (r->length() == 1) { + UChar c = (*r)[0]; + if (c <= maxSingleCharacterString) + r = vm->smallStrings.singleCharacterStringRep(c); + if (r->isIdentifier()) + return r; + } + + return *vm->identifierTable->add(r).iterator; +} - return *AtomicStringImpl::add(s, length); +PassRefPtr<StringImpl> Identifier::addSlowCase(ExecState* exec, StringImpl* r) +{ + return addSlowCase(&exec->vm(), r); } Identifier Identifier::from(ExecState* exec, unsigned value) @@ -97,34 +185,26 @@ Identifier Identifier::from(VM* vm, double value) return Identifier(vm, vm->numericStrings.add(value)); } -void Identifier::dump(PrintStream& out) const -{ - if (impl()) - out.print(impl()); - else - out.print("<null identifier>"); -} - #ifndef NDEBUG -void Identifier::checkCurrentAtomicStringTable(VM* vm) +void Identifier::checkCurrentIdentifierTable(VM* vm) { // Check the identifier table accessible through the threadspecific matches the // vm's identifier table. - ASSERT_UNUSED(vm, vm->atomicStringTable() == wtfThreadData().atomicStringTable()); + ASSERT_UNUSED(vm, vm->identifierTable == wtfThreadData().currentIdentifierTable()); } -void Identifier::checkCurrentAtomicStringTable(ExecState* exec) +void Identifier::checkCurrentIdentifierTable(ExecState* exec) { - checkCurrentAtomicStringTable(&exec->vm()); + checkCurrentIdentifierTable(&exec->vm()); } #else // These only exists so that our exports are the same for debug and release builds. // This would be an RELEASE_ASSERT_NOT_REACHED(), but we're in NDEBUG only code here! -NO_RETURN_DUE_TO_CRASH void Identifier::checkCurrentAtomicStringTable(VM*) { CRASH(); } -NO_RETURN_DUE_TO_CRASH void Identifier::checkCurrentAtomicStringTable(ExecState*) { CRASH(); } +NO_RETURN_DUE_TO_CRASH void Identifier::checkCurrentIdentifierTable(VM*) { CRASH(); } +NO_RETURN_DUE_TO_CRASH void Identifier::checkCurrentIdentifierTable(ExecState*) { CRASH(); } #endif |