Title: [220724] trunk
Revision
220724
Author
[email protected]
Date
2017-08-14 16:37:06 -0700 (Mon, 14 Aug 2017)

Log Message

JSTests:
Support the with keyword in DFG
https://bugs.webkit.org/show_bug.cgi?id=175470

Patch by Robin Morisset <[email protected]> on 2017-08-14
Reviewed by Saam Barati.

Added a new stress-test for the 'with' keyword, that caught a bug in a
previous version of this code.

* stress/with.js: Added.
(i.with):

Source/_javascript_Core:
Support the 'with' keyword in DFG
https://bugs.webkit.org/show_bug.cgi?id=175470

Patch by Robin Morisset <[email protected]> on 2017-08-14
Reviewed by Saam Barati.

Not particularly optimized at the moment, the goal is just to avoid
the DFG bailing out of any function with this keyword.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compilePushWithScope):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* jit/JITOperations.cpp:
* jit/JITOperations.h:

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (220723 => 220724)


--- trunk/JSTests/ChangeLog	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/JSTests/ChangeLog	2017-08-14 23:37:06 UTC (rev 220724)
@@ -1,3 +1,16 @@
+2017-08-14  Robin Morisset  <[email protected]>
+
+        Support the with keyword in DFG
+        https://bugs.webkit.org/show_bug.cgi?id=175470
+
+        Reviewed by Saam Barati.
+
+        Added a new stress-test for the 'with' keyword, that caught a bug in a
+        previous version of this code.
+
+        * stress/with.js: Added.
+        (i.with):
+
 2017-08-14  Ryan Haddad  <[email protected]>
 
         Skip flaky JSC test test/fieldopts/objtypespec-newobj-invalidation.1.js

Added: trunk/JSTests/stress/with.js (0 => 220724)


--- trunk/JSTests/stress/with.js	                        (rev 0)
+++ trunk/JSTests/stress/with.js	2017-08-14 23:37:06 UTC (rev 220724)
@@ -0,0 +1,36 @@
+for (var i = 0; i < 10000; ++i) {
+    var x = 1;
+    var y = 2;
+
+    var z = {a: 42};
+    with (z) {
+        x = y;
+    }
+    if (x !== 2 || y !== 2 || z.a !== 42) {
+        throw "Error: bad result, first case, for i = " + i;
+    }
+
+    z = {y: 42}
+    with (z) {
+        x = y;
+    }
+    if (x !== 42 || y !== 2 || z.y !== 42) {
+        throw "Error: bad result, second case, for i = " + i;
+    }
+
+    z = {x: 13};
+    with (z) {
+        x = y;
+    }
+    if (x !== 42 || y !== 2 || z.x !== 2) {
+        throw "Error: bad result, third case, for i = " + i;
+    }
+
+    z = {x:13, y:14};
+    with (z) {
+        x = y;
+    }
+    if (x !== 42 || y !== 2 || z.x !== 14 || z.y !== 14) {
+        throw "Error: bad result, fourth case, for i = " + i;
+    }
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (220723 => 220724)


--- trunk/Source/_javascript_Core/ChangeLog	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-08-14 23:37:06 UTC (rev 220724)
@@ -1,3 +1,40 @@
+2017-08-14  Robin Morisset  <[email protected]>
+
+        Support the 'with' keyword in DFG
+        https://bugs.webkit.org/show_bug.cgi?id=175470
+
+        Reviewed by Saam Barati.
+
+        Not particularly optimized at the moment, the goal is just to avoid
+        the DFG bailing out of any function with this keyword.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compilePushWithScope):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+
 2017-08-14  Mark Lam  <[email protected]>
 
         Add some convenience utility accessor methods to MacroAssembler::CPUState.

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2017-08-14 23:37:06 UTC (rev 220724)
@@ -2062,6 +2062,13 @@
         break;
     }
 
+    case PushWithScope:
+        clobberWorld(node->origin.semantic, clobberLimit);
+
+        // We don't use the more precise withScopeStructure() here because it is a LazyProperty and may not yet be allocated.
+        forNode(node).setType(m_graph, SpecObjectOther);
+        break;
+
     case CreateActivation:
     case MaterializeCreateActivation:
         forNode(node).set(

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2017-08-14 23:37:06 UTC (rev 220724)
@@ -5639,6 +5639,13 @@
             NEXT_OPCODE(op_create_lexical_environment);
         }
 
