Blame SOURCES/v8-3.14.5.10-CVE-2013-6668.patch

e93883
From fd80a31e0697d6317ce8c2d289575399f4e06d21 Mon Sep 17 00:00:00 2001
e93883
From: Fedor Indutny <fedor@indutny.com>
e93883
Date: Thu, 14 Aug 2014 19:29:28 +0400
e93883
Subject: [PATCH] deps: backport 5f836c from v8 upstream
e93883
e93883
Original commit message:
e93883
e93883
    Fix Hydrogen bounds check elimination
e93883
e93883
    When combining bounds checks, they must all be moved before the first load/store
e93883
    that they are guarding.
e93883
e93883
    BUG=chromium:344186
e93883
    LOG=y
e93883
    R=svenpanne@chromium.org
e93883
e93883
    Review URL: https://codereview.chromium.org/172093002
e93883
e93883
    git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@19475 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
e93883
e93883
fix #8070
e93883
---
e93883
 src/hydrogen.cc | 106 +++++++++++++++++++++++-------------------------
e93883
 1 file changed, 50 insertions(+), 56 deletions(-)
e93883
e93883
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
e93883
index e3f79ee..50d8e49 100644
e93883
--- a/src/hydrogen.cc
e93883
+++ b/src/hydrogen.cc
e93883
@@ -3487,13 +3487,7 @@ class BoundsCheckBbData: public ZoneObject {
e93883
         keep_new_check = true;
e93883
         upper_check_ = new_check;
e93883
       } else {
e93883
-        BuildOffsetAdd(upper_check_,
e93883
-                       &added_upper_index_,
e93883
-                       &added_upper_offset_,
e93883
-                       Key()->IndexBase(),
e93883
-                       new_check->index()->representation(),
e93883
-                       new_offset);
e93883
-        upper_check_->SetOperandAt(0, added_upper_index_);
e93883
+        TightenCheck(upper_check_, new_check);
e93883
       }
e93883
     } else if (new_offset < lower_offset_) {
e93883
       lower_offset_ = new_offset;
e93883
@@ -3501,28 +3495,27 @@ class BoundsCheckBbData: public ZoneObject {
e93883
         keep_new_check = true;
e93883
         lower_check_ = new_check;
e93883
       } else {
e93883
-        BuildOffsetAdd(lower_check_,
e93883
-                       &added_lower_index_,
e93883
-                       &added_lower_offset_,
e93883
-                       Key()->IndexBase(),
e93883
-                       new_check->index()->representation(),
e93883
-                       new_offset);
e93883
-        lower_check_->SetOperandAt(0, added_lower_index_);
e93883
+        TightenCheck(lower_check_, new_check);
e93883
       }
e93883
     } else {
e93883
-      ASSERT(false);
e93883
+      // Should never have called CoverCheck() in this case.
e93883
+      UNREACHABLE();
e93883
     }
e93883
 
e93883
     if (!keep_new_check) {
e93883
       new_check->DeleteAndReplaceWith(NULL);
e93883
+    } else {
e93883
+      HBoundsCheck* first_check = new_check == lower_check_ ? upper_check_
e93883
+                                                            : lower_check_;
e93883
+      // The length is guaranteed to be live at first_check.
e93883
+      ASSERT(new_check->length() == first_check->length());
e93883
+      HInstruction* old_position = new_check->next();
e93883
+      new_check->Unlink();
e93883
+      new_check->InsertAfter(first_check);
e93883
+      MoveIndexIfNecessary(new_check->index(), new_check, old_position);
e93883
     }
e93883
   }
e93883
 
