Reviewers: Jakob,
Description:
Version 4.2.77.8 (cherry-pick)
Merged 0902b5f4dfdea599bf3d96fb9fb258904aff84ec
Incorrect handling of HTransitionElementsKind in hydrogen check elimination
phase fixed.
BUG=chromium:460917
LOG=N
[email protected]
Please review this at https://codereview.chromium.org/1019033004/
Base URL: https://chromium.googlesource.com/v8/[email protected]
Affected files (+65, -12 lines):
M include/v8-version.h
M src/hydrogen-check-elimination.cc
M src/hydrogen-instructions.h
A test/mjsunit/regress/regress-460917.js
Index: include/v8-version.h
diff --git a/include/v8-version.h b/include/v8-version.h
index
bfb02f0471e2eba79fc951370bd7db49d4a801d6..1aa052e640c7dfdd507c42259da5d4acbb4a12be
100644
--- a/include/v8-version.h
+++ b/include/v8-version.h
@@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 4
#define V8_MINOR_VERSION 2
#define V8_BUILD_NUMBER 77
-#define V8_PATCH_LEVEL 7
+#define V8_PATCH_LEVEL 8
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
Index: src/hydrogen-check-elimination.cc
diff --git a/src/hydrogen-check-elimination.cc
b/src/hydrogen-check-elimination.cc
index
3542fa601a0ee2e003cc3230ba1b5e2fc5063156..cdfedb4e51957c650e66980d0e47be4b50caf317
100644
--- a/src/hydrogen-check-elimination.cc
+++ b/src/hydrogen-check-elimination.cc
@@ -628,14 +628,23 @@ class HCheckTable : public ZoneObject {
HValue* object = instr->object()->ActualValue();
HCheckTableEntry* entry = Find(object);
// Can only learn more about an object that already has a known set of
maps.
- if (entry == NULL) return;
+ if (entry == NULL) {
+ Kill(object);
+ return;
+ }
EnsureChecked(entry, object, instr);
if (entry->maps_->Contains(instr->original_map())) {
// If the object has the original map, it will be transitioned.
UniqueSet<Map>* maps = entry->maps_->Copy(zone());
maps->Remove(instr->original_map());
maps->Add(instr->transitioned_map(), zone());
- entry->maps_ = maps;
+ HCheckTableEntry::State state =
+ (entry->state_ == HCheckTableEntry::CHECKED_STABLE &&
+ instr->map_is_stable())
+ ? HCheckTableEntry::CHECKED_STABLE
+ : HCheckTableEntry::CHECKED;
+ Kill(object);
+ Insert(object, NULL, maps, state);
} else {
// Object does not have the given map, thus the transition is
redundant.
instr->DeleteAndReplaceWith(object);
Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index
e85600aacf436ab4e350b3b6e8de18e4e1027a24..8fd2aed0afe6fc8bbb3672d4f3b97a5c7068ee3f
100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -7270,8 +7270,13 @@ class HTransitionElementsKind FINAL : public
HTemplateInstruction<2> {
HValue* context() const { return OperandAt(1); }
Unique<Map> original_map() const { return original_map_; }
Unique<Map> transitioned_map() const { return transitioned_map_; }
- ElementsKind from_kind() const { return from_kind_; }
- ElementsKind to_kind() const { return to_kind_; }
+ ElementsKind from_kind() const {
+ return FromElementsKindField::decode(bit_field_);
+ }
+ ElementsKind to_kind() const {
+ return ToElementsKindField::decode(bit_field_);
+ }
+ bool map_is_stable() const { return
MapIsStableField::decode(bit_field_); }
std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT
@@ -7287,29 +7292,33 @@ class HTransitionElementsKind FINAL : public
HTemplateInstruction<2> {
int RedefinedOperandIndex() OVERRIDE { return 0; }
private:
- HTransitionElementsKind(HValue* context,
- HValue* object,
+ HTransitionElementsKind(HValue* context, HValue* object,
Handle<Map> original_map,
Handle<Map> transitioned_map)
: original_map_(Unique<Map>(original_map)),
transitioned_map_(Unique<Map>(transitioned_map)),
- from_kind_(original_map->elements_kind()),
- to_kind_(transitioned_map->elements_kind()) {
+ bit_field_(
+ FromElementsKindField::encode(original_map->elements_kind()) |
+ ToElementsKindField::encode(transitioned_map->elements_kind())
|
+ MapIsStableField::encode(transitioned_map->is_stable())) {
SetOperandAt(0, object);
SetOperandAt(1, context);
SetFlag(kUseGVN);
SetChangesFlag(kElementsKind);
- if (!IsSimpleMapChangeTransition(from_kind_, to_kind_)) {
+ if (!IsSimpleMapChangeTransition(from_kind(), to_kind())) {
SetChangesFlag(kElementsPointer);
SetChangesFlag(kNewSpacePromotion);
}
set_representation(Representation::Tagged());
}
+ class FromElementsKindField : public BitField<ElementsKind, 0, 5> {};
+ class ToElementsKindField : public BitField<ElementsKind, 5, 5> {};
+ class MapIsStableField : public BitField<bool, 10, 1> {};
+
Unique<Map> original_map_;
Unique<Map> transitioned_map_;
- ElementsKind from_kind_;
- ElementsKind to_kind_;
+ uint32_t bit_field_;
};
Index: test/mjsunit/regress/regress-460917.js
diff --git a/test/mjsunit/regress/regress-460917.js
b/test/mjsunit/regress/regress-460917.js
new file mode 100644
index
0000000000000000000000000000000000000000..68e1b6308821751ca7e62d4cdb73f63bad497051
--- /dev/null
+++ b/test/mjsunit/regress/regress-460917.js
@@ -0,0 +1,35 @@
+// 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
+
+function boom(a1, a2) {
+ // Do something with a2 that needs a map check (for DOUBLE_ELEMENTS).
+ var s = a2[0];
+ // Emit a load that transitions a1 to FAST_ELEMENTS.
+ var t = a1[0];
+ // Emit a store to a2 that assumes DOUBLE_ELEMENTS.
+ // The map check is considered redundant and will be eliminated.
+ a2[0] = 0.3;
+}
+
+// Prepare type feedback for the "t = a1[0]" load: fast elements.
+var fast_elem = new Array(1);
+fast_elem[0] = "tagged";
+boom(fast_elem, [1]);
+
+// Prepare type feedback for the "a2[0] = 0.3" store: double elements.
+var double_elem = new Array(1);
+double_elem[0] = 0.1;
+boom(double_elem, double_elem);
+
+// Reset |double_elem| and go have a party.
+double_elem = new Array(10);
+double_elem[0] = 0.1;
+
+%OptimizeFunctionOnNextCall(boom);
+boom(double_elem, double_elem);
+
+assertEquals(0.3, double_elem[0]);
+assertEquals(undefined, double_elem[1]);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.