Title: [205627] releases/WebKitGTK/webkit-2.14
Revision
205627
Author
[email protected]
Date
2016-09-08 05:02:30 -0700 (Thu, 08 Sep 2016)

Log Message

Merge r205321 - GetByIdWithThis/GetByValWithThis should have ValueProfiles so that they can predict their result types
https://bugs.webkit.org/show_bug.cgi?id=160922

Patch by JF Bastien <[email protected]> on 2016-09-01
Reviewed by Keith Miller.

JSTests:

Benchmark GetBy{Id,Val}WithThis in monomorphic and polymorphic uses.
The value profile is used by the calc functions, which do some mild math with the result.
These benchmarks get ~4% faster with value profiling.

* microbenchmarks/super-get-by-id-with-this-monomorphic.js: Added.
(A):
(A.prototype.set value):
(A.prototype.get value):
(B.prototype.set value):
(B.prototype.get value):
(B):
(const.bench):
* microbenchmarks/super-get-by-id-with-this-polymorphic.js: Added.
(A):
(A.prototype.set value):
(A.prototype.get value):
(B.prototype.set value):
(B.prototype.get value):
(B):
(const.bench):
* microbenchmarks/super-get-by-val-with-this-monomorphic.js: Added.
(value):
(A):
(A.prototype.set v):
(A.prototype.get v):
(B.prototype.set v):
(B.prototype.get v):
(B):
(const.bench):
* microbenchmarks/super-get-by-val-with-this-polymorphic.js: Added.
(value):
(A):
(A.prototype.set v):
(A.prototype.get v):
(B.prototype.set v):
(B.prototype.get v):
(B):
(const.bench):

Source/_javascript_Core:

Add value profiling to GetBy{Id,Val}WithThis.

* bytecode/BytecodeList.json:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::finishCreation):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitGetById):
(JSC::BytecodeGenerator::emitGetByVal):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasHeapPrediction):
* dfg/DFGPredictionPropagationPhase.cpp:
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.14/JSTests/ChangeLog (205626 => 205627)


--- releases/WebKitGTK/webkit-2.14/JSTests/ChangeLog	2016-09-08 11:22:59 UTC (rev 205626)
+++ releases/WebKitGTK/webkit-2.14/JSTests/ChangeLog	2016-09-08 12:02:30 UTC (rev 205627)
@@ -1,3 +1,49 @@
+2016-09-01  JF Bastien  <[email protected]>
+
+        GetByIdWithThis/GetByValWithThis should have ValueProfiles so that they can predict their result types
+        https://bugs.webkit.org/show_bug.cgi?id=160922
+
+        Reviewed by Keith Miller.
+
+        Benchmark GetBy{Id,Val}WithThis in monomorphic and polymorphic uses.
+        The value profile is used by the calc functions, which do some mild math with the result.
+        These benchmarks get ~4% faster with value profiling.
+
+        * microbenchmarks/super-get-by-id-with-this-monomorphic.js: Added.
+        (A):
+        (A.prototype.set value):
+        (A.prototype.get value):
+        (B.prototype.set value):
+        (B.prototype.get value):
+        (B):
+        (const.bench):
+        * microbenchmarks/super-get-by-id-with-this-polymorphic.js: Added.
+        (A):
+        (A.prototype.set value):
+        (A.prototype.get value):
+        (B.prototype.set value):
+        (B.prototype.get value):
+        (B):
+        (const.bench):
+        * microbenchmarks/super-get-by-val-with-this-monomorphic.js: Added.
+        (value):
+        (A):
+        (A.prototype.set v):
+        (A.prototype.get v):
+        (B.prototype.set v):
+        (B.prototype.get v):
+        (B):
+        (const.bench):
+        * microbenchmarks/super-get-by-val-with-this-polymorphic.js: Added.
+        (value):
+        (A):
+        (A.prototype.set v):
+        (A.prototype.get v):
+        (B.prototype.set v):
+        (B.prototype.get v):
+        (B):
+        (const.bench):
+
 2016-09-01  Filip Pizlo  <[email protected]>
 
         ObjectAllocationSinkingPhase::insertOSRHintsForUpdate() fails to emit updated hints in some cases

Added: releases/WebKitGTK/webkit-2.14/JSTests/microbenchmarks/super-get-by-id-with-this-monomorphic.js (0 => 205627)


