Add asserts to String::GetFlatContent.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 23 May 2013 13:53:49 +0000 (13:53 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 23 May 2013 13:53:49 +0000 (13:53 +0000)
R=verwaest@chromium.org
BUG=

Review URL: https://chromiumcodereview.appspot.com/13841012

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

src/json-stringifier.h
src/objects.cc
src/runtime.cc

index b67a9f6..f548a2e 100644 (file)
@@ -773,9 +773,16 @@ void BasicJsonStringifier::SerializeString_(Handle<String> string) {
           length);
     }
   } else {
-    String* string_location = *string;
-    Vector<const Char> vector = GetCharVector<Char>(string);
+    String* string_location = NULL;
+    Vector<const Char> vector(NULL, 0);
     for (int i = 0; i < length; i++) {
+      // If GC moved the string, we need to refresh the vector.
+      if (*string != string_location) {
+        AssertNoAllocation no_gc;
+        // This does not actually prevent the string from being relocated later.
+        vector = GetCharVector<Char>(string);
+        string_location = *string;
+      }
       Char c = vector[i];
       if (DoNotEscape(c)) {
         Append_<is_ascii, Char>(c);
@@ -783,11 +790,6 @@ void BasicJsonStringifier::SerializeString_(Handle<String> string) {
         Append_<is_ascii, uint8_t>(reinterpret_cast<const uint8_t*>(
             &JsonEscapeTable[c * kJsonEscapeTableEntrySize]));
       }
-      // If GC moved the string, we need to refresh the vector.
-      if (*string != string_location) {
-        vector = GetCharVector<Char>(string);
-        string_location = *string;
-      }
     }
   }
 
@@ -825,17 +827,16 @@ Vector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) {
 
 
 void BasicJsonStringifier::SerializeString(Handle<String> object) {
-  FlattenString(object);
-  String::FlatContent flat = object->GetFlatContent();
+  object = FlattenGetString(object);
   if (is_ascii_) {
-    if (flat.IsAscii()) {
+    if (object->IsOneByteRepresentation()) {
       SerializeString_<true, uint8_t>(object);
     } else {
       ChangeEncoding();
       SerializeString(object);
     }
   } else {
-    if (flat.IsAscii()) {
+    if (object->IsOneByteRepresentation()) {
       SerializeString_<false, uint8_t>(object);
     } else {
       SerializeString_<false, uc16>(object);
index 40b8dfb..99fd8e2 100644 (file)
@@ -7841,6 +7841,7 @@ bool String::LooksValid() {
 
 
 String::FlatContent String::GetFlatContent() {
+  ASSERT(!GetHeap()->allow_allocation(false));
   int length = this->length();
   StringShape shape(this);
   String* string = this;
@@ -8067,6 +8068,8 @@ void FlatStringReader::PostGarbageCollection() {
   if (str_ == NULL) return;
   Handle<String> str(str_);
   ASSERT(str->IsFlat());
+  AssertNoAllocation no_gc;
+  // This does not actually prevent the vector from being relocated later.
   String::FlatContent content = str->GetFlatContent();
   ASSERT(content.IsFlat());
   is_ascii_ = content.IsAscii();
@@ -8618,6 +8621,7 @@ bool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) {
 bool String::IsOneByteEqualTo(Vector<const uint8_t> str) {
   int slen = length();
   if (str.length() != slen) return false;
+  AssertNoAllocation no_gc;
   FlatContent content = GetFlatContent();
   if (content.IsAscii()) {
     return CompareChars(content.ToOneByteVector().start(),
@@ -8633,6 +8637,7 @@ bool String::IsOneByteEqualTo(Vector<const uint8_t> str) {
 bool String::IsTwoByteEqualTo(Vector<const uc16> str) {
   int slen = length();
   if (str.length() != slen) return false;
+  AssertNoAllocation no_gc;
   FlatContent content = GetFlatContent();
   if (content.IsTwoByte()) {
     return CompareChars(content.ToUC16Vector().start(), str.start(), slen) == 0;
index 36cd206..1d0d262 100644 (file)
@@ -5663,11 +5663,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_URIEscape) {
   ASSERT(args.length() == 1);
   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   Handle<String> string = FlattenGetString(source);
-  String::FlatContent content = string->GetFlatContent();
-  ASSERT(content.IsFlat());
-  Handle<String> result =
-      content.IsAscii() ? URIEscape::Escape<uint8_t>(isolate, source)
-                        : URIEscape::Escape<uc16>(isolate, source);
+  ASSERT(string->IsFlat());
+  Handle<String> result = string->IsOneByteRepresentationUnderneath()
+      ? URIEscape::Escape<uint8_t>(isolate, source)
+      : URIEscape::Escape<uc16>(isolate, source);
   if (result.is_null()) return Failure::OutOfMemoryException(0x12);
   return *result;
 }
@@ -5678,10 +5677,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_URIUnescape) {
   ASSERT(args.length() == 1);
   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
   Handle<String> string = FlattenGetString(source);
-  String::FlatContent content = string->GetFlatContent();
-  ASSERT(content.IsFlat());
-  return content.IsAscii() ? *URIUnescape::Unescape<uint8_t>(isolate, source)
-                           : *URIUnescape::Unescape<uc16>(isolate, source);
+  ASSERT(string->IsFlat());
+  return string->IsOneByteRepresentationUnderneath()
+      ? *URIUnescape::Unescape<uint8_t>(isolate, source)
+      : *URIUnescape::Unescape<uc16>(isolate, source);
 }
 
 
@@ -6210,6 +6209,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) {
       if (!maybe_obj->ToObject(&obj)) return maybe_obj;
     }
     elements = Handle<FixedArray>(FixedArray::cast(obj), isolate);
+    AssertNoAllocation no_gc;
     String::FlatContent content = s->GetFlatContent();
     if (content.IsAscii()) {
       Vector<const uint8_t> chars = content.ToOneByteVector();
@@ -7076,6 +7076,7 @@ static Object* FlatStringCompare(String* x, String* y) {
     equal_prefix_result = Smi::FromInt(LESS);
   }
   int r;
+  AssertNoAllocation no_gc;
   String::FlatContent x_content = x->GetFlatContent();
   String::FlatContent y_content = y->GetFlatContent();
   if (x_content.IsAscii()) {
@@ -13295,6 +13296,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) {
   ASSERT(args.length() == 2);
   CONVERT_ARG_CHECKED(String, format, 0);
   CONVERT_ARG_CHECKED(JSArray, elms, 1);
+  AssertNoAllocation no_gc;
   String::FlatContent format_content = format->GetFlatContent();
   RUNTIME_ASSERT(format_content.IsAscii());
   Vector<const uint8_t> chars = format_content.ToOneByteVector();