Commit 5d4e11a7 authored by Michael Achenbach's avatar Michael Achenbach Committed by Commit Bot

Revert "[turbofan] Handle mixed packed/unpacked multimaps in Array.prototype.push"

This reverts commit ae14edca.

Reason for revert: Test fails with gc stress:
https://build.chromium.org/p/client.v8/builders/V8%20Linux64%20GC%20Stress%20-%20custom%20snapshot/builds/17067

Original change's description:
> [turbofan] Handle mixed packed/unpacked multimaps in Array.prototype.push
> 
> Bug: v8:7127, v8:7204, v8:7205
> Change-Id: I4eb009492222b208ff8875b4b7940174dfb132ff
> Reviewed-on: https://chromium-review.googlesource.com/847576
> Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
> Reviewed-by: Michael Stanton <mvstanton@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#50451}

TBR=mvstanton@chromium.org,sigurds@chromium.org

Change-Id: Ic1dac13e59565d2f0f2a4265c24f6532973f630a
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:7127, v8:7204, v8:7205
Reviewed-on: https://chromium-review.googlesource.com/857636Reviewed-by: 's avatarMichael Achenbach <machenbach@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50455}
parent 163b5d70
...@@ -3612,12 +3612,11 @@ Reduction JSCallReducer::ReduceArrayPrototypePush(Node* node) { ...@@ -3612,12 +3612,11 @@ Reduction JSCallReducer::ReduceArrayPrototypePush(Node* node) {
if (result == NodeProperties::kNoReceiverMaps) return NoChange(); if (result == NodeProperties::kNoReceiverMaps) return NoChange();
DCHECK_NE(0, receiver_maps.size()); DCHECK_NE(0, receiver_maps.size());
ElementsKind kind = receiver_maps[0]->elements_kind(); const ElementsKind kind = receiver_maps[0]->elements_kind();
for (Handle<Map> receiver_map : receiver_maps) { for (Handle<Map> receiver_map : receiver_maps) {
if (!CanInlineArrayResizeOperation(receiver_map)) return NoChange(); if (!CanInlineArrayResizeOperation(receiver_map)) return NoChange();
if (!UnionElementsKindUptoPackedness(&kind, receiver_map->elements_kind())) if (receiver_map->elements_kind() != kind) return NoChange();
return NoChange();
} }
// Install code dependencies on the {receiver} global array protector cell. // Install code dependencies on the {receiver} global array protector cell.
......
...@@ -191,43 +191,6 @@ inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) { ...@@ -191,43 +191,6 @@ inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) {
return packed_kind; return packed_kind;
} }
inline bool UnionElementsKindUptoPackedness(ElementsKind* a_out,
ElementsKind b) {
// Assert that the union of two ElementKinds can be computed via std::max.
static_assert(PACKED_SMI_ELEMENTS < HOLEY_SMI_ELEMENTS,
"ElementsKind union not computable via std::max.");
static_assert(PACKED_ELEMENTS < HOLEY_ELEMENTS,
"ElementsKind union not computable via std::max.");
static_assert(PACKED_DOUBLE_ELEMENTS < HOLEY_DOUBLE_ELEMENTS,
"ElementsKind union not computable via std::max.");
ElementsKind a = *a_out;
switch (a) {
case HOLEY_SMI_ELEMENTS:
case PACKED_SMI_ELEMENTS:
if (b == PACKED_SMI_ELEMENTS || b == HOLEY_SMI_ELEMENTS) {
*a_out = std::max(a, b);
return true;
}
break;
case PACKED_ELEMENTS:
case HOLEY_ELEMENTS:
if (b == PACKED_ELEMENTS || b == HOLEY_ELEMENTS) {
*a_out = std::max(a, b);
return true;
}
break;
case PACKED_DOUBLE_ELEMENTS:
case HOLEY_DOUBLE_ELEMENTS:
if (b == PACKED_DOUBLE_ELEMENTS || b == HOLEY_DOUBLE_ELEMENTS) {
*a_out = std::max(a, b);
return true;
}
break;
default:
break;
}
return false;
}
inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) { inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) {
DCHECK(IsSmiElementsKind(from_kind)); DCHECK(IsSmiElementsKind(from_kind));
......
...@@ -2,108 +2,98 @@ ...@@ -2,108 +2,98 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax --opt --no-always-opt // Flags: --allow-natives-syntax --opt
function runTest(f, message, mkICTraining, deoptArg) { (function singleUnreliableReceiverMap() {
function test(f, message, ictraining, deoptArg) { function f(a, g) {
// Train the call ic to the maps. a.push(2, g());
let t = ictraining;
for (let a of t()) {
f(a.arr, () => a.el);
}
for (let a of t()) {
f(a.arr, () => a.el);
} }
f([1], () => 3);
f([1], () => 3);
%OptimizeFunctionOnNextCall(f); %OptimizeFunctionOnNextCall(f);
message += " trained with" + JSON.stringify(t()); f([1], () => 3);
if (deoptArg == undefined) { assertOptimized(f);
// Make sure the optimized function can handle })();
// all trained maps without deopt.
for (let a of t()) { (function singleUnreliableReceiverMapDeopt() {
f(a.arr, () => a.el); function f(a, g) {
message += " for args " + JSON.stringify(a); a.push(2, g());
assertOptimized(f, undefined, message);
} }
} else {
// Trigger deopt, causing no-speculation bit to be set. f([1], () => 3);
let a1 = deoptArg, a2 = deoptArg; f([1], () => 3);
message += " for args " + JSON.stringify(a1);
f(a1.arr, () => a1.el);
assertUnoptimized(f, undefined, message + " should have been unoptimized");
%OptimizeFunctionOnNextCall(f); %OptimizeFunctionOnNextCall(f);
// No speculation should protect against further deopts. f([1], () => true);
f(a2.arr, () => a2.el); %OptimizeFunctionOnNextCall(f);
assertOptimized(f, undefined, message + " should have been optimized"); f([1], () => true);
} assertOptimized(f);
} })();
// Get function as a string. (function multipleUnreliableReceiverMaps(){
var testString = test.toString(); function f(a, g) {
// Remove the function header.. a.push(2, g());
testString = testString.replace(new RegExp("[^\n]*"), "let f = " + f.toString() + ";"); }
// ..and trailing '}'. let b = [1]
testString = testString.replace(new RegExp("[^\n]*$"), ""); b.x = 3;
// Substitute parameters.
testString = testString.replace(new RegExp("ictraining", 'g'), mkICTraining.toString());
testString = testString.replace(new RegExp("deoptArg", 'g'),
deoptArg ? JSON.stringify(deoptArg) : "undefined");
var modTest = new Function("message", testString); f([1], () => 3);
//print(modTest); f(b, () => 3);
modTest(message); f([1], () => 3);
} f(b, () => 3);
%OptimizeFunctionOnNextCall(f);
f([1], () => 3);
assertOptimized(f);
})();
let checks = { (function multipleUnreliableReceiverMapsDeopt(){
smiReceiver: function f(a, g) {
{ mkTrainingArguments : () => [{arr:[1], el:3}], a.push(2, g());
deoptingArguments : [{arr:[1], el:true}, {arr:[0.1], el:1}, {arr:[{}], el:1}] }
}, let b = [1]
objectReceiver: b.x = 3;
{ mkTrainingArguments : () => [{arr:[{}], el:0.1}],
deoptingArguments : []
},
multipleSmiReceivers:
{ mkTrainingArguments : () => { let b = [1]; b.x=3; return [{arr:[1], el:3}, {arr:b, el:3}] },
deoptingArguments : [{arr:[1], el:true}, {arr:[0.1], el:1}, {arr:[{}], el:1}]
},
multipleSmiReceiversPackedUnpacked:
{ mkTrainingArguments : () => { let b = [1]; b[100] = 3; return [{arr:[1], el:3}, {arr:b, el:3}] },
deoptingArguments : [ {arr:[1], el:true} ]
},
multipleDoubleReceivers:
{ mkTrainingArguments : () => { let b = [0.1]; b.x=0.3; return [{arr:[0.1], el:0.3}, {arr:b, el:0.3}] },
deoptingArguments : [{arr:[{}], el:true}, {arr:[0.1], el:true}]
},
multipleDoubleReceiversPackedUnpacked:
{ mkTrainingArguments : () => { let b = [0.1]; b[100] = 0.3; return [{arr:[0.1], el:0.3}, {arr:b, el:0.3}] },
deoptingArguments : [{arr:[{}], el:true}, {arr:[0.1], el:true}]
},
multipleMixedReceivers:
{ mkTrainingArguments : () => { let b = [0.1]; b.x=0.3; return [{arr:[1], el:0.3}, {arr:[{}], el:true}, {arr:b, el:0.3}] },
deoptingArguments : []
},
multipleMixedReceiversPackedUnpacked:
{ mkTrainingArguments : () => { let b = [0.1]; b[100] = 0.3; return [{arr:[1], el:0.3}, {arr:[{}], el:true}, {arr:b, el:0.3}] },
deoptingArguments : []
},
};
f([1], () => 3);
f(b, () => 3);
f([1], () => 3);
f(b, () => 3);
%OptimizeFunctionOnNextCall(f);
f([0.1], () => 3);
%OptimizeFunctionOnNextCall(f);
f([0.1], () => 3);
assertOptimized(f);
})();
const functions = { (function multipleReliableReceiverMaps(){
push_reliable: (a,g) => { let b = g(); return a.push(2, b); }, function f(a) {
push_unreliable: (a,g) => { return a.push(2, g()); }, a.push(2);
} }
let b = [1]
b.x = 3;
Object.keys(checks).forEach( f([1]);
key => { f(b);
let check = checks[key]; f([1]);
f(b);
%OptimizeFunctionOnNextCall(f);
f([1]);
assertOptimized(f);
})();
for (fnc in functions) { (function multipleReliableReceiverMapsDeopt(){
runTest(functions[fnc], "test-reliable-" + key, check.mkTrainingArguments); function f(a) {
// Test each deopting arg separately. a.push(2);
for (let deoptArg of check.deoptingArguments) {
runTest(functions[fnc], "testDeopt-reliable-" + key, check.mkTrainingArguments, deoptArg);
}
} }
} let b = [1]
); b.x = 3;
f([1]);
f(b);
f([1]);
f(b);
%OptimizeFunctionOnNextCall(f);
f([0.1]);
%OptimizeFunctionOnNextCall(f);
f([0.1]);
assertOptimized(f);
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment