Make max size and max length of strings consistent.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 20 Mar 2014 08:33:06 +0000 (08:33 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 20 Mar 2014 08:33:06 +0000 (08:33 +0000)
R=bmeurer@chromium.org

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

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

src/heap-inl.h
src/heap.cc
src/hydrogen.cc
src/objects.h
src/runtime.cc

index c36a6fd..efad2fb 100644 (file)
@@ -137,7 +137,7 @@ MaybeObject* Heap::AllocateInternalizedStringImpl(
 
 MaybeObject* Heap::AllocateOneByteInternalizedString(Vector<const uint8_t> str,
                                                      uint32_t hash_field) {
-  if (str.length() > SeqOneByteString::kMaxLength) {
+  if (str.length() > String::kMaxLength) {
     return Failure::OutOfMemoryException(0x2);
   }
   // Compute map and object size.
@@ -170,7 +170,7 @@ MaybeObject* Heap::AllocateOneByteInternalizedString(Vector<const uint8_t> str,
 
 MaybeObject* Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
                                                      uint32_t hash_field) {
-  if (str.length() > SeqTwoByteString::kMaxLength) {
+  if (str.length() > String::kMaxLength) {
     return Failure::OutOfMemoryException(0x3);
   }
   // Compute map and object size.
index 6790fe9..e2b83f5 100644 (file)
@@ -4972,16 +4972,13 @@ MaybeObject* Heap::AllocateInternalizedStringImpl(
   int size;
   Map* map;
 
+  if (chars > String::kMaxLength) {
+    return Failure::OutOfMemoryException(0x9);
+  }
   if (is_one_byte) {
-    if (chars > SeqOneByteString::kMaxLength) {
-      return Failure::OutOfMemoryException(0x9);
-    }
     map = ascii_internalized_string_map();
     size = SeqOneByteString::SizeFor(chars);
   } else {
-    if (chars > SeqTwoByteString::kMaxLength) {
-      return Failure::OutOfMemoryException(0xa);
-    }
     map = internalized_string_map();
     size = SeqTwoByteString::SizeFor(chars);
   }
@@ -5023,7 +5020,7 @@ MaybeObject* Heap::AllocateInternalizedStringImpl<false>(
 
 MaybeObject* Heap::AllocateRawOneByteString(int length,
                                             PretenureFlag pretenure) {
-  if (length < 0 || length > SeqOneByteString::kMaxLength) {
+  if (length < 0 || length > String::kMaxLength) {
     return Failure::OutOfMemoryException(0xb);
   }
   int size = SeqOneByteString::SizeFor(length);
@@ -5047,7 +5044,7 @@ MaybeObject* Heap::AllocateRawOneByteString(int length,
 
 MaybeObject* Heap::AllocateRawTwoByteString(int length,
                                             PretenureFlag pretenure) {
-  if (length < 0 || length > SeqTwoByteString::kMaxLength) {
+  if (length < 0 || length > String::kMaxLength) {
     return Failure::OutOfMemoryException(0xc);
   }
   int size = SeqTwoByteString::SizeFor(length);
index d214fcb..f6e22d8 100644 (file)
@@ -1791,19 +1791,13 @@ HAllocate* HGraphBuilder::BuildAllocate(
 
 HValue* HGraphBuilder::BuildAddStringLengths(HValue* left_length,
                                              HValue* right_length) {
-  // Compute the combined string length. If the result is larger than the max
-  // supported string length, we bailout to the runtime. This is done implicitly
-  // when converting the result back to a smi in case the max string length
-  // equals the max smi value. Otherwise, for platforms with 32-bit smis, we do
+  // Compute the combined string length and check against max string length.
   HValue* length = AddUncasted<HAdd>(left_length, right_length);
-  STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
-  if (String::kMaxLength != Smi::kMaxValue) {
-    IfBuilder if_nooverflow(this);
-    if_nooverflow.If<HCompareNumericAndBranch>(
-        length, Add<HConstant>(String::kMaxLength), Token::LTE);
-    if_nooverflow.Then();
-    if_nooverflow.ElseDeopt("String length exceeds limit");
-  }
+  IfBuilder if_nooverflow(this);
+  if_nooverflow.If<HCompareNumericAndBranch>(
+      length, Add<HConstant>(String::kMaxLength), Token::LTE);
+  if_nooverflow.Then();
+  if_nooverflow.ElseDeopt("String length exceeds limit");
   return length;
 }
 
index cbe9553..a87e389 100644 (file)
@@ -8904,7 +8904,7 @@ class String: public Name {
   static const int kEmptyStringHash = kIsNotArrayIndexMask;
 
   // Maximal string length.
-  static const int kMaxLength = (1 << (32 - 2)) - 1;
+  static const int kMaxLength = (1 << 28) - 16;
 
   // Max length for computing hash. For strings longer than this limit the
   // string length is used as the hash value.
@@ -9066,9 +9066,7 @@ class SeqOneByteString: public SeqString {
 
   // Maximal memory usage for a single sequential ASCII string.
   static const int kMaxSize = 512 * MB - 1;
-  // Maximal length of a single sequential ASCII string.
-  // Q.v. String::kMaxLength which is the maximal size of concatenated strings.
-  static const int kMaxLength = (kMaxSize - kHeaderSize);
+  STATIC_CHECK((kMaxSize - kHeaderSize) >= String::kMaxLength);
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
@@ -9108,9 +9106,8 @@ class SeqTwoByteString: public SeqString {
 
   // Maximal memory usage for a single sequential two-byte string.
   static const int kMaxSize = 512 * MB - 1;
-  // Maximal length of a single sequential two-byte string.
-  // Q.v. String::kMaxLength which is the maximal size of concatenated strings.
-  static const int kMaxLength = (kMaxSize - kHeaderSize) / sizeof(uint16_t);
+  STATIC_CHECK(static_cast<int>((kMaxSize - kHeaderSize)/sizeof(uint16_t)) >=
+               String::kMaxLength);
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
index 6403858..762b7a5 100644 (file)
@@ -7315,12 +7315,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
   // Find total length of join result.
   int string_length = 0;
   bool is_ascii = separator->IsOneByteRepresentation();
-  int max_string_length;
-  if (is_ascii) {
-    max_string_length = SeqOneByteString::kMaxLength;
-  } else {
-    max_string_length = SeqTwoByteString::kMaxLength;
-  }
   bool overflow = false;
   CONVERT_NUMBER_CHECKED(int, elements_length,
                          Int32, elements_array->length());
@@ -7333,10 +7327,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
     int length = string->length();
     if (is_ascii && !string->IsOneByteRepresentation()) {
       is_ascii = false;
-      max_string_length = SeqTwoByteString::kMaxLength;
     }
-    if (length > max_string_length ||
-        max_string_length - length < string_length) {
+    if (length > String::kMaxLength ||
+        String::kMaxLength - length < string_length) {
       overflow = true;
       break;
     }
@@ -7346,7 +7339,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
   if (!overflow && separator_length > 0) {
     if (array_length <= 0x7fffffffu) {
       int separator_count = static_cast<int>(array_length) - 1;
-      int remaining_length = max_string_length - string_length;
+      int remaining_length = String::kMaxLength - string_length;
       if ((remaining_length / separator_length) >= separator_count) {
         string_length += separator_length * (array_length - 1);
       } else {