e93883
-  void RemoveZeroOperations() {
e93883
-    RemoveZeroAdd(&added_lower_index_, &added_lower_offset_);
e93883
-    RemoveZeroAdd(&added_upper_index_, &added_upper_offset_);
e93883
-  }
e93883
-
e93883
   BoundsCheckBbData(BoundsCheckKey* key,
e93883
                     int32_t lower_offset,
e93883
                     int32_t upper_offset,
e93883
@@ -3537,10 +3530,6 @@ class BoundsCheckBbData: public ZoneObject {
e93883
     basic_block_(bb),
e93883
     lower_check_(lower_check),
e93883
     upper_check_(upper_check),
e93883
-    added_lower_index_(NULL),
e93883
-    added_lower_offset_(NULL),
e93883
-    added_upper_index_(NULL),
e93883
-    added_upper_offset_(NULL),
e93883
     next_in_bb_(next_in_bb),
e93883
     father_in_dt_(father_in_dt) { }
e93883
 
e93883
@@ -3551,44 +3540,50 @@ class BoundsCheckBbData: public ZoneObject {
e93883
   HBasicBlock* basic_block_;
e93883
   HBoundsCheck* lower_check_;
e93883
   HBoundsCheck* upper_check_;
e93883
-  HAdd* added_lower_index_;
e93883
-  HConstant* added_lower_offset_;
e93883
-  HAdd* added_upper_index_;
e93883
-  HConstant* added_upper_offset_;
e93883
   BoundsCheckBbData* next_in_bb_;
e93883
   BoundsCheckBbData* father_in_dt_;
e93883
 
e93883
-  void BuildOffsetAdd(HBoundsCheck* check,
e93883
-                      HAdd** add,
e93883
-                      HConstant** constant,
e93883
-                      HValue* original_value,
e93883
-                      Representation representation,
e93883
-                      int32_t new_offset) {
e93883
-    HConstant* new_constant = new(BasicBlock()->zone())
e93883
-       HConstant(new_offset, Representation::Integer32());
e93883
-    if (*add == NULL) {
e93883
-      new_constant->InsertBefore(check);
e93883
-      // Because of the bounds checks elimination algorithm, the index is always
e93883
-      // an HAdd or an HSub here, so we can safely cast to an HBinaryOperation.
e93883
-      HValue* context = HBinaryOperation::cast(check->index())->context();
e93883
-      *add = new(BasicBlock()->zone()) HAdd(context,
e93883
-                                            original_value,
e93883
-                                            new_constant);
e93883
-      (*add)->AssumeRepresentation(representation);
e93883
-      (*add)->InsertBefore(check);
e93883
-    } else {
e93883
-      new_constant->InsertBefore(*add);
e93883
-      (*constant)->DeleteAndReplaceWith(new_constant);
e93883
+  void MoveIndexIfNecessary(HValue* index_raw,
e93883
+                            HBoundsCheck* insert_before,
e93883
+                            HInstruction* end_of_scan_range) {
e93883
+    ASSERT(index_raw->IsAdd() || index_raw->IsSub());
e93883
+    HBinaryOperation* index =
e93883
+        HArithmeticBinaryOperation::cast(index_raw);
e93883
+    HValue* left_input = index->left();
e93883
+    HValue* right_input = index->right();
e93883
+    bool must_move_index = false;
e93883
+    bool must_move_left_input = false;
e93883
+    bool must_move_right_input = false;
e93883
+    for (HInstruction* cursor = end_of_scan_range; cursor != insert_before;) {
e93883
+      if (cursor == left_input) must_move_left_input = true;
e93883
+      if (cursor == right_input) must_move_right_input = true;
e93883
+      if (cursor == index) must_move_index = true;
e93883
+      if (cursor->previous() == NULL) {
e93883
+        cursor = cursor->block()->dominator()->end();
e93883
+      } else {
e93883
+        cursor = cursor->previous();
e93883
+      }
e93883
     }
e93883
-    *constant = new_constant;
e93883
-  }
e93883
 
e93883
-  void RemoveZeroAdd(HAdd** add, HConstant** constant) {
e93883
-    if (*add != NULL && (*constant)->Integer32Value() == 0) {
e93883
-      (*add)->DeleteAndReplaceWith((*add)->left());
e93883
-      (*constant)->DeleteAndReplaceWith(NULL);
e93883
+    // The BCE algorithm only selects mergeable bounds checks that share
e93883
+    // the same "index_base", so we'll only ever have to move constants.
e93883
+    if (must_move_left_input) {
e93883
+      HConstant::cast(left_input)->Unlink();
e93883
+      HConstant::cast(left_input)->InsertBefore(index);
e93883
+    }
e93883
+    if (must_move_right_input) {
e93883
+      HConstant::cast(right_input)->Unlink();
e93883
+      HConstant::cast(right_input)->InsertBefore(index);
e93883
     }
e93883
   }
e93883
+
e93883
+  void TightenCheck(HBoundsCheck* original_check,
e93883
+                    HBoundsCheck* tighter_check) {
e93883
+    ASSERT(original_check->length() == tighter_check->length());
e93883
+    MoveIndexIfNecessary(tighter_check->index(), original_check, tighter_check);
e93883
+    original_check->ReplaceAllUsesWith(original_check->index());
e93883
+    original_check->SetOperandAt(0, tighter_check->index());
e93883
+  }
e93883
 };
e93883
 
e93883
 
e93883
@@ -3683,7 +3678,6 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb,
e93883
   for (BoundsCheckBbData* data = bb_data_list;
e93883
        data != NULL;
e93883
        data = data->NextInBasicBlock()) {
e93883
-    data->RemoveZeroOperations();
e93883
     if (data->FatherInDominatorTree()) {
e93883
       table->Insert(data->Key(), data->FatherInDominatorTree(), zone());
e93883
     } else {