Diff
Modified: trunk/JSTests/ChangeLog (214930 => 214931)
--- trunk/JSTests/ChangeLog 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/JSTests/ChangeLog 2017-04-05 07:09:41 UTC (rev 214931)
@@ -1,3 +1,14 @@
+2017-03-16 Yusuke Suzuki <[email protected]>
+
+ [JSC] Generate TemplateObjects at linking time
+ https://bugs.webkit.org/show_bug.cgi?id=169743
+
+ Reviewed by Keith Miller.
+
+ * stress/template-string-tags-eval.js: Added.
+ (shouldBe):
+ (tag):
+
2017-04-04 Mark Lam <[email protected]>
On ARM64, DFG::SpeculativeJIT::compileArithMod() failed to ensure result is of DataFormatInt32.
Added: trunk/JSTests/stress/template-string-tags-eval.js (0 => 214931)
--- trunk/JSTests/stress/template-string-tags-eval.js (rev 0)
+++ trunk/JSTests/stress/template-string-tags-eval.js 2017-04-05 07:09:41 UTC (rev 214931)
@@ -0,0 +1,17 @@
+function shouldBe(actual, expected)
+{
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+function tag(site)
+{
+ return site;
+}
+
+var site1 = eval("0, tag`Cocoa`");
+var site2 = eval("1, tag`Cappuccino`");
+var site3 = eval("2, tag`Cocoa`");
+
+shouldBe(site1 === site3, true);
+shouldBe(site1 !== site2, true);
Modified: trunk/Source/_javascript_Core/ChangeLog (214930 => 214931)
--- trunk/Source/_javascript_Core/ChangeLog 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-04-05 07:09:41 UTC (rev 214931)
@@ -1,3 +1,35 @@
+2017-03-16 Yusuke Suzuki <[email protected]>
+
+ [JSC] Generate TemplateObjects at linking time
+ https://bugs.webkit.org/show_bug.cgi?id=169743
+
+ Reviewed by Keith Miller.
+
+ Currently, the code calls getTemplateObject to get appropriate template objects at runtime.
+ But this template object is constant value and never changed. So instead of creating it
+ at runtime, we should create it at linking time and store it in the constant registers.
+
+ * builtins/BuiltinNames.h:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::finishCreation):
+ (JSC::CodeBlock::setConstantRegisters):
+ * bytecode/CodeBlock.h:
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::UnlinkedCodeBlock::shrinkToFit):
+ * bytecode/UnlinkedCodeBlock.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::addTemplateRegistryKeyConstant):
+ (JSC::BytecodeGenerator::emitGetTemplateObject):
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::TaggedTemplateNode::emitBytecode):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::init):
+ (JSC::getTemplateObject): Deleted.
+ * runtime/JSTemplateRegistryKey.cpp:
+ * runtime/JSTemplateRegistryKey.h:
+ (JSC::isTemplateRegistryKey):
+
2017-04-04 Mark Lam <[email protected]>
On ARM64, DFG::SpeculativeJIT::compileArithMod() failed to ensure result is of DataFormatInt32.
Modified: trunk/Source/_javascript_Core/builtins/BuiltinNames.h (214930 => 214931)
--- trunk/Source/_javascript_Core/builtins/BuiltinNames.h 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/Source/_javascript_Core/builtins/BuiltinNames.h 2017-04-05 07:09:41 UTC (rev 214931)
@@ -80,7 +80,6 @@
macro(typedArraySubarrayCreate) \
macro(BuiltinLog) \
macro(homeObject) \
- macro(getTemplateObject) \
macro(templateRegistryKey) \
macro(enqueueJob) \
macro(promiseState) \
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (214930 => 214931)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2017-04-05 07:09:41 UTC (rev 214931)
@@ -60,6 +60,7 @@
#include "JSModuleEnvironment.h"
#include "JSSet.h"
#include "JSString.h"
+#include "JSTemplateRegistryKey.h"
#include "LLIntData.h"
#include "LLIntEntrypoint.h"
#include "LLIntPrototypeLoadAdaptiveStructureWatchpoint.h"
@@ -404,7 +405,8 @@
if (vm.typeProfiler() || vm.controlFlowProfiler())
vm.functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(), ownerExecutable->typeProfilingEndOffset());
- setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation());
+ if (!setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation()))
+ return false;
if (!setConstantIdentifierSetRegisters(vm, unlinkedCodeBlock->constantIdentifierSets()))
return false;
if (unlinkedCodeBlock->usesGlobalObject())
@@ -885,13 +887,15 @@
}
m_constantRegisters[entry.second].set(vm, this, JSValue(jsSet));
}
-
- scope.release();
return true;
}
-void CodeBlock::setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation)
+bool CodeBlock::setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation)
{
+ auto scope = DECLARE_THROW_SCOPE(*m_vm);
+ JSGlobalObject* globalObject = m_globalObject.get();
+ ExecState* exec = globalObject->globalExec();
+
ASSERT(constants.size() == constantsSourceCodeRepresentation.size());
size_t count = constants.size();
m_constantRegisters.resizeToFit(count);
@@ -900,7 +904,7 @@
JSValue constant = constants[i].get();
if (!constant.isEmpty()) {
- if (SymbolTable* symbolTable = jsDynamicCast<SymbolTable*>(*vm(), constant)) {
+ if (SymbolTable* symbolTable = jsDynamicCast<SymbolTable*>(*m_vm, constant)) {
if (hasTypeProfiler) {
ConcurrentJSLocker locker(symbolTable->m_lock);
symbolTable->prepareForTypeProfiling(locker);
@@ -911,6 +915,10 @@
clone->setRareDataCodeBlock(this);
constant = clone;
+ } else if (isTemplateRegistryKey(*m_vm, constant)) {
+ auto* templateObject = globalObject->templateRegistry().getTemplateObject(exec, jsCast<JSTemplateRegistryKey*>(constant));
+ RETURN_IF_EXCEPTION(scope, false);
+ constant = templateObject;
}
}
@@ -918,6 +926,8 @@
}
m_constantsSourceCodeRepresentation = constantsSourceCodeRepresentation;
+
+ return true;
}
void CodeBlock::setAlternative(VM& vm, CodeBlock* alternative)
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (214930 => 214931)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2017-04-05 07:09:41 UTC (rev 214931)
@@ -921,7 +921,7 @@
bool setConstantIdentifierSetRegisters(VM&, const Vector<ConstantIndentifierSetEntry>& constants);
- void setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation);
+ bool setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation);
void replaceConstant(int index, JSValue value)
{
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp (214930 => 214931)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp 2017-04-05 07:09:41 UTC (rev 214931)
@@ -410,6 +410,7 @@
m_rareData->m_switchJumpTables.shrinkToFit();
m_rareData->m_stringSwitchJumpTables.shrinkToFit();
m_rareData->m_expressionInfoFatPositions.shrinkToFit();
+ m_rareData->m_opProfileControlFlowBytecodeOffsets.shrinkToFit();
}
}
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (214930 => 214931)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2017-04-05 07:09:41 UTC (rev 214931)
@@ -220,6 +220,7 @@
m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
return result;
}
+
unsigned registerIndexForLinkTimeConstant(LinkTimeConstant type)
{
unsigned index = static_cast<unsigned>(type);
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (214930 => 214931)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2017-04-05 07:09:41 UTC (rev 214931)
@@ -3057,12 +3057,15 @@
return stringInMap;
}
-JSTemplateRegistryKey* BytecodeGenerator::addTemplateRegistryKeyConstant(Ref<TemplateRegistryKey>&& templateRegistryKey)
+RegisterID* BytecodeGenerator::addTemplateRegistryKeyConstant(Ref<TemplateRegistryKey>&& templateRegistryKey)
{
return m_templateRegistryKeyMap.ensure(templateRegistryKey.copyRef(), [&] {
auto* result = JSTemplateRegistryKey::create(*vm(), WTFMove(templateRegistryKey));
- addConstantValue(result);
- return result;
+ unsigned index = m_nextConstantOffset;
+ m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
+ ++m_nextConstantOffset;
+ m_codeBlock->addConstant(result);
+ return &m_constantPoolRegisters[index];
}).iterator->value;
}
@@ -4311,11 +4314,10 @@
else
cookedStrings.append(string->cooked()->impl());
}
-
- RefPtr<RegisterID> getTemplateObject = emitGetGlobalPrivate(newTemporary(), propertyNames().builtinNames().getTemplateObjectPrivateName());
- CallArguments arguments(*this, nullptr);
- emitLoad(arguments.thisRegister(), JSValue(addTemplateRegistryKeyConstant(m_vm->templateRegistryKeyTable().createKey(WTFMove(rawStrings), WTFMove(cookedStrings)))));
- return emitCall(dst, getTemplateObject.get(), NoExpectedFunction, arguments, taggedTemplate->divot(), taggedTemplate->divotStart(), taggedTemplate->divotEnd(), DebuggableCall::No);
+ RefPtr<RegisterID> constant = addTemplateRegistryKeyConstant(m_vm->templateRegistryKeyTable().createKey(WTFMove(rawStrings), WTFMove(cookedStrings)));
+ if (!dst)
+ return constant.get();
+ return emitMove(dst, constant.get());
}
RegisterID* BytecodeGenerator::emitGetGlobalPrivate(RegisterID* dst, const Identifier& property)
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (214930 => 214931)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2017-04-05 07:09:41 UTC (rev 214931)
@@ -943,7 +943,7 @@
typedef HashMap<double, JSValue> NumberMap;
typedef HashMap<UniquedStringImpl*, JSString*, IdentifierRepHash> IdentifierStringMap;
- typedef HashMap<Ref<TemplateRegistryKey>, JSTemplateRegistryKey*> TemplateRegistryKeyMap;
+ typedef HashMap<Ref<TemplateRegistryKey>, RegisterID*> TemplateRegistryKeyMap;
// Helper for emitCall() and emitConstruct(). This works because the set of
// expected functions have identical behavior for both call and construct
@@ -1028,7 +1028,7 @@
public:
JSString* addStringConstant(const Identifier&);
- JSTemplateRegistryKey* addTemplateRegistryKeyConstant(Ref<TemplateRegistryKey>&&);
+ RegisterID* addTemplateRegistryKeyConstant(Ref<TemplateRegistryKey>&&);
Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>& instructions() { return m_instructions; }
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (214930 => 214931)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2017-04-05 07:09:41 UTC (rev 214931)
@@ -344,7 +344,7 @@
tag = generator.emitGetById(generator.newTemporary(), base.get(), dot->identifier());
}
- RefPtr<RegisterID> templateObject = generator.emitGetTemplateObject(generator.newTemporary(), this);
+ RefPtr<RegisterID> templateObject = generator.emitGetTemplateObject(nullptr, this);
unsigned expressionsCount = 0;
for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (214930 => 214931)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2017-04-05 07:09:41 UTC (rev 214931)
@@ -297,14 +297,6 @@
@end
*/
-static EncodedJSValue JSC_HOST_CALL getTemplateObject(ExecState* exec)
-{
- JSValue thisValue = exec->thisValue();
- ASSERT(thisValue.inherits(exec->vm(), JSTemplateRegistryKey::info()));
- return JSValue::encode(exec->lexicalGlobalObject()->templateRegistry().getTemplateObject(exec, jsCast<JSTemplateRegistryKey*>(thisValue)));
-}
-
-
static EncodedJSValue JSC_HOST_CALL enqueueJob(ExecState* exec)
{
VM& vm = exec->vm();
@@ -731,7 +723,6 @@
JSFunction* privateFuncFloor = JSFunction::create(vm, this, 0, String(), mathProtoFuncFloor, FloorIntrinsic);
JSFunction* privateFuncTrunc = JSFunction::create(vm, this, 0, String(), mathProtoFuncTrunc, TruncIntrinsic);
- JSFunction* privateFuncGetTemplateObject = JSFunction::create(vm, this, 0, String(), getTemplateObject);
JSFunction* privateFuncImportModule = JSFunction::create(vm, this, 0, String(), globalFuncImportModule);
JSFunction* privateFuncTypedArrayLength = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncLength);
JSFunction* privateFuncTypedArrayGetOriginalConstructor = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncGetOriginalConstructor);
@@ -785,7 +776,6 @@
GlobalPropertyInfo(vm.propertyNames->Infinity, jsNumber(std::numeric_limits<double>::infinity()), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(vm.propertyNames->undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(vm.propertyNames->builtinNames().ownEnumerablePropertyKeysPrivateName(), JSFunction::create(vm, this, 0, String(), ownEnumerablePropertyKeys), DontEnum | DontDelete | ReadOnly),
- GlobalPropertyInfo(vm.propertyNames->builtinNames().getTemplateObjectPrivateName(), privateFuncGetTemplateObject, DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(vm.propertyNames->builtinNames().importModulePrivateName(), privateFuncImportModule, DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(vm.propertyNames->builtinNames().enqueueJobPrivateName(), JSFunction::create(vm, this, 0, String(), enqueueJob), DontEnum | DontDelete | ReadOnly),
GlobalPropertyInfo(vm.propertyNames->builtinNames().ErrorPrivateName(), m_errorConstructor.get(), DontEnum | DontDelete | ReadOnly),
Modified: trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.cpp (214930 => 214931)
--- trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.cpp 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.cpp 2017-04-05 07:09:41 UTC (rev 214931)
@@ -32,7 +32,7 @@
namespace JSC {
-const ClassInfo JSTemplateRegistryKey::s_info = { "TemplateRegistryKey", &Base::s_info, nullptr, CREATE_METHOD_TABLE(JSTemplateRegistryKey) };
+const ClassInfo JSTemplateRegistryKey::s_info = { "TemplateRegistryKey", nullptr, nullptr, CREATE_METHOD_TABLE(JSTemplateRegistryKey) };
JSTemplateRegistryKey::JSTemplateRegistryKey(VM& vm, Ref<TemplateRegistryKey>&& templateRegistryKey)
Modified: trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.h (214930 => 214931)
--- trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.h 2017-04-05 05:38:25 UTC (rev 214930)
+++ trunk/Source/_javascript_Core/runtime/JSTemplateRegistryKey.h 2017-04-05 07:09:41 UTC (rev 214931)
@@ -31,19 +31,21 @@
namespace JSC {
-class JSTemplateRegistryKey final : public JSDestructibleObject {
+class JSTemplateRegistryKey final : public JSCell {
public:
- typedef JSDestructibleObject Base;
+ using Base = JSCell;
+ static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+ static const bool needsDestruction = true;
+ DECLARE_INFO;
+
static JSTemplateRegistryKey* create(VM&, Ref<TemplateRegistryKey>&&);
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+ return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
}
- DECLARE_INFO;
-
const TemplateRegistryKey& templateRegistryKey() const { return m_templateRegistryKey.get(); }
protected:
@@ -55,4 +57,14 @@
Ref<TemplateRegistryKey> m_templateRegistryKey;
};
+inline bool isTemplateRegistryKey(VM& vm, JSCell* cell)
+{
+ return cell->classInfo(vm) == JSTemplateRegistryKey::info();
+}
+
+inline bool isTemplateRegistryKey(VM& vm, JSValue v)
+{
+ return v.isCell() && isTemplateRegistryKey(vm, v.asCell());
+}
+
} // namespace JSC