Revision: 15906
Author:   [email protected]
Date:     Fri Jul 26 05:32:06 2013
Log:      Do not allow external strings in old pointer space.

[email protected]
BUG=

Review URL: https://codereview.chromium.org/20723002
http://code.google.com/p/v8/source/detail?r=15906

Modified:
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/src/mark-compact.cc
 /branches/bleeding_edge/test/cctest/cctest.status
 /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/src/api.cc  Fri Jul 26 03:40:00 2013
+++ /branches/bleeding_edge/src/api.cc  Fri Jul 26 05:32:06 2013
@@ -5928,6 +5928,23 @@
       isolate->factory()->NewExternalStringFromAscii(resource);
   return result;
 }
+
+
+bool RedirectToExternalString(i::Isolate* isolate,
+                              i::Handle<i::String> parent,
+                              i::Handle<i::String> external) {
+  if (parent->IsConsString()) {
+    i::Handle<i::ConsString> cons = i::Handle<i::ConsString>::cast(parent);
+    cons->set_first(*external);
+    cons->set_second(isolate->heap()->empty_string());
+  } else {
+    ASSERT(parent->IsSlicedString());
+ i::Handle<i::SlicedString> slice = i::Handle<i::SlicedString>::cast(parent);
+    slice->set_parent(*external);
+    slice->set_offset(0);
+  }
+  return true;
+}


 Local<String> v8::String::NewExternal(
@@ -5958,9 +5975,23 @@
     return false;
   }
   CHECK(resource && resource->data());
-  bool result = obj->MakeExternal(resource);
-  if (result && !obj->IsInternalizedString()) {
-    isolate->heap()->external_string_table()->AddString(*obj);
+
+  bool result;
+  i::Handle<i::String> external;
+  if (isolate->heap()->old_pointer_space()->Contains(*obj)) {
+ // We do not allow external strings in the old pointer space. Instead of
+    // converting the string in-place, we keep the cons/sliced string and
+    // point it to a newly-allocated external string.
+    external = NewExternalStringHandle(isolate, resource);
+    result = RedirectToExternalString(isolate, obj, external);
+  } else {
+    result = obj->MakeExternal(resource);
+    external = obj;
+  }
+
+  ASSERT(external->IsExternalString());
+  if (result && !external->IsInternalizedString()) {
+    isolate->heap()->external_string_table()->AddString(*external);
   }
   return result;
 }
@@ -5995,9 +6026,23 @@
     return false;
   }
   CHECK(resource && resource->data());
-  bool result = obj->MakeExternal(resource);
-  if (result && !obj->IsInternalizedString()) {
-    isolate->heap()->external_string_table()->AddString(*obj);
+
+  bool result;
+  i::Handle<i::String> external;
+  if (isolate->heap()->old_pointer_space()->Contains(*obj)) {
+ // We do not allow external strings in the old pointer space. Instead of
+    // converting the string in-place, we keep the cons/sliced string and
+    // point it to a newly-allocated external string.
+    external = NewExternalAsciiStringHandle(isolate, resource);
+    result = RedirectToExternalString(isolate, obj, external);
+  } else {
+    result = obj->MakeExternal(resource);
+    external = obj;
+  }
+
+  ASSERT(external->IsExternalString());
+  if (result && !external->IsInternalizedString()) {
+    isolate->heap()->external_string_table()->AddString(*external);
   }
   return result;
 }
=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Thu Jul 25 05:10:45 2013
+++ /branches/bleeding_edge/src/mark-compact.cc Fri Jul 26 05:32:06 2013
@@ -2743,8 +2743,7 @@
   if (dest == OLD_POINTER_SPACE) {
     // TODO(hpayer): Replace this check with an assert.
     HeapObject* heap_object = HeapObject::FromAddress(src);
-    CHECK(heap_object->IsExternalString() ||
-          heap_->TargetSpace(heap_object) == heap_->old_pointer_space());
+    CHECK(heap_->TargetSpace(heap_object) == heap_->old_pointer_space());
     Address src_slot = src;
     Address dst_slot = dst;
     ASSERT(IsAligned(size, kPointerSize));
=======================================
--- /branches/bleeding_edge/test/cctest/cctest.status Fri Jul 26 04:37:54 2013 +++ /branches/bleeding_edge/test/cctest/cctest.status Fri Jul 26 05:32:06 2013
@@ -42,9 +42,6 @@
# This test always fails. It tests that LiveEdit causes abort when turned off.
 test-debug/LiveEditDisabled: FAIL

-# TODO(yangguo,mstarzinger): Fix bug in String::MakeExternal.
-test-api/MakingExternalUnalignedAsciiString: PASS || CRASH
-
 # TODO(gc): Temporarily disabled in the GC branch.
 test-log/EquivalenceOfLoggingAndTraversal: PASS || FAIL

=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Fri Jul 26 04:37:54 2013
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Fri Jul 26 05:32:06 2013
@@ -625,10 +625,14 @@
   LocalContext env;
   v8::HandleScope scope(env->GetIsolate());

+  CompileRun("function cons(a, b) { return a + b; }"
+             "function slice(a) { return a.substring(1); }");
   // Create a cons string that will land in old pointer space.
-  Local<String> string = Local<String>::Cast(CompileRun(
-      "function cons(a, b) { return a + b; }"
+  Local<String> cons = Local<String>::Cast(CompileRun(
       "cons('abcdefghijklm', 'nopqrstuvwxyz');"));
+  // Create a sliced string that will land in old pointer space.
+  Local<String> slice = Local<String>::Cast(CompileRun(
+      "slice('abcdefghijklmnopqrstuvwxyz');"));

   // Trigger GCs so that the newly allocated string moves to old gen.
   SimulateFullSpace(HEAP->old_pointer_space());
@@ -637,9 +641,13 @@

   // Turn into external string with unaligned resource data.
   int dispose_count = 0;
-  const char* c_source = "_abcdefghijklmnopqrstuvwxyz";
-  bool success = string->MakeExternal(
-      new TestAsciiResource(i::StrDup(c_source) + 1, &dispose_count));
+  const char* c_cons = "_abcdefghijklmnopqrstuvwxyz";
+  bool success = cons->MakeExternal(
+      new TestAsciiResource(i::StrDup(c_cons) + 1, &dispose_count));
+  CHECK(success);
+  const char* c_slice = "_bcdefghijklmnopqrstuvwxyz";
+  success = slice->MakeExternal(
+      new TestAsciiResource(i::StrDup(c_slice) + 1, &dispose_count));
   CHECK(success);

   // Trigger GCs and force evacuation.

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to