Revert "No longer OOM on invalid string length."
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 24 Mar 2014 15:36:15 +0000 (15:36 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 24 Mar 2014 15:36:15 +0000 (15:36 +0000)
This reverts r20202.

TBR=machenbach@chromium.org

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

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

20 files changed:
src/api.cc
src/bootstrapper.cc
src/bootstrapper.h
src/contexts.cc
src/debug.cc
src/factory.cc
src/heap-inl.h
src/heap.cc
src/hydrogen-instructions.cc
src/json-parser.h
src/json-stringifier.h
src/jsregexp.cc
src/liveedit.cc
src/parser.cc
src/runtime.cc
src/uri.h
test/cctest/cctest.status
test/cctest/test-strings.cc
test/mjsunit/string-oom-replace-global-regexp-with-string.js
tools/lexer-shell.cc

index 31e8193ef118ae4556568333396d77fea71b7c1e..c89b61937923f99f49bf44da5de976038c850901 100644 (file)
@@ -5403,8 +5403,6 @@ inline Local<String> NewString(Isolate* v8_isolate,
   if (length == -1) length = StringLength(data);
   i::Handle<i::String> result = NewString(
       isolate->factory(), type, i::Vector<const Char>(data, length));
-  // We do not expect this to fail. Change this if it does.
-  CHECK(!result.is_null());
   if (type == String::kUndetectableString) {
     result->MarkAsUndetectable();
   }
@@ -5462,8 +5460,8 @@ Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
   i::Handle<i::String> right_string = Utils::OpenHandle(*right);
   i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
                                                                   right_string);
-  // We do not expect this to fail. Change this if it does.
-  CHECK(!result.is_null());
+  // We do not expect this to throw an exception. Change this if it does.
+  CHECK_NOT_EMPTY_HANDLE(isolate, result);
   return Utils::ToLocal(result);
 }
 
@@ -5471,22 +5469,14 @@ Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
 static i::Handle<i::String> NewExternalStringHandle(
     i::Isolate* isolate,
     v8::String::ExternalStringResource* resource) {
-  i::Handle<i::String> result =
-      isolate->factory()->NewExternalStringFromTwoByte(resource);
-  // We do not expect this to fail. Change this if it does.
-  CHECK(!result.is_null());
-  return result;
+  return isolate->factory()->NewExternalStringFromTwoByte(resource);
 }
 
 
 static i::Handle<i::String> NewExternalAsciiStringHandle(
     i::Isolate* isolate,
     v8::String::ExternalAsciiStringResource* resource) {
-  i::Handle<i::String> result =
-      isolate->factory()->NewExternalStringFromAscii(resource);
-  // We do not expect this to fail. Change this if it does.
-  CHECK(!result.is_null());
-  return result;
+  return isolate->factory()->NewExternalStringFromAscii(resource);
 }
 
 
@@ -6140,8 +6130,6 @@ Local<Symbol> v8::Symbol::New(Isolate* isolate, const char* data, int length) {
     if (length == -1) length = i::StrLength(data);
     i::Handle<i::String> name = i_isolate->factory()->NewStringFromUtf8(
         i::Vector<const char>(data, length));
-    // We do not expect this to fail. Change this if it does.
-    CHECK(!name.is_null());
     result->set_name(*name);
   }
   return Utils::ToLocal(result);
@@ -6963,8 +6951,8 @@ Handle<String> CpuProfileNode::GetFunctionName() const {
     i::Handle<i::String> cons = isolate->factory()->NewConsString(
         isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
         isolate->factory()->InternalizeUtf8String(entry->name()));
-    // We do not expect this to fail. Change this if it does.
-    CHECK(!cons.is_null());
+    // We do not expect this to throw an exception. Change this if it does.
+    CHECK_NOT_EMPTY_HANDLE(isolate, cons);
     return ToApiHandle<String>(cons);
   }
 }
index b2a52cd906d8c531d0a7feb606f306a36066ae95..7942c7f8b5677d6ead7500928dc617a90bb4375e 100644 (file)
@@ -88,8 +88,6 @@ Handle<String> Bootstrapper::NativesSourceLookup(int index) {
                                           source.length());
     Handle<String> source_code =
         isolate_->factory()->NewExternalStringFromAscii(resource);
