Title: [214931] trunk
Revision
214931
Author
[email protected]
Date
2017-04-05 00:09:41 -0700 (Wed, 05 Apr 2017)

Log Message

[JSC] Generate TemplateObjects at linking time
https://bugs.webkit.org/show_bug.cgi?id=169743

Reviewed by Keith Miller.

JSTests:

* stress/template-string-tags-eval.js: Added.
(shouldBe):
(tag):

Source/_javascript_Core:

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):

Modified Paths

Added Paths

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
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to