Changeset 208953 in webkit


Ignore:
Timestamp:
Nov 21, 2016 3:54:43 PM (7 years ago)
Author:
Yusuke Suzuki
Message:

Crash in com.apple.JavaScriptCore: WTF::ThreadSpecific<WTF::WTFThreadData, + 142
https://bugs.webkit.org/show_bug.cgi?id=164898

Reviewed by Darin Adler.

JSTests:

  • stress/tagged-template-registry-key-collect.js: Added.

(shouldBe):
(tag):
(i.eval):

  • stress/tagged-template-registry-key.js: Added.

(shouldBe):
(tag):
(a):
(b):

Source/JavaScriptCore:

The callsite object (JSArray) of tagged template literal is managed by WeakGCMap since
same tagged template literal need to return an identical object.
The problem is that we used TemplateRegistryKey as the key of the WeakGCMap. WeakGCMap
can prune its entries in the collector thread. At that time, this TemplateRegistryKey
is deallocated. Since it includes String (and then, StringImpl), we accidentally call
ref(), deref() and StringImpl::destroy() in the different thread from the main thread
while this TemplateRegistryKey is allocated in the main thread.

Instead, we use TemplateRegistryKey* as the key of WeakGCMap. Then, to keep its liveness
while the entry of the WeakGCMap is alive, the callsite object has the reference to
the JSTemplateRegistryKey. And it holds Ref<TemplateRegistryKey>.

And now we need to lookup WeakGCMap with TemplateRegistryKey*. To do so, we create
interning system for TemplateRegistryKey. It is similar to AtomicStringTable and
SymbolRegistry. TemplateRegistryKey is allocated from this table. This table atomize the
TemplateRegistryKey. So we can use the pointer comparison between TemplateRegistryKey.
It allows us to lookup the entry from WeakGCMap by TemplateRegistryKey*.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • builtins/BuiltinNames.h:
  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::addTemplateRegistryKeyConstant):
(JSC::BytecodeGenerator::emitGetTemplateObject):

  • bytecompiler/BytecodeGenerator.h:
  • runtime/JSGlobalObject.cpp:

(JSC::getTemplateObject):

  • runtime/JSTemplateRegistryKey.cpp:

(JSC::JSTemplateRegistryKey::JSTemplateRegistryKey):
(JSC::JSTemplateRegistryKey::create):

  • runtime/JSTemplateRegistryKey.h:
  • runtime/TemplateRegistry.cpp:

(JSC::TemplateRegistry::getTemplateObject):

  • runtime/TemplateRegistry.h:
  • runtime/TemplateRegistryKey.cpp: Copied from Source/JavaScriptCore/runtime/TemplateRegistry.h.

(JSC::TemplateRegistryKey::~TemplateRegistryKey):

  • runtime/TemplateRegistryKey.h:

(JSC::TemplateRegistryKey::calculateHash):
(JSC::TemplateRegistryKey::create):
(JSC::TemplateRegistryKey::TemplateRegistryKey):

  • runtime/TemplateRegistryKeyTable.cpp: Added.

(JSC::TemplateRegistryKeyTranslator::hash):
(JSC::TemplateRegistryKeyTranslator::equal):
(JSC::TemplateRegistryKeyTranslator::translate):
(JSC::TemplateRegistryKeyTable::~TemplateRegistryKeyTable):
(JSC::TemplateRegistryKeyTable::createKey):
(JSC::TemplateRegistryKeyTable::unregister):

  • runtime/TemplateRegistryKeyTable.h: Copied from Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h.

(JSC::TemplateRegistryKeyTable::KeyHash::hash):
(JSC::TemplateRegistryKeyTable::KeyHash::equal):

  • runtime/VM.h:

(JSC::VM::templateRegistryKeyTable):

