From 4b0c0760528dc452ac269a7ccc67f8e93a19c1a3 Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Tue, 9 Sep 2014 11:41:56 +0000 Subject: [PATCH] Turn old space cons strings into regular external strings (not short). R=hpayer@chromium.org BUG=v8:3530 LOG=N Review URL: https://codereview.chromium.org/368223002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23794 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/heap/heap-inl.h | 3 +-- src/objects.cc | 26 ++++++------------- .../regress-sliced-external-cons-regexp.js | 21 +++++++++++++++ 3 files changed, 30 insertions(+), 20 deletions(-) create mode 100644 test/mjsunit/regress/regress-sliced-external-cons-regexp.js diff --git a/src/heap/heap-inl.h b/src/heap/heap-inl.h index adb6e25bb7..0a899d525c 100644 --- a/src/heap/heap-inl.h +++ b/src/heap/heap-inl.h @@ -461,8 +461,7 @@ bool Heap::AllowedToBeMigrated(HeapObject* obj, AllocationSpace dst) { return dst == src || dst == TargetSpaceId(type); case OLD_POINTER_SPACE: return dst == src && (dst == TargetSpaceId(type) || obj->IsFiller() || - (obj->IsExternalString() && - ExternalString::cast(obj)->is_short())); + obj->IsExternalString()); case OLD_DATA_SPACE: return dst == src && dst == TargetSpaceId(type); case CODE_SPACE: diff --git a/src/objects.cc b/src/objects.cc index 7b942ffd26..62e33b7a73 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -1010,18 +1010,13 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) { bool is_internalized = this->IsInternalizedString(); // Morph the string to an external string by replacing the map and - // reinitializing the fields. This won't work if - // - the space the existing string occupies is too small for a regular - // external string. - // - the existing string is in old pointer space and the backing store of - // the external string is not aligned. The GC cannot deal with a field - // containing a possibly unaligned address to outside of V8's heap. - // In either case we resort to a short external string instead, omitting + // reinitializing the fields. This won't work if the space the existing + // string occupies is too small for a regular external string. + // Instead, we resort to a short external string instead, omitting // the field caching the address of the backing store. When we encounter // short external strings in generated code, we need to bailout to runtime. Map* new_map; - if (size < ExternalString::kSize || - heap->old_pointer_space()->Contains(this)) { + if (size < ExternalString::kSize) { new_map = is_internalized ? (is_ascii ? heap-> @@ -1084,18 +1079,13 @@ bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { bool is_internalized = this->IsInternalizedString(); // Morph the string to an external string by replacing the map and - // reinitializing the fields. This won't work if - // - the space the existing string occupies is too small for a regular - // external string. - // - the existing string is in old pointer space and the backing store of - // the external string is not aligned. The GC cannot deal with a field - // containing a possibly unaligned address to outside of V8's heap. - // In either case we resort to a short external string instead, omitting + // reinitializing the fields. This won't work if the space the existing + // string occupies is too small for a regular external string. + // Instead, we resort to a short external string instead, omitting // the field caching the address of the backing store. When we encounter // short external strings in generated code, we need to bailout to runtime. Map* new_map; - if (size < ExternalString::kSize || - heap->old_pointer_space()->Contains(this)) { + if (size < ExternalString::kSize) { new_map = is_internalized ? heap->short_external_ascii_internalized_string_map() : heap->short_external_ascii_string_map(); diff --git a/test/mjsunit/regress/regress-sliced-external-cons-regexp.js b/test/mjsunit/regress/regress-sliced-external-cons-regexp.js new file mode 100644 index 0000000000..145c831896 --- /dev/null +++ b/test/mjsunit/regress/regress-sliced-external-cons-regexp.js @@ -0,0 +1,21 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-externalize-string --expose-gc + +var re = /(B)/; +var cons1 = "0123456789" + "ABCDEFGHIJ"; +var cons2 = "0123456789\u1234" + "ABCDEFGHIJ"; +gc(); +gc(); // Promote cons. + +try { externalizeString(cons1, false); } catch (e) { } +try { externalizeString(cons2, true); } catch (e) { } + +var slice1 = cons1.slice(1,-1); +var slice2 = cons2.slice(1,-1); +for (var i = 0; i < 10; i++) { + assertEquals(["B", "B"], re.exec(slice1)); + assertEquals(["B", "B"], re.exec(slice2)); +}