Commit 6744ff61 authored by ulan@chromium.org's avatar ulan@chromium.org

Fix dictionary element load to pass correct elements kind.

Using FAST_SMI_ELEMENTS triggers optimization on 64-bit architectures that load
only the higher 32 bits of the element. If the element is a pointer to undefined
that has 0 in the higher half than it is erroneously treated as SMI 0.

BUG=v8:3158
LOG=N
TEST=mjsunit/sparse-array-reverse,mjsunit/regress/regress-3158.js
R=danno@chromium.org, ishell@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19387 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c532977d
...@@ -1451,7 +1451,7 @@ HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoadHelper( ...@@ -1451,7 +1451,7 @@ HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoadHelper(
HValue* candidate_key = Add<HLoadKeyed>(elements, key_index, HValue* candidate_key = Add<HLoadKeyed>(elements, key_index,
static_cast<HValue*>(NULL), static_cast<HValue*>(NULL),
FAST_SMI_ELEMENTS); FAST_ELEMENTS);
IfBuilder key_compare(this); IfBuilder key_compare(this);
key_compare.IfNot<HCompareObjectEqAndBranch>(key, candidate_key); key_compare.IfNot<HCompareObjectEqAndBranch>(key, candidate_key);
...@@ -1477,7 +1477,7 @@ HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoadHelper( ...@@ -1477,7 +1477,7 @@ HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoadHelper(
HValue* details = Add<HLoadKeyed>(elements, details_index, HValue* details = Add<HLoadKeyed>(elements, details_index,
static_cast<HValue*>(NULL), static_cast<HValue*>(NULL),
FAST_SMI_ELEMENTS); FAST_ELEMENTS);
IfBuilder details_compare(this); IfBuilder details_compare(this);
details_compare.If<HCompareNumericAndBranch>(details, details_compare.If<HCompareNumericAndBranch>(details,
graph()->GetConstant0(), graph()->GetConstant0(),
...@@ -1547,7 +1547,7 @@ HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver, ...@@ -1547,7 +1547,7 @@ HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver,
elements, elements,
Add<HConstant>(NameDictionary::kCapacityIndex), Add<HConstant>(NameDictionary::kCapacityIndex),
static_cast<HValue*>(NULL), static_cast<HValue*>(NULL),
FAST_SMI_ELEMENTS); FAST_ELEMENTS);
HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1());
mask->ChangeRepresentation(Representation::Integer32()); mask->ChangeRepresentation(Representation::Integer32());
......
...@@ -2781,6 +2781,12 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { ...@@ -2781,6 +2781,12 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
Representation representation = access.representation(); Representation representation = access.representation();
if (representation.IsSmi() && if (representation.IsSmi() &&
instr->hydrogen()->representation().IsInteger32()) { instr->hydrogen()->representation().IsInteger32()) {
#ifdef DEBUG
Register scratch = kScratchRegister;
__ Load(scratch, FieldOperand(object, offset), representation);
__ AssertSmi(scratch);
#endif
// Read int value directly from upper half of the smi. // Read int value directly from upper half of the smi.
STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTag == 0);
STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
...@@ -3026,6 +3032,17 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { ...@@ -3026,6 +3032,17 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
if (representation.IsInteger32() && if (representation.IsInteger32() &&
hinstr->elements_kind() == FAST_SMI_ELEMENTS) { hinstr->elements_kind() == FAST_SMI_ELEMENTS) {
ASSERT(!requires_hole_check); ASSERT(!requires_hole_check);
#ifdef DEBUG
Register scratch = kScratchRegister;
__ Load(scratch,
BuildFastArrayOperand(instr->elements(),
key,
FAST_ELEMENTS,
offset,
instr->additional_index()),
Representation::Smi());
__ AssertSmi(scratch);
#endif
// Read int value directly from upper half of the smi. // Read int value directly from upper half of the smi.
STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTag == 0);
STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
......
...@@ -182,11 +182,6 @@ ...@@ -182,11 +182,6 @@
# BUG(v8:3156): Fails on gc stress bots. # BUG(v8:3156): Fails on gc stress bots.
'compiler/concurrent-invalidate-transition-map': [PASS, ['gc_stress == True', FAIL]], 'compiler/concurrent-invalidate-transition-map': [PASS, ['gc_stress == True', FAIL]],
# BUG(v8:3157): Fails on gc stress bots.
'sparse-array-reverse': [PASS, ['gc_stress == True', FAIL]],
# BUG(v8:3158): Fails on no_snap debug bots.
'sparse-array-reverse': [PASS, ['mode == debug', FAIL]],
}], # 'arch == a64' }], # 'arch == a64'
['arch == a64 and mode == debug and simulator_run == True', { ['arch == a64 and mode == debug and simulator_run == True', {
......
// Copyright 2014 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
Array.prototype[0] = 'a';
delete Array.prototype[0];
function foo(a, i) {
return a[i];
}
var a = new Array(100000);
a[3] = 'x';
foo(a, 3);
foo(a, 3);
foo(a, 3);
%OptimizeFunctionOnNextCall(foo);
foo(a, 3);
Array.prototype[0] = 'a';
var z = foo(a, 0);
assertEquals('a', z);
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