Commit b0ebd51e authored by Matt Gardner's avatar Matt Gardner Committed by Commit Bot

[turbofan] Use heap constant optimizations for has property

Call to ReduceKeyedLoadFromHeapConstant got lost in rebasing,
as did the kHas check in ReduceElementAccessOnString. Added
some tests to ensure both cases are covered.

Change-Id: I8d6992c33315436b6228471b9bc57e3b267ad09f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1508837Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Matt Gardner <magardn@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#60132}
parent 5af460f5
......@@ -1484,6 +1484,9 @@ Reduction JSNativeContextSpecialization::ReduceElementAccessOnString(
// Strings are immutable in JavaScript.
if (access_mode == AccessMode::kStore) return NoChange();
// `in` cannot be used on strings.
if (access_mode == AccessMode::kHas) return NoChange();
// Ensure that the {receiver} is actually a String.
receiver = effect = graph()->NewNode(
simplified()->CheckString(VectorSlotPair()), receiver, effect, control);
......@@ -1744,7 +1747,8 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
Reduction JSNativeContextSpecialization::ReduceKeyedLoadFromHeapConstant(
Node* node, Node* index, FeedbackNexus const& nexus, AccessMode access_mode,
KeyedAccessLoadMode load_mode) {
DCHECK_EQ(node->opcode(), IrOpcode::kJSLoadProperty);
DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
node->opcode() == IrOpcode::kJSHasProperty);
Node* receiver = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
......@@ -1754,7 +1758,7 @@ Reduction JSNativeContextSpecialization::ReduceKeyedLoadFromHeapConstant(
if (receiver_ref.map().oddball_type() == OddballType::kHole ||
receiver_ref.map().oddball_type() == OddballType::kNull ||
receiver_ref.map().oddball_type() == OddballType::kUndefined ||
(receiver_ref.map().IsString() && access_mode == AccessMode::kHas)) {
(receiver_ref.IsString() && access_mode == AccessMode::kHas)) {
return NoChange();
}
......@@ -1846,7 +1850,7 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
Node* receiver = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node);
if (access_mode == AccessMode::kLoad &&
if ((access_mode == AccessMode::kLoad || access_mode == AccessMode::kHas) &&
receiver->opcode() == IrOpcode::kHeapConstant) {
Reduction reduction = ReduceKeyedLoadFromHeapConstant(
node, index, nexus, access_mode, load_mode);
......
......@@ -271,6 +271,7 @@ for (test in tests) {
proto();
proto();
%OptimizeFunctionOnNextCall(proto);
proto();
})();
......@@ -281,6 +282,9 @@ for (test in tests) {
};
assertThrows(test, TypeError);
assertThrows(test, TypeError);
%OptimizeFunctionOnNextCall(test);
assertThrows(test, TypeError);
})();
// `in` is allowed on `this` even when `this` is a string
......@@ -291,6 +295,7 @@ for (test in tests) {
test.call("");
test.call("");
%OptimizeFunctionOnNextCall(test);
test.call("");
})();
......@@ -310,6 +315,10 @@ for (test in tests) {
assertFalse(test(0));
assertFalse(test(0,1));
assertTrue(test(0,1,2));
%OptimizeFunctionOnNextCall(test);
assertFalse(test(0,1));
assertTrue(test(0,1,2));
})();
(function() {
......@@ -320,6 +329,7 @@ for (test in tests) {
assertFalse(test(1));
assertFalse(test(1));
%OptimizeFunctionOnNextCall(test);
assertFalse(test(1));
})();
......@@ -347,6 +357,8 @@ for (test in tests) {
assertFalse(test(str, 0));
assertFalse(test(str, 0));
%OptimizeFunctionOnNextCall(test);
assertFalse(test(str, 0));
})();
(function() {
......@@ -362,6 +374,7 @@ for (test in tests) {
var str = "string";
assertFalse(test(str, "length"));
assertFalse(test(str, "length"));
%OptimizeFunctionOnNextCall(test);
assertFalse(test(str, "length"));
})();
......@@ -378,6 +391,7 @@ for (test in tests) {
var str = "string";
assertFalse(test(str, 0));
assertFalse(test(str, 0));
%OptimizeFunctionOnNextCall(test);
assertFalse(test(str, 0));
})();
......@@ -398,5 +412,26 @@ for (test in tests) {
var str = "string";
assertFalse(test(str, 0));
assertFalse(test(str, 0));
%OptimizeFunctionOnNextCall(test);
assertFalse(test(str, 0));
})();
const heap_constant_ary = [0,1,2,3];
(function() {
function test() {
return 1 in heap_constant_ary;
}
assertTrue(test());
assertTrue(test());
%OptimizeFunctionOnNextCall(test);
assertTrue(test());
heap_constant_ary[1] = 2;
assertTrue(test());
%OptimizeFunctionOnNextCall(test);
assertTrue(test());
})()
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