Diff
Modified: trunk/JSTests/ChangeLog (208952 => 208953)
--- trunk/JSTests/ChangeLog 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/JSTests/ChangeLog 2016-11-21 23:54:43 UTC (rev 208953)
@@ -1,3 +1,20 @@
+2016-11-21 Yusuke Suzuki <[email protected]>
+
+ Crash in com.apple._javascript_Core: WTF::ThreadSpecific<WTF::WTFThreadData, + 142
+ https://bugs.webkit.org/show_bug.cgi?id=164898
+
+ Reviewed by Darin Adler.
+
+ * stress/tagged-template-registry-key-collect.js: Added.
+ (shouldBe):
+ (tag):
+ (i.eval):
+ * stress/tagged-template-registry-key.js: Added.
+ (shouldBe):
+ (tag):
+ (a):
+ (b):
+
2016-11-20 Caitlin Potter <[email protected]>
[JSC] speed up parsing of async functions
Added: trunk/JSTests/stress/tagged-template-registry-key-collect.js (0 => 208953)
--- trunk/JSTests/stress/tagged-template-registry-key-collect.js (rev 0)
+++ trunk/JSTests/stress/tagged-template-registry-key-collect.js 2016-11-21 23:54:43 UTC (rev 208953)
@@ -0,0 +1,16 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+
+function tag(site)
+{
+ return site;
+}
+
+{
+ for (var i = 0; i < 1e4; ++i)
+ eval(`(function () { return tag\`${i}\`; })()`);
+}
+gc();
Added: trunk/JSTests/stress/tagged-template-registry-key.js (0 => 208953)
--- trunk/JSTests/stress/tagged-template-registry-key.js (rev 0)
+++ trunk/JSTests/stress/tagged-template-registry-key.js 2016-11-21 23:54:43 UTC (rev 208953)
@@ -0,0 +1,25 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+function tag(site)
+{
+ return site;
+}
+
+{
+ function a() {
+ return tag`Hello`;
+ }
+
+ function b() {
+ return tag`Hello`;
+ }
+
+ shouldBe(a() === b(), true);
+ gc();
+ var tagA = a();
+ gc();
+ shouldBe(tagA === b(), true);
+}
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (208952 => 208953)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2016-11-21 23:54:43 UTC (rev 208953)
@@ -866,6 +866,8 @@
runtime/SymbolPrototype.cpp
runtime/SymbolTable.cpp
runtime/TemplateRegistry.cpp
+ runtime/TemplateRegistryKey.cpp
+ runtime/TemplateRegistryKeyTable.cpp
runtime/TestRunnerUtils.cpp
runtime/ThrowScope.cpp
runtime/TypeLocationCache.cpp
Modified: trunk/Source/_javascript_Core/ChangeLog (208952 => 208953)
--- trunk/Source/_javascript_Core/ChangeLog 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-11-21 23:54:43 UTC (rev 208953)
@@ -1,3 +1,63 @@
+2016-11-21 Yusuke Suzuki <[email protected]>
+
+ Crash in com.apple._javascript_Core: WTF::ThreadSpecific<WTF::WTFThreadData, + 142
+ https://bugs.webkit.org/show_bug.cgi?id=164898
+
+ Reviewed by Darin Adler.
+
+ 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:
+ * _javascript_Core.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/_javascript_Core/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/_javascript_Core/runtime/JSTemplateRegistryKey.h.
+ (JSC::TemplateRegistryKeyTable::KeyHash::hash):
+ (JSC::TemplateRegistryKeyTable::KeyHash::equal):
+ * runtime/VM.h:
+ (JSC::VM::templateRegistryKeyTable):
+
2016-11-21 Mark Lam <[email protected]>
Fix exception scope verification failures in runtime/Error* files.
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (208952 => 208953)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-11-21 23:54:43 UTC (rev 208953)
@@ -2329,6 +2329,9 @@
FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; };
FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1A8826B1653C4CD1A642983B /* TemplateRegistryKeyTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8B47F234366C4B72AC852A7E /* TemplateRegistryKeyTable.cpp */; };
+ 78274D8E4C4D4FCD9A1DC6E6 /* TemplateRegistryKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BDB4B5E099CD4C1BB3C1CF05 /* TemplateRegistryKey.cpp */; };
+ 95D4261AF4C84CE2ACBAC981 /* TemplateRegistryKeyTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 08FC2F37AB76483A9966688F /* TemplateRegistryKeyTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -4819,6 +4822,9 @@
FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = "<group>"; };
FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = "<group>"; };
FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringInlines.h; sourceTree = "<group>"; };
+ 8B47F234366C4B72AC852A7E /* TemplateRegistryKeyTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TemplateRegistryKeyTable.cpp; path = TemplateRegistryKeyTable.cpp; sourceTree = "<group>"; };
+ BDB4B5E099CD4C1BB3C1CF05 /* TemplateRegistryKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TemplateRegistryKey.cpp; path = TemplateRegistryKey.cpp; sourceTree = "<group>"; };
+ 08FC2F37AB76483A9966688F /* TemplateRegistryKeyTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemplateRegistryKeyTable.h; path = TemplateRegistryKeyTable.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -6637,6 +6643,9 @@
147341D91DC0300100AA29BA /* WebAssemblyExecutable.h */,
A7DCB77912E3D90500911940 /* WriteBarrier.h */,
C2B6D75218A33793004A9301 /* WriteBarrierInlines.h */,
+ 8B47F234366C4B72AC852A7E /* TemplateRegistryKeyTable.cpp */,
+ BDB4B5E099CD4C1BB3C1CF05 /* TemplateRegistryKey.cpp */,
+ 08FC2F37AB76483A9966688F /* TemplateRegistryKeyTable.h */,
);
path = runtime;
sourceTree = "<group>";
@@ -8971,6 +8980,7 @@
A79D3ED9C5064DD0A8466A3A /* ModuleScopeData.h in Headers */,
D9722752DC54459B9125B539 /* JSModuleLoader.h in Headers */,
473DA4A4764C45FE871B0485 /* DefinePropertyAttributes.h in Headers */,
+ 95D4261AF4C84CE2ACBAC981 /* TemplateRegistryKeyTable.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -10363,6 +10373,8 @@
86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
0F2BBD991C5FF3F50023EF23 /* B3VariableValue.cpp in Sources */,
13FECE06D3B445FCB6C93461 /* JSModuleLoader.cpp in Sources */,
+ 1A8826B1653C4CD1A642983B /* TemplateRegistryKeyTable.cpp in Sources */,
+ 78274D8E4C4D4FCD9A1DC6E6 /* TemplateRegistryKey.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: trunk/Source/_javascript_Core/builtins/BuiltinNames.h (208952 => 208953)
--- trunk/Source/_javascript_Core/builtins/BuiltinNames.h 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/builtins/BuiltinNames.h 2016-11-21 23:54:43 UTC (rev 208953)
@@ -81,6 +81,7 @@
macro(BuiltinLog) \
macro(homeObject) \
macro(getTemplateObject) \
+ macro(templateRegistryKey) \
macro(enqueueJob) \
macro(handler) \
macro(promiseState) \
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (208952 => 208953)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2016-11-21 23:54:43 UTC (rev 208953)
@@ -2995,14 +2995,13 @@
return stringInMap;
}
-JSTemplateRegistryKey* BytecodeGenerator::addTemplateRegistryKeyConstant(const TemplateRegistryKey& templateRegistryKey)
+JSTemplateRegistryKey* BytecodeGenerator::addTemplateRegistryKeyConstant(Ref<TemplateRegistryKey>&& templateRegistryKey)
{
- JSTemplateRegistryKey*& templateRegistryKeyInMap = m_templateRegistryKeyMap.add(templateRegistryKey, nullptr).iterator->value;
- if (!templateRegistryKeyInMap) {
- templateRegistryKeyInMap = JSTemplateRegistryKey::create(*vm(), templateRegistryKey);
- addConstantValue(templateRegistryKeyInMap);
- }
- return templateRegistryKeyInMap;
+ return m_templateRegistryKeyMap.ensure(templateRegistryKey.copyRef(), [&] {
+ auto* result = JSTemplateRegistryKey::create(*vm(), WTFMove(templateRegistryKey));
+ addConstantValue(result);
+ return result;
+ }).iterator->value;
}
RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements, unsigned length)
@@ -4398,7 +4397,7 @@
}
CallArguments arguments(*this, nullptr);
- emitLoad(arguments.thisRegister(), JSValue(addTemplateRegistryKeyConstant(TemplateRegistryKey(rawStrings, cookedStrings))));
+ emitLoad(arguments.thisRegister(), JSValue(addTemplateRegistryKeyConstant(m_vm->templateRegistryKeyTable().createKey(rawStrings, cookedStrings))));
return emitCall(dst, getTemplateObject.get(), NoExpectedFunction, arguments, taggedTemplate->divot(), taggedTemplate->divotStart(), taggedTemplate->divotEnd(), DebuggableCall::No);
}
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (208952 => 208953)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2016-11-21 23:54:43 UTC (rev 208953)
@@ -801,7 +801,7 @@
typedef HashMap<double, JSValue> NumberMap;
typedef HashMap<UniquedStringImpl*, JSString*, IdentifierRepHash> IdentifierStringMap;
- typedef HashMap<TemplateRegistryKey, JSTemplateRegistryKey*> TemplateRegistryKeyMap;
+ typedef HashMap<Ref<TemplateRegistryKey>, JSTemplateRegistryKey*> TemplateRegistryKeyMap;
// Helper for emitCall() and emitConstruct(). This works because the set of
// expected functions have identical behavior for both call and construct
@@ -885,7 +885,7 @@
public:
JSString* addStringConstant(const Identifier&);
- JSTemplateRegistryKey* addTemplateRegistryKeyConstant(const TemplateRegistryKey&);
+ JSTemplateRegistryKey* addTemplateRegistryKeyConstant(Ref<TemplateRegistryKey>&&);
Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>& instructions() { return m_instructions; }
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (208952 => 208953)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2016-11-21 23:54:43 UTC (rev 208953)
@@ -290,7 +290,7 @@
{
JSValue thisValue = exec->thisValue();
ASSERT(thisValue.inherits(JSTemplateRegistryKey::info()));
- return JSValue::encode(exec->lexicalGlobalObject()->templateRegistry().getTemplateObject(exec, jsCast<JSTemplateRegistryKey*>(thisValue)->templateRegistryKey()));
+ return JSValue::encode(exec->lexicalGlobalObject()->templateRegistry().getTemplateObject(exec, jsCast<JSTemplateRegistryKey*>(thisValue)));
}
Modified: trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.cpp (208952 => 208953)
--- trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.cpp 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.cpp 2016-11-21 23:54:43 UTC (rev 208953)
@@ -35,15 +35,15 @@
const ClassInfo JSTemplateRegistryKey::s_info = { "TemplateRegistryKey", &Base::s_info, nullptr, CREATE_METHOD_TABLE(JSTemplateRegistryKey) };
-JSTemplateRegistryKey::JSTemplateRegistryKey(VM& vm, const TemplateRegistryKey& templateRegistryKey)
+JSTemplateRegistryKey::JSTemplateRegistryKey(VM& vm, Ref<TemplateRegistryKey>&& templateRegistryKey)
: Base(vm, vm.templateRegistryKeyStructure.get())
- , m_templateRegistryKey(templateRegistryKey)
+ , m_templateRegistryKey(WTFMove(templateRegistryKey))
{
}
-JSTemplateRegistryKey* JSTemplateRegistryKey::create(VM& vm, const TemplateRegistryKey& templateRegistryKey)
+JSTemplateRegistryKey* JSTemplateRegistryKey::create(VM& vm, Ref<TemplateRegistryKey>&& templateRegistryKey)
{
- JSTemplateRegistryKey* result = new (NotNull, allocateCell<JSTemplateRegistryKey>(vm.heap)) JSTemplateRegistryKey(vm, templateRegistryKey);
+ JSTemplateRegistryKey* result = new (NotNull, allocateCell<JSTemplateRegistryKey>(vm.heap)) JSTemplateRegistryKey(vm, WTFMove(templateRegistryKey));
result->finishCreation(vm);
return result;
}
Modified: trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.h (208952 => 208953)
--- trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.h 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.h 2016-11-21 23:54:43 UTC (rev 208953)
@@ -35,7 +35,7 @@
public:
typedef JSDestructibleObject Base;
- static JSTemplateRegistryKey* create(VM&, const TemplateRegistryKey&);
+ static JSTemplateRegistryKey* create(VM&, Ref<TemplateRegistryKey>&&);
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
@@ -44,15 +44,15 @@
DECLARE_INFO;
- const TemplateRegistryKey& templateRegistryKey() const { return m_templateRegistryKey; }
+ const TemplateRegistryKey& templateRegistryKey() const { return m_templateRegistryKey.get(); }
protected:
static void destroy(JSCell*);
private:
- JSTemplateRegistryKey(VM&, const TemplateRegistryKey&);
+ JSTemplateRegistryKey(VM&, Ref<TemplateRegistryKey>&&);
- TemplateRegistryKey m_templateRegistryKey;
+ Ref<TemplateRegistryKey> m_templateRegistryKey;
};
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/TemplateRegistry.cpp (208952 => 208953)
--- trunk/Source/_javascript_Core/runtime/TemplateRegistry.cpp 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/runtime/TemplateRegistry.cpp 2016-11-21 23:54:43 UTC (rev 208953)
@@ -27,9 +27,12 @@
#include "config.h"
#include "TemplateRegistry.h"
+#include "BuiltinNames.h"
#include "JSCInlines.h"
#include "JSGlobalObject.h"
+#include "JSTemplateRegistryKey.h"
#include "ObjectConstructor.h"
+#include "TemplateRegistryKey.h"
#include "WeakGCMapInlines.h"
namespace JSC {
@@ -39,9 +42,10 @@
{
}
-JSArray* TemplateRegistry::getTemplateObject(ExecState* exec, const TemplateRegistryKey& templateKey)
+JSArray* TemplateRegistry::getTemplateObject(ExecState* exec, JSTemplateRegistryKey* templateKeyObject)
{
- JSArray* cached = m_templateMap.get(templateKey);
+ auto& templateKey = templateKeyObject->templateRegistryKey();
+ JSArray* cached = m_templateMap.get(&templateKey);
if (cached)
return cached;
@@ -63,10 +67,14 @@
templateObject->putDirect(vm, exec->propertyNames().raw, rawObject, ReadOnly | DontEnum | DontDelete);
+ // Template JSArray hold the reference to JSTemplateRegistryKey to make TemplateRegistryKey pointer live until this JSArray is collected.
+ // TemplateRegistryKey pointer is used for TemplateRegistry's key.
+ templateObject->putDirect(vm, vm.propertyNames->builtinNames().templateRegistryKeyPrivateName(), templateKeyObject, ReadOnly | DontEnum | DontDelete);
+
objectConstructorFreeze(exec, templateObject);
ASSERT(!scope.exception());
- m_templateMap.set(templateKey, templateObject);
+ m_templateMap.set(&templateKey, templateObject);
return templateObject;
}
Modified: trunk/Source/_javascript_Core/runtime/TemplateRegistry.h (208952 => 208953)
--- trunk/Source/_javascript_Core/runtime/TemplateRegistry.h 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/runtime/TemplateRegistry.h 2016-11-21 23:54:43 UTC (rev 208953)
@@ -26,20 +26,22 @@
#pragma once
#include "JSArray.h"
-#include "TemplateRegistryKey.h"
#include "WeakGCMap.h"
#include <limits>
namespace JSC {
+class JSTemplateRegistryKey;
+class TemplateRegistryKey;
+
class TemplateRegistry {
public:
TemplateRegistry(VM&);
- JSArray* getTemplateObject(ExecState*, const TemplateRegistryKey&);
+ JSArray* getTemplateObject(ExecState*, JSTemplateRegistryKey*);
private:
- WeakGCMap<TemplateRegistryKey, JSArray> m_templateMap;
+ WeakGCMap<const TemplateRegistryKey*, JSArray> m_templateMap;
};
} // namespace JSC
Copied: trunk/Source/_javascript_Core/runtime/TemplateRegistryKey.cpp (from rev 208952, trunk/Source/_javascript_Core/runtime/TemplateRegistry.h) (0 => 208953)
--- trunk/Source/_javascript_Core/runtime/TemplateRegistryKey.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/TemplateRegistryKey.cpp 2016-11-21 23:54:43 UTC (rev 208953)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 Yusuke Suzuki <[email protected]>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TemplateRegistryKey.h"
+
+#include "TemplateRegistryKeyTable.h"
+
+namespace JSC {
+
+TemplateRegistryKey::~TemplateRegistryKey()
+{
+ if (m_table)
+ m_table->unregister(*this);
+}
+
+} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/TemplateRegistryKey.h (208952 => 208953)
--- trunk/Source/_javascript_Core/runtime/TemplateRegistryKey.h 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/runtime/TemplateRegistryKey.h 2016-11-21 23:54:43 UTC (rev 208953)
@@ -32,11 +32,13 @@
namespace JSC {
-class TemplateRegistryKey {
+class TemplateRegistryKeyTable;
+
+class TemplateRegistryKey : public RefCounted<TemplateRegistryKey> {
public:
+ friend class TemplateRegistryKeyTable;
typedef Vector<String, 4> StringVector;
- TemplateRegistryKey(const StringVector& rawStrings, const StringVector& cookedStrings);
enum DeletedValueTag { DeletedValue };
TemplateRegistryKey(DeletedValueTag);
enum EmptyValueTag { EmptyValue };
@@ -60,7 +62,18 @@
static const bool safeToCompareToEmptyOrDeleted = false;
};
+ static unsigned calculateHash(const StringVector& rawStrings);
+ ~TemplateRegistryKey();
+
private:
+ static Ref<TemplateRegistryKey> create(const StringVector& rawStrings, const StringVector& cookedStrings)
+ {
+ return adoptRef(*new TemplateRegistryKey(rawStrings, cookedStrings));
+ }
+
+ TemplateRegistryKey(const StringVector& rawStrings, const StringVector& cookedStrings);
+
+ TemplateRegistryKeyTable* m_table { nullptr };
StringVector m_rawStrings;
StringVector m_cookedStrings;
unsigned m_hash { 0 };
@@ -69,10 +82,8 @@
inline TemplateRegistryKey::TemplateRegistryKey(const StringVector& rawStrings, const StringVector& cookedStrings)
: m_rawStrings(rawStrings)
, m_cookedStrings(cookedStrings)
+ , m_hash(calculateHash(rawStrings))
{
- m_hash = 0;
- for (const String& string : rawStrings)
- m_hash += WTF::StringHash::hash(string);
}
inline TemplateRegistryKey::TemplateRegistryKey(DeletedValueTag)
@@ -85,6 +96,18 @@
{
}
+inline unsigned TemplateRegistryKey::calculateHash(const StringVector& rawStrings)
+{
+ StringHasher hasher;
+ for (const String& string : rawStrings) {
+ if (string.is8Bit())
+ hasher.addCharacters(string.characters8(), string.length());
+ else
+ hasher.addCharacters(string.characters16(), string.length());
+ }
+ return hasher.hash();
+}
+
} // namespace JSC
namespace WTF {
Added: trunk/Source/_javascript_Core/runtime/TemplateRegistryKeyTable.cpp (0 => 208953)
--- trunk/Source/_javascript_Core/runtime/TemplateRegistryKeyTable.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/TemplateRegistryKeyTable.cpp 2016-11-21 23:54:43 UTC (rev 208953)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2016 Yusuke Suzuki <[email protected]>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TemplateRegistryKeyTable.h"
+
+#include "TemplateRegistryKey.h"
+
+namespace JSC {
+
+struct TemplateRegistryKeyTranslator {
+ static unsigned hash(TemplateRegistryKey* generator) { return generator->hash(); }
+ static inline bool equal(TemplateRegistryKey* key, TemplateRegistryKey* generator) { return *key == *generator; }
+ static void translate(TemplateRegistryKey*& location, TemplateRegistryKey* generator, unsigned) { location = generator; }
+};
+
+TemplateRegistryKeyTable::~TemplateRegistryKeyTable()
+{
+ for (auto& key : m_atomicTable)
+ key->m_table = nullptr;
+}
+
+Ref<TemplateRegistryKey> TemplateRegistryKeyTable::createKey(const TemplateRegistryKey::StringVector& rawStrings, const TemplateRegistryKey::StringVector& cookedStrings)
+{
+ auto key = TemplateRegistryKey::create(rawStrings, cookedStrings);
+ auto addResult = m_atomicTable.add<TemplateRegistryKeyTranslator>(key.ptr());
+ if (addResult.isNewEntry)
+ (*addResult.iterator)->m_table = this;
+
+ return **addResult.iterator;
+}
+
+void TemplateRegistryKeyTable::unregister(TemplateRegistryKey& key)
+{
+ ASSERT(key.m_table == this);
+ auto iterator = m_atomicTable.find(&key);
+ ASSERT_WITH_MESSAGE(iterator != m_atomicTable.end(), "The TemplateRegistryKey being removed is registered in the other TemplateRegistryKeyTable.");
+ m_atomicTable.remove(iterator);
+
+}
+
+} // namespace JSC
Copied: trunk/Source/_javascript_Core/runtime/TemplateRegistryKeyTable.h (from rev 208952, trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.h) (0 => 208953)
--- trunk/Source/_javascript_Core/runtime/TemplateRegistryKeyTable.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/TemplateRegistryKeyTable.h 2016-11-21 23:54:43 UTC (rev 208953)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 Yusuke Suzuki <[email protected]>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "TemplateRegistryKey.h"
+#include <wtf/Forward.h>
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+
+class TemplateRegistryKeyTable {
+ WTF_MAKE_NONCOPYABLE(TemplateRegistryKeyTable);
+public:
+ using StringVector = Vector<String, 4>;
+
+ TemplateRegistryKeyTable() = default;
+
+ Ref<TemplateRegistryKey> createKey(const StringVector& rawStrings, const StringVector& cookedStrings);
+
+ void unregister(TemplateRegistryKey&);
+
+ ~TemplateRegistryKeyTable();
+
+private:
+ struct KeyHash {
+ static unsigned hash(const TemplateRegistryKey* key) { return key->hash(); }
+ static bool equal(const TemplateRegistryKey* a, const TemplateRegistryKey* b) { return *a == *b; }
+ static const bool safeToCompareToEmptyOrDeleted = false;
+ };
+
+ HashSet<TemplateRegistryKey*, KeyHash> m_atomicTable;
+};
+
+} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/VM.h (208952 => 208953)
--- trunk/Source/_javascript_Core/runtime/VM.h 2016-11-21 23:24:18 UTC (rev 208952)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2016-11-21 23:54:43 UTC (rev 208953)
@@ -48,6 +48,7 @@
#include "SmallStrings.h"
#include "SourceCode.h"
#include "Strong.h"
+#include "TemplateRegistryKeyTable.h"
#include "ThunkGenerators.h"
#include "VMEntryRecord.h"
#include "Watchpoint.h"
@@ -349,6 +350,7 @@
AtomicStringTable* m_atomicStringTable;
WTF::SymbolRegistry m_symbolRegistry;
+ TemplateRegistryKeyTable m_templateRegistryKeytable;
CommonIdentifiers* propertyNames;
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.
SmallStrings smallStrings;
@@ -362,6 +364,8 @@
AtomicStringTable* atomicStringTable() const { return m_atomicStringTable; }
WTF::SymbolRegistry& symbolRegistry() { return m_symbolRegistry; }
+ TemplateRegistryKeyTable& templateRegistryKeyTable() { return m_templateRegistryKeytable; }
+
WeakGCMap<SymbolImpl*, Symbol, PtrHash<SymbolImpl*>> symbolImplToSymbolMap;
enum class DeletePropertyMode {