+        case op_push_with_scope: {
+            Node* scopeObject = get(VirtualRegister(currentInstruction[2].u.operand));
+            Node* currentScope = get(VirtualRegister(currentInstruction[3].u.operand));
+            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(PushWithScope, scopeObject, currentScope));
+            NEXT_OPCODE(op_push_with_scope);
+        }
+
         case op_get_parent_scope: {
             Node* currentScope = get(VirtualRegister(currentInstruction[2].u.operand));
             Node* newScope = addToGraph(SkipScope, currentScope);

Modified: trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp	2017-08-14 23:37:06 UTC (rev 220724)
@@ -245,6 +245,7 @@
     case op_new_async_func_exp:
     case op_set_function_name:
     case op_create_lexical_environment:
+    case op_push_with_scope:
     case op_get_parent_scope:
     case op_catch:
     case op_create_rest:

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2017-08-14 23:37:06 UTC (rev 220724)
@@ -478,7 +478,7 @@
         write(HeapObjectCount);
         return;
     }
-        
+
     case CreateDirectArguments:
     case CreateScopedArguments:
     case CreateClonedArguments:
@@ -604,6 +604,7 @@
     case PutDynamicVar:
     case ResolveScopeForHoistingFuncDeclInEval:
     case ResolveScope:
+    case PushWithScope:
         read(World);
         write(Heap);
         return;

Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp	2017-08-14 23:37:06 UTC (rev 220724)
@@ -279,6 +279,7 @@
     case AtomicsSub:
     case AtomicsXor:
     case AtomicsIsLockFree:
+    case PushWithScope:
         return false;
 
     case CreateActivation:

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2017-08-14 23:37:06 UTC (rev 220724)
@@ -1717,6 +1717,12 @@
             break;
         }
 
+        case PushWithScope: {
+            // Child2 is always the current scope, which is guaranteed to be an object.
+            fixEdge<KnownCellUse>(node->child2());
+            break;
+        }
+
         case SetFunctionName: {
             // The first child is guaranteed to be a cell because op_set_function_name is only used
             // on a newly instantiated function object (the first child).

Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2017-08-14 23:37:06 UTC (rev 220724)
@@ -359,6 +359,7 @@
     macro(HasOwnProperty, NodeResultBoolean) \
     \
     macro(CreateActivation, NodeResultJS) \
+    macro(PushWithScope, NodeResultJS | NodeMustGenerate) \
     \
     macro(CreateDirectArguments, NodeResultJS) \
     macro(PhantomDirectArguments, NodeResultJS | NodeMustGenerate) \

Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2017-08-14 23:37:06 UTC (rev 220724)
@@ -895,6 +895,7 @@
             break;
         }
             
+        case PushWithScope:
         case CreateActivation: {
             setPrediction(SpecObjectOther);
             break;

Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2017-08-14 23:37:06 UTC (rev 220724)
@@ -294,6 +294,7 @@
     case MakeRope:
     case In:
     case HasOwnProperty:
+    case PushWithScope:
     case CreateActivation:
     case CreateDirectArguments:
     case CreateScopedArguments:

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2017-08-14 23:37:06 UTC (rev 220724)
@@ -1124,6 +1124,23 @@
     unblessedBooleanResult(resultGPR, node, UseChildrenCalledExplicitly);
 }
 
+void SpeculativeJIT::compilePushWithScope(Node* node)
+{
+    JSValueOperand scopeObject(this, node->child1());
+    SpeculateCellOperand currentScope(this, node->child2());
+    JSValueRegs scopeObjectRegs = scopeObject.jsValueRegs();
+    GPRReg currentScopeGPR = currentScope.gpr();
+
+    GPRFlushedCallResult result(this);
+    GPRReg resultGPR = result.gpr();
+    
+    flushRegisters();
+    callOperation(operationPushWithScope, resultGPR, currentScopeGPR, scopeObjectRegs);
+    m_jit.exceptionCheck();
+    
+    cellResult(resultGPR, node);
+}
+
 bool SpeculativeJIT::nonSpeculativeCompare(Node* node, MacroAssembler::RelationalCondition cond, S_JITOperation_EJJ helperFunction)
 {
     unsigned branchIndexInBlock = detectPeepHoleBranch();

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2017-08-14 23:37:06 UTC (rev 220724)
@@ -744,6 +744,7 @@
 
     void compileDeleteById(Node*);
     void compileDeleteByVal(Node*);
+    void compilePushWithScope(Node*);
     void compileTryGetById(Node*);
     void compileIn(Node*);
     
@@ -1390,6 +1391,11 @@
         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
         return appendCallSetResult(operation, result);
     }
