Limit size of dehoistable array indices
authorjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 15 Nov 2013 17:24:10 +0000 (17:24 +0000)
committerjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 15 Nov 2013 17:24:10 +0000 (17:24 +0000)
LOG=Y
BUG=chromium:319835,chromium:319860
R=dslomov@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17801 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/elements-kind.cc
src/elements-kind.h
src/hydrogen-dehoist.cc
src/hydrogen-instructions.h
src/lithium.cc
src/lithium.h
test/mjsunit/regress/regress-crbug-319835.js [new file with mode: 0644]
test/mjsunit/regress/regress-crbug-319860.js [new file with mode: 0644]

index 16f5bff..689c220 100644 (file)
@@ -35,6 +35,36 @@ namespace v8 {
 namespace internal {
 
 
+int ElementsKindToShiftSize(ElementsKind elements_kind) {
+  switch (elements_kind) {
+    case EXTERNAL_BYTE_ELEMENTS:
+    case EXTERNAL_PIXEL_ELEMENTS:
+    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+      return 0;
+    case EXTERNAL_SHORT_ELEMENTS:
+    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+      return 1;
+    case EXTERNAL_INT_ELEMENTS:
+    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
+    case EXTERNAL_FLOAT_ELEMENTS:
+      return 2;
+    case EXTERNAL_DOUBLE_ELEMENTS:
+    case FAST_DOUBLE_ELEMENTS:
+    case FAST_HOLEY_DOUBLE_ELEMENTS:
+      return 3;
+    case FAST_SMI_ELEMENTS:
+    case FAST_ELEMENTS:
+    case FAST_HOLEY_SMI_ELEMENTS:
+    case FAST_HOLEY_ELEMENTS:
+    case DICTIONARY_ELEMENTS:
+    case NON_STRICT_ARGUMENTS_ELEMENTS:
+      return kPointerSizeLog2;
+  }
+  UNREACHABLE();
+  return 0;
+}
+
+
 const char* ElementsKindToString(ElementsKind kind) {
   ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
   return accessor->name();
index f5280d6..51a6902 100644 (file)
@@ -81,6 +81,7 @@ const int kFastElementsKindCount = LAST_FAST_ELEMENTS_KIND -
 const int kFastElementsKindPackedToHoley =
     FAST_HOLEY_SMI_ELEMENTS - FAST_SMI_ELEMENTS;
 
+int ElementsKindToShiftSize(ElementsKind elements_kind);
 const char* ElementsKindToString(ElementsKind kind);
 void PrintElementsKind(FILE* out, ElementsKind kind);
 
index 67e6718..bdf2cfb 100644 (file)
@@ -53,7 +53,7 @@ static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) {
   int32_t value = constant->Integer32Value() * sign;
   // We limit offset values to 30 bits because we want to avoid the risk of
   // overflows when the offset is added to the object header size.
-  if (value >= 1 << 30 || value < 0) return;
+  if (value >= 1 << array_operation->MaxIndexOffsetBits() || value < 0) return;
   array_operation->SetKey(subexpression);
   if (binary_operation->HasNoUses()) {
     binary_operation->DeleteAndReplaceWith(NULL);
index e336c49..6b92d5b 100644 (file)
@@ -6141,6 +6141,7 @@ class ArrayInstructionInterface {
   virtual HValue* GetKey() = 0;
   virtual void SetKey(HValue* key) = 0;
   virtual void SetIndexOffset(uint32_t index_offset) = 0;
+  virtual int MaxIndexOffsetBits() = 0;
   virtual bool IsDehoisted() = 0;
   virtual void SetDehoisted(bool is_dehoisted) = 0;
   virtual ~ArrayInstructionInterface() { };
@@ -6180,6 +6181,9 @@ class HLoadKeyed V8_FINAL
   void SetIndexOffset(uint32_t index_offset) {
     bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
   }
+  virtual int MaxIndexOffsetBits() {
+    return kBitsForIndexOffset;
+  }
   HValue* GetKey() { return key(); }
   void SetKey(HValue* key) { SetOperandAt(1, key); }
   bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
@@ -6566,6 +6570,9 @@ class HStoreKeyed V8_FINAL
   ElementsKind elements_kind() const { return elements_kind_; }
   uint32_t index_offset() { return index_offset_; }
   void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
+  virtual int MaxIndexOffsetBits() {
+    return 31 - ElementsKindToShiftSize(elements_kind_);
+  }
   HValue* GetKey() { return key(); }
   void SetKey(HValue* key) { SetOperandAt(1, key); }
   bool IsDehoisted() { return is_dehoisted_; }
index 432e81b..ee8ea3e 100644 (file)
@@ -233,36 +233,6 @@ void LPointerMap::PrintTo(StringStream* stream) {
 }
 
 
-int ElementsKindToShiftSize(ElementsKind elements_kind) {
-  switch (elements_kind) {
-    case EXTERNAL_BYTE_ELEMENTS:
-    case EXTERNAL_PIXEL_ELEMENTS:
-    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
-      return 0;
-    case EXTERNAL_SHORT_ELEMENTS:
-    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
-      return 1;
-    case EXTERNAL_INT_ELEMENTS:
-    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
-    case EXTERNAL_FLOAT_ELEMENTS:
-      return 2;
-    case EXTERNAL_DOUBLE_ELEMENTS:
-    case FAST_DOUBLE_ELEMENTS:
-    case FAST_HOLEY_DOUBLE_ELEMENTS:
-      return 3;
-    case FAST_SMI_ELEMENTS:
-    case FAST_ELEMENTS:
-    case FAST_HOLEY_SMI_ELEMENTS:
-    case FAST_HOLEY_ELEMENTS:
-    case DICTIONARY_ELEMENTS:
-    case NON_STRICT_ARGUMENTS_ELEMENTS:
-      return kPointerSizeLog2;
-  }
-  UNREACHABLE();
-  return 0;
-}
-
-
 int StackSlotOffset(int index) {
   if (index >= 0) {
     // Local or spill slot. Skip the frame pointer, function, and
index 4f84087..d4395f2 100644 (file)
@@ -791,7 +791,6 @@ class LChunk : public ZoneObject {
 };
 
 
-int ElementsKindToShiftSize(ElementsKind elements_kind);
 int StackSlotOffset(int index);
 
 enum NumberUntagDMode {
diff --git a/test/mjsunit/regress/regress-crbug-319835.js b/test/mjsunit/regress/regress-crbug-319835.js
new file mode 100644 (file)
index 0000000..48f871f
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+try {} catch(e) {}  // No need to optimize the top level.
+
+var size = 0x20000;
+var a = new Float64Array(size);
+var training = new Float64Array(10);
+function store(a, index) {
+  var offset = 0x20000000;
+  for (var i = 0; i < 1; i++) {
+    a[index + offset] = 0xcc;
+  }
+}
+
+store(training, -0x20000000);
+store(training, -0x20000000 + 1);
+store(training, -0x20000000);
+store(training, -0x20000000 + 1);
+%OptimizeFunctionOnNextCall(store);
+
+// Segfault maybe?
+for (var i = -0x20000000; i < -0x20000000 + size; i++) {
+  store(a, i);
+}
diff --git a/test/mjsunit/regress/regress-crbug-319860.js b/test/mjsunit/regress/regress-crbug-319860.js
new file mode 100644 (file)
index 0000000..b81fb85
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function read(a, index) {
+  var offset = 0x2000000;
+  var result;
+  for (var i = 0; i < 1; i++) {
+    result = a[index + offset];
+  }
+  return result;
+}
+
+var a = new Int8Array(0x2000001);
+read(a, 0);
+read(a, 0);
+%OptimizeFunctionOnNextCall(read);
+
+// Segfault maybe?
+for (var i = 0; i > -1000000; --i) {
+  read(a, i);
+}