--- releases/WebKitGTK/webkit-2.14/JSTests/microbenchmarks/super-get-by-id-with-this-monomorphic.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.14/JSTests/microbenchmarks/super-get-by-id-with-this-monomorphic.js	2016-09-08 12:02:30 UTC (rev 205627)
@@ -0,0 +1,32 @@
+const run = new Function("init", "num", `
+const calc = val => {
+    let c = 0;
+    for (let v = val; v; v >>>= 1) c += v & 1;
+    return val * 2 + val / 2 + c;
+}
+
+class A {
+    constructor(x) { this._value = x; }
+    set value(x) { this._value = x; }
+    get value() { return this._value; }
+}
+class B extends A {
+    set value(x) { super.value = x; }
+    get value() { return calc(super.value); }
+}
+
+const bench = (init, num) => {
+    let arr = [];
+    for (let i = 0; i != num; ++i) arr.push(new B(init));
+    for (let i = 0; i != num; ++i) arr[i].value += i;
+    let sum = 0;
+    for (let i = 0; i != num; ++i) sum += arr[i].value;
+};
+
+bench(init, num);
+`);
+
+run(2, 10000);
+run(1 << 30, 10000);
+run(42.2, 10000);
+run(42.5e10, 10000);

Added: releases/WebKitGTK/webkit-2.14/JSTests/microbenchmarks/super-get-by-id-with-this-polymorphic.js (0 => 205627)


--- releases/WebKitGTK/webkit-2.14/JSTests/microbenchmarks/super-get-by-id-with-this-polymorphic.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.14/JSTests/microbenchmarks/super-get-by-id-with-this-polymorphic.js	2016-09-08 12:02:30 UTC (rev 205627)
@@ -0,0 +1,28 @@
+const calc = val => {
+    let c = 0;
+    for (let v = val; v; v >>>= 1) c += v & 1;
+    return val * 2 + val / 2 + c;
+}
+
+class A {
+    constructor(x) { this._value = x; }
+    set value(x) { this._value = x; }
+    get value() { return this._value; }
+}
+class B extends A {
+    set value(x) { super.value = x; }
+    get value() { return calc(super.value); }
+}
+
+const bench = (init, num) => {
+    let arr = [];
+    for (let i = 0; i != num; ++i) arr.push(new B(init));
+    for (let i = 0; i != num; ++i) arr[i].value += i;
+    let sum = 0;
+    for (let i = 0; i != num; ++i) sum += arr[i].value;
+};
+
+bench(2, 10000);
+bench(1 << 30, 10000);
+bench(42.2, 10000);
+bench(42.5e10, 10000);

Added: releases/WebKitGTK/webkit-2.14/JSTests/microbenchmarks/super-get-by-val-with-this-monomorphic.js (0 => 205627)


--- releases/WebKitGTK/webkit-2.14/JSTests/microbenchmarks/super-get-by-val-with-this-monomorphic.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.14/JSTests/microbenchmarks/super-get-by-val-with-this-monomorphic.js	2016-09-08 12:02:30 UTC (rev 205627)
@@ -0,0 +1,36 @@
+const run = new Function("init", "num", `
+
+function value() { return 'v'; }
+noInline(value);
+
+const calc = val => {
+    let c = 0;
+    for (let v = val; v; v >>>= 1) c += v & 1;
+    return val * 2 + val / 2 + c;
+}
+
+class A {
+    constructor(x) { this._v = x; }
+    set v(x) { this._v = x; }
+    get v() { return this._v; }
+}
+class B extends A {
+    set v(x) { super[value()] = x; }
+    get v() { return calc(super[value()]); }
+}
+
+const bench = (init, num) => {
+    let arr = [];
+    for (let i = 0; i != num; ++i) arr.push(new B(init));
+    for (let i = 0; i != num; ++i) arr[i].v += i;
+    let sum = 0;
+    for (let i = 0; i != num; ++i) sum += arr[i].v;
+};
+
+bench(init, num);
+`);
+
+run(2, 10000);
+run(1 << 30, 10000);
+run(42.2, 10000);
+run(42.5e10, 10000);

Added: releases/WebKitGTK/webkit-2.14/JSTests/microbenchmarks/super-get-by-val-with-this-polymorphic.js (0 => 205627)