+    JITCompiler::Call callOperation(C_JITOperation_ECJ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2.gpr());
+        return appendCallSetResult(operation, result);
+    }
     JITCompiler::Call callOperation(J_JITOperation_EJMic operation, JSValueRegs result, JSValueRegs arg, TrustedImmPtr mathIC)
     {
         m_jit.setupArgumentsWithExecState(arg.gpr(), mathIC);
@@ -1939,6 +1945,11 @@
         m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), arg3);
         return appendCallSetResult(operation, result);
     }
+    JITCompiler::Call callOperation(C_JITOperation_ECJ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR());
+        return appendCallSetResult(operation, result);
+    }
     JITCompiler::Call callOperation(J_JITOperation_EJMic operation, JSValueRegs result, JSValueRegs arg, TrustedImmPtr mathIC)
     {
         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg.payloadGPR(), arg.tagGPR(), mathIC);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2017-08-14 23:37:06 UTC (rev 220724)
@@ -5017,6 +5017,11 @@
         compileCreateActivation(node);
         break;
     }
+
+    case PushWithScope: {
+        compilePushWithScope(node);
+        break;
+    }
         
     case CreateDirectArguments: {
         compileCreateDirectArguments(node);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (220723 => 220724)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2017-08-14 23:37:06 UTC (rev 220724)
@@ -5425,7 +5425,12 @@
         compileCreateActivation(node);
         break;
     }
-        
+    
+    case PushWithScope: {
+        compilePushWithScope(node);
+        break;
+    }
+
     case CreateDirectArguments: {
         compileCreateDirectArguments(node);
         break;

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (220723 => 220724)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2017-08-14 23:37:06 UTC (rev 220724)
@@ -57,6 +57,7 @@
 #include "JSGlobalObjectFunctions.h"
 #include "JSLexicalEnvironment.h"
 #include "JSPropertyNameEnumerator.h"
+#include "JSWithScope.h"
 #include "ModuleProgramCodeBlock.h"
 #include "ObjectConstructor.h"
 #include "PolymorphicAccess.h"
@@ -1995,6 +1996,20 @@
     return couldDelete;
 }
 
+JSCell* JIT_OPERATION operationPushWithScope(ExecState* exec, JSCell* currentScopeCell, EncodedJSValue scopeObjectValue)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSObject* newScope = JSValue::decode(scopeObjectValue).toObject(exec);
+    RETURN_IF_EXCEPTION(scope, nullptr);
+
+    JSScope* currentScope = jsCast<JSScope*>(currentScopeCell);
+
+    return JSWithScope::create(vm, exec->lexicalGlobalObject(), newScope, currentScope);
+}
+
 EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedProto)
 {
     VM& vm = exec->vm();

Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (220723 => 220724)


--- trunk/Source/_javascript_Core/jit/JITOperations.h	2017-08-14 23:33:27 UTC (rev 220723)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h	2017-08-14 23:37:06 UTC (rev 220724)
@@ -212,6 +212,7 @@
 typedef JSCell* (JIT_OPERATION *C_JITOperation_EZ)(ExecState*, int32_t);
 typedef JSCell* (JIT_OPERATION *C_JITOperation_EJscI)(ExecState*, JSScope*, UniquedStringImpl*);
 typedef JSCell* (JIT_OPERATION *C_JITOperation_ECJZ)(ExecState*, JSCell*, EncodedJSValue, int32_t);
+typedef JSCell* (JIT_OPERATION *C_JITOperation_ECJ)(ExecState*, JSCell*, EncodedJSValue);
 typedef double (JIT_OPERATION *D_JITOperation_D)(double);
 typedef double (JIT_OPERATION *D_JITOperation_G)(JSGlobalObject*);
 typedef double (JIT_OPERATION *D_JITOperation_DD)(double, double);
@@ -418,6 +419,7 @@
 size_t JIT_OPERATION operationDeleteById(ExecState*, EncodedJSValue base, UniquedStringImpl*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationDeleteByValJSResult(ExecState*, EncodedJSValue base, EncodedJSValue target) WTF_INTERNAL;
 size_t JIT_OPERATION operationDeleteByVal(ExecState*, EncodedJSValue base, EncodedJSValue target) WTF_INTERNAL;
+JSCell* JIT_OPERATION operationPushWithScope(ExecState*, JSCell* currentScopeCell, EncodedJSValue scopeObject) WTF_INTERNAL;
 JSCell* JIT_OPERATION operationGetPNames(ExecState*, JSObject*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState*, EncodedJSValue, EncodedJSValue proto) WTF_INTERNAL;
 int32_t JIT_OPERATION operationSizeFrameForForwardArguments(ExecState*, EncodedJSValue arguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset) WTF_INTERNAL;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to