-    // We do not expect this to throw an exception. Change this if it does.
-    CHECK_NOT_EMPTY_HANDLE(isolate_, source_code);
     heap->natives_source_cache()->set(index, *source_code);
   }
   Handle<Object> cached_source(heap->natives_source_cache()->get(index),
@@ -1465,7 +1463,6 @@ bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
   Handle<String> source_code =
       factory->NewStringFromAscii(
           ExperimentalNatives::GetRawScriptSource(index));
-  RETURN_IF_EMPTY_HANDLE_VALUE(isolate, source_code, false);
   return CompileNative(isolate, name, source_code);
 }
 
@@ -1515,7 +1512,6 @@ bool Genesis::CompileScriptCached(Isolate* isolate,
   if (cache == NULL || !cache->Lookup(name, &function_info)) {
     ASSERT(source->IsOneByteRepresentation());
     Handle<String> script_name = factory->NewStringFromUtf8(name);
-    ASSERT(!script_name.is_null());
     function_info = Compiler::CompileScript(
         source,
         script_name,
@@ -2084,10 +2080,8 @@ static Handle<JSObject> ResolveBuiltinIdHolder(
   ASSERT_EQ(".prototype", period_pos);
   Vector<const char> property(holder_expr,
                               static_cast<int>(period_pos - holder_expr));
-  Handle<String> property_string = factory->InternalizeUtf8String(property);
-  ASSERT(!property_string.is_null());
   Handle<JSFunction> function = Handle<JSFunction>::cast(
-      GetProperty(isolate, global, property_string));
+      GetProperty(isolate, global, factory->InternalizeUtf8String(property)));
   return Handle<JSObject>(JSObject::cast(function->prototype()));
 }
 
@@ -2355,8 +2349,6 @@ bool Genesis::InstallExtension(Isolate* isolate,
   }
   Handle<String> source_code =
       isolate->factory()->NewExternalStringFromAscii(extension->source());
-  // We do not expect this to throw an exception. Change this if it does.
-  CHECK_NOT_EMPTY_HANDLE(isolate, source_code);
   bool result = CompileScriptCached(isolate,
                                     CStrVector(extension->name()),
                                     source_code,
index e683a45f048c6a32349fb66e1c26f4fc4333f539..14dd1bd99753d78a44541286c0625e3e0cfc24dc 100644 (file)
@@ -73,7 +73,6 @@ class SourceCodeCache BASE_EMBEDDED {
     cache_->CopyTo(0, *new_array, 0, cache_->length());
     cache_ = *new_array;
     Handle<String> str = factory->NewStringFromAscii(name, TENURED);
-    ASSERT(!str.is_null());
     cache_->set(length, *str);
     cache_->set(length + 1, *shared);
     Script::cast(shared->script())->set_type(Smi::FromInt(type_));
index 33d47e9c4bb73eeceec550c0116cea6c6cf5db51..ada6e049a67727baa66362f198497cbaa7ed1f03 100644 (file)
@@ -368,7 +368,7 @@ Handle<Object> Context::ErrorMessageForCodeGenerationFromStrings() {
   Handle<Object> result(error_message_for_code_gen_from_strings(),
                         GetIsolate());
   if (!result->IsUndefined()) return result;
-  return GetIsolate()->factory()->NewStringFromOneByte(STATIC_ASCII_VECTOR(
+  return GetIsolate()->factory()->NewStringFromAscii(i::CStrVector(
       "Code generation from strings disallowed for this context"));
 }
 
index d7667f19c8b2d6ed0a5d7dc3b3705f7a8f37cd13..c8a99d51711fa44b3f832e023ef0efc22e27f012 100644 (file)
@@ -754,7 +754,6 @@ bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
       isolate->bootstrapper()->NativesSourceLookup(index);
   Vector<const char> name = Natives::GetScriptName(index);
   Handle<String> script_name = factory->NewStringFromAscii(name);
-  ASSERT(!script_name.is_null());
   Handle<Context> context = isolate->native_context();
 
   // Compile the script.
@@ -2600,7 +2599,6 @@ Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
   // Create the execution state object.
   Handle<String> constructor_str =
       isolate_->factory()->InternalizeUtf8String(constructor_name);
-  ASSERT(!constructor_str.is_null());
   Handle<Object> constructor(
       isolate_->global_object()->GetPropertyNoExceptionThrown(*constructor_str),
       isolate_);
index 5c4ac9c5d0da3cbad2dc3a56bbb83f52a1db9905..5e66202ded50ffeb8047f7c150377cef71423f5b 100644 (file)
@@ -289,7 +289,7 @@ Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string,
 
 
 Handle<SeqOneByteString> Factory::NewRawOneByteString(int length,
-                                                      PretenureFlag pretenure) {
+                                                  PretenureFlag pretenure) {
   CALL_HEAP_FUNCTION(
       isolate(),
       isolate()->heap()->AllocateRawOneByteString(length, pretenure),
@@ -411,7 +411,6 @@ Handle<String> Factory::NewConsString(Handle<String> left,
     ASSERT(left->IsFlat());
     ASSERT(right->IsFlat());
 
-    STATIC_ASSERT(ConsString::kMinLength <= String::kMaxLength);
     if (is_one_byte) {
       Handle<SeqOneByteString> result = NewRawOneByteString(length);
       DisallowHeapAllocation no_gc;
@@ -497,14 +496,12 @@ Handle<String> Factory::NewProperSubString(Handle<String> str,
   if (!FLAG_string_slices || length < SlicedString::kMinLength) {
     if (str->IsOneByteRepresentation()) {
       Handle<SeqOneByteString> result = NewRawOneByteString(length);
-      ASSERT(!result.is_null());
       uint8_t* dest = result->GetChars();
       DisallowHeapAllocation no_gc;
       String::WriteToFlat(*str, dest, begin, end);
       return result;
     } else {
       Handle<SeqTwoByteString> result = NewRawTwoByteString(length);
-      ASSERT(!result.is_null());
       uc16* dest = result->GetChars();
       DisallowHeapAllocation no_gc;
       String::WriteToFlat(*str, dest, begin, end);
index 063cf30ff3cd178b4c7efda22fcc2447252e90c8..7e465d5c9386858c05088c89073d3365c232167e 100644 (file)
@@ -138,7 +138,7 @@ MaybeObject* Heap::AllocateInternalizedStringImpl(
 MaybeObject* Heap::AllocateOneByteInternalizedString(Vector<const uint8_t> str,
                                                      uint32_t hash_field) {
   if (str.length() > String::kMaxLength) {
-    return isolate()->ThrowInvalidStringLength();
+    v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true);
   }
   // Compute map and object size.
   Map* map = ascii_internalized_string_map();
@@ -171,7 +171,7 @@ MaybeObject* Heap::AllocateOneByteInternalizedString(Vector<const uint8_t> str,
 MaybeObject* Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
                                                      uint32_t hash_field) {
   if (str.length() > String::kMaxLength) {
-    return isolate()->ThrowInvalidStringLength();
+    v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true);
   }
   // Compute map and object size.
   Map* map = internalized_string_map();
index f4578831c877c2782fed75435253db2676988d84..6b2f8f7a1cf9f1a9847163468118510ecef64d33 100644 (file)
@@ -3871,7 +3871,7 @@ MaybeObject* Heap::AllocateExternalStringFromAscii(
     const ExternalAsciiString::Resource* resource) {
   size_t length = resource->length();
   if (length > static_cast<size_t>(String::kMaxLength)) {
-    return isolate()->ThrowInvalidStringLength();
+    v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true);
   }
 
   Map* map = external_ascii_string_map();
@@ -3893,7 +3893,7 @@ MaybeObject* Heap::AllocateExternalStringFromTwoByte(
     const ExternalTwoByteString::Resource* resource) {
   size_t length = resource->length();
   if (length > static_cast<size_t>(String::kMaxLength)) {
-    return isolate()->ThrowInvalidStringLength();
+    v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true);
   }
 
   // For small strings we check whether the resource contains only
@@ -4978,8 +4978,8 @@ MaybeObject* Heap::AllocateInternalizedStringImpl(
   int size;
   Map* map;
 
-  if (chars < 0 || chars > String::kMaxLength) {
-    return isolate()->ThrowInvalidStringLength();
+  if (chars > String::kMaxLength) {
+    v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true);
   }
   if (is_one_byte) {
     map = ascii_internalized_string_map();
@@ -5027,7 +5027,7 @@ MaybeObject* Heap::AllocateInternalizedStringImpl<false>(
 MaybeObject* Heap::AllocateRawOneByteString(int length,
                                             PretenureFlag pretenure) {
   if (length < 0 || length > String::kMaxLength) {
-    return isolate()->ThrowInvalidStringLength();
+    v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true);
   }
   int size = SeqOneByteString::SizeFor(length);
   ASSERT(size <= SeqOneByteString::kMaxSize);
@@ -5051,7 +5051,7 @@ MaybeObject* Heap::AllocateRawOneByteString(int length,
 MaybeObject* Heap::AllocateRawTwoByteString(int length,
                                             PretenureFlag pretenure) {
   if (length < 0 || length > String::kMaxLength) {
-    return isolate()->ThrowInvalidStringLength();
+    v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true);
   }
   int size = SeqTwoByteString::SizeFor(length);
   ASSERT(size <= SeqTwoByteString::kMaxSize);
index dfa584a72ac228ee980ae516c17b6bc9e1c66652..cfe5f1a60cd7f2a15ece7f75d3da2a989fb12168 100644 (file)
@@ -3923,15 +3923,9 @@ HInstruction* HStringAdd::New(Zone* zone,
     HConstant* c_right = HConstant::cast(right);
     HConstant* c_left = HConstant::cast(left);
     if (c_left->HasStringValue() && c_right->HasStringValue()) {
-      Handle<String> left_string = c_left->StringValue();
-      Handle<String> right_string = c_right->StringValue();
-      // Prevent possible exception by invalid string length.
-      if (left_string->length() + right_string->length() < String::kMaxLength) {
-        Handle<String> concat = zone->isolate()->factory()->NewFlatConcatString(
-            c_left->StringValue(), c_right->StringValue());
-        ASSERT(!concat.is_null());
-        return HConstant::New(zone, context, concat);
-      }
+      Handle<String> concat = zone->isolate()->factory()->NewFlatConcatString(
+          c_left->StringValue(), c_right->StringValue());
+      return HConstant::New(zone, context, concat);
     }
   }
   return new(zone) HStringAdd(
index 4c2b479182db68654866d2fbb128dff6987548ed..097358932f18df46bb19f85521aefb18eeadc552 100644 (file)
@@ -606,7 +606,6 @@ Handle<String> JsonParser<seq_ascii>::SlowScanJsonString(
   int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
   Handle<StringType> seq_string =
       NewRawString<StringType>(factory(), length, pretenure_);
-  ASSERT(!seq_string.is_null());
   // Copy prefix into seq_str.
   SinkChar* dest = seq_string->GetChars();
   String::WriteToFlat(*prefix, dest, start, end);
@@ -794,7 +793,6 @@ Handle<String> JsonParser<seq_ascii>::ScanJsonString() {
   } while (c0_ != '"');
   int length = position_ - beg_pos;
   Handle<String> result = factory()->NewRawOneByteString(length, pretenure_);
-  ASSERT(!result.is_null());
   uint8_t* dest = SeqOneByteString::cast(*result)->GetChars();
   String::WriteToFlat(*source_, dest, beg_pos, position_);
 
index c063b67c08e0c26b53599d24f131f89c182b3303..a75b3deed50eacb0863ef2eed4957302674e3ac6 100644 (file)
@@ -266,7 +266,6 @@ BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
                            factory_->ToObject(factory_->empty_string()));
   part_length_ = kInitialPartLength;
   current_part_ = factory_->NewRawOneByteString(part_length_);
-  ASSERT(!current_part_.is_null());
   tojson_string_ = factory_->toJSON_string();
   stack_ = factory_->NewJSArray(8);
 }
@@ -310,7 +309,6 @@ MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate,
   if (object->IsOneByteRepresentationUnderneath()) {
     Handle<String> result =
         isolate->factory()->NewRawOneByteString(worst_case_length);
-    ASSERT(!result.is_null());
     DisallowHeapAllocation no_gc;
     return StringifyString_<SeqOneByteString>(
         isolate,
@@ -319,7 +317,6 @@ MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate,
   } else {
     Handle<String> result =
         isolate->factory()->NewRawTwoByteString(worst_case_length);
-    ASSERT(!result.is_null());
     DisallowHeapAllocation no_gc;
     return StringifyString_<SeqTwoByteString>(
         isolate,
@@ -725,6 +722,7 @@ void BasicJsonStringifier::ShrinkCurrentPart() {
 void BasicJsonStringifier::Accumulate() {
   if (accumulator()->length() + current_part_->length() > String::kMaxLength) {
     // Screw it.  Simply set the flag and carry on.  Throw exception at the end.
+    // We most likely will trigger a real OOM before even reaching this point.
     set_accumulator(factory_->empty_string());
     overflowed_ = true;
   } else {
@@ -743,7 +741,6 @@ void BasicJsonStringifier::Extend() {
   } else {
     current_part_ = factory_->NewRawTwoByteString(part_length_);
   }
-  ASSERT(!current_part_.is_null());
   current_index_ = 0;
 }
 
@@ -752,7 +749,6 @@ void BasicJsonStringifier::ChangeEncoding() {
   ShrinkCurrentPart();
   Accumulate();
   current_part_ = factory_->NewRawTwoByteString(part_length_);
-  ASSERT(!current_part_.is_null());
   current_index_ = 0;
   is_ascii_ = false;
 }
index 830dd7b35ef3576f0153ae8f1c8e279eeb8f8988..012c251e21d3035d3a290eb88f635851888f06f2 100644 (file)
@@ -466,7 +466,6 @@ bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
     // Unable to compile regexp.
     Handle<String> error_message =
         isolate->factory()->NewStringFromUtf8(CStrVector(result.error_message));
-    ASSERT(!error_message.is_null());
     CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate);
     return false;
   }
index 5eae1073a469e58137a35e8c860e88428d2c8689..a812b759da07e82a5d2b7cf95b2df614a9649f52 100644 (file)
@@ -2013,8 +2013,8 @@ Handle<JSArray> LiveEdit::CheckAndDropActivations(
       DropActivationsInActiveThread(shared_info_array, result, do_drop);
   if (error_message != NULL) {
     // Add error message as an array extra element.
-    Handle<String> str = isolate->factory()->NewStringFromAscii(
-        CStrVector(error_message));
+    Vector<const char> vector_message(error_message, StrLength(error_message));
+    Handle<String> str = isolate->factory()->NewStringFromAscii(vector_message);
     SetElementSloppy(result, len, str);
   }
   return result;
index c7ea634a3d7a04ab0803bbec401fc36a36d19511..56eec541eba6534b77f2aa59ebec00fc414d11ba 100644 (file)
@@ -215,7 +215,6 @@ Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
   Handle<String> result = symbol_cache_.at(symbol_id);
   if (result.is_null()) {
     result = scanner()->AllocateInternalizedString(isolate_);
-    ASSERT(!result.is_null());
     symbol_cache_.at(symbol_id) = result;
     return result;
   }
@@ -616,7 +615,6 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location,
   Handle<FixedArray> elements = factory->NewFixedArray(args.length());
   for (int i = 0; i < args.length(); i++) {
     Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
-    ASSERT(!arg_string.is_null());
     elements->set(i, *arg_string);
   }
   Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
@@ -674,10 +672,7 @@ Handle<String> ParserTraits::GetSymbol(Scanner* scanner) {
       parser_->scanner()->LogSymbol(parser_->log_, parser_->position());
     }
   }
-  Handle<String> result =
-      parser_->scanner()->AllocateInternalizedString(parser_->isolate_);
-  ASSERT(!result.is_null());
-  return result;
+  return parser_->scanner()->AllocateInternalizedString(parser_->isolate_);
 }
 
 
@@ -1714,8 +1709,8 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
         return;
       }
       Handle<String> message_string =
-          isolate()->factory()->InternalizeOneByteString(
-              STATIC_ASCII_VECTOR("Variable"));
+          isolate()->factory()->NewStringFromUtf8(CStrVector("Variable"),
+                                                  TENURED);
       Expression* expression =
           NewThrowTypeError(isolate()->factory()->redeclaration_string(),
                             message_string, name);
@@ -3821,7 +3816,6 @@ bool RegExpParser::simple() {
 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
   failed_ = true;
   *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED);
-  ASSERT(!error_->is_null());
   // Zip to the end to make sure the no more input is read.
   current_ = kEndMarker;
   next_pos_ = in()->length();
index 706f1ff09fa11a0c45e62ba455572b12bacc1056..89dbb0b2730a4c7ea1e300249f718a92cafc85b1 100644 (file)
@@ -3344,7 +3344,8 @@ class ReplacementStringBuilder {
         array_builder_(heap->isolate(), estimated_part_count),
         subject_(subject),
         character_count_(0),
-        is_ascii_(subject->IsOneByteRepresentation()) {
+        is_ascii_(subject->IsOneByteRepresentation()),
+        overflowed_(false) {
     // Require a non-zero initial size. Ensures that doubling the size to
     // extend the array will work.
     ASSERT(estimated_part_count > 0);
@@ -3392,6 +3393,11 @@ class ReplacementStringBuilder {
 
 
   Handle<String> ToString() {
+    if (overflowed_) {
+      heap_->isolate()->ThrowInvalidStringLength();
+      return Handle<String>();
+    }
+
     if (array_builder_.length() == 0) {
       return heap_->isolate()->factory()->empty_string();
     }
@@ -3399,7 +3405,6 @@ class ReplacementStringBuilder {
     Handle<String> joined_string;
     if (is_ascii_) {
       Handle<SeqOneByteString> seq = NewRawOneByteString(character_count_);
-      RETURN_IF_EMPTY_HANDLE_VALUE(heap_->isolate(), seq, Handle<String>());
       DisallowHeapAllocation no_gc;
       uint8_t* char_buffer = seq->GetChars();
       StringBuilderConcatHelper(*subject_,
@@ -3410,7 +3415,6 @@ class ReplacementStringBuilder {
     } else {
       // Non-ASCII.
       Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_);
-      RETURN_IF_EMPTY_HANDLE_VALUE(heap_->isolate(), seq, Handle<String>());
       DisallowHeapAllocation no_gc;
       uc16* char_buffer = seq->GetChars();
       StringBuilderConcatHelper(*subject_,
@@ -3425,11 +3429,9 @@ class ReplacementStringBuilder {
 
   void IncrementCharacterCount(int by) {
     if (character_count_ > String::kMaxLength - by) {
-      STATIC_ASSERT(String::kMaxLength < kMaxInt);
-      character_count_ = kMaxInt;
-    } else {
-      character_count_ += by;
+      overflowed_ = true;
     }
+    character_count_ += by;
   }
 
  private:
@@ -3454,6 +3456,7 @@ class ReplacementStringBuilder {
   Handle<String> subject_;
   int character_count_;
   bool is_ascii_;
+  bool overflowed_;
 };
 
 
@@ -3910,13 +3913,10 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString(
        static_cast<int64_t>(pattern_len)) *
       static_cast<int64_t>(matches) +
       static_cast<int64_t>(subject_len);
-  int result_len;
-  if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) {
-    STATIC_ASSERT(String::kMaxLength < kMaxInt);
-    result_len = kMaxInt;  // Provoke exception.
-  } else {
-    result_len = static_cast<int>(result_len_64);
+  if (result_len_64 > INT_MAX) {
+    v8::internal::Heap::FatalProcessOutOfMemory("invalid string length", true);
   }
+  int result_len = static_cast<int>(result_len_64);
 
   int subject_pos = 0;
   int result_pos = 0;
@@ -3929,7 +3929,6 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString(
     result = Handle<ResultSeqString>::cast(
         isolate->factory()->NewRawTwoByteString(result_len));
   }
-  RETURN_IF_EMPTY_HANDLE(isolate, result);
 
   for (int i = 0; i < matches; i++) {
     // Copy non-matched subject content.
@@ -4109,7 +4108,6 @@ MUST_USE_RESULT static MaybeObject* StringReplaceGlobalRegExpWithEmptyString(
     answer = Handle<ResultSeqString>::cast(
         isolate->factory()->NewRawTwoByteString(new_length));
   }
-  ASSERT(!answer.is_null());
 
   int prev = 0;
   int position = 0;
@@ -6567,7 +6565,7 @@ MUST_USE_RESULT static MaybeObject* ConvertCase(
   if (s->IsOneByteRepresentationUnderneath()) {
     Handle<SeqOneByteString> result =
         isolate->factory()->NewRawOneByteString(length);
-    ASSERT(!result.is_null());  // Same length as input.
+
     DisallowHeapAllocation no_gc;
     String::FlatContent flat_content = s->GetFlatContent();
     ASSERT(flat_content.IsFlat());
@@ -6587,8 +6585,6 @@ MUST_USE_RESULT static MaybeObject* ConvertCase(
   } else {
     result = isolate->factory()->NewRawTwoByteString(length);
   }
-  ASSERT(!result.is_null());  // Same length as input.
-
   MaybeObject* maybe = ConvertCaseHelper(isolate, *s, *result, length, mapping);
   Object* answer;
   if (!maybe->ToObject(&answer)) return maybe;
@@ -6602,7 +6598,6 @@ MUST_USE_RESULT static MaybeObject* ConvertCase(
     if (length < 0) length = -length;
     result = isolate->factory()->NewRawTwoByteString(length);
   }
-  RETURN_IF_EMPTY_HANDLE(isolate, result);
   return ConvertCaseHelper(isolate, *s, *result, length, mapping);
 }
 
@@ -7247,16 +7242,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
     String* element = String::cast(element_obj);
     int increment = element->length();
     if (increment > String::kMaxLength - length) {
-      STATIC_ASSERT(String::kMaxLength < kMaxInt);
-      length = kMaxInt;  // Provoke exception;
-      break;
+      return isolate->ThrowInvalidStringLength();
     }
     length += increment;
   }
 
   Handle<SeqTwoByteString> answer =
       isolate->factory()->NewRawTwoByteString(length);
-  RETURN_IF_EMPTY_HANDLE(isolate, answer);
 
   DisallowHeapAllocation no_gc;
 
@@ -9501,9 +9493,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ThrowMessage) {
   CONVERT_SMI_ARG_CHECKED(message_id, 0);
   const char* message = GetBailoutReason(
       static_cast<BailoutReason>(message_id));
-  Handle<String> message_handle =
+  Handle<Name> message_handle =
       isolate->factory()->NewStringFromAscii(CStrVector(message));
-  RETURN_IF_EMPTY_HANDLE(isolate, message_handle);
   return isolate->Throw(*message_handle);
 }
 
index 1e73ddd3d22464a654404704e043a9420b77a9cc..81ec0c58cff93c4d896b97f5b83e64e78a5e96e8 100644 (file)
--- a/src/uri.h
+++ b/src/uri.h
@@ -127,11 +127,9 @@ Handle<String> URIUnescape::UnescapeSlow(
 
   int dest_position = 0;
   Handle<String> second_part;
-  ASSERT(unescaped_length <= String::kMaxLength);
   if (one_byte) {
     Handle<SeqOneByteString> dest =
         isolate->factory()->NewRawOneByteString(unescaped_length);
-    ASSERT(!dest.is_null());
     DisallowHeapAllocation no_allocation;
     Vector<const Char> vector = GetCharVector<Char>(string);
     for (int i = start_index; i < length; dest_position++) {
@@ -144,7 +142,6 @@ Handle<String> URIUnescape::UnescapeSlow(
   } else {
     Handle<SeqTwoByteString> dest =
         isolate->factory()->NewRawTwoByteString(unescaped_length);
-    ASSERT(!dest.is_null());
     DisallowHeapAllocation no_allocation;
     Vector<const Char> vector = GetCharVector<Char>(string);
     for (int i = start_index; i < length; dest_position++) {
@@ -266,7 +263,11 @@ Handle<String> URIEscape::Escape(Isolate* isolate, Handle<String> string) {
 
       // We don't allow strings that are longer than a maximal length.
       ASSERT(String::kMaxLength < 0x7fffffff - 6);  // Cannot overflow.
-      if (escaped_length > String::kMaxLength) break;  // Provoke exception.
+      if (escaped_length > String::kMaxLength) {
+        AllowHeapAllocation allocate_error_and_return;
+        isolate->ThrowInvalidStringLength();
+        return Handle<String>::null();
+      }
     }
   }
 
@@ -275,7 +276,6 @@ Handle<String> URIEscape::Escape(Isolate* isolate, Handle<String> string) {
 
   Handle<SeqOneByteString> dest =
       isolate->factory()->NewRawOneByteString(escaped_length);
-  RETURN_IF_EMPTY_HANDLE_VALUE(isolate, dest, Handle<String>());
   int dest_position = 0;
 
   { DisallowHeapAllocation no_allocation;
index d8a427c0c5027317c0f5b3e734bc264cc13fb63c..7e5fe2adc52fd355684cadf2d5c1fe9cd0169b37 100644 (file)
@@ -74,7 +74,6 @@
   'test-api/Threading2': [PASS, ['mode == debug', SLOW]],
   'test-api/Threading3': [PASS, ['mode == debug', SLOW]],
   'test-api/Threading4': [PASS, ['mode == debug', SLOW]],
-  'test-strings/StringOOM*': [PASS, ['mode == debug', SLOW]],
 }],  # ALWAYS
 
 ##############################################################################
index 9168d86c4f38e74e5ad3d17073dcb7ffcb871582..0f37c3e5172d659bc249675ea5d8d829be3226ba 100644 (file)
@@ -1352,64 +1352,3 @@ TEST(Latin1IgnoreCase) {
     CHECK_EQ(Min(upper, lower), test);
   }
 }
-
-
-class DummyResource: public v8::String::ExternalStringResource {
- public:
-  virtual const uint16_t* data() const { return NULL; }
-  virtual size_t length() const { return 1 << 30; }
-};
-
-
-class DummyOneByteResource: public v8::String::ExternalOneByteStringResource {
- public:
-  virtual const char* data() const { return NULL; }
-  virtual size_t length() const { return 1 << 30; }
-};
-
-
-TEST(InvalidExternalString) {
-  CcTest::InitializeVM();
-  LocalContext context;
-  Isolate* isolate = CcTest::i_isolate();
-  { HandleScope scope(isolate);
-    DummyOneByteResource r;
-    CHECK(isolate->factory()->NewExternalStringFromAscii(&r).is_null());
-    CHECK(isolate->has_pending_exception());
-    isolate->clear_pending_exception();
-  }
-
-  { HandleScope scope(isolate);
-    DummyResource r;
-    CHECK(isolate->factory()->NewExternalStringFromTwoByte(&r).is_null());
-    CHECK(isolate->has_pending_exception());
-    isolate->clear_pending_exception();
-  }
-}
-
-
-#define INVALID_STRING_TEST(FUN, TYPE)                                         \
-  TEST(StringOOM##FUN) {                                                       \
-    CcTest::InitializeVM();                                                    \
-    LocalContext context;                                                      \
-    Isolate* isolate = CcTest::i_isolate();                                    \
-    STATIC_ASSERT(String::kMaxLength < kMaxInt);                               \
-    static const int invalid = String::kMaxLength + 1;                         \
-    HandleScope scope(isolate);                                                \
-    Vector<TYPE> dummy = Vector<TYPE>::New(invalid);                           \
-    CHECK(isolate->factory()->FUN(Vector<const TYPE>::cast(dummy)).is_null()); \
-    memset(dummy.start(), 0x20, dummy.length() * sizeof(TYPE));                \
-    CHECK(isolate->has_pending_exception());                                   \
-    isolate->clear_pending_exception();                                        \
-    dummy.Dispose();                                                           \
-  }
-
-INVALID_STRING_TEST(NewStringFromAscii, char)
-INVALID_STRING_TEST(NewStringFromUtf8, char)
-INVALID_STRING_TEST(NewStringFromOneByte, uint8_t)
-INVALID_STRING_TEST(NewStringFromTwoByte, uint16_t)
-INVALID_STRING_TEST(InternalizeOneByteString, uint8_t)
-INVALID_STRING_TEST(InternalizeUtf8String, char)
-INVALID_STRING_TEST(InternalizeTwoByteString, uint16_t)
-
-#undef INVALID_STRING_TEST
index 2de01109eb80a1fa043ed5b61ad15fe44f53ee42..a527ae6aa81c27b001ee7724b58252f971328e1c 100644 (file)
@@ -2,25 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-
-
 var a = 'a';
 for (var i = 0; i < 5; i++) a += a;
 var b = 'b';
 for (var i = 0; i < 23; i++) b += b;
 
-function replace1() {
+function replace() {
   a.replace(/./g, b);
 }
 
-assertThrows(replace1, RangeError);
-
-
-var a = 'a';
-for (var i = 0; i < 16; i++) a += a;
-
-function replace2() {
-  a.replace(/a/g, a);
-}
-
-assertThrows(replace2, RangeError);
+assertThrows(replace, RangeError);
index e2e4a9c2521f55a4074214afe82492c2096d4031..8c7debcab8b1554fa6026cd8d7d283b213e87016 100644 (file)
@@ -68,7 +68,6 @@ class BaselineScanner {
             Vector<const uint16_t>(
                 reinterpret_cast<const uint16_t*>(source_),
                 length / 2));
-        CHECK_NOT_EMPTY_HANDLE(isolate, result);
         stream_ =
             new GenericStringUtf16CharacterStream(result, 0, result->length());
         break;
@@ -76,7 +75,6 @@ class BaselineScanner {
       case LATIN1: {
         Handle<String> result = isolate->factory()->NewStringFromOneByte(
             Vector<const uint8_t>(source_, length));
-        CHECK_NOT_EMPTY_HANDLE(isolate, result);
         stream_ =
             new GenericStringUtf16CharacterStream(result, 0, result->length());
         break;