Location:
trunk
Files:
3 added
14 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r208933 r208953  
     12016-11-21  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Crash in com.apple.JavaScriptCore: WTF::ThreadSpecific<WTF::WTFThreadData, + 142
     4        https://bugs.webkit.org/show_bug.cgi?id=164898
     5
     6        Reviewed by Darin Adler.
     7
     8        * stress/tagged-template-registry-key-collect.js: Added.
     9        (shouldBe):
     10        (tag):
     11        (i.eval):
     12        * stress/tagged-template-registry-key.js: Added.
     13        (shouldBe):
     14        (tag):
     15        (a):
     16        (b):
     17
    1182016-11-20  Caitlin Potter  <caitp@igalia.com>
    219
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r208821 r208953  
    867867    runtime/SymbolTable.cpp
    868868    runtime/TemplateRegistry.cpp
     869    runtime/TemplateRegistryKey.cpp
     870    runtime/TemplateRegistryKeyTable.cpp
    869871    runtime/TestRunnerUtils.cpp
    870872    runtime/ThrowScope.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r208952 r208953  
     12016-11-21  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Crash in com.apple.JavaScriptCore: WTF::ThreadSpecific<WTF::WTFThreadData, + 142
     4        https://bugs.webkit.org/show_bug.cgi?id=164898
     5
     6        Reviewed by Darin Adler.
     7
     8        The callsite object (JSArray) of tagged template literal is managed by WeakGCMap since
     9        same tagged template literal need to return an identical object.
     10        The problem is that we used TemplateRegistryKey as the key of the WeakGCMap. WeakGCMap
     11        can prune its entries in the collector thread. At that time, this TemplateRegistryKey
     12        is deallocated. Since it includes String (and then, StringImpl), we accidentally call
     13        ref(), deref() and StringImpl::destroy() in the different thread from the main thread
     14        while this TemplateRegistryKey is allocated in the main thread.
     15
     16        Instead, we use TemplateRegistryKey* as the key of WeakGCMap. Then, to keep its liveness
     17        while the entry of the WeakGCMap is alive, the callsite object has the reference to
     18        the JSTemplateRegistryKey. And it holds Ref<TemplateRegistryKey>.
     19
     20        And now we need to lookup WeakGCMap with TemplateRegistryKey*. To do so, we create
     21        interning system for TemplateRegistryKey. It is similar to AtomicStringTable and
     22        SymbolRegistry. TemplateRegistryKey is allocated from this table. This table atomize the
     23        TemplateRegistryKey. So we can use the pointer comparison between TemplateRegistryKey.
     24        It allows us to lookup the entry from WeakGCMap by TemplateRegistryKey*.
     25
     26        * CMakeLists.txt:
     27        * JavaScriptCore.xcodeproj/project.pbxproj:
     28        * builtins/BuiltinNames.h:
     29        * bytecompiler/BytecodeGenerator.cpp:
     30        (JSC::BytecodeGenerator::addTemplateRegistryKeyConstant):
     31        (JSC::BytecodeGenerator::emitGetTemplateObject):
     32        * bytecompiler/BytecodeGenerator.h:
     33        * runtime/JSGlobalObject.cpp:
     34        (JSC::getTemplateObject):
     35        * runtime/JSTemplateRegistryKey.cpp:
     36        (JSC::JSTemplateRegistryKey::JSTemplateRegistryKey):
     37        (JSC::JSTemplateRegistryKey::create):
     38        * runtime/JSTemplateRegistryKey.h:
     39        * runtime/TemplateRegistry.cpp:
     40        (JSC::TemplateRegistry::getTemplateObject):
     41        * runtime/TemplateRegistry.h:
     42        * runtime/TemplateRegistryKey.cpp: Copied from Source/JavaScriptCore/runtime/TemplateRegistry.h.
     43        (JSC::TemplateRegistryKey::~TemplateRegistryKey):
     44        * runtime/TemplateRegistryKey.h:
     45        (JSC::TemplateRegistryKey::calculateHash):
     46        (JSC::TemplateRegistryKey::create):
     47        (JSC::TemplateRegistryKey::TemplateRegistryKey):
     48        * runtime/TemplateRegistryKeyTable.cpp: Added.
     49        (JSC::TemplateRegistryKeyTranslator::hash):
     50        (JSC::TemplateRegistryKeyTranslator::equal):
     51        (JSC::TemplateRegistryKeyTranslator::translate):
     52        (JSC::TemplateRegistryKeyTable::~TemplateRegistryKeyTable):
     53        (JSC::TemplateRegistryKeyTable::createKey):
     54        (JSC::TemplateRegistryKeyTable::unregister):
     55        * runtime/TemplateRegistryKeyTable.h: Copied from Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h.
     56        (JSC::TemplateRegistryKeyTable::KeyHash::hash):
     57        (JSC::TemplateRegistryKeyTable::KeyHash::equal):
     58        * runtime/VM.h:
     59        (JSC::VM::templateRegistryKeyTable):
     60
    1612016-11-21  Mark Lam  <mark.lam@apple.com>
    262
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r208761 r208953  
    23302330                FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; };
    23312331                FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2332                1A8826B1653C4CD1A642983B /* TemplateRegistryKeyTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8B47F234366C4B72AC852A7E /* TemplateRegistryKeyTable.cpp */; };
     2333                78274D8E4C4D4FCD9A1DC6E6 /* TemplateRegistryKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BDB4B5E099CD4C1BB3C1CF05 /* TemplateRegistryKey.cpp */; };
     2334                95D4261AF4C84CE2ACBAC981 /* TemplateRegistryKeyTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 08FC2F37AB76483A9966688F /* TemplateRegistryKeyTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
    23322335/* End PBXBuildFile section */
    23332336
     
    48204823                FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = "<group>"; };
    48214824                FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringInlines.h; sourceTree = "<group>"; };
     4825                8B47F234366C4B72AC852A7E /* TemplateRegistryKeyTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TemplateRegistryKeyTable.cpp; path = TemplateRegistryKeyTable.cpp; sourceTree = "<group>"; };
     4826                BDB4B5E099CD4C1BB3C1CF05 /* TemplateRegistryKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TemplateRegistryKey.cpp; path = TemplateRegistryKey.cpp; sourceTree = "<group>"; };
     4827                08FC2F37AB76483A9966688F /* TemplateRegistryKeyTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemplateRegistryKeyTable.h; path = TemplateRegistryKeyTable.h; sourceTree = "<group>"; };
    48224828/* End PBXFileReference section */
    48234829
     
    66386644                                A7DCB77912E3D90500911940 /* WriteBarrier.h */,
    66396645                                C2B6D75218A33793004A9301 /* WriteBarrierInlines.h */,
     6646                                8B47F234366C4B72AC852A7E /* TemplateRegistryKeyTable.cpp */,
     6647                                BDB4B5E099CD4C1BB3C1CF05 /* TemplateRegistryKey.cpp */,
     6648                                08FC2F37AB76483A9966688F /* TemplateRegistryKeyTable.h */,
    66406649                        );
    66416650                        path = runtime;
     
    89728981                                D9722752DC54459B9125B539 /* JSModuleLoader.h in Headers */,
    89738982                                473DA4A4764C45FE871B0485 /* DefinePropertyAttributes.h in Headers */,
     8983                                95D4261AF4C84CE2ACBAC981 /* TemplateRegistryKeyTable.h in Headers */,
    89748984                        );
    89758985                        runOnlyForDeploymentPostprocessing = 0;
     
    1036410374                                0F2BBD991C5FF3F50023EF23 /* B3VariableValue.cpp in Sources */,
    1036510375                                13FECE06D3B445FCB6C93461 /* JSModuleLoader.cpp in Sources */,
     10376                                1A8826B1653C4CD1A642983B /* TemplateRegistryKeyTable.cpp in Sources */,
     10377                                78274D8E4C4D4FCD9A1DC6E6 /* TemplateRegistryKey.cpp in Sources */,
    1036610378                        );
    1036710379                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/JavaScriptCore/builtins/BuiltinNames.h

    r207432 r208953  
    8282    macro(homeObject) \
    8383    macro(getTemplateObject) \
     84    macro(templateRegistryKey) \
    8485    macro(enqueueJob) \
    8586    macro(handler) \
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r208726 r208953  
    29962996}
    29972997
    2998 JSTemplateRegistryKey* BytecodeGenerator::addTemplateRegistryKeyConstant(const TemplateRegistryKey& templateRegistryKey)
    2999 {
    3000     JSTemplateRegistryKey*& templateRegistryKeyInMap = m_templateRegistryKeyMap.add(templateRegistryKey, nullptr).iterator->value;
    3001     if (!templateRegistryKeyInMap) {
    3002         templateRegistryKeyInMap = JSTemplateRegistryKey::create(*vm(), templateRegistryKey);
    3003         addConstantValue(templateRegistryKeyInMap);
    3004     }
    3005     return templateRegistryKeyInMap;
     2998JSTemplateRegistryKey* BytecodeGenerator::addTemplateRegistryKeyConstant(Ref<TemplateRegistryKey>&& templateRegistryKey)
     2999{
     3000    return m_templateRegistryKeyMap.ensure(templateRegistryKey.copyRef(), [&] {
     3001        auto* result = JSTemplateRegistryKey::create(*vm(), WTFMove(templateRegistryKey));
     3002        addConstantValue(result);
     3003        return result;
     3004    }).iterator->value;
    30063005}
    30073006
     
    43994398
    44004399    CallArguments arguments(*this, nullptr);
    4401     emitLoad(arguments.thisRegister(), JSValue(addTemplateRegistryKeyConstant(TemplateRegistryKey(rawStrings, cookedStrings))));
     4400    emitLoad(arguments.thisRegister(), JSValue(addTemplateRegistryKeyConstant(m_vm->templateRegistryKeyTable().createKey(rawStrings, cookedStrings))));
    44024401    return emitCall(dst, getTemplateObject.get(), NoExpectedFunction, arguments, taggedTemplate->divot(), taggedTemplate->divotStart(), taggedTemplate->divotEnd(), DebuggableCall::No);
    44034402}
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r208841 r208953  
    802802        typedef HashMap<double, JSValue> NumberMap;
    803803        typedef HashMap<UniquedStringImpl*, JSString*, IdentifierRepHash> IdentifierStringMap;
    804         typedef HashMap<TemplateRegistryKey, JSTemplateRegistryKey*> TemplateRegistryKeyMap;
     804        typedef HashMap<Ref<TemplateRegistryKey>, JSTemplateRegistryKey*> TemplateRegistryKeyMap;
    805805       
    806806        // Helper for emitCall() and emitConstruct(). This works because the set of
     
    886886    public:
    887887        JSString* addStringConstant(const Identifier&);
    888         JSTemplateRegistryKey* addTemplateRegistryKeyConstant(const TemplateRegistryKey&);
     888        JSTemplateRegistryKey* addTemplateRegistryKeyConstant(Ref<TemplateRegistryKey>&&);
    889889
    890890        Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>& instructions() { return m_instructions; }
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r208808 r208953  
    291291    JSValue thisValue = exec->thisValue();
    292292    ASSERT(thisValue.inherits(JSTemplateRegistryKey::info()));
    293     return JSValue::encode(exec->lexicalGlobalObject()->templateRegistry().getTemplateObject(exec, jsCast<JSTemplateRegistryKey*>(thisValue)->templateRegistryKey()));
     293    return JSValue::encode(exec->lexicalGlobalObject()->templateRegistry().getTemplateObject(exec, jsCast<JSTemplateRegistryKey*>(thisValue)));
    294294}
    295295
  • trunk/Source/JavaScriptCore/runtime/JSTemplateRegistryKey.cpp

    r205462 r208953  
    3636
    3737
    38 JSTemplateRegistryKey::JSTemplateRegistryKey(VM& vm, const TemplateRegistryKey& templateRegistryKey)
     38JSTemplateRegistryKey::JSTemplateRegistryKey(VM& vm, Ref<TemplateRegistryKey>&& templateRegistryKey)
    3939    : Base(vm, vm.templateRegistryKeyStructure.get())
    40     , m_templateRegistryKey(templateRegistryKey)
     40    , m_templateRegistryKey(WTFMove(templateRegistryKey))
    4141{
    4242}
    4343
    44 JSTemplateRegistryKey* JSTemplateRegistryKey::create(VM& vm, const TemplateRegistryKey& templateRegistryKey)
     44JSTemplateRegistryKey* JSTemplateRegistryKey::create(VM& vm, Ref<TemplateRegistryKey>&& templateRegistryKey)
    4545{
    46     JSTemplateRegistryKey* result = new (NotNull, allocateCell<JSTemplateRegistryKey>(vm.heap)) JSTemplateRegistryKey(vm, templateRegistryKey);
     46    JSTemplateRegistryKey* result = new (NotNull, allocateCell<JSTemplateRegistryKey>(vm.heap)) JSTemplateRegistryKey(vm, WTFMove(templateRegistryKey));
    4747    result->finishCreation(vm);
    4848    return result;
  • trunk/Source/JavaScriptCore/runtime/JSTemplateRegistryKey.h

    r206525 r208953  
    3636    typedef JSDestructibleObject Base;
    3737
    38     static JSTemplateRegistryKey* create(VM&, const TemplateRegistryKey&);
     38    static JSTemplateRegistryKey* create(VM&, Ref<TemplateRegistryKey>&&);
    3939
    4040    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     
    4545    DECLARE_INFO;
    4646
    47     const TemplateRegistryKey& templateRegistryKey() const { return m_templateRegistryKey; }
     47    const TemplateRegistryKey& templateRegistryKey() const { return m_templateRegistryKey.get(); }
    4848
    4949protected:
     
    5151
    5252private:
    53     JSTemplateRegistryKey(VM&, const TemplateRegistryKey&);
     53    JSTemplateRegistryKey(VM&, Ref<TemplateRegistryKey>&&);
    5454
    55     TemplateRegistryKey m_templateRegistryKey;
     55    Ref<TemplateRegistryKey> m_templateRegistryKey;
    5656};
    5757
  • trunk/Source/JavaScriptCore/runtime/TemplateRegistry.cpp

    r206386 r208953  
    2828#include "TemplateRegistry.h"
    2929
     30#include "BuiltinNames.h"
    3031#include "JSCInlines.h"
    3132#include "JSGlobalObject.h"
     33#include "JSTemplateRegistryKey.h"
    3234#include "ObjectConstructor.h"
     35#include "TemplateRegistryKey.h"
    3336#include "WeakGCMapInlines.h"
    3437
     
    4043}
    4144
    42 JSArray* TemplateRegistry::getTemplateObject(ExecState* exec, const TemplateRegistryKey& templateKey)
     45JSArray* TemplateRegistry::getTemplateObject(ExecState* exec, JSTemplateRegistryKey* templateKeyObject)
    4346{
    44     JSArray* cached = m_templateMap.get(templateKey);
     47    auto& templateKey = templateKeyObject->templateRegistryKey();
     48    JSArray* cached = m_templateMap.get(&templateKey);
    4549    if (cached)
    4650        return cached;
     
    6468    templateObject->putDirect(vm, exec->propertyNames().raw, rawObject, ReadOnly | DontEnum | DontDelete);
    6569
     70    // Template JSArray hold the reference to JSTemplateRegistryKey to make TemplateRegistryKey pointer live until this JSArray is collected.
     71    // TemplateRegistryKey pointer is used for TemplateRegistry's key.
     72    templateObject->putDirect(vm, vm.propertyNames->builtinNames().templateRegistryKeyPrivateName(), templateKeyObject, ReadOnly | DontEnum | DontDelete);
     73
    6674    objectConstructorFreeze(exec, templateObject);
    6775    ASSERT(!scope.exception());
    6876
    69     m_templateMap.set(templateKey, templateObject);
     77    m_templateMap.set(&templateKey, templateObject);
    7078
    7179    return templateObject;
  • trunk/Source/JavaScriptCore/runtime/TemplateRegistry.h

    r206525 r208953  
    2727
    2828#include "JSArray.h"
    29 #include "TemplateRegistryKey.h"
    3029#include "WeakGCMap.h"
    3130#include <limits>
     
    3332namespace JSC {
    3433
     34class JSTemplateRegistryKey;
     35class TemplateRegistryKey;
     36
    3537class TemplateRegistry {
    3638public:
    3739    TemplateRegistry(VM&);
    3840
    39     JSArray* getTemplateObject(ExecState*, const TemplateRegistryKey&);
     41    JSArray* getTemplateObject(ExecState*, JSTemplateRegistryKey*);
    4042
    4143private:
    42     WeakGCMap<TemplateRegistryKey, JSArray> m_templateMap;
     44    WeakGCMap<const TemplateRegistryKey*, JSArray> m_templateMap;
    4345};
    4446
  • trunk/Source/JavaScriptCore/runtime/TemplateRegistryKey.cpp

    r208952 r208953  
    11/*
    2  * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
     2 * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #pragma once
     26#include "config.h"
     27#include "TemplateRegistryKey.h"
    2728
    28 #include "JSArray.h"
    29 #include "TemplateRegistryKey.h"
    30 #include "WeakGCMap.h"
    31 #include <limits>
     29#include "TemplateRegistryKeyTable.h"
    3230
    3331namespace JSC {
    3432
    35 class TemplateRegistry {
    36 public:
    37     TemplateRegistry(VM&);
    38 
    39     JSArray* getTemplateObject(ExecState*, const TemplateRegistryKey&);
    40 
    41 private:
    42     WeakGCMap<TemplateRegistryKey, JSArray> m_templateMap;
    43 };
     33TemplateRegistryKey::~TemplateRegistryKey()
     34{
     35    if (m_table)
     36        m_table->unregister(*this);
     37}
    4438
    4539} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/TemplateRegistryKey.h

    r206525 r208953  
    3333namespace JSC {
    3434
    35 class TemplateRegistryKey {
     35class TemplateRegistryKeyTable;
     36
     37class TemplateRegistryKey : public RefCounted<TemplateRegistryKey> {
    3638public:
     39    friend class TemplateRegistryKeyTable;
    3740    typedef Vector<String, 4> StringVector;
    3841
    39     TemplateRegistryKey(const StringVector& rawStrings, const StringVector& cookedStrings);
    4042    enum DeletedValueTag { DeletedValue };
    4143    TemplateRegistryKey(DeletedValueTag);
     
    6163    };
    6264
     65    static unsigned calculateHash(const StringVector& rawStrings);
     66    ~TemplateRegistryKey();
     67
    6368private:
     69    static Ref<TemplateRegistryKey> create(const StringVector& rawStrings, const StringVector& cookedStrings)
     70    {
     71        return adoptRef(*new TemplateRegistryKey(rawStrings, cookedStrings));
     72    }
     73
     74    TemplateRegistryKey(const StringVector& rawStrings, const StringVector& cookedStrings);
     75
     76    TemplateRegistryKeyTable* m_table { nullptr };
    6477    StringVector m_rawStrings;
    6578    StringVector m_cookedStrings;
     
    7083    : m_rawStrings(rawStrings)
    7184    , m_cookedStrings(cookedStrings)
     85    , m_hash(calculateHash(rawStrings))
    7286{
    73     m_hash = 0;
    74     for (const String& string : rawStrings)
    75         m_hash += WTF::StringHash::hash(string);
    7687}
    7788
     
    8495    : m_hash(0)
    8596{
     97}
     98
     99inline unsigned TemplateRegistryKey::calculateHash(const StringVector& rawStrings)
     100{
     101    StringHasher hasher;
     102    for (const String& string : rawStrings) {
     103        if (string.is8Bit())
     104            hasher.addCharacters(string.characters8(), string.length());
     105        else
     106            hasher.addCharacters(string.characters16(), string.length());
     107    }
     108    return hasher.hash();
    86109}
    87110
  • trunk/Source/JavaScriptCore/runtime/TemplateRegistryKeyTable.h

    r208952 r208953  
    11/*
    2  * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
     2 * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
    28 #include "JSDestructibleObject.h"
    29 #include "Structure.h"
    3028#include "TemplateRegistryKey.h"
     29#include <wtf/Forward.h>
     30#include <wtf/HashSet.h>
     31#include <wtf/Noncopyable.h>
    3132
    3233namespace JSC {
    3334
    34 class JSTemplateRegistryKey final : public JSDestructibleObject {
     35class TemplateRegistryKeyTable {
     36    WTF_MAKE_NONCOPYABLE(TemplateRegistryKeyTable);
    3537public:
    36     typedef JSDestructibleObject Base;
     38    using StringVector = Vector<String, 4>;
    3739
    38     static JSTemplateRegistryKey* create(VM&, const TemplateRegistryKey&);
     40    TemplateRegistryKeyTable() = default;
    3941
    40     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    41     {
    42         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    43     }
     42    Ref<TemplateRegistryKey> createKey(const StringVector& rawStrings, const StringVector& cookedStrings);
    4443
    45     DECLARE_INFO;
     44    void unregister(TemplateRegistryKey&);
    4645
    47     const TemplateRegistryKey& templateRegistryKey() const { return m_templateRegistryKey; }
    48 
    49 protected:
    50     static void destroy(JSCell*);
     46    ~TemplateRegistryKeyTable();
    5147
    5248private:
    53     JSTemplateRegistryKey(VM&, const TemplateRegistryKey&);
     49    struct KeyHash {
     50        static unsigned hash(const TemplateRegistryKey* key) { return key->hash(); }
     51        static bool equal(const TemplateRegistryKey* a, const TemplateRegistryKey* b) { return *a == *b; }
     52        static const bool safeToCompareToEmptyOrDeleted = false;
     53    };
    5454
    55     TemplateRegistryKey m_templateRegistryKey;
     55    HashSet<TemplateRegistryKey*, KeyHash> m_atomicTable;
    5656};
    5757
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r208761 r208953  
    4949#include "SourceCode.h"
    5050#include "Strong.h"
     51#include "TemplateRegistryKeyTable.h"
    5152#include "ThunkGenerators.h"
    5253#include "VMEntryRecord.h"
     
    350351    AtomicStringTable* m_atomicStringTable;
    351352    WTF::SymbolRegistry m_symbolRegistry;
     353    TemplateRegistryKeyTable m_templateRegistryKeytable;
    352354    CommonIdentifiers* propertyNames;
    353355    const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
     
    362364    AtomicStringTable* atomicStringTable() const { return m_atomicStringTable; }
    363365    WTF::SymbolRegistry& symbolRegistry() { return m_symbolRegistry; }
     366
     367    TemplateRegistryKeyTable& templateRegistryKeyTable() { return m_templateRegistryKeytable; }
    364368
    365369    WeakGCMap<SymbolImpl*, Symbol, PtrHash<SymbolImpl*>> symbolImplToSymbolMap;
Note: See TracChangeset for help on using the changeset viewer.