Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(855)

Unified Diff: test/cctest/test-api.cc

Issue 185653004: Experimental parser: merge to r19637 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « test/cctest/test-alloc.cc ('k') | test/cctest/test-assembler-a64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index fc4d630ecc9101db1ff835a50f2e73e2b8cf4b89..c5c932b7516cc70738ad918a9311dabe1e985427 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -462,13 +462,13 @@ static uint16_t* AsciiToTwoByteString(const char* source) {
class TestResource: public String::ExternalStringResource {
public:
- explicit TestResource(uint16_t* data, int* counter = NULL)
- : data_(data), length_(0), counter_(counter) {
+ TestResource(uint16_t* data, int* counter = NULL, bool owning_data = true)
+ : data_(data), length_(0), counter_(counter), owning_data_(owning_data) {
while (data[length_]) ++length_;
}
~TestResource() {
- i::DeleteArray(data_);
+ if (owning_data_) i::DeleteArray(data_);
if (counter_ != NULL) ++*counter_;
}
@@ -479,20 +479,25 @@ class TestResource: public String::ExternalStringResource {
size_t length() const {
return length_;
}
+
private:
uint16_t* data_;
size_t length_;
int* counter_;
+ bool owning_data_;
};
class TestAsciiResource: public String::ExternalAsciiStringResource {
public:
- explicit TestAsciiResource(const char* data, int* counter = NULL)
- : data_(data), length_(strlen(data)), counter_(counter) { }
+ TestAsciiResource(const char* data, int* counter = NULL, size_t offset = 0)
+ : orig_data_(data),
+ data_(data + offset),
+ length_(strlen(data) - offset),
+ counter_(counter) { }
~TestAsciiResource() {
- i::DeleteArray(data_);
+ i::DeleteArray(orig_data_);
if (counter_ != NULL) ++*counter_;
}
@@ -503,7 +508,9 @@ class TestAsciiResource: public String::ExternalAsciiStringResource {
size_t length() const {
return length_;
}
+
private:
+ const char* orig_data_;
const char* data_;
size_t length_;
int* counter_;
@@ -730,14 +737,13 @@ TEST(MakingExternalUnalignedAsciiString) {
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
// Turn into external string with unaligned resource data.
- int dispose_count = 0;
const char* c_cons = "_abcdefghijklmnopqrstuvwxyz";
bool success = cons->MakeExternal(
- new TestAsciiResource(i::StrDup(c_cons) + 1, &dispose_count));
+ new TestAsciiResource(i::StrDup(c_cons), NULL, 1));
CHECK(success);
const char* c_slice = "_bcdefghijklmnopqrstuvwxyz";
success = slice->MakeExternal(
- new TestAsciiResource(i::StrDup(c_slice) + 1, &dispose_count));
+ new TestAsciiResource(i::StrDup(c_slice), NULL, 1));
CHECK(success);
// Trigger GCs and force evacuation.
@@ -758,7 +764,7 @@ THREADED_TEST(UsingExternalString) {
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
i::Handle<i::String> isymbol =
- factory->InternalizedStringFromString(istring);
+ factory->InternalizeString(istring);
CHECK(isymbol->IsInternalizedString());
}
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
@@ -778,7 +784,7 @@ THREADED_TEST(UsingExternalAsciiString) {
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
i::Handle<i::String> isymbol =
- factory->InternalizedStringFromString(istring);
+ factory->InternalizeString(istring);
CHECK(isymbol->IsInternalizedString());
}
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
@@ -1999,6 +2005,21 @@ THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) {
}
+THREADED_TEST(EmptyInterceptorBreakTransitions) {
+ v8::HandleScope scope(CcTest::isolate());
+ Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
+ AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Constructor"), templ->GetFunction());
+ CompileRun("var o1 = new Constructor;"
+ "o1.a = 1;" // Ensure a and x share the descriptor array.
+ "Object.defineProperty(o1, 'x', {value: 10});");
+ CompileRun("var o2 = new Constructor;"
+ "o2.a = 1;"
+ "Object.defineProperty(o2, 'x', {value: 10});");
+}
+
+
THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
@@ -2765,7 +2786,7 @@ THREADED_TEST(SymbolProperties) {
CHECK(sym_obj->IsSymbolObject());
CHECK(!sym2->IsSymbolObject());
CHECK(!obj->IsSymbolObject());
- CHECK(sym_obj->Equals(sym2));
+ CHECK(!sym_obj->Equals(sym2));
CHECK(!sym_obj->StrictEquals(sym2));
CHECK(v8::SymbolObject::Cast(*sym_obj)->Equals(sym_obj));
CHECK(v8::SymbolObject::Cast(*sym_obj)->ValueOf()->Equals(sym2));
@@ -6598,7 +6619,7 @@ static const char* kSimpleExtensionSource =
"}";
-THREADED_TEST(SimpleExtensions) {
+TEST(SimpleExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource));
const char* extension_names[] = { "simpletest" };
@@ -6611,7 +6632,7 @@ THREADED_TEST(SimpleExtensions) {
}
-THREADED_TEST(NullExtensions) {
+TEST(NullExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("nulltest", NULL));
const char* extension_names[] = { "nulltest" };
@@ -6630,7 +6651,7 @@ static const char* kEmbeddedExtensionSource =
static const int kEmbeddedExtensionSourceValidLen = 34;
-THREADED_TEST(ExtensionMissingSourceLength) {
+TEST(ExtensionMissingSourceLength) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("srclentest_fail",
kEmbeddedExtensionSource));
@@ -6642,7 +6663,7 @@ THREADED_TEST(ExtensionMissingSourceLength) {
}
-THREADED_TEST(ExtensionWithSourceLength) {
+TEST(ExtensionWithSourceLength) {
for (int source_len = kEmbeddedExtensionSourceValidLen - 1;
source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) {
v8::HandleScope handle_scope(CcTest::isolate());
@@ -6684,7 +6705,7 @@ static const char* kEvalExtensionSource2 =
"})()";
-THREADED_TEST(UseEvalFromExtension) {
+TEST(UseEvalFromExtension) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("evaltest1", kEvalExtensionSource1));
v8::RegisterExtension(new Extension("evaltest2", kEvalExtensionSource2));
@@ -6718,7 +6739,7 @@ static const char* kWithExtensionSource2 =
"})()";
-THREADED_TEST(UseWithFromExtension) {
+TEST(UseWithFromExtension) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("withtest1", kWithExtensionSource1));
v8::RegisterExtension(new Extension("withtest2", kWithExtensionSource2));
@@ -6734,7 +6755,7 @@ THREADED_TEST(UseWithFromExtension) {
}
-THREADED_TEST(AutoExtensions) {
+TEST(AutoExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
Extension* extension = new Extension("autotest", kSimpleExtensionSource);
extension->set_auto_enable(true);
@@ -6753,7 +6774,7 @@ static const char* kSyntaxErrorInExtensionSource =
// Test that a syntax error in an extension does not cause a fatal
// error but results in an empty context.
-THREADED_TEST(SyntaxErrorExtensions) {
+TEST(SyntaxErrorExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("syntaxerror",
kSyntaxErrorInExtensionSource));
@@ -6771,7 +6792,7 @@ static const char* kExceptionInExtensionSource =
// Test that an exception when installing an extension does not cause
// a fatal error but results in an empty context.
-THREADED_TEST(ExceptionExtensions) {
+TEST(ExceptionExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("exception",
kExceptionInExtensionSource));
@@ -6793,7 +6814,7 @@ static const char* kNativeCallTest =
"call_runtime_last_index_of('bobbobboellebobboellebobbob');";
// Test that a native runtime calls are supported in extensions.
-THREADED_TEST(NativeCallInExtensions) {
+TEST(NativeCallInExtensions) {
v8::HandleScope handle_scope(CcTest::isolate());
v8::RegisterExtension(new Extension("nativecall",
kNativeCallInExtensionSource));
@@ -6829,7 +6850,7 @@ class NativeFunctionExtension : public Extension {
};
-THREADED_TEST(NativeFunctionDeclaration) {
+TEST(NativeFunctionDeclaration) {
v8::HandleScope handle_scope(CcTest::isolate());
const char* name = "nativedecl";
v8::RegisterExtension(new NativeFunctionExtension(name,
@@ -6844,7 +6865,7 @@ THREADED_TEST(NativeFunctionDeclaration) {
}
-THREADED_TEST(NativeFunctionDeclarationError) {
+TEST(NativeFunctionDeclarationError) {
v8::HandleScope handle_scope(CcTest::isolate());
const char* name = "nativedeclerr";
// Syntax error in extension code.
@@ -6858,7 +6879,7 @@ THREADED_TEST(NativeFunctionDeclarationError) {
}
-THREADED_TEST(NativeFunctionDeclarationErrorEscape) {
+TEST(NativeFunctionDeclarationErrorEscape) {
v8::HandleScope handle_scope(CcTest::isolate());
const char* name = "nativedeclerresc";
// Syntax error in extension code - escape code in "native" means that
@@ -7025,28 +7046,6 @@ TEST(ErrorReporting) {
}
-static const char* js_code_causing_huge_string_flattening =
- "var str = 'X';"
- "for (var i = 0; i < 30; i++) {"
- " str = str + str;"
- "}"
- "str.match(/X/);";
-
-
-TEST(RegexpOutOfMemory) {
- // Execute a script that causes out of memory when flattening a string.
- v8::HandleScope scope(CcTest::isolate());
- v8::V8::SetFatalErrorHandler(OOMCallback);
- LocalContext context;
- Local<Script> script = Script::Compile(String::NewFromUtf8(
- CcTest::isolate(), js_code_causing_huge_string_flattening));
- last_location = NULL;
- script->Run();
-
- CHECK(false); // Should not return.
-}
-
-
static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK(message->GetScriptResourceName()->IsUndefined());
@@ -7065,92 +7064,6 @@ THREADED_TEST(ErrorWithMissingScriptInfo) {
}
-int global_index = 0;
-
-template<typename T>
-class Snorkel {
- public:
- explicit Snorkel(v8::Persistent<T>* handle) : handle_(handle) {
- index_ = global_index++;
- }
- v8::Persistent<T>* handle_;
- int index_;
-};
-
-class Whammy {
- public:
- explicit Whammy(v8::Isolate* isolate) : cursor_(0), isolate_(isolate) { }
- ~Whammy() { script_.Reset(); }
- v8::Handle<Script> getScript() {
- if (script_.IsEmpty()) script_.Reset(isolate_, v8_compile("({}).blammo"));
- return Local<Script>::New(isolate_, script_);
- }
-
- public:
- static const int kObjectCount = 256;
- int cursor_;
- v8::Isolate* isolate_;
- v8::Persistent<v8::Object> objects_[kObjectCount];
- v8::Persistent<Script> script_;
-};
-
-static void HandleWeakReference(
- const v8::WeakCallbackData<v8::Value, Snorkel<v8::Value> >& data) {
- data.GetParameter()->handle_->ClearWeak();
- delete data.GetParameter();
-}
-
-void WhammyPropertyGetter(Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
- Whammy* whammy =
- static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value());
-
- v8::Persistent<v8::Object>& prev = whammy->objects_[whammy->cursor_];
-
- v8::Handle<v8::Object> obj = v8::Object::New(info.GetIsolate());
- if (!prev.IsEmpty()) {
- v8::Local<v8::Object>::New(info.GetIsolate(), prev)
- ->Set(v8_str("next"), obj);
- prev.SetWeak<Value, Snorkel<Value> >(new Snorkel<Value>(&prev.As<Value>()),
- &HandleWeakReference);
- }
- whammy->objects_[whammy->cursor_].Reset(info.GetIsolate(), obj);
- whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount;
- info.GetReturnValue().Set(whammy->getScript()->Run());
-}
-
-
-THREADED_TEST(WeakReference) {
- v8::Isolate* isolate = CcTest::isolate();
- v8::HandleScope handle_scope(isolate);
- v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New(isolate);
- Whammy* whammy = new Whammy(CcTest::isolate());
- templ->SetNamedPropertyHandler(WhammyPropertyGetter,
- 0, 0, 0, 0,
- v8::External::New(CcTest::isolate(), whammy));
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- v8::Handle<Context> context =
- Context::New(CcTest::isolate(), &extensions);
- Context::Scope context_scope(context);
-
- v8::Handle<v8::Object> interceptor = templ->NewInstance();
- context->Global()->Set(v8_str("whammy"), interceptor);
- const char* code =
- "var last;"
- "for (var i = 0; i < 10000; i++) {"
- " var obj = whammy.length;"
- " if (last) last.next = obj;"
- " last = obj;"
- "}"
- "gc();"
- "4";
- v8::Handle<Value> result = CompileRun(code);
- CHECK_EQ(4.0, result->NumberValue());
- delete whammy;
-}
-
-
struct FlagAndPersistent {
bool flag;
v8::Persistent<v8::Object> handle;
@@ -7186,14 +7099,14 @@ THREADED_TEST(IndependentWeakHandle) {
object_a.handle.MarkIndependent();
object_b.handle.MarkIndependent();
CHECK(object_b.handle.IsIndependent());
- CcTest::heap()->PerformScavenge();
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
CHECK(object_a.flag);
CHECK(object_b.flag);
}
static void InvokeScavenge() {
- CcTest::heap()->PerformScavenge();
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
}
@@ -7275,7 +7188,7 @@ THREADED_TEST(IndependentHandleRevival) {
object.flag = false;
object.handle.SetWeak(&object, &RevivingCallback);
object.handle.MarkIndependent();
- CcTest::heap()->PerformScavenge();
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
CHECK(object.flag);
CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
{
@@ -7614,6 +7527,22 @@ THREADED_TEST(StringWrite) {
v8::Handle<String> str2 = v8_str("abc\303\260\342\230\203");
v8::Handle<String> str3 = v8::String::NewFromUtf8(
context->GetIsolate(), "abc\0def", v8::String::kNormalString, 7);
+ // "ab" + lead surrogate + "cd" + trail surrogate + "ef"
+ uint16_t orphans[8] = { 0x61, 0x62, 0xd800, 0x63, 0x64, 0xdc00, 0x65, 0x66 };
+ v8::Handle<String> orphans_str = v8::String::NewFromTwoByte(
+ context->GetIsolate(), orphans, v8::String::kNormalString, 8);
+ // single lead surrogate
+ uint16_t lead[1] = { 0xd800 };
+ v8::Handle<String> lead_str = v8::String::NewFromTwoByte(
+ context->GetIsolate(), lead, v8::String::kNormalString, 1);
+ // single trail surrogate
+ uint16_t trail[1] = { 0xdc00 };
+ v8::Handle<String> trail_str = v8::String::NewFromTwoByte(
+ context->GetIsolate(), trail, v8::String::kNormalString, 1);
+ // surrogate pair
+ uint16_t pair[2] = { 0xd800, 0xdc00 };
+ v8::Handle<String> pair_str = v8::String::NewFromTwoByte(
+ context->GetIsolate(), pair, v8::String::kNormalString, 2);
const int kStride = 4; // Must match stride in for loops in JS below.
CompileRun(
"var left = '';"
@@ -7687,6 +7616,53 @@ THREADED_TEST(StringWrite) {
CHECK_EQ(2, charlen);
CHECK_EQ(0, strncmp(utf8buf, "ab\1", 3));
+ // allow orphan surrogates by default
+ memset(utf8buf, 0x1, 1000);
+ len = orphans_str->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen);
+ CHECK_EQ(13, len);
+ CHECK_EQ(8, charlen);
+ CHECK_EQ(0, strcmp(utf8buf, "ab\355\240\200cd\355\260\200ef"));
+
+ // replace orphan surrogates with unicode replacement character
+ memset(utf8buf, 0x1, 1000);
+ len = orphans_str->WriteUtf8(utf8buf,
+ sizeof(utf8buf),
+ &charlen,
+ String::REPLACE_INVALID_UTF8);
+ CHECK_EQ(13, len);
+ CHECK_EQ(8, charlen);
+ CHECK_EQ(0, strcmp(utf8buf, "ab\357\277\275cd\357\277\275ef"));
+
+ // replace single lead surrogate with unicode replacement character
+ memset(utf8buf, 0x1, 1000);
+ len = lead_str->WriteUtf8(utf8buf,
+ sizeof(utf8buf),
+ &charlen,
+ String::REPLACE_INVALID_UTF8);
+ CHECK_EQ(4, len);
+ CHECK_EQ(1, charlen);
+ CHECK_EQ(0, strcmp(utf8buf, "\357\277\275"));
+
+ // replace single trail surrogate with unicode replacement character
+ memset(utf8buf, 0x1, 1000);
+ len = trail_str->WriteUtf8(utf8buf,
+ sizeof(utf8buf),
+ &charlen,
+ String::REPLACE_INVALID_UTF8);
+ CHECK_EQ(4, len);
+ CHECK_EQ(1, charlen);
+ CHECK_EQ(0, strcmp(utf8buf, "\357\277\275"));
+
+ // do not replace / write anything if surrogate pair does not fit the buffer
+ // space
+ memset(utf8buf, 0x1, 1000);
+ len = pair_str->WriteUtf8(utf8buf,
+ 3,
+ &charlen,
+ String::REPLACE_INVALID_UTF8);
+ CHECK_EQ(0, len);
+ CHECK_EQ(0, charlen);
+
memset(utf8buf, 0x1, sizeof(utf8buf));
len = GetUtf8Length(left_tree);
int utf8_expected =
@@ -10589,9 +10565,9 @@ THREADED_TEST(FunctionDescriptorException) {
" (new Fun()).blah()"
" } catch (e) {"
" var str = String(e);"
- " if (str.indexOf('TypeError') == -1) return 1;"
- " if (str.indexOf('[object Fun]') != -1) return 2;"
- " if (str.indexOf('#<Fun>') == -1) return 3;"
+ // " if (str.indexOf('TypeError') == -1) return 1;"
+ // " if (str.indexOf('[object Fun]') != -1) return 2;"
+ // " if (str.indexOf('#<Fun>') == -1) return 3;"
" return 0;"
" }"
" return 4;"
@@ -10866,7 +10842,8 @@ THREADED_TEST(CallAsFunction) {
CHECK(value.IsEmpty());
CHECK(try_catch.HasCaught());
String::Utf8Value exception_value1(try_catch.Exception());
- CHECK_EQ("TypeError: Property 'obj2' of object #<Object> is not a function",
+ // TODO(verwaest): Better message
+ CHECK_EQ("TypeError: object is not a function",
*exception_value1);
try_catch.Reset();
@@ -12249,7 +12226,8 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) {
" }"
"}");
CHECK(try_catch.HasCaught());
- CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"),
+ // TODO(verwaest): Adjust message.
+ CHECK_EQ(v8_str("TypeError: undefined is not a function"),
try_catch.Exception()->ToString());
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
CHECK_GE(interceptor_call_count, 50);
@@ -12423,7 +12401,8 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss2) {
" }"
"}");
CHECK(try_catch.HasCaught());
- CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"),
+ // TODO(verwaest): Adjust message.
+ CHECK_EQ(v8_str("TypeError: undefined is not a function"),
try_catch.Exception()->ToString());
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
}
@@ -13416,6 +13395,7 @@ static void CheckSurvivingGlobalObjectsCount(int expected) {
TEST(DontLeakGlobalObjects) {
// Regression test for issues 1139850 and 1174891.
+ i::FLAG_expose_gc = true;
v8::V8::Initialize();
for (int i = 0; i < 5; i++) {
@@ -14845,6 +14825,7 @@ TEST(PreCompileSerialization) {
delete sd;
delete deserialized_sd;
+ i::DeleteArray(serialized_data);
}
@@ -14893,6 +14874,7 @@ TEST(PreCompileInvalidPreparseDataError) {
*exception_value);
try_catch.Reset();
+ delete sd;
// Overwrite function bar's start position with 200. The function entry
// will not be found when searching for it by position and we should fall
@@ -15133,13 +15115,10 @@ TEST(CompileExternalTwoByteSource) {
// Compile the sources as external two byte strings.
for (int i = 0; ascii_sources[i] != NULL; i++) {
uint16_t* two_byte_string = AsciiToTwoByteString(ascii_sources[i]);
- UC16VectorResource uc16_resource(
- i::Vector<const uint16_t>(two_byte_string,
- i::StrLength(ascii_sources[i])));
+ TestResource* uc16_resource = new TestResource(two_byte_string);
v8::Local<v8::String> source =
- v8::String::NewExternal(context->GetIsolate(), &uc16_resource);
+ v8::String::NewExternal(context->GetIsolate(), uc16_resource);
v8::Script::Compile(source);
- i::DeleteArray(two_byte_string);
}
}
@@ -15211,8 +15190,8 @@ TEST(RegExpInterruption) {
timeout_thread.Join();
- delete regexp_interruption_data.string_resource;
regexp_interruption_data.string.Reset();
+ i::DeleteArray(uc16_content);
}
#endif // V8_INTERPRETED_REGEXP
@@ -15625,10 +15604,10 @@ THREADED_TEST(PixelArray) {
v8::HandleScope scope(context->GetIsolate());
const int kElementCount = 260;
uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
- i::Handle<i::ExternalPixelArray> pixels =
- i::Handle<i::ExternalPixelArray>::cast(
+ i::Handle<i::ExternalUint8ClampedArray> pixels =
+ i::Handle<i::ExternalUint8ClampedArray>::cast(
factory->NewExternalArray(kElementCount,
- v8::kExternalPixelArray,
+ v8::kExternalUint8ClampedArray,
pixel_data));
// Force GC to trigger verification.
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
@@ -16039,10 +16018,10 @@ THREADED_TEST(PixelArrayWithInterceptor) {
v8::HandleScope scope(isolate);
const int kElementCount = 260;
uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
- i::Handle<i::ExternalPixelArray> pixels =
- i::Handle<i::ExternalPixelArray>::cast(
+ i::Handle<i::ExternalUint8ClampedArray> pixels =
+ i::Handle<i::ExternalUint8ClampedArray>::cast(
factory->NewExternalArray(kElementCount,
- v8::kExternalPixelArray,
+ v8::kExternalUint8ClampedArray,
pixel_data));
for (int i = 0; i < kElementCount; i++) {
pixels->set(i, i % 256);
@@ -16070,21 +16049,21 @@ THREADED_TEST(PixelArrayWithInterceptor) {
static int ExternalArrayElementSize(v8::ExternalArrayType array_type) {
switch (array_type) {
- case v8::kExternalByteArray:
- case v8::kExternalUnsignedByteArray:
- case v8::kExternalPixelArray:
+ case v8::kExternalInt8Array:
+ case v8::kExternalUint8Array:
+ case v8::kExternalUint8ClampedArray:
return 1;
break;
- case v8::kExternalShortArray:
- case v8::kExternalUnsignedShortArray:
+ case v8::kExternalInt16Array:
+ case v8::kExternalUint16Array:
return 2;
break;
- case v8::kExternalIntArray:
- case v8::kExternalUnsignedIntArray:
- case v8::kExternalFloatArray:
+ case v8::kExternalInt32Array:
+ case v8::kExternalUint32Array:
+ case v8::kExternalFloat32Array:
return 4;
break;
- case v8::kExternalDoubleArray:
+ case v8::kExternalFloat64Array:
return 8;
break;
default:
@@ -16246,8 +16225,8 @@ static void ObjectWithExternalArrayTestHelper(
"}"
"ext_array[7];");
CHECK_EQ(0, result->Int32Value());
- if (array_type == v8::kExternalDoubleArray ||
- array_type == v8::kExternalFloatArray) {
+ if (array_type == v8::kExternalFloat64Array ||
+ array_type == v8::kExternalFloat32Array) {
CHECK_EQ(static_cast<int>(i::OS::nan_value()),
static_cast<int>(
jsobj->GetElement(isolate, 7)->ToObjectChecked()->Number()));
@@ -16264,8 +16243,8 @@ static void ObjectWithExternalArrayTestHelper(
static_cast<int>(
jsobj->GetElement(isolate, 6)->ToObjectChecked()->Number()));
- if (array_type != v8::kExternalFloatArray &&
- array_type != v8::kExternalDoubleArray) {
+ if (array_type != v8::kExternalFloat32Array &&
+ array_type != v8::kExternalFloat64Array) {
// Though the specification doesn't state it, be explicit about
// converting NaNs and +/-Infinity to zero.
result = CompileRun("for (var i = 0; i < 8; i++) {"
@@ -16286,7 +16265,7 @@ static void ObjectWithExternalArrayTestHelper(
"}"
"ext_array[5];");
int expected_value =
- (array_type == v8::kExternalPixelArray) ? 255 : 0;
+ (array_type == v8::kExternalUint8ClampedArray) ? 255 : 0;
CHECK_EQ(expected_value, result->Int32Value());
CheckElementValue(isolate, expected_value, jsobj, 5);
@@ -16311,10 +16290,10 @@ static void ObjectWithExternalArrayTestHelper(
"var source_data = [0.6, 10.6];"
"var expected_results = [1, 11];";
bool is_unsigned =
- (array_type == v8::kExternalUnsignedByteArray ||
- array_type == v8::kExternalUnsignedShortArray ||
- array_type == v8::kExternalUnsignedIntArray);
- bool is_pixel_data = array_type == v8::kExternalPixelArray;
+ (array_type == v8::kExternalUint8Array ||
+ array_type == v8::kExternalUint16Array ||
+ array_type == v8::kExternalUint32Array);
+ bool is_pixel_data = array_type == v8::kExternalUint8ClampedArray;
i::OS::SNPrintF(test_buf,
"%s"
@@ -16444,7 +16423,7 @@ static void FixedTypedArrayTestHelper(
THREADED_TEST(FixedUint8Array) {
FixedTypedArrayTestHelper<i::FixedUint8Array, i::UINT8_ELEMENTS, uint8_t>(
- v8::kExternalUnsignedByteArray,
+ v8::kExternalUint8Array,
0x0, 0xFF);
}
@@ -16452,56 +16431,56 @@ THREADED_TEST(FixedUint8Array) {
THREADED_TEST(FixedUint8ClampedArray) {
FixedTypedArrayTestHelper<i::FixedUint8ClampedArray,
i::UINT8_CLAMPED_ELEMENTS, uint8_t>(
- v8::kExternalPixelArray,
+ v8::kExternalUint8ClampedArray,
0x0, 0xFF);
}
THREADED_TEST(FixedInt8Array) {
FixedTypedArrayTestHelper<i::FixedInt8Array, i::INT8_ELEMENTS, int8_t>(
- v8::kExternalByteArray,
+ v8::kExternalInt8Array,
-0x80, 0x7F);
}
THREADED_TEST(FixedUint16Array) {
FixedTypedArrayTestHelper<i::FixedUint16Array, i::UINT16_ELEMENTS, uint16_t>(
- v8::kExternalUnsignedShortArray,
+ v8::kExternalUint16Array,
0x0, 0xFFFF);
}
THREADED_TEST(FixedInt16Array) {
FixedTypedArrayTestHelper<i::FixedInt16Array, i::INT16_ELEMENTS, int16_t>(
- v8::kExternalShortArray,
+ v8::kExternalInt16Array,
-0x8000, 0x7FFF);
}
THREADED_TEST(FixedUint32Array) {
FixedTypedArrayTestHelper<i::FixedUint32Array, i::UINT32_ELEMENTS, uint32_t>(
- v8::kExternalUnsignedIntArray,
+ v8::kExternalUint32Array,
0x0, UINT_MAX);
}
THREADED_TEST(FixedInt32Array) {
FixedTypedArrayTestHelper<i::FixedInt32Array, i::INT32_ELEMENTS, int32_t>(
- v8::kExternalIntArray,
+ v8::kExternalInt32Array,
INT_MIN, INT_MAX);
}
THREADED_TEST(FixedFloat32Array) {
FixedTypedArrayTestHelper<i::FixedFloat32Array, i::FLOAT32_ELEMENTS, float>(
- v8::kExternalFloatArray,
+ v8::kExternalFloat32Array,
-500, 500);
}
THREADED_TEST(FixedFloat64Array) {
FixedTypedArrayTestHelper<i::FixedFloat64Array, i::FLOAT64_ELEMENTS, float>(
- v8::kExternalDoubleArray,
+ v8::kExternalFloat64Array,
-500, 500);
}
@@ -16723,86 +16702,86 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
}
-THREADED_TEST(ExternalByteArray) {
- ExternalArrayTestHelper<i::ExternalByteArray, int8_t>(
- v8::kExternalByteArray,
+THREADED_TEST(ExternalInt8Array) {
+ ExternalArrayTestHelper<i::ExternalInt8Array, int8_t>(
+ v8::kExternalInt8Array,
-128,
127);
}
-THREADED_TEST(ExternalUnsignedByteArray) {
- ExternalArrayTestHelper<i::ExternalUnsignedByteArray, uint8_t>(
- v8::kExternalUnsignedByteArray,
+THREADED_TEST(ExternalUint8Array) {
+ ExternalArrayTestHelper<i::ExternalUint8Array, uint8_t>(
+ v8::kExternalUint8Array,
0,
255);
}
-THREADED_TEST(ExternalPixelArray) {
- ExternalArrayTestHelper<i::ExternalPixelArray, uint8_t>(
- v8::kExternalPixelArray,
+THREADED_TEST(ExternalUint8ClampedArray) {
+ ExternalArrayTestHelper<i::ExternalUint8ClampedArray, uint8_t>(
+ v8::kExternalUint8ClampedArray,
0,
255);
}
-THREADED_TEST(ExternalShortArray) {
- ExternalArrayTestHelper<i::ExternalShortArray, int16_t>(
- v8::kExternalShortArray,
+THREADED_TEST(ExternalInt16Array) {
+ ExternalArrayTestHelper<i::ExternalInt16Array, int16_t>(
+ v8::kExternalInt16Array,
-32768,
32767);
}
-THREADED_TEST(ExternalUnsignedShortArray) {
- ExternalArrayTestHelper<i::ExternalUnsignedShortArray, uint16_t>(
- v8::kExternalUnsignedShortArray,
+THREADED_TEST(ExternalUint16Array) {
+ ExternalArrayTestHelper<i::ExternalUint16Array, uint16_t>(
+ v8::kExternalUint16Array,
0,
65535);
}
-THREADED_TEST(ExternalIntArray) {
- ExternalArrayTestHelper<i::ExternalIntArray, int32_t>(
- v8::kExternalIntArray,
+THREADED_TEST(ExternalInt32Array) {
+ ExternalArrayTestHelper<i::ExternalInt32Array, int32_t>(
+ v8::kExternalInt32Array,
INT_MIN, // -2147483648
INT_MAX); // 2147483647
}
-THREADED_TEST(ExternalUnsignedIntArray) {
- ExternalArrayTestHelper<i::ExternalUnsignedIntArray, uint32_t>(
- v8::kExternalUnsignedIntArray,
+THREADED_TEST(ExternalUint32Array) {
+ ExternalArrayTestHelper<i::ExternalUint32Array, uint32_t>(
+ v8::kExternalUint32Array,
0,
UINT_MAX); // 4294967295
}
-THREADED_TEST(ExternalFloatArray) {
- ExternalArrayTestHelper<i::ExternalFloatArray, float>(
- v8::kExternalFloatArray,
+THREADED_TEST(ExternalFloat32Array) {
+ ExternalArrayTestHelper<i::ExternalFloat32Array, float>(
+ v8::kExternalFloat32Array,
-500,
500);
}
-THREADED_TEST(ExternalDoubleArray) {
- ExternalArrayTestHelper<i::ExternalDoubleArray, double>(
- v8::kExternalDoubleArray,
+THREADED_TEST(ExternalFloat64Array) {
+ ExternalArrayTestHelper<i::ExternalFloat64Array, double>(
+ v8::kExternalFloat64Array,
-500,
500);
}
THREADED_TEST(ExternalArrays) {
- TestExternalByteArray();
- TestExternalUnsignedByteArray();
- TestExternalShortArray();
- TestExternalUnsignedShortArray();
- TestExternalIntArray();
- TestExternalUnsignedIntArray();
- TestExternalFloatArray();
+ TestExternalInt8Array();
+ TestExternalUint8Array();
+ TestExternalInt16Array();
+ TestExternalUint16Array();
+ TestExternalInt32Array();
+ TestExternalUint32Array();
+ TestExternalFloat32Array();
}
@@ -16825,15 +16804,15 @@ void ExternalArrayInfoTestHelper(v8::ExternalArrayType array_type) {
THREADED_TEST(ExternalArrayInfo) {
- ExternalArrayInfoTestHelper(v8::kExternalByteArray);
- ExternalArrayInfoTestHelper(v8::kExternalUnsignedByteArray);
- ExternalArrayInfoTestHelper(v8::kExternalShortArray);
- ExternalArrayInfoTestHelper(v8::kExternalUnsignedShortArray);
- ExternalArrayInfoTestHelper(v8::kExternalIntArray);
- ExternalArrayInfoTestHelper(v8::kExternalUnsignedIntArray);
- ExternalArrayInfoTestHelper(v8::kExternalFloatArray);
- ExternalArrayInfoTestHelper(v8::kExternalDoubleArray);
- ExternalArrayInfoTestHelper(v8::kExternalPixelArray);
+ ExternalArrayInfoTestHelper(v8::kExternalInt8Array);
+ ExternalArrayInfoTestHelper(v8::kExternalUint8Array);
+ ExternalArrayInfoTestHelper(v8::kExternalInt16Array);
+ ExternalArrayInfoTestHelper(v8::kExternalUint16Array);
+ ExternalArrayInfoTestHelper(v8::kExternalInt32Array);
+ ExternalArrayInfoTestHelper(v8::kExternalUint32Array);
+ ExternalArrayInfoTestHelper(v8::kExternalFloat32Array);
+ ExternalArrayInfoTestHelper(v8::kExternalFloat64Array);
+ ExternalArrayInfoTestHelper(v8::kExternalUint8ClampedArray);
}
@@ -16854,24 +16833,24 @@ TEST(ExternalArrayLimits) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- ExtArrayLimitsHelper(isolate, v8::kExternalByteArray, 0x40000000);
- ExtArrayLimitsHelper(isolate, v8::kExternalByteArray, 0xffffffff);
- ExtArrayLimitsHelper(isolate, v8::kExternalUnsignedByteArray, 0x40000000);
- ExtArrayLimitsHelper(isolate, v8::kExternalUnsignedByteArray, 0xffffffff);
- ExtArrayLimitsHelper(isolate, v8::kExternalShortArray, 0x40000000);
- ExtArrayLimitsHelper(isolate, v8::kExternalShortArray, 0xffffffff);
- ExtArrayLimitsHelper(isolate, v8::kExternalUnsignedShortArray, 0x40000000);
- ExtArrayLimitsHelper(isolate, v8::kExternalUnsignedShortArray, 0xffffffff);
- ExtArrayLimitsHelper(isolate, v8::kExternalIntArray, 0x40000000);
- ExtArrayLimitsHelper(isolate, v8::kExternalIntArray, 0xffffffff);
- ExtArrayLimitsHelper(isolate, v8::kExternalUnsignedIntArray, 0x40000000);
- ExtArrayLimitsHelper(isolate, v8::kExternalUnsignedIntArray, 0xffffffff);
- ExtArrayLimitsHelper(isolate, v8::kExternalFloatArray, 0x40000000);
- ExtArrayLimitsHelper(isolate, v8::kExternalFloatArray, 0xffffffff);
- ExtArrayLimitsHelper(isolate, v8::kExternalDoubleArray, 0x40000000);
- ExtArrayLimitsHelper(isolate, v8::kExternalDoubleArray, 0xffffffff);
- ExtArrayLimitsHelper(isolate, v8::kExternalPixelArray, 0x40000000);
- ExtArrayLimitsHelper(isolate, v8::kExternalPixelArray, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalInt8Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalInt8Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint8Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint8Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalInt16Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalInt16Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint16Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint16Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalInt32Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalInt32Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint32Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint32Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalFloat32Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalFloat32Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalFloat64Array, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalFloat64Array, 0xffffffff);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint8ClampedArray, 0x40000000);
+ ExtArrayLimitsHelper(isolate, v8::kExternalUint8ClampedArray, 0xffffffff);
}
@@ -16910,58 +16889,59 @@ void TypedArrayTestHelper(v8::ExternalArrayType array_type,
THREADED_TEST(Uint8Array) {
- TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUnsignedByteArray>(
- v8::kExternalUnsignedByteArray, 0, 0xFF);
+ TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUint8Array>(
+ v8::kExternalUint8Array, 0, 0xFF);
}
THREADED_TEST(Int8Array) {
- TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalByteArray>(
- v8::kExternalByteArray, -0x80, 0x7F);
+ TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalInt8Array>(
+ v8::kExternalInt8Array, -0x80, 0x7F);
}
THREADED_TEST(Uint16Array) {
TypedArrayTestHelper<uint16_t,
v8::Uint16Array,
- i::ExternalUnsignedShortArray>(
- v8::kExternalUnsignedShortArray, 0, 0xFFFF);
+ i::ExternalUint16Array>(
+ v8::kExternalUint16Array, 0, 0xFFFF);
}
THREADED_TEST(Int16Array) {
- TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalShortArray>(
- v8::kExternalShortArray, -0x8000, 0x7FFF);
+ TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalInt16Array>(
+ v8::kExternalInt16Array, -0x8000, 0x7FFF);
}
THREADED_TEST(Uint32Array) {
- TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUnsignedIntArray>(
- v8::kExternalUnsignedIntArray, 0, UINT_MAX);
+ TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUint32Array>(
+ v8::kExternalUint32Array, 0, UINT_MAX);
}
THREADED_TEST(Int32Array) {
- TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalIntArray>(
- v8::kExternalIntArray, INT_MIN, INT_MAX);
+ TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalInt32Array>(
+ v8::kExternalInt32Array, INT_MIN, INT_MAX);
}
THREADED_TEST(Float32Array) {
- TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloatArray>(
- v8::kExternalFloatArray, -500, 500);
+ TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloat32Array>(
+ v8::kExternalFloat32Array, -500, 500);
}
THREADED_TEST(Float64Array) {
- TypedArrayTestHelper<double, v8::Float64Array, i::ExternalDoubleArray>(
- v8::kExternalDoubleArray, -500, 500);
+ TypedArrayTestHelper<double, v8::Float64Array, i::ExternalFloat64Array>(
+ v8::kExternalFloat64Array, -500, 500);
}
THREADED_TEST(Uint8ClampedArray) {
- TypedArrayTestHelper<uint8_t, v8::Uint8ClampedArray, i::ExternalPixelArray>(
- v8::kExternalPixelArray, 0, 0xFF);
+ TypedArrayTestHelper<uint8_t,
+ v8::Uint8ClampedArray, i::ExternalUint8ClampedArray>(
+ v8::kExternalUint8ClampedArray, 0, 0xFF);
}
@@ -17540,6 +17520,29 @@ TEST(DynamicWithSourceURLInStackTrace) {
}
+TEST(DynamicWithSourceURLInStackTraceString) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+
+ const char *source =
+ "function outer() {\n"
+ " function foo() {\n"
+ " FAIL.FAIL;\n"
+ " }\n"
+ " foo();\n"
+ "}\n"
+ "outer()\n%s";
+
+ i::ScopedVector<char> code(1024);
+ i::OS::SNPrintF(code, source, "//# sourceURL=source_url");
+ v8::TryCatch try_catch;
+ CompileRunWithOrigin(code.start(), "", 0, 0);
+ CHECK(try_catch.HasCaught());
+ v8::String::Utf8Value stack(try_catch.StackTrace());
+ CHECK(strstr(*stack, "at foo (source_url:3:5)") != NULL);
+}
+
+
static void CreateGarbageInOldSpace() {
i::Factory* factory = CcTest::i_isolate()->factory();
v8::HandleScope scope(CcTest::isolate());
@@ -17647,7 +17650,7 @@ TEST(Regress2107) {
TEST(Regress2333) {
LocalContext env;
for (int i = 0; i < 3; i++) {
- CcTest::heap()->PerformScavenge();
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
}
}
@@ -17776,6 +17779,50 @@ class VisitorImpl : public v8::ExternalResourceVisitor {
};
+TEST(ExternalizeOldSpaceTwoByteCons) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::Local<v8::String> cons =
+ CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString();
+ CHECK(v8::Utils::OpenHandle(*cons)->IsConsString());
+ CcTest::heap()->CollectAllAvailableGarbage();
+ CHECK(CcTest::heap()->old_pointer_space()->Contains(
+ *v8::Utils::OpenHandle(*cons)));
+
+ TestResource* resource = new TestResource(
+ AsciiToTwoByteString("Romeo Montague Juliet Capulet"));
+ cons->MakeExternal(resource);
+
+ CHECK(cons->IsExternal());
+ CHECK_EQ(resource, cons->GetExternalStringResource());
+ String::Encoding encoding;
+ CHECK_EQ(resource, cons->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::TWO_BYTE_ENCODING, encoding);
+}
+
+
+TEST(ExternalizeOldSpaceOneByteCons) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::Local<v8::String> cons =
+ CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString();
+ CHECK(v8::Utils::OpenHandle(*cons)->IsConsString());
+ CcTest::heap()->CollectAllAvailableGarbage();
+ CHECK(CcTest::heap()->old_pointer_space()->Contains(
+ *v8::Utils::OpenHandle(*cons)));
+
+ TestAsciiResource* resource =
+ new TestAsciiResource(i::StrDup("Romeo Montague Juliet Capulet"));
+ cons->MakeExternal(resource);
+
+ CHECK(cons->IsExternalAscii());
+ CHECK_EQ(resource, cons->GetExternalAsciiStringResource());
+ String::Encoding encoding;
+ CHECK_EQ(resource, cons->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::ONE_BYTE_ENCODING, encoding);
+}
+
+
TEST(VisitExternalStrings) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -17785,12 +17832,12 @@ TEST(VisitExternalStrings) {
resource[0] = new TestResource(two_byte_string);
v8::Local<v8::String> string0 =
v8::String::NewExternal(env->GetIsolate(), resource[0]);
- resource[1] = new TestResource(two_byte_string);
+ resource[1] = new TestResource(two_byte_string, NULL, false);
v8::Local<v8::String> string1 =
v8::String::NewExternal(env->GetIsolate(), resource[1]);
// Externalized symbol.
- resource[2] = new TestResource(two_byte_string);
+ resource[2] = new TestResource(two_byte_string, NULL, false);
v8::Local<v8::String> string2 = v8::String::NewFromUtf8(
env->GetIsolate(), string, v8::String::kInternalizedString);
CHECK(string2->MakeExternal(resource[2]));
@@ -18866,8 +18913,9 @@ TEST(ContainsOnlyOneByte) {
}
string_contents[length-1] = 0;
// Simple case.
- Handle<String> string;
- string = String::NewExternal(isolate, new TestResource(string_contents));
+ Handle<String> string =
+ String::NewExternal(isolate,
+ new TestResource(string_contents, NULL, false));
CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte());
// Counter example.
string = String::NewFromTwoByte(isolate, string_contents);
@@ -18884,7 +18932,9 @@ TEST(ContainsOnlyOneByte) {
balanced = String::Concat(balanced, right);
Handle<String> cons_strings[] = {left, balanced, right};
Handle<String> two_byte =
- String::NewExternal(isolate, new TestResource(string_contents));
+ String::NewExternal(isolate,
+ new TestResource(string_contents, NULL, false));
+ USE(two_byte); USE(cons_strings);
for (size_t i = 0; i < ARRAY_SIZE(cons_strings); i++) {
// Base assumptions.
string = cons_strings[i];
@@ -18905,7 +18955,8 @@ TEST(ContainsOnlyOneByte) {
int shift = 8 + (i % 7);
string_contents[alignment + i] = 1 << shift;
string = String::NewExternal(
- isolate, new TestResource(string_contents + alignment));
+ isolate,
+ new TestResource(string_contents + alignment, NULL, false));
CHECK_EQ(size, string->Length());
CHECK(!string->ContainsOnlyOneByte());
string_contents[alignment + i] = 0x41;
@@ -19022,18 +19073,20 @@ TEST(IsolateNewDispose) {
UNINITIALIZED_TEST(DisposeIsolateWhenInUse) {
v8::Isolate* isolate = v8::Isolate::New();
- CHECK(isolate);
- isolate->Enter();
- v8::HandleScope scope(isolate);
- LocalContext context(isolate);
- // Run something in this isolate.
- ExpectTrue("true");
- v8::V8::SetFatalErrorHandler(StoringErrorCallback);
- last_location = last_message = NULL;
- // Still entered, should fail.
+ {
+ v8::Isolate::Scope i_scope(isolate);
+ v8::HandleScope scope(isolate);
+ LocalContext context(isolate);
+ // Run something in this isolate.
+ ExpectTrue("true");
+ v8::V8::SetFatalErrorHandler(StoringErrorCallback);
+ last_location = last_message = NULL;
+ // Still entered, should fail.
+ isolate->Dispose();
+ CHECK_NE(last_location, NULL);
+ CHECK_NE(last_message, NULL);
+ }
isolate->Dispose();
- CHECK_NE(last_location, NULL);
- CHECK_NE(last_message, NULL);
}
@@ -19248,6 +19301,7 @@ TEST(IsolateDifferentContexts) {
CHECK(v->IsNumber());
CHECK_EQ(22, static_cast<int>(v->NumberValue()));
}
+ isolate->Dispose();
}
class InitDefaultIsolateThread : public v8::internal::Thread {
@@ -20460,6 +20514,102 @@ TEST(CallCompletedCallbackTwoExceptions) {
}
+static void MicrotaskOne(const v8::FunctionCallbackInfo<Value>& info) {
+ v8::HandleScope scope(info.GetIsolate());
+ CompileRun("ext1Calls++;");
+}
+
+
+static void MicrotaskTwo(const v8::FunctionCallbackInfo<Value>& info) {
+ v8::HandleScope scope(info.GetIsolate());
+ CompileRun("ext2Calls++;");
+}
+
+
+TEST(EnqueueMicrotask) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ CompileRun(
+ "var ext1Calls = 0;"
+ "var ext2Calls = 0;");
+ CompileRun("1+1;");
+ CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());
+
+ v8::V8::EnqueueMicrotask(env->GetIsolate(),
+ Function::New(env->GetIsolate(), MicrotaskOne));
+ CompileRun("1+1;");
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());
+
+ v8::V8::EnqueueMicrotask(env->GetIsolate(),
+ Function::New(env->GetIsolate(), MicrotaskOne));
+ v8::V8::EnqueueMicrotask(env->GetIsolate(),
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ CompileRun("1+1;");
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value());
+
+ v8::V8::EnqueueMicrotask(env->GetIsolate(),
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ CompileRun("1+1;");
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value());
+
+ CompileRun("1+1;");
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value());
+}
+
+
+TEST(SetAutorunMicrotasks) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ CompileRun(
+ "var ext1Calls = 0;"
+ "var ext2Calls = 0;");
+ CompileRun("1+1;");
+ CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());
+
+ v8::V8::EnqueueMicrotask(env->GetIsolate(),
+ Function::New(env->GetIsolate(), MicrotaskOne));
+ CompileRun("1+1;");
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());
+
+ V8::SetAutorunMicrotasks(env->GetIsolate(), false);
+ v8::V8::EnqueueMicrotask(env->GetIsolate(),
+ Function::New(env->GetIsolate(), MicrotaskOne));
+ v8::V8::EnqueueMicrotask(env->GetIsolate(),
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ CompileRun("1+1;");
+ CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value());
+
+ V8::RunMicrotasks(env->GetIsolate());
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value());
+
+ v8::V8::EnqueueMicrotask(env->GetIsolate(),
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ CompileRun("1+1;");
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value());
+
+ V8::RunMicrotasks(env->GetIsolate());
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value());
+
+ V8::SetAutorunMicrotasks(env->GetIsolate(), true);
+ v8::V8::EnqueueMicrotask(env->GetIsolate(),
+ Function::New(env->GetIsolate(), MicrotaskTwo));
+ CompileRun("1+1;");
+ CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value());
+ CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value());
+}
+
+
static int probes_counter = 0;
static int misses_counter = 0;
static int updates_counter = 0;
@@ -20513,7 +20663,11 @@ static void StubCacheHelper(bool primary) {
int updates = updates_counter - initial_updates;
CHECK_LT(updates, 10);
CHECK_LT(misses, 10);
- CHECK_GE(probes, 10000);
+ // TODO(verwaest): Update this test to overflow the degree of polymorphism
+ // before megamorphism. The number of probes will only work once we teach the
+ // serializer to embed references to counters in the stubs, given that the
+ // megamorphic_stub_cache_probes is updated in a snapshot-generated stub.
+ CHECK_GE(probes, 0);
#endif
}
@@ -21759,3 +21913,206 @@ TEST(Regress239669) {
" new C1();"
"}");
}
+
+
+class ApiCallOptimizationChecker {
+ private:
+ static Local<Object> data;
+ static Local<Object> receiver;
+ static Local<Object> holder;
+ static Local<Object> callee;
+ static int count;
+
+ static void OptimizationCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ CHECK(callee == info.Callee());
+ CHECK(data == info.Data());
+ CHECK(receiver == info.This());
+ if (info.Length() == 1) {
+ CHECK_EQ(v8_num(1), info[0]);
+ }
+ CHECK(holder == info.Holder());
+ count++;
+ info.GetReturnValue().Set(v8_str("returned"));
+ }
+
+ // TODO(dcarney): move this to v8.h
+ static void SetAccessorProperty(Local<Object> object,
+ Local<String> name,
+ Local<Function> getter,
+ Local<Function> setter = Local<Function>()) {
+ i::Isolate* isolate = CcTest::i_isolate();
+ v8::AccessControl settings = v8::DEFAULT;
+ v8::PropertyAttribute attribute = v8::None;
+ i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
+ i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
+ if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
+ i::JSObject::DefineAccessor(v8::Utils::OpenHandle(*object),
+ v8::Utils::OpenHandle(*name),
+ getter_i,
+ setter_i,
+ static_cast<PropertyAttributes>(attribute),
+ settings);
+ }
+
+ public:
+ enum SignatureType {
+ kNoSignature,
+ kSignatureOnReceiver,
+ kSignatureOnPrototype
+ };
+
+ void RunAll() {
+ SignatureType signature_types[] =
+ {kNoSignature, kSignatureOnReceiver, kSignatureOnPrototype};
+ for (unsigned i = 0; i < ARRAY_SIZE(signature_types); i++) {
+ SignatureType signature_type = signature_types[i];
+ for (int j = 0; j < 2; j++) {
+ bool global = j == 0;
+ int key = signature_type +
+ ARRAY_SIZE(signature_types) * (global ? 1 : 0);
+ Run(signature_type, global, key);
+ }
+ }
+ }
+
+ void Run(SignatureType signature_type, bool global, int key) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ // Build a template for signature checks.
+ Local<v8::ObjectTemplate> signature_template;
+ Local<v8::Signature> signature;
+ {
+ Local<v8::FunctionTemplate> parent_template =
+ FunctionTemplate::New(isolate);
+ parent_template->SetHiddenPrototype(true);
+ Local<v8::FunctionTemplate> function_template
+ = FunctionTemplate::New(isolate);
+ function_template->Inherit(parent_template);
+ switch (signature_type) {
+ case kNoSignature:
+ break;
+ case kSignatureOnReceiver:
+ signature = v8::Signature::New(isolate, function_template);
+ break;
+ case kSignatureOnPrototype:
+ signature = v8::Signature::New(isolate, parent_template);
+ break;
+ }
+ signature_template = function_template->InstanceTemplate();
+ }
+ // Global object must pass checks.
+ Local<v8::Context> context =
+ v8::Context::New(isolate, NULL, signature_template);
+ v8::Context::Scope context_scope(context);
+ // Install regular object that can pass signature checks.
+ Local<Object> function_receiver = signature_template->NewInstance();
+ context->Global()->Set(v8_str("function_receiver"), function_receiver);
+ // Get the holder objects.
+ Local<Object> inner_global =
+ Local<Object>::Cast(context->Global()->GetPrototype());
+ // Install functions on hidden prototype object if there is one.
+ data = Object::New(isolate);
+ Local<FunctionTemplate> function_template = FunctionTemplate::New(
+ isolate, OptimizationCallback, data, signature);
+ Local<Function> function = function_template->GetFunction();
+ Local<Object> global_holder = inner_global;
+ Local<Object> function_holder = function_receiver;
+ if (signature_type == kSignatureOnPrototype) {
+ function_holder = Local<Object>::Cast(function_holder->GetPrototype());
+ global_holder = Local<Object>::Cast(global_holder->GetPrototype());
+ }
+ global_holder->Set(v8_str("g_f"), function);
+ SetAccessorProperty(global_holder, v8_str("g_acc"), function, function);
+ function_holder->Set(v8_str("f"), function);
+ SetAccessorProperty(function_holder, v8_str("acc"), function, function);
+ // Initialize expected values.
+ callee = function;
+ count = 0;
+ if (global) {
+ receiver = context->Global();
+ holder = inner_global;
+ } else {
+ holder = function_receiver;
+ // If not using a signature, add something else to the prototype chain
+ // to test the case that holder != receiver
+ if (signature_type == kNoSignature) {
+ receiver = Local<Object>::Cast(CompileRun(
+ "var receiver_subclass = {};\n"
+ "receiver_subclass.__proto__ = function_receiver;\n"
+ "receiver_subclass"));
+ } else {
+ receiver = Local<Object>::Cast(CompileRun(
+ "var receiver_subclass = function_receiver;\n"
+ "receiver_subclass"));
+ }
+ }
+ // With no signature, the holder is not set.
+ if (signature_type == kNoSignature) holder = receiver;
+ // build wrap_function
+ i::ScopedVector<char> wrap_function(200);
+ if (global) {
+ i::OS::SNPrintF(
+ wrap_function,
+ "function wrap_f_%d() { var f = g_f; return f(); }\n"
+ "function wrap_get_%d() { return this.g_acc; }\n"
+ "function wrap_set_%d() { return this.g_acc = 1; }\n",
+ key, key, key);
+ } else {
+ i::OS::SNPrintF(
+ wrap_function,
+ "function wrap_f_%d() { return receiver_subclass.f(); }\n"
+ "function wrap_get_%d() { return receiver_subclass.acc; }\n"
+ "function wrap_set_%d() { return receiver_subclass.acc = 1; }\n",
+ key, key, key);
+ }
+ // build source string
+ i::ScopedVector<char> source(1000);
+ i::OS::SNPrintF(
+ source,
+ "%s\n" // wrap functions
+ "function wrap_f() { return wrap_f_%d(); }\n"
+ "function wrap_get() { return wrap_get_%d(); }\n"
+ "function wrap_set() { return wrap_set_%d(); }\n"
+ "check = function(returned) {\n"
+ " if (returned !== 'returned') { throw returned; }\n"
+ "}\n"
+ "\n"
+ "check(wrap_f());\n"
+ "check(wrap_f());\n"
+ "%%OptimizeFunctionOnNextCall(wrap_f_%d);\n"
+ "check(wrap_f());\n"
+ "\n"
+ "check(wrap_get());\n"
+ "check(wrap_get());\n"
+ "%%OptimizeFunctionOnNextCall(wrap_get_%d);\n"
+ "check(wrap_get());\n"
+ "\n"
+ "check = function(returned) {\n"
+ " if (returned !== 1) { throw returned; }\n"
+ "}\n"
+ "check(wrap_set());\n"
+ "check(wrap_set());\n"
+ "%%OptimizeFunctionOnNextCall(wrap_set_%d);\n"
+ "check(wrap_set());\n",
+ wrap_function.start(), key, key, key, key, key, key);
+ v8::TryCatch try_catch;
+ CompileRun(source.start());
+ ASSERT(!try_catch.HasCaught());
+ CHECK_EQ(9, count);
+ }
+};
+
+
+Local<Object> ApiCallOptimizationChecker::data;
+Local<Object> ApiCallOptimizationChecker::receiver;
+Local<Object> ApiCallOptimizationChecker::holder;
+Local<Object> ApiCallOptimizationChecker::callee;
+int ApiCallOptimizationChecker::count = 0;
+
+
+TEST(TestFunctionCallOptimization) {
+ i::FLAG_allow_natives_syntax = true;
+ ApiCallOptimizationChecker checker;
+ checker.RunAll();
+}
« no previous file with comments | « test/cctest/test-alloc.cc ('k') | test/cctest/test-assembler-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698