| Index: test/cctest/test-strings.cc
|
| diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc
|
| index 344fa2fe561d5018e0a0198ac8b46f2a64f8cb65..9793ae7f18fdd51dbef9d26e3566963b75247cb4 100644
|
| --- a/test/cctest/test-strings.cc
|
| +++ b/test/cctest/test-strings.cc
|
| @@ -40,6 +40,7 @@
|
| #include "src/objects.h"
|
| #include "src/unicode-decoder.h"
|
| #include "test/cctest/cctest.h"
|
| +#include "test/cctest/heap/heap-utils.h"
|
|
|
| // Adapted from http://en.wikipedia.org/wiki/Multiply-with-carry
|
| class MyRandomNumberGenerator {
|
| @@ -1319,6 +1320,46 @@ TEST(RobustSubStringStub) {
|
| CheckException("%_SubString(slice, 0, 17);");
|
| }
|
|
|
| +TEST(RobustSubStringStubExternalStrings) {
|
| + // Ensure that the specific combination of calling the SubStringStub on an
|
| + // external string and triggering a GC on string allocation does not crash.
|
| + // See crbug.com/649967.
|
| +
|
| + FLAG_allow_natives_syntax = true;
|
| +#ifdef VERIFY_HEAP
|
| + FLAG_verify_heap = true;
|
| +#endif
|
| +
|
| + CcTest::InitializeVM();
|
| + v8::HandleScope handle_scope(CcTest::isolate());
|
| +
|
| + v8::Local<v8::String> underlying =
|
| + CompileRun(
|
| + "var str = 'abcdefghijklmnopqrstuvwxyz';"
|
| + "str")
|
| + ->ToString(CcTest::isolate()->GetCurrentContext())
|
| + .ToLocalChecked();
|
| + CHECK(v8::Utils::OpenHandle(*underlying)->IsSeqOneByteString());
|
| +
|
| + const int length = underlying->Length();
|
| + uc16* two_byte = NewArray<uc16>(length + 1);
|
| + underlying->Write(two_byte);
|
| +
|
| + Resource* resource = new Resource(two_byte, length);
|
| + CHECK(underlying->MakeExternal(resource));
|
| + CHECK(v8::Utils::OpenHandle(*underlying)->IsExternalTwoByteString());
|
| +
|
| + v8::Local<v8::Script> script = v8_compile(v8_str("%_SubString(str, 5, 8)"));
|
| +
|
| + // Trigger a GC on string allocation.
|
| + i::heap::SimulateFullSpace(CcTest::heap()->new_space());
|
| +
|
| + v8::Local<v8::Value> result;
|
| + CHECK(script->Run(v8::Isolate::GetCurrent()->GetCurrentContext())
|
| + .ToLocal(&result));
|
| + Handle<String> string = v8::Utils::OpenHandle(v8::String::Cast(*result));
|
| + CHECK_EQ(0, strcmp("fgh", string->ToCString().get()));
|
| +}
|
|
|
| namespace {
|
|
|
|
|