Commit b71f1cc2 authored by mvstanton's avatar mvstanton Committed by Commit bot

Bugfix: Crankshaft array literals with incorrect values.

In VisitArrayLiteral(), we stopped creating boilerplates during
 compilation. This created a bug, because we'd emit an HStoreKeyed with an
 ElementsKind based on the initial elements kind of the boilerplate. Since
 boilerplates may transition as part of elements transition feedback, this can
 lead to incorrect values (storing a smi in a double array).

BUG=chromium:606021

Review-Url: https://codereview.chromium.org/2000673002
Cr-Commit-Position: refs/heads/master@{#36408}
parent 84ee9470
......@@ -6180,11 +6180,6 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
JSObject::cast(site->transition_info()), isolate());
}
ElementsKind boilerplate_elements_kind = expr->constant_elements_kind();
if (!boilerplate_object.is_null()) {
boilerplate_elements_kind = boilerplate_object->GetElementsKind();
}
// Check whether to use fast or slow deep-copying for boilerplate.
int max_properties = kMaxFastLiteralProperties;
if (!boilerplate_object.is_null() &&
......@@ -6235,6 +6230,9 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
HValue* key = Add<HConstant>(i);
if (!boilerplate_object.is_null()) {
ElementsKind boilerplate_elements_kind =
boilerplate_object->GetElementsKind();
switch (boilerplate_elements_kind) {
case FAST_SMI_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
......@@ -6250,6 +6248,11 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
UNREACHABLE();
break;
}
} else {
HInstruction* instr = BuildKeyedGeneric(
STORE, expr, expr->LiteralFeedbackSlot(), literal, key, value);
AddInstruction(instr);
}
Add<HSimulate>(expr->GetIdForElement(i));
}
......
// Copyright 2016 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
function foo() {
return function(c) {
var double_var = [3.0, 3.5][0];
var literal = c ? [1, double_var] : [double_var, 3.5];
return literal[0];
};
}
var f1 = foo();
var f2 = foo();
// Both closures point to full code.
f1(false);
f2(false);
// Optimize f1, but don't initialize the [1, double_var] literal.
%OptimizeFunctionOnNextCall(f1);
f1(false);
// Initialize the [1, double_var] literal, and transition the boilerplate to
// double.
f2(true);
// Trick crankshaft into writing double_var at the wrong position.
var l = f1(true);
assertEquals(1, l);
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