Commit 3d7c4537 authored by bmeurer's avatar bmeurer Committed by Commit bot

[crankshaft] Handle @@toStringTag accessor correctly for BuildCompareInstruction.

If @@toStringTag is an accessor property, we cannot assume that the result
of calling Object.prototype.toString() for objects with the same map.

R=adamk@chromium.org
BUG=chromium:534200
LOG=n

Review URL: https://codereview.chromium.org/1360723002

Cr-Commit-Position: refs/heads/master@{#30856}
parent 9308f8f9
......@@ -11600,7 +11600,12 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
this, LOAD, map, isolate()->factory()->to_primitive_symbol());
PropertyAccessInfo to_string(this, LOAD, map,
isolate()->factory()->toString_string());
PropertyAccessInfo to_string_tag(
this, LOAD, map, isolate()->factory()->to_string_tag_symbol());
if (to_primitive.CanAccessMonomorphic() && !to_primitive.IsFound() &&
to_string_tag.CanAccessMonomorphic() &&
(!to_string_tag.IsFound() || to_string_tag.IsData() ||
to_string_tag.IsDataConstant()) &&
value_of.CanAccessMonomorphic() && value_of.IsDataConstant() &&
value_of.constant().is_identical_to(isolate()->object_value_of()) &&
to_string.CanAccessMonomorphic() && to_string.IsDataConstant() &&
......@@ -11608,7 +11613,7 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
isolate()->object_to_string())) {
// We depend on the prototype chain to stay the same, because we
// also need to deoptimize when someone installs @@toPrimitive
// somewhere in the prototype chain.
// or @@toStringTag somewhere in the prototype chain.
BuildCheckPrototypeMaps(handle(JSObject::cast(map->prototype())),
Handle<JSObject>::null());
AddCheckMap(left, map);
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --harmony-tostring
function le(a, b) {
return a <= b;
}
function lt(a, b) {
return a < b;
}
function ge(a, b) {
return a >= b;
}
function gt(a, b) {
return a > b;
}
function test(a, b) {
// Check CompareIC for less than or equal of known objects.
assertThrows(function() {le(a, a)});
assertThrows(function() {le(a, b)});
assertThrows(function() {le(b, a)});
// Check CompareIC for less than of known objects.
assertThrows(function() {lt(a, a)});
assertThrows(function() {lt(a, b)});
assertThrows(function() {lt(b, a)});
// Check CompareIC for greater than or equal of known objects.
assertThrows(function() {ge(a, a)});
assertThrows(function() {ge(a, b)});
assertThrows(function() {ge(b, a)});
// Check CompareIC for greater than of known objects.
assertThrows(function() {gt(a, a)});
assertThrows(function() {gt(a, b)});
assertThrows(function() {gt(b, a)});
}
function O() { }
Object.defineProperty(O.prototype, Symbol.toStringTag, {
get: function() { throw "@@toStringTag called!" }
});
var obj1 = new O;
var obj2 = new O;
assertTrue(%HaveSameMap(obj1, obj2));
test(obj1, obj2);
test(obj1, obj2);
%OptimizeFunctionOnNextCall(le);
%OptimizeFunctionOnNextCall(lt);
%OptimizeFunctionOnNextCall(ge);
%OptimizeFunctionOnNextCall(gt);
test(obj1, obj2);
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