--- releases/WebKitGTK/webkit-2.14/JSTests/microbenchmarks/super-get-by-val-with-this-polymorphic.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.14/JSTests/microbenchmarks/super-get-by-val-with-this-polymorphic.js	2016-09-08 12:02:30 UTC (rev 205627)
@@ -0,0 +1,31 @@
+function value() { return 'v'; }
+noInline(value);
+
+const calc = val => {
+    let c = 0;
+    for (let v = val; v; v >>>= 1) c += v & 1;
+    return val * 2 + val / 2 + c;
+}
+
+class A {
+    constructor(x) { this._v = x; }
+    set v(x) { this._v = x; }
+    get v() { return this._v; }
+}
+class B extends A {
+    set v(x) { super[value()] = x; }
+    get v() { return calc(super[value()]); }
+}
+
+const bench = (init, num) => {
+    let arr = [];
+    for (let i = 0; i != num; ++i) arr.push(new B(init));
+    for (let i = 0; i != num; ++i) arr[i].v += i;
+    let sum = 0;
+    for (let i = 0; i != num; ++i) sum += arr[i].v;
+};
+
+bench(2, 10000);
+bench(1 << 30, 10000);
+bench(42.2, 10000);
+bench(42.5e10, 10000);

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog (205626 => 205627)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog	2016-09-08 11:22:59 UTC (rev 205626)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog	2016-09-08 12:02:30 UTC (rev 205627)
@@ -1,3 +1,28 @@
+2016-09-01  JF Bastien  <[email protected]>
+
+        GetByIdWithThis/GetByValWithThis should have ValueProfiles so that they can predict their result types
+        https://bugs.webkit.org/show_bug.cgi?id=160922
+
+        Reviewed by Keith Miller.
+
+        Add value profiling to GetBy{Id,Val}WithThis.
+
+        * bytecode/BytecodeList.json:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::CodeBlock::finishCreation):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitGetById):
+        (JSC::BytecodeGenerator::emitGetByVal):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasHeapPrediction):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * llint/LowLevelInterpreter.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+
 2016-09-01  Keith Miller  <[email protected]>
 
         Rename WASM classes dropping the WASM prefix

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/bytecode/BytecodeList.json (205626 => 205627)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/bytecode/BytecodeList.json	2016-09-08 11:22:59 UTC (rev 205626)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/bytecode/BytecodeList.json	2016-09-08 12:02:30 UTC (rev 205627)
@@ -65,8 +65,8 @@
             { "name" : "op_get_by_id", "length" : 9  },
             { "name" : "op_get_by_id_proto_load", "length" : 9 },
             { "name" : "op_get_by_id_unset", "length" : 9 },
-            { "name" : "op_get_by_id_with_this", "length" : 5 },
-            { "name" : "op_get_by_val_with_this", "length" : 5 },
+            { "name" : "op_get_by_id_with_this", "length" : 6 },
+            { "name" : "op_get_by_val_with_this", "length" : 6 },
             { "name" : "op_try_get_by_id", "length" : 5 },
             { "name" : "op_put_by_id", "length" : 9 },
             { "name" : "op_put_by_id_with_this", "length" : 5 },

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/bytecode/CodeBlock.cpp (205626 => 205627)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/bytecode/CodeBlock.cpp	2016-09-08 11:22:59 UTC (rev 205626)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/bytecode/CodeBlock.cpp	2016-09-08 12:02:30 UTC (rev 205627)
@@ -1149,6 +1149,7 @@
             int r2 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), idName(id0, identifier(id0)).data());
+            dumpValueProfiling(out, it, hasPrintedProfiling);
             break;
         }
         case op_get_by_val_with_this: {
@@ -1158,6 +1159,7 @@
             int r3 = (++it)->u.operand;
             printLocationAndOp(out, exec, location, it, "get_by_val_with_this");
             out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data());
+            dumpValueProfiling(out, it, hasPrintedProfiling);
             break;
         }
         case op_put_by_id: {
@@ -2076,7 +2078,9 @@
         }
         case op_get_direct_pname:
         case op_get_by_id:
+        case op_get_by_id_with_this:
         case op_try_get_by_id:
+        case op_get_by_val_with_this:
         case op_get_from_arguments:
         case op_to_number: {
             linkValueProfile(i, opLength);

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (205626 => 205627)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2016-09-08 11:22:59 UTC (rev 205626)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2016-09-08 12:02:30 UTC (rev 205627)
@@ -2492,11 +2492,12 @@
 {
     ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with get_by_val.");
 
-    emitOpcode(op_get_by_id_with_this);
+    UnlinkedValueProfile profile = ""
     instructions().append(kill(dst));
     instructions().append(base->index());
     instructions().append(thisVal->index());
     instructions().append(addConstant(property));
+    instructions().append(profile);
     return dst;
 }
 
@@ -2664,11 +2665,12 @@
 
 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* thisValue, RegisterID* property)
 {
-    emitOpcode(op_get_by_val_with_this);
+    UnlinkedValueProfile profile = ""
     instructions().append(kill(dst));
     instructions().append(base->index());
     instructions().append(thisValue->index());
     instructions().append(property->index());
+    instructions().append(profile);
     return dst;
 }
 

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (205626 => 205627)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2016-09-08 11:22:59 UTC (rev 205626)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2016-09-08 12:02:30 UTC (rev 205627)
@@ -4129,10 +4129,12 @@
         }
 
         case op_get_by_val_with_this: {
+            SpeculatedType prediction = getPrediction();
+
             Node* base = get(VirtualRegister(currentInstruction[2].u.operand));
             Node* thisValue = get(VirtualRegister(currentInstruction[3].u.operand));
             Node* property = get(VirtualRegister(currentInstruction[4].u.operand));
-            Node* getByValWithThis = addToGraph(GetByValWithThis, base, thisValue, property);
+            Node* getByValWithThis = addToGraph(GetByValWithThis, OpInfo(prediction), base, thisValue, property);
             set(VirtualRegister(currentInstruction[1].u.operand), getByValWithThis);
 
             NEXT_OPCODE(op_get_by_val_with_this);
@@ -4226,12 +4228,14 @@
                 NEXT_OPCODE(op_get_by_id);
         }
         case op_get_by_id_with_this: {
+            SpeculatedType prediction = getPrediction();
+
             Node* base = get(VirtualRegister(currentInstruction[2].u.operand));
             Node* thisValue = get(VirtualRegister(currentInstruction[3].u.operand));
             unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[4].u.operand];
 
             set(VirtualRegister(currentInstruction[1].u.operand),
-                addToGraph(GetByIdWithThis, OpInfo(identifierNumber), base, thisValue));
+                addToGraph(GetByIdWithThis, OpInfo(identifierNumber), OpInfo(prediction), base, thisValue));
 
             NEXT_OPCODE(op_get_by_id_with_this);
         }

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGNode.h (205626 => 205627)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGNode.h	2016-09-08 11:22:59 UTC (rev 205626)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGNode.h	2016-09-08 12:02:30 UTC (rev 205627)
@@ -1395,8 +1395,10 @@
         case GetDirectPname:
         case GetById:
         case GetByIdFlush:
