- Revision
- 249337
- Author
- ysuz...@apple.com
- Date
- 2019-08-30 11:53:26 -0700 (Fri, 30 Aug 2019)
Log Message
[JSC] Generate new.target register only when it is used
https://bugs.webkit.org/show_bug.cgi?id=201335
Reviewed by Mark Lam.
JSTests:
* stress/ensure-new-register-allocated.js: Added.
(shouldBe):
(basic):
(arrow):
(Base):
(Derived):
(evaluate):
Source/_javascript_Core:
Since bytecode generator knows whether new.target register can be used, we should emit and use new.target register
only when it is actually required.
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::newTarget):
* parser/Nodes.h:
(JSC::ScopeNode::needsNewTargetRegisterForThisScope const):
Modified Paths
Added Paths
Diff
Modified: trunk/JSTests/ChangeLog (249336 => 249337)
--- trunk/JSTests/ChangeLog 2019-08-30 18:23:29 UTC (rev 249336)
+++ trunk/JSTests/ChangeLog 2019-08-30 18:53:26 UTC (rev 249337)
@@ -1,5 +1,20 @@
2019-08-30 Yusuke Suzuki <ysuz...@apple.com>
+ [JSC] Generate new.target register only when it is used
+ https://bugs.webkit.org/show_bug.cgi?id=201335
+
+ Reviewed by Mark Lam.
+
+ * stress/ensure-new-register-allocated.js: Added.
+ (shouldBe):
+ (basic):
+ (arrow):
+ (Base):
+ (Derived):
+ (evaluate):
+
+2019-08-30 Yusuke Suzuki <ysuz...@apple.com>
+
[JSC] DFG ByteCodeParser should not copy JIT-related part of SimpleJumpTable
https://bugs.webkit.org/show_bug.cgi?id=201331
Added: trunk/JSTests/stress/ensure-new-register-allocated.js (0 => 249337)
--- trunk/JSTests/stress/ensure-new-register-allocated.js (rev 0)
+++ trunk/JSTests/stress/ensure-new-register-allocated.js 2019-08-30 18:53:26 UTC (rev 249337)
@@ -0,0 +1,44 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+(function () {
+ function basic() {
+ return new.target;
+ }
+
+ shouldBe(basic(), undefined);
+ shouldBe(new basic(), basic);
+
+ function arrow() {
+ return () => new.target;
+ }
+
+ shouldBe(arrow()(), undefined);
+ shouldBe(new arrow()(), arrow);
+
+ class Base {
+ constructor()
+ {
+ this.value = new.target;
+ }
+ }
+
+ class Derived extends Base {
+ constructor()
+ {
+ super();
+ }
+ }
+
+ var derived = new Derived();
+ shouldBe(derived.value, Derived);
+}());
+(function () {
+ function evaluate() {
+ return eval(`new.target`);
+ }
+ shouldBe(evaluate(), undefined);
+ shouldBe(new evaluate(), evaluate);
+}());
Modified: trunk/Source/_javascript_Core/ChangeLog (249336 => 249337)
--- trunk/Source/_javascript_Core/ChangeLog 2019-08-30 18:23:29 UTC (rev 249336)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-08-30 18:53:26 UTC (rev 249337)
@@ -1,5 +1,22 @@
2019-08-30 Yusuke Suzuki <ysuz...@apple.com>
+ [JSC] Generate new.target register only when it is used
+ https://bugs.webkit.org/show_bug.cgi?id=201335
+
+ Reviewed by Mark Lam.
+
+ Since bytecode generator knows whether new.target register can be used, we should emit and use new.target register
+ only when it is actually required.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::newTarget):
+ * parser/Nodes.h:
+ (JSC::ScopeNode::needsNewTargetRegisterForThisScope const):
+
+2019-08-30 Yusuke Suzuki <ysuz...@apple.com>
+
[JSC] DFG ByteCodeParser should not copy JIT-related part of SimpleJumpTable
https://bugs.webkit.org/show_bug.cgi?id=201331
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (249336 => 249337)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2019-08-30 18:23:29 UTC (rev 249336)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2019-08-30 18:53:26 UTC (rev 249337)
@@ -667,7 +667,9 @@
}
- m_newTargetRegister = addVar();
+ if (functionNode->needsNewTargetRegisterForThisScope() || isNewTargetUsedInInnerArrowFunction() || codeBlock->usesEval())
+ m_newTargetRegister = addVar();
+
switch (parseMode) {
case SourceParseMode::GeneratorWrapperFunctionMode:
case SourceParseMode::GeneratorWrapperMethodMode:
@@ -725,7 +727,8 @@
case SourceParseMode::AsyncArrowFunctionBodyMode:
case SourceParseMode::GeneratorBodyMode: {
// |this| is already filled correctly before here.
- emitLoad(m_newTargetRegister, jsUndefined());
+ if (m_newTargetRegister)
+ emitLoad(m_newTargetRegister, jsUndefined());
break;
}
@@ -732,7 +735,8 @@
default: {
if (SourceParseMode::ArrowFunctionMode != parseMode) {
if (isConstructor()) {
- move(m_newTargetRegister, &m_thisRegister);
+ if (m_newTargetRegister)
+ move(m_newTargetRegister, &m_thisRegister);
if (constructorKind() == ConstructorKind::Extends) {
moveEmptyValue(&m_thisRegister);
} else
@@ -772,7 +776,7 @@
if (functionNode->usesThis() || functionNode->usesSuperProperty())
emitLoadThisFromArrowFunctionLexicalEnvironment();
- if (m_scopeNode->usesNewTarget() || m_scopeNode->usesSuperCall())
+ if (m_scopeNode->needsNewTargetRegisterForThisScope())
emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
}
@@ -829,7 +833,7 @@
if (functionNode->usesThis() || functionNode->usesSuperProperty())
emitLoadThisFromArrowFunctionLexicalEnvironment();
- if (m_scopeNode->usesNewTarget() || m_scopeNode->usesSuperCall())
+ if (m_scopeNode->needsNewTargetRegisterForThisScope())
emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
}
@@ -899,13 +903,13 @@
codeBlock->adoptVariables(variables);
codeBlock->adoptFunctionHoistingCandidates(WTFMove(hoistedFunctions));
- if (evalNode->usesSuperCall() || evalNode->usesNewTarget())
+ if (evalNode->needsNewTargetRegisterForThisScope())
m_newTargetRegister = addVar();
if (codeBlock->isArrowFunctionContext() && (evalNode->usesThis() || evalNode->usesSuperProperty()))
emitLoadThisFromArrowFunctionLexicalEnvironment();
- if (evalNode->usesSuperCall() || evalNode->usesNewTarget())
+ if (evalNode->needsNewTargetRegisterForThisScope())
emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunctionContext() && !isDerivedConstructorContext()) {
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (249336 => 249337)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2019-08-30 18:23:29 UTC (rev 249336)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2019-08-30 18:53:26 UTC (rev 249337)
@@ -423,6 +423,7 @@
RegisterID* argumentsRegister() { return m_argumentsRegister; }
RegisterID* newTarget()
{
+ ASSERT(m_newTargetRegister);
return m_newTargetRegister;
}
Modified: trunk/Source/_javascript_Core/parser/Nodes.h (249336 => 249337)
--- trunk/Source/_javascript_Core/parser/Nodes.h 2019-08-30 18:23:29 UTC (rev 249336)
+++ trunk/Source/_javascript_Core/parser/Nodes.h 2019-08-30 18:53:26 UTC (rev 249337)
@@ -1799,6 +1799,11 @@
bool captures(const Identifier& ident) { return captures(ident.impl()); }
bool hasSloppyModeHoistedFunction(UniquedStringImpl* uid) const { return m_sloppyModeHoistedFunctions.contains(uid); }
+ bool needsNewTargetRegisterForThisScope() const
+ {
+ return usesSuperCall() || usesNewTarget();
+ }
+
VariableEnvironment& varDeclarations() { return m_varDeclarations; }
int neededConstants()