+        case GetByIdWithThis:
         case TryGetById:
         case GetByVal:
+        case GetByValWithThis:
         case Call:
         case TailCallInlinedCaller:
         case Construct:

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (205626 => 205627)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2016-09-08 11:22:59 UTC (rev 205626)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2016-09-08 12:02:30 UTC (rev 205627)
@@ -680,11 +680,6 @@
             break;
         }
 
-        case GetByValWithThis:
-        case GetByIdWithThis: {
-            setPrediction(SpecBytecodeTop);
-            break;
-        }
         case ArrayPop:
         case ArrayPush:
         case RegExpExec:
@@ -693,7 +688,9 @@
         case StringReplaceRegExp:
         case GetById:
         case GetByIdFlush:
+        case GetByIdWithThis:
         case TryGetById:
+        case GetByValWithThis:
         case GetByOffset:
         case MultiGetByOffset:
         case GetDirectPname:

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/llint/LowLevelInterpreter.asm (205626 => 205627)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2016-09-08 11:22:59 UTC (rev 205626)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2016-09-08 12:02:30 UTC (rev 205627)
@@ -1806,12 +1806,12 @@
 _llint_op_get_by_id_with_this:
     traceExecution()
     callOpcodeSlowPath(_slow_path_get_by_id_with_this)
-    dispatch(5)
+    dispatch(6)
 
 _llint_op_get_by_val_with_this:
     traceExecution()
     callOpcodeSlowPath(_slow_path_get_by_val_with_this)
-    dispatch(5)
+    dispatch(6)
 
 _llint_op_put_by_id_with_this:
     traceExecution()

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (205626 => 205627)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2016-09-08 11:22:59 UTC (rev 205626)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2016-09-08 12:02:30 UTC (rev 205627)
@@ -828,7 +828,7 @@
     JSValue thisVal = OP_C(3).jsValue();
     PropertySlot slot(thisVal, PropertySlot::PropertySlot::InternalMethodType::Get);
     JSValue result = baseValue.get(exec, ident, slot);
-    RETURN(result);
+    RETURN_PROFILED(op_get_by_id_with_this, result);
 }
 
 SLOW_PATH_DECL(slow_path_get_by_val_with_this)
@@ -845,7 +845,7 @@
         if (JSCell::canUseFastGetOwnProperty(structure)) {
             if (RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
                 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
-                    RETURN(result); 
+                    RETURN_PROFILED(op_get_by_val_with_this, result);
             }
         }
     }
@@ -854,9 +854,9 @@
     if (subscript.isUInt32()) {
         uint32_t i = subscript.asUInt32();
         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
-            RETURN(asString(baseValue)->getIndex(exec, i));
+            RETURN_PROFILED(op_get_by_val_with_this, asString(baseValue)->getIndex(exec, i));
         
-        RETURN(baseValue.get(exec, i, slot));
+        RETURN_PROFILED(op_get_by_val_with_this, baseValue.get(exec, i, slot));
     }
 
     baseValue.requireObjectCoercible(exec);
@@ -863,7 +863,7 @@
     CHECK_EXCEPTION();
     auto property = subscript.toPropertyKey(exec);
     CHECK_EXCEPTION();
-    RETURN(baseValue.get(exec, property, slot));
+    RETURN_PROFILED(op_get_by_val_with_this, baseValue.get(exec, property, slot));
 }
 
 SLOW_PATH_DECL(slow_path_put_by_id_with_this)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to