aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-api.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest/test-api.cc')
-rw-r--r--deps/v8/test/cctest/test-api.cc798
1 files changed, 613 insertions, 185 deletions
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index 484d2f3226..8317a06aa2 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -47,7 +47,7 @@
#include "src/execution.h"
#include "src/futex-emulation.h"
#include "src/objects.h"
-#include "src/parsing/parser.h"
+#include "src/parsing/preparse-data.h"
#include "src/profiler/cpu-profiler.h"
#include "src/unicode-inl.h"
#include "src/utils.h"
@@ -453,11 +453,11 @@ THREADED_TEST(ScriptUsingStringResource) {
CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource),
source->GetExternalStringResourceBase(&encoding));
CHECK_EQ(String::TWO_BYTE_ENCODING, encoding);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(0, dispose_count);
}
CcTest::i_isolate()->compilation_cache()->Clear();
- CcTest::heap()->CollectAllAvailableGarbage();
+ CcTest::CollectAllAvailableGarbage();
CHECK_EQ(1, dispose_count);
}
@@ -484,11 +484,11 @@ THREADED_TEST(ScriptUsingOneByteStringResource) {
Local<Value> value = script->Run(env.local()).ToLocalChecked();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value(env.local()).FromJust());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(0, dispose_count);
}
CcTest::i_isolate()->compilation_cache()->Clear();
- CcTest::heap()->CollectAllAvailableGarbage();
+ CcTest::CollectAllAvailableGarbage();
CHECK_EQ(1, dispose_count);
}
@@ -504,8 +504,8 @@ THREADED_TEST(ScriptMakingExternalString) {
v8::NewStringType::kNormal)
.ToLocalChecked();
// Trigger GCs so that the newly allocated string moves to old gen.
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in survivor space now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now
CHECK_EQ(source->IsExternal(), false);
CHECK_EQ(source->IsExternalOneByte(), false);
String::Encoding encoding = String::UNKNOWN_ENCODING;
@@ -518,11 +518,11 @@ THREADED_TEST(ScriptMakingExternalString) {
Local<Value> value = script->Run(env.local()).ToLocalChecked();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value(env.local()).FromJust());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(0, dispose_count);
}
CcTest::i_isolate()->compilation_cache()->Clear();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(1, dispose_count);
}
@@ -535,8 +535,8 @@ THREADED_TEST(ScriptMakingExternalOneByteString) {
v8::HandleScope scope(env->GetIsolate());
Local<String> source = v8_str(c_source);
// Trigger GCs so that the newly allocated string moves to old gen.
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in survivor space now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now
bool success = source->MakeExternal(
new TestOneByteResource(i::StrDup(c_source), &dispose_count));
CHECK(success);
@@ -544,11 +544,11 @@ THREADED_TEST(ScriptMakingExternalOneByteString) {
Local<Value> value = script->Run(env.local()).ToLocalChecked();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value(env.local()).FromJust());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(0, dispose_count);
}
CcTest::i_isolate()->compilation_cache()->Clear();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(1, dispose_count);
}
@@ -558,8 +558,8 @@ TEST(MakingExternalStringConditions) {
v8::HandleScope scope(env->GetIsolate());
// Free some space in the new space so that we can check freshness.
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
uint16_t* two_byte_string = AsciiToTwoByteString("s1");
Local<String> local_string =
@@ -571,8 +571,8 @@ TEST(MakingExternalStringConditions) {
// We should refuse to externalize new space strings.
CHECK(!local_string->CanMakeExternal());
// Trigger GCs so that the newly allocated string moves to old gen.
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in survivor space now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now
// Old space strings should be accepted.
CHECK(local_string->CanMakeExternal());
}
@@ -583,15 +583,15 @@ TEST(MakingExternalOneByteStringConditions) {
v8::HandleScope scope(env->GetIsolate());
// Free some space in the new space so that we can check freshness.
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
Local<String> local_string = v8_str("s1");
// We should refuse to externalize new space strings.
CHECK(!local_string->CanMakeExternal());
// Trigger GCs so that the newly allocated string moves to old gen.
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in survivor space now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now
// Old space strings should be accepted.
CHECK(local_string->CanMakeExternal());
}
@@ -612,8 +612,8 @@ TEST(MakingExternalUnalignedOneByteString) {
// Trigger GCs so that the newly allocated string moves to old gen.
i::heap::SimulateFullSpace(CcTest::heap()->old_space());
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in survivor space now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now
// Turn into external string with unaligned resource data.
const char* c_cons = "_abcdefghijklmnopqrstuvwxyz";
@@ -626,8 +626,8 @@ TEST(MakingExternalUnalignedOneByteString) {
CHECK(success);
// Trigger GCs and force evacuation.
- CcTest::heap()->CollectAllGarbage();
- CcTest::heap()->CollectAllGarbage(i::Heap::kReduceMemoryFootprintMask);
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(i::Heap::kReduceMemoryFootprintMask);
}
@@ -642,14 +642,14 @@ THREADED_TEST(UsingExternalString) {
.ToLocalChecked();
i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
// Trigger GCs so that the newly allocated string moves to old gen.
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in survivor space now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now
i::Handle<i::String> isymbol =
factory->InternalizeString(istring);
CHECK(isymbol->IsInternalizedString());
}
- CcTest::heap()->CollectAllGarbage();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
}
@@ -665,14 +665,14 @@ THREADED_TEST(UsingExternalOneByteString) {
.ToLocalChecked();
i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
// Trigger GCs so that the newly allocated string moves to old gen.
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in survivor space now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now
i::Handle<i::String> isymbol =
factory->InternalizeString(istring);
CHECK(isymbol->IsInternalizedString());
}
- CcTest::heap()->CollectAllGarbage();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
}
@@ -739,12 +739,12 @@ THREADED_TEST(ScavengeExternalString) {
new TestResource(two_byte_string, &dispose_count))
.ToLocalChecked();
i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
in_new_space = CcTest::heap()->InNewSpace(*istring);
CHECK(in_new_space || CcTest::heap()->old_space()->Contains(*istring));
CHECK_EQ(0, dispose_count);
}
- CcTest::heap()->CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_SPACE);
+ CcTest::CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_SPACE);
CHECK_EQ(1, dispose_count);
}
@@ -763,12 +763,12 @@ THREADED_TEST(ScavengeExternalOneByteString) {
new TestOneByteResource(i::StrDup(one_byte_string), &dispose_count))
.ToLocalChecked();
i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
in_new_space = CcTest::heap()->InNewSpace(*istring);
CHECK(in_new_space || CcTest::heap()->old_space()->Contains(*istring));
CHECK_EQ(0, dispose_count);
}
- CcTest::heap()->CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_SPACE);
+ CcTest::CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_SPACE);
CHECK_EQ(1, dispose_count);
}
@@ -812,11 +812,11 @@ TEST(ExternalStringWithDisposeHandling) {
Local<Value> value = script->Run(env.local()).ToLocalChecked();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value(env.local()).FromJust());
- CcTest::heap()->CollectAllAvailableGarbage();
+ CcTest::CollectAllAvailableGarbage();
CHECK_EQ(0, TestOneByteResourceWithDisposeControl::dispose_count);
}
CcTest::i_isolate()->compilation_cache()->Clear();
- CcTest::heap()->CollectAllAvailableGarbage();
+ CcTest::CollectAllAvailableGarbage();
CHECK_EQ(1, TestOneByteResourceWithDisposeControl::dispose_calls);
CHECK_EQ(0, TestOneByteResourceWithDisposeControl::dispose_count);
@@ -835,11 +835,11 @@ TEST(ExternalStringWithDisposeHandling) {
Local<Value> value = script->Run(env.local()).ToLocalChecked();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value(env.local()).FromJust());
- CcTest::heap()->CollectAllAvailableGarbage();
+ CcTest::CollectAllAvailableGarbage();
CHECK_EQ(0, TestOneByteResourceWithDisposeControl::dispose_count);
}
CcTest::i_isolate()->compilation_cache()->Clear();
- CcTest::heap()->CollectAllAvailableGarbage();
+ CcTest::CollectAllAvailableGarbage();
CHECK_EQ(1, TestOneByteResourceWithDisposeControl::dispose_calls);
CHECK_EQ(1, TestOneByteResourceWithDisposeControl::dispose_count);
}
@@ -897,8 +897,8 @@ THREADED_TEST(StringConcat) {
CHECK_EQ(68, value->Int32Value(env.local()).FromJust());
}
CcTest::i_isolate()->compilation_cache()->Clear();
- CcTest::heap()->CollectAllGarbage();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
}
@@ -1581,6 +1581,26 @@ THREADED_TEST(IsGeneratorFunctionOrObject) {
CHECK(!func->IsGeneratorObject());
}
+THREADED_TEST(IsAsyncFunction) {
+ i::FLAG_harmony_async_await = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ CompileRun("async function foo() {}");
+ v8::Local<Value> foo = CompileRun("foo");
+
+ CHECK(foo->IsAsyncFunction());
+ CHECK(foo->IsFunction());
+ CHECK(!foo->IsGeneratorFunction());
+ CHECK(!foo->IsGeneratorObject());
+
+ CompileRun("function bar() {}");
+ v8::Local<Value> bar = CompileRun("bar");
+
+ CHECK(!bar->IsAsyncFunction());
+ CHECK(bar->IsFunction());
+}
THREADED_TEST(ArgumentsObject) {
LocalContext env;
@@ -2651,7 +2671,7 @@ static void CheckAlignedPointerInInternalField(Local<v8::Object> obj,
void* value) {
CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1));
obj->SetAlignedPointerInInternalField(0, value);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(value, obj->GetAlignedPointerFromInternalField(0));
}
@@ -2707,14 +2727,14 @@ THREADED_TEST(SetAlignedPointerInInternalFields) {
void* values[] = {heap_allocated_1, heap_allocated_2};
obj->SetAlignedPointerInInternalFields(2, indices, values);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(heap_allocated_1, obj->GetAlignedPointerFromInternalField(0));
CHECK_EQ(heap_allocated_2, obj->GetAlignedPointerFromInternalField(1));
indices[0] = 1;
indices[1] = 0;
obj->SetAlignedPointerInInternalFields(2, indices, values);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(heap_allocated_2, obj->GetAlignedPointerFromInternalField(0));
CHECK_EQ(heap_allocated_1, obj->GetAlignedPointerFromInternalField(1));
@@ -2726,7 +2746,7 @@ static void CheckAlignedPointerInEmbedderData(LocalContext* env, int index,
void* value) {
CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1));
(*env)->SetAlignedPointerInEmbedderData(index, value);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(value, (*env)->GetAlignedPointerFromEmbedderData(index));
}
@@ -2756,7 +2776,7 @@ THREADED_TEST(EmbedderDataAlignedPointers) {
for (int i = 0; i < 100; i++) {
env->SetAlignedPointerInEmbedderData(i, AlignedTestPointer(i));
}
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
for (int i = 0; i < 100; i++) {
CHECK_EQ(AlignedTestPointer(i), env->GetAlignedPointerFromEmbedderData(i));
}
@@ -2788,7 +2808,7 @@ THREADED_TEST(IdentityHash) {
// Ensure that the test starts with an fresh heap to test whether the hash
// code is based on the address.
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
Local<v8::Object> obj = v8::Object::New(isolate);
int hash = obj->GetIdentityHash();
int hash1 = obj->GetIdentityHash();
@@ -2798,7 +2818,7 @@ THREADED_TEST(IdentityHash) {
// objects should not be assigned the same hash code. If the test below fails
// the random number generator should be evaluated.
CHECK_NE(hash, hash2);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
int hash3 = v8::Object::New(isolate)->GetIdentityHash();
// Make sure that the identity hash is not based on the initial address of
// the object alone. If the test below fails the random number generator
@@ -2874,7 +2894,7 @@ TEST(SymbolIdentityHash) {
int hash = symbol->GetIdentityHash();
int hash1 = symbol->GetIdentityHash();
CHECK_EQ(hash, hash1);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
int hash3 = symbol->GetIdentityHash();
CHECK_EQ(hash, hash3);
}
@@ -2885,7 +2905,7 @@ TEST(SymbolIdentityHash) {
int hash = js_symbol->GetIdentityHash();
int hash1 = js_symbol->GetIdentityHash();
CHECK_EQ(hash, hash1);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
int hash3 = js_symbol->GetIdentityHash();
CHECK_EQ(hash, hash3);
}
@@ -2901,7 +2921,7 @@ TEST(StringIdentityHash) {
int hash = str->GetIdentityHash();
int hash1 = str->GetIdentityHash();
CHECK_EQ(hash, hash1);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
int hash3 = str->GetIdentityHash();
CHECK_EQ(hash, hash3);
@@ -2921,7 +2941,7 @@ THREADED_TEST(SymbolProperties) {
v8::Local<v8::Symbol> sym2 = v8::Symbol::New(isolate, v8_str("my-symbol"));
v8::Local<v8::Symbol> sym3 = v8::Symbol::New(isolate, v8_str("sym3"));
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// Check basic symbol functionality.
CHECK(sym1->IsSymbol());
@@ -2990,7 +3010,7 @@ THREADED_TEST(SymbolProperties) {
CHECK_EQ(num_props + 1,
obj->GetPropertyNames(env.local()).ToLocalChecked()->Length());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK(obj->SetAccessor(env.local(), sym3, SymbolAccessorGetter,
SymbolAccessorSetter)
@@ -3100,7 +3120,7 @@ THREADED_TEST(PrivatePropertiesOnProxies) {
v8::Local<v8::Private> priv2 =
v8::Private::New(isolate, v8_str("my-private"));
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK(priv2->Name()
->Equals(env.local(),
@@ -3142,7 +3162,7 @@ THREADED_TEST(PrivatePropertiesOnProxies) {
CHECK_EQ(num_props + 1,
proxy->GetPropertyNames(env.local()).ToLocalChecked()->Length());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// Add another property and delete it afterwards to force the object in
// slow case.
@@ -3194,7 +3214,7 @@ THREADED_TEST(PrivateProperties) {
v8::Local<v8::Private> priv2 =
v8::Private::New(isolate, v8_str("my-private"));
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK(priv2->Name()
->Equals(env.local(),
@@ -3236,7 +3256,7 @@ THREADED_TEST(PrivateProperties) {
CHECK_EQ(num_props + 1,
obj->GetPropertyNames(env.local()).ToLocalChecked()->Length());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// Add another property and delete it afterwards to force the object in
// slow case.
@@ -3385,7 +3405,7 @@ THREADED_TEST(ArrayBuffer_ApiInternalToExternal) {
CheckInternalFieldsAreZero(ab);
CHECK_EQ(1024, static_cast<int>(ab->ByteLength()));
CHECK(!ab->IsExternal());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
ScopedArrayBufferContents ab_contents(ab->Externalize());
CHECK(ab->IsExternal());
@@ -3661,7 +3681,7 @@ THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) {
CheckInternalFieldsAreZero(ab);
CHECK_EQ(1024, static_cast<int>(ab->ByteLength()));
CHECK(!ab->IsExternal());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
ScopedSharedArrayBufferContents ab_contents(ab->Externalize());
CHECK(ab->IsExternal());
@@ -3778,7 +3798,7 @@ THREADED_TEST(HiddenProperties) {
v8::Local<v8::String> empty = v8_str("");
v8::Local<v8::String> prop_name = v8_str("prop_name");
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// Make sure delete of a non-existent hidden value works
obj->DeletePrivate(env.local(), key).FromJust();
@@ -3796,7 +3816,7 @@ THREADED_TEST(HiddenProperties) {
->Int32Value(env.local())
.FromJust());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// Make sure we do not find the hidden property.
CHECK(!obj->Has(env.local(), empty).FromJust());
@@ -3820,7 +3840,7 @@ THREADED_TEST(HiddenProperties) {
->Int32Value(env.local())
.FromJust());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// Add another property and delete it afterwards to force the object in
// slow case.
@@ -3844,7 +3864,7 @@ THREADED_TEST(HiddenProperties) {
->Int32Value(env.local())
.FromJust());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK(obj->SetPrivate(env.local(), key, v8::Integer::New(isolate, 2002))
.FromJust());
@@ -4135,7 +4155,7 @@ void SecondPassCallback(const v8::WeakCallbackInfo<TwoPassCallbackData>& data) {
if (!trigger_gc) return;
auto data_2 = new TwoPassCallbackData(data.GetIsolate(), instance_counter);
data_2->SetWeak();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
}
@@ -4156,7 +4176,7 @@ TEST(TwoPassPhantomCallbacks) {
data->SetWeak();
}
CHECK_EQ(static_cast<int>(kLength), instance_counter);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
EmptyMessageQueues(isolate);
CHECK_EQ(0, instance_counter);
}
@@ -4175,7 +4195,7 @@ TEST(TwoPassPhantomCallbacksNestedGc) {
array[10]->MarkTriggerGc();
array[15]->MarkTriggerGc();
CHECK_EQ(static_cast<int>(kLength), instance_counter);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
EmptyMessageQueues(isolate);
CHECK_EQ(0, instance_counter);
}
@@ -4286,8 +4306,7 @@ void TestGlobalValueMap() {
}
CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count());
if (map.IsWeak()) {
- CcTest::i_isolate()->heap()->CollectAllGarbage(
- i::Heap::kAbortIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
} else {
map.Clear();
}
@@ -4518,9 +4537,7 @@ THREADED_TEST(ApiObjectGroups) {
iso->SetReferenceFromGroup(id2, g2c1.handle);
}
// Do a single full GC, ensure incremental marking is stopped.
- v8::internal::Heap* heap =
- reinterpret_cast<v8::internal::Isolate*>(iso)->heap();
- heap->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// All object should be alive.
CHECK_EQ(0, counter.NumberOfWeakCalls());
@@ -4545,7 +4562,7 @@ THREADED_TEST(ApiObjectGroups) {
iso->SetReferenceFromGroup(id2, g2c1.handle);
}
- heap->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// All objects should be gone. 5 global handles in total.
CHECK_EQ(5, counter.NumberOfWeakCalls());
@@ -4556,7 +4573,7 @@ THREADED_TEST(ApiObjectGroups) {
g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback,
v8::WeakCallbackType::kParameter);
- heap->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(7, counter.NumberOfWeakCalls());
}
@@ -4623,9 +4640,7 @@ THREADED_TEST(ApiObjectGroupsForSubtypes) {
iso->SetReferenceFromGroup(id2, g2c1.handle);
}
// Do a single full GC, ensure incremental marking is stopped.
- v8::internal::Heap* heap =
- reinterpret_cast<v8::internal::Isolate*>(iso)->heap();
- heap->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// All object should be alive.
CHECK_EQ(0, counter.NumberOfWeakCalls());
@@ -4650,7 +4665,7 @@ THREADED_TEST(ApiObjectGroupsForSubtypes) {
iso->SetReferenceFromGroup(id2, g2c1.handle);
}
- heap->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// All objects should be gone. 5 global handles in total.
CHECK_EQ(5, counter.NumberOfWeakCalls());
@@ -4661,7 +4676,7 @@ THREADED_TEST(ApiObjectGroupsForSubtypes) {
g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback,
v8::WeakCallbackType::kParameter);
- heap->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(7, counter.NumberOfWeakCalls());
}
@@ -4746,9 +4761,7 @@ THREADED_TEST(ApiObjectGroupsCycle) {
iso->SetReferenceFromGroup(id4, g1s1.handle);
}
// Do a single full GC
- v8::internal::Heap* heap =
- reinterpret_cast<v8::internal::Isolate*>(iso)->heap();
- heap->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// All object should be alive.
CHECK_EQ(0, counter.NumberOfWeakCalls());
@@ -4777,7 +4790,7 @@ THREADED_TEST(ApiObjectGroupsCycle) {
iso->SetReferenceFromGroup(id4, g1s1.handle);
}
- heap->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// All objects should be gone. 9 global handles in total.
CHECK_EQ(9, counter.NumberOfWeakCalls());
@@ -5077,7 +5090,7 @@ TEST(NativeWeakMap) {
CHECK(value->Equals(env.local(), weak_map->Get(obj2)).FromJust());
CHECK(value->Equals(env.local(), weak_map->Get(sym1)).FromJust());
}
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
{
HandleScope scope(isolate);
CHECK(value->Equals(env.local(), weak_map->Get(local1)).FromJust());
@@ -5099,7 +5112,7 @@ TEST(NativeWeakMap) {
s1.handle.SetWeak(&s1, &WeakPointerCallback,
v8::WeakCallbackType::kParameter);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(3, counter.NumberOfWeakCalls());
CHECK(o1.handle.IsEmpty());
@@ -7458,13 +7471,11 @@ TEST(ExceptionExtensions) {
CHECK(context.IsEmpty());
}
-
static const char* kNativeCallInExtensionSource =
"function call_runtime_last_index_of(x) {"
- " return %StringLastIndexOf(x, 'bob', 10);"
+ " return %StringLastIndexOf(x, 'bob');"
"}";
-
static const char* kNativeCallTest =
"call_runtime_last_index_of('bobbobboellebobboellebobbob');";
@@ -7478,7 +7489,7 @@ TEST(NativeCallInExtensions) {
v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions);
Context::Scope lock(context);
v8::Local<Value> result = CompileRun(kNativeCallTest);
- CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 3))
+ CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 24))
.FromJust());
}
@@ -7770,9 +7781,9 @@ static void IndependentWeakHandle(bool global_gc, bool interlinked) {
b->Set(context, v8_str("x"), a).FromJust();
}
if (global_gc) {
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
} else {
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
}
// We are relying on this creating a big flag array and reserving the space
// up front.
@@ -7792,9 +7803,9 @@ static void IndependentWeakHandle(bool global_gc, bool interlinked) {
object_b.handle.MarkIndependent();
CHECK(object_b.handle.IsIndependent());
if (global_gc) {
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
} else {
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
}
// A single GC should be enough to reclaim the memory, since we are using
// phantom handles.
@@ -7891,9 +7902,9 @@ void InternalFieldCallback(bool global_gc) {
}
}
if (global_gc) {
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
} else {
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
}
CHECK_EQ(1729, t1->x());
@@ -7938,9 +7949,9 @@ void v8::internal::HeapTester::ResetWeakHandle(bool global_gc) {
object_a.handle.Reset(iso, a);
object_b.handle.Reset(iso, b);
if (global_gc) {
- CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
} else {
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
}
}
@@ -7956,9 +7967,9 @@ void v8::internal::HeapTester::ResetWeakHandle(bool global_gc) {
CHECK(object_b.handle.IsIndependent());
}
if (global_gc) {
- CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
} else {
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
}
CHECK(object_a.flag);
CHECK(object_b.flag);
@@ -7970,12 +7981,11 @@ THREADED_HEAP_TEST(ResetWeakHandle) {
v8::internal::HeapTester::ResetWeakHandle(true);
}
+static void InvokeScavenge() { CcTest::CollectGarbage(i::NEW_SPACE); }
-static void InvokeScavenge() { CcTest::heap()->CollectGarbage(i::NEW_SPACE); }
-
-
-static void InvokeMarkSweep() { CcTest::heap()->CollectAllGarbage(); }
-
+static void InvokeMarkSweep() {
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
+}
static void ForceScavenge2(
const v8::WeakCallbackInfo<FlagAndPersistent>& data) {
@@ -8051,7 +8061,7 @@ static void ArgumentsTestCallback(
CHECK(v8::Integer::New(isolate, 3)->Equals(context, args[2]).FromJust());
CHECK(v8::Undefined(isolate)->Equals(context, args[3]).FromJust());
v8::HandleScope scope(args.GetIsolate());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
}
@@ -9381,7 +9391,7 @@ static bool security_check_with_gc_called;
static bool SecurityTestCallbackWithGC(Local<v8::Context> accessing_context,
Local<v8::Object> accessed_object,
Local<v8::Value> data) {
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
security_check_with_gc_called = true;
return true;
}
@@ -12169,7 +12179,7 @@ static void InterceptorCallICFastApi(
reinterpret_cast<int*>(v8::External::Cast(*info.Data())->Value());
++(*call_count);
if ((*call_count) % 20 == 0) {
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
}
}
@@ -12226,8 +12236,8 @@ static void GenerateSomeGarbage() {
void DirectApiCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
static int count = 0;
if (count++ % 3 == 0) {
- CcTest::heap()->CollectAllGarbage();
- // This should move the stub
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
+ // This should move the stub
GenerateSomeGarbage(); // This should ensure the old stub memory is flushed
}
}
@@ -12296,7 +12306,7 @@ static int p_getter_count_3;
static Local<Value> DoDirectGetter() {
if (++p_getter_count_3 % 3 == 0) {
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
GenerateSomeGarbage();
}
return v8_str("Direct Getter Result");
@@ -14016,8 +14026,8 @@ static void CheckSurvivingGlobalObjectsCount(int expected) {
// the first garbage collection but some of the maps have already
// been marked at that point. Therefore some of the maps are not
// collected until the second garbage collection.
- CcTest::heap()->CollectAllGarbage();
- CcTest::heap()->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
int count = GetGlobalObjectsCount();
#ifdef DEBUG
if (count != expected) CcTest::heap()->TracePathToGlobal();
@@ -14118,7 +14128,8 @@ TEST(WeakCallbackApi) {
handle, WeakApiCallback, v8::WeakCallbackType::kParameter);
}
reinterpret_cast<i::Isolate*>(isolate)->heap()->CollectAllGarbage(
- i::Heap::kAbortIncrementalMarkingMask);
+ i::Heap::kAbortIncrementalMarkingMask,
+ i::GarbageCollectionReason::kTesting);
// Verify disposed.
CHECK_EQ(initial_handles, globals->global_handles_count());
}
@@ -14160,7 +14171,7 @@ THREADED_TEST(NewPersistentHandleFromWeakCallback) {
handle1.SetWeak(&handle1, NewPersistentHandleCallback1,
v8::WeakCallbackType::kParameter);
handle2.Reset();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
}
@@ -14170,7 +14181,7 @@ v8::Persistent<v8::Object> to_be_disposed;
void DisposeAndForceGcCallback2(
const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
to_be_disposed.Reset();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
}
@@ -14194,7 +14205,7 @@ THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) {
handle1.SetWeak(&handle1, DisposeAndForceGcCallback1,
v8::WeakCallbackType::kParameter);
to_be_disposed.Reset(isolate, handle2);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
}
void DisposingCallback(
@@ -14232,7 +14243,7 @@ THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) {
v8::WeakCallbackType::kParameter);
handle3.SetWeak(&handle3, HandleCreatingCallback1,
v8::WeakCallbackType::kParameter);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
EmptyMessageQueues(isolate);
}
@@ -14282,11 +14293,6 @@ THREADED_TEST(NestedHandleScopeAndContexts) {
}
-static bool MatchPointers(void* key1, void* key2) {
- return key1 == key2;
-}
-
-
struct SymbolInfo {
size_t id;
size_t size;
@@ -14793,14 +14799,14 @@ UNINITIALIZED_TEST(SetJitCodeEventHandler) {
i::Heap* heap = i_isolate->heap();
// Start with a clean slate.
- heap->CollectAllAvailableGarbage("TestSetJitCodeEventHandler_Prepare");
+ heap->CollectAllAvailableGarbage(i::GarbageCollectionReason::kTesting);
{
v8::HandleScope scope(isolate);
- v8::base::HashMap code(MatchPointers);
+ v8::base::HashMap code;
code_map = &code;
- v8::base::HashMap lineinfo(MatchPointers);
+ v8::base::HashMap lineinfo;
jitcode_line_info = &lineinfo;
saw_bar = 0;
@@ -14837,7 +14843,7 @@ UNINITIALIZED_TEST(SetJitCodeEventHandler) {
}
// Force code movement.
- heap->CollectAllAvailableGarbage("TestSetJitCodeEventHandler_Move");
+ heap->CollectAllAvailableGarbage(i::GarbageCollectionReason::kTesting);
isolate->SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
@@ -14863,10 +14869,10 @@ UNINITIALIZED_TEST(SetJitCodeEventHandler) {
CompileRun(script);
// Now get code through initial iteration.
- v8::base::HashMap code(MatchPointers);
+ v8::base::HashMap code;
code_map = &code;
- v8::base::HashMap lineinfo(MatchPointers);
+ v8::base::HashMap lineinfo;
jitcode_line_info = &lineinfo;
isolate->SetJitCodeEventHandler(v8::kJitCodeEventEnumExisting,
@@ -14887,8 +14893,7 @@ UNINITIALIZED_TEST(SetJitCodeEventHandler) {
isolate->Dispose();
}
-
-THREADED_TEST(ExternalAllocatedMemory) {
+TEST(ExternalAllocatedMemory) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope outer(isolate);
v8::Local<Context> env(Context::New(isolate));
@@ -14899,7 +14904,8 @@ THREADED_TEST(ExternalAllocatedMemory) {
isolate->AdjustAmountOfExternalAllocatedMemory(kSize));
CHECK_EQ(baseline,
isolate->AdjustAmountOfExternalAllocatedMemory(-kSize));
- const int64_t kTriggerGCSize = i::kExternalAllocationLimit + 1;
+ const int64_t kTriggerGCSize =
+ CcTest::i_isolate()->heap()->external_memory_hard_limit() + 1;
CHECK_EQ(baseline + kTriggerGCSize,
isolate->AdjustAmountOfExternalAllocatedMemory(kTriggerGCSize));
CHECK_EQ(baseline,
@@ -14911,7 +14917,8 @@ TEST(Regress51719) {
i::FLAG_incremental_marking = false;
CcTest::InitializeVM();
- const int64_t kTriggerGCSize = i::kExternalAllocationLimit + 1;
+ const int64_t kTriggerGCSize =
+ CcTest::i_isolate()->heap()->external_memory_hard_limit() + 1;
v8::Isolate* isolate = CcTest::isolate();
isolate->AdjustAmountOfExternalAllocatedMemory(kTriggerGCSize);
}
@@ -16004,6 +16011,292 @@ TEST(DefineOwnProperty) {
}
}
+TEST(DefineProperty) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::Local<v8::Name> p;
+
+ CompileRun(
+ "var a = {};"
+ "var b = [];"
+ "Object.defineProperty(a, 'v1', {value: 23});"
+ "Object.defineProperty(a, 'v2', {value: 23, configurable: true});");
+
+ v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(
+ env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked());
+ v8::Local<v8::Array> arr = v8::Local<v8::Array>::Cast(
+ env->Global()->Get(env.local(), v8_str("b")).ToLocalChecked());
+
+ v8::PropertyDescriptor desc(v8_num(42));
+ {
+ // Use a data descriptor.
+
+ // Cannot change a non-configurable property.
+ p = v8_str("v1");
+ v8::TryCatch try_catch(isolate);
+ CHECK(!obj->DefineProperty(env.local(), p, desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(23.0, val->NumberValue(env.local()).FromJust());
+
+ // Change a configurable property.
+ p = v8_str("v2");
+ obj->DefineProperty(env.local(), p, desc).FromJust();
+ CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+ val = obj->Get(env.local(), p).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+
+ // Check that missing writable has default value false.
+ p = v8_str("v12");
+ CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+ val = obj->Get(env.local(), p).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ v8::PropertyDescriptor desc2(v8_num(43));
+ CHECK(!obj->DefineProperty(env.local(), p, desc2).FromJust());
+ val = obj->Get(env.local(), p).ToLocalChecked();
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ // Set a regular property.
+ p = v8_str("v3");
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Set an indexed property.
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineProperty(env.local(), v8_str("1"), desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val = obj->Get(env.local(), 1).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // No special case when changing array length.
+ v8::TryCatch try_catch(isolate);
+ // Use a writable descriptor, otherwise the next test, that changes
+ // the array length will fail.
+ v8::PropertyDescriptor desc(v8_num(42), true);
+ CHECK(arr->DefineProperty(env.local(), v8_str("length"), desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ // Special cases for arrays: index exceeds the array's length.
+ v8::TryCatch try_catch(isolate);
+ CHECK(arr->DefineProperty(env.local(), v8_str("100"), desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(101U, arr->Length());
+ v8::Local<v8::Value> val = arr->Get(env.local(), 100).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+
+ // Set an existing entry.
+ CHECK(arr->DefineProperty(env.local(), v8_str("0"), desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+ val = arr->Get(env.local(), 0).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Use a generic descriptor.
+ v8::PropertyDescriptor desc_generic;
+
+ p = v8_str("v4");
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineProperty(env.local(), p, desc_generic).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
+ CHECK(val->IsUndefined());
+
+ obj->Set(env.local(), p, v8_num(1)).FromJust();
+ CHECK(!try_catch.HasCaught());
+
+ val = obj->Get(env.local(), p).ToLocalChecked();
+ CHECK(val->IsUndefined());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ // Use a data descriptor with undefined value.
+ v8::PropertyDescriptor desc_empty(v8::Undefined(isolate));
+
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineProperty(env.local(), p, desc_empty).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
+ CHECK(val->IsUndefined());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ // Use a descriptor with attribute == v8::ReadOnly.
+ v8::PropertyDescriptor desc_read_only(v8_num(42), false);
+ desc_read_only.set_enumerable(true);
+ desc_read_only.set_configurable(true);
+
+ p = v8_str("v5");
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineProperty(env.local(), p, desc_read_only).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ CHECK_EQ(v8::ReadOnly,
+ obj->GetPropertyAttributes(env.local(), p).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ // Use an accessor descriptor with empty handles.
+ v8::PropertyDescriptor desc_empty(v8::Undefined(isolate),
+ v8::Undefined(isolate));
+
+ p = v8_str("v6");
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineProperty(env.local(), p, desc_empty).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
+ CHECK(val->IsUndefined());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ // Use an accessor descriptor.
+ CompileRun(
+ "var set = function(x) {this.val = 2*x;};"
+ "var get = function() {return this.val || 0;};");
+
+ v8::Local<v8::Function> get = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(env.local(), v8_str("get")).ToLocalChecked());
+ v8::Local<v8::Function> set = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(env.local(), v8_str("set")).ToLocalChecked());
+ v8::PropertyDescriptor desc(get, set);
+
+ p = v8_str("v7");
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+
+ v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(0.0, val->NumberValue(env.local()).FromJust());
+ CHECK(!try_catch.HasCaught());
+
+ obj->Set(env.local(), p, v8_num(7)).FromJust();
+ CHECK(!try_catch.HasCaught());
+
+ val = obj->Get(env.local(), p).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(14.0, val->NumberValue(env.local()).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ // Redefine an existing property.
+
+ // desc = {value: 42, enumerable: true}
+ v8::PropertyDescriptor desc(v8_num(42));
+ desc.set_enumerable(true);
+
+ p = v8_str("v8");
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+
+ // desc = {enumerable: true}
+ v8::PropertyDescriptor desc_true((v8::Local<v8::Value>()));
+ desc_true.set_enumerable(true);
+
+ // Successful redefinition because all present attributes have the same
+ // value as the current descriptor.
+ CHECK(obj->DefineProperty(env.local(), p, desc_true).FromJust());
+ CHECK(!try_catch.HasCaught());
+
+ // desc = {}
+ v8::PropertyDescriptor desc_empty;
+ // Successful redefinition because no attributes are overwritten in the
+ // current descriptor.
+ CHECK(obj->DefineProperty(env.local(), p, desc_empty).FromJust());
+ CHECK(!try_catch.HasCaught());
+
+ // desc = {enumerable: false}
+ v8::PropertyDescriptor desc_false((v8::Local<v8::Value>()));
+ desc_false.set_enumerable(false);
+ // Not successful because we cannot define a different value for enumerable.
+ CHECK(!obj->DefineProperty(env.local(), p, desc_false).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ // Redefine a property that has a getter.
+ CompileRun("var get = function() {};");
+ v8::Local<v8::Function> get = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(env.local(), v8_str("get")).ToLocalChecked());
+
+ // desc = {get: function() {}}
+ v8::PropertyDescriptor desc(get, v8::Local<v8::Function>());
+ v8::TryCatch try_catch(isolate);
+
+ p = v8_str("v9");
+ CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+
+ // desc_empty = {}
+ // Successful because we are not redefining the current getter.
+ v8::PropertyDescriptor desc_empty;
+ CHECK(obj->DefineProperty(env.local(), p, desc_empty).FromJust());
+ CHECK(!try_catch.HasCaught());
+
+ // desc = {get: function() {}}
+ // Successful because we redefine the getter with its current value.
+ CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+
+ // desc = {get: undefined}
+ v8::PropertyDescriptor desc_undefined(v8::Undefined(isolate),
+ v8::Local<v8::Function>());
+ // Not successful because we cannot redefine with the current value of get
+ // with undefined.
+ CHECK(!obj->DefineProperty(env.local(), p, desc_undefined).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ CompileRun("Object.freeze(a);");
+ {
+ // We cannot change non-extensible objects.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!obj->DefineProperty(env.local(), v8_str("v10"), desc).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
+ templ->SetAccessCheckCallback(AccessAlwaysBlocked);
+ v8::Local<v8::Object> access_checked =
+ templ->NewInstance(env.local()).ToLocalChecked();
+ {
+ v8::TryCatch try_catch(isolate);
+ CHECK(access_checked->DefineProperty(env.local(), v8_str("v11"), desc)
+ .IsNothing());
+ CHECK(try_catch.HasCaught());
+ }
+}
THREADED_TEST(GetCurrentContextWhenNotInContext) {
i::Isolate* isolate = CcTest::i_isolate();
@@ -16177,7 +16470,7 @@ static void ObjectWithExternalArrayTestHelper(Local<Context> context,
"}"
"sum;");
// Force GC to trigger verification.
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(28, result->Int32Value(context).FromJust());
// Make sure out-of-range loads do not throw.
@@ -16393,12 +16686,12 @@ static void FixedTypedArrayTestHelper(i::ExternalArrayType array_type,
CHECK_EQ(FixedTypedArrayClass::kInstanceType,
fixed_array->map()->instance_type());
CHECK_EQ(kElementCount, fixed_array->length());
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
for (int i = 0; i < kElementCount; i++) {
fixed_array->set(i, static_cast<ElementType>(i));
}
// Force GC to trigger verification.
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
for (int i = 0; i < kElementCount; i++) {
CHECK_EQ(static_cast<int64_t>(static_cast<ElementType>(i)),
static_cast<int64_t>(fixed_array->get_scalar(i)));
@@ -16588,10 +16881,10 @@ THREADED_TEST(SkipArrayBufferBackingStoreDuringGC) {
Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, store_ptr, 8);
// Should not crash
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
- CcTest::heap()->CollectAllGarbage();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectGarbage(i::NEW_SPACE); // in survivor space now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// Should not move the pointer
CHECK_EQ(ab->GetContents().Data(), store_ptr);
@@ -16609,15 +16902,15 @@ THREADED_TEST(SkipArrayBufferDuringScavenge) {
reinterpret_cast<uint8_t*>(*reinterpret_cast<uintptr_t*>(*tmp));
// Make `store_ptr` point to from space
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
// Create ArrayBuffer with pointer-that-cannot-be-visited in the backing store
Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, store_ptr, 8);
// Should not crash,
// i.e. backing store pointer should not be treated as a heap object pointer
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in survivor space now
+ CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now
// Use `ab` to silence compiler warning
CHECK_EQ(ab->GetContents().Data(), store_ptr);
@@ -17918,7 +18211,8 @@ TEST(TestIdleNotification) {
bool finished = false;
for (int i = 0; i < 200 && !finished; i++) {
if (i < 10 && CcTest::heap()->incremental_marking()->IsStopped()) {
- CcTest::heap()->StartIdleIncrementalMarking();
+ CcTest::heap()->StartIdleIncrementalMarking(
+ i::GarbageCollectionReason::kTesting);
}
finished = env->GetIsolate()->IdleNotificationDeadline(
(v8::base::TimeTicks::HighResolutionNow().ToInternalValue() /
@@ -17937,7 +18231,7 @@ TEST(TestIdleNotification) {
TEST(Regress2333) {
LocalContext env;
for (int i = 0; i < 3; i++) {
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ CcTest::CollectGarbage(i::NEW_SPACE);
}
}
@@ -18075,7 +18369,7 @@ TEST(ExternalizeOldSpaceTwoByteCons) {
->ToString(env.local())
.ToLocalChecked();
CHECK(v8::Utils::OpenHandle(*cons)->IsConsString());
- CcTest::heap()->CollectAllAvailableGarbage();
+ CcTest::CollectAllAvailableGarbage();
CHECK(CcTest::heap()->old_space()->Contains(*v8::Utils::OpenHandle(*cons)));
TestResource* resource = new TestResource(
@@ -18099,7 +18393,7 @@ TEST(ExternalizeOldSpaceOneByteCons) {
->ToString(env.local())
.ToLocalChecked();
CHECK(v8::Utils::OpenHandle(*cons)->IsConsString());
- CcTest::heap()->CollectAllAvailableGarbage();
+ CcTest::CollectAllAvailableGarbage();
CHECK(CcTest::heap()->old_space()->Contains(*v8::Utils::OpenHandle(*cons)));
TestOneByteResource* resource =
@@ -18143,7 +18437,7 @@ TEST(VisitExternalStrings) {
v8::Local<v8::String> string3 =
v8::String::NewExternalTwoByte(env->GetIsolate(), resource[3])
.ToLocalChecked();
- CcTest::heap()->CollectAllAvailableGarbage(); // Tenure string.
+ CcTest::CollectAllAvailableGarbage(); // Tenure string.
// Turn into a symbol.
i::Handle<i::String> string3_i = v8::Utils::OpenHandle(*string3);
CHECK(!CcTest::i_isolate()->factory()->InternalizeString(
@@ -18230,7 +18524,7 @@ TEST(ExternalInternalizedStringCollectedAtGC) {
// Garbage collector deals swift blows to evil.
CcTest::i_isolate()->compilation_cache()->Clear();
- CcTest::heap()->CollectAllAvailableGarbage();
+ CcTest::CollectAllAvailableGarbage();
// Ring has been destroyed. Free Peoples of Middle-earth Rejoice.
CHECK_EQ(1, destroyed);
@@ -18431,7 +18725,7 @@ TEST(Regress528) {
other_context->Enter();
CompileRun(source_simple);
other_context->Exit();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
if (GetGlobalObjectsCount() == 1) break;
}
CHECK_GE(2, gc_count);
@@ -18453,7 +18747,7 @@ TEST(Regress528) {
other_context->Enter();
CompileRun(source_eval);
other_context->Exit();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
if (GetGlobalObjectsCount() == 1) break;
}
CHECK_GE(2, gc_count);
@@ -18480,7 +18774,7 @@ TEST(Regress528) {
other_context->Enter();
CompileRun(source_exception);
other_context->Exit();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
if (GetGlobalObjectsCount() == 1) break;
}
CHECK_GE(2, gc_count);
@@ -19097,8 +19391,7 @@ void PrologueCallbackAlloc(v8::Isolate* isolate,
Local<Object> obj = Object::New(isolate);
CHECK(!obj.IsEmpty());
- CcTest::heap()->CollectAllGarbage(
- i::Heap::kAbortIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
}
@@ -19117,8 +19410,7 @@ void EpilogueCallbackAlloc(v8::Isolate* isolate,
Local<Object> obj = Object::New(isolate);
CHECK(!obj.IsEmpty());
- CcTest::heap()->CollectAllGarbage(
- i::Heap::kAbortIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
}
@@ -19131,26 +19423,26 @@ TEST(GCCallbacksOld) {
context->GetIsolate()->AddGCEpilogueCallback(EpilogueCallback);
CHECK_EQ(0, prologue_call_count);
CHECK_EQ(0, epilogue_call_count);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(1, prologue_call_count);
CHECK_EQ(1, epilogue_call_count);
context->GetIsolate()->AddGCPrologueCallback(PrologueCallbackSecond);
context->GetIsolate()->AddGCEpilogueCallback(EpilogueCallbackSecond);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(2, prologue_call_count);
CHECK_EQ(2, epilogue_call_count);
CHECK_EQ(1, prologue_call_count_second);
CHECK_EQ(1, epilogue_call_count_second);
context->GetIsolate()->RemoveGCPrologueCallback(PrologueCallback);
context->GetIsolate()->RemoveGCEpilogueCallback(EpilogueCallback);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(2, prologue_call_count);
CHECK_EQ(2, epilogue_call_count);
CHECK_EQ(2, prologue_call_count_second);
CHECK_EQ(2, epilogue_call_count_second);
context->GetIsolate()->RemoveGCPrologueCallback(PrologueCallbackSecond);
context->GetIsolate()->RemoveGCEpilogueCallback(EpilogueCallbackSecond);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(2, prologue_call_count);
CHECK_EQ(2, epilogue_call_count);
CHECK_EQ(2, prologue_call_count_second);
@@ -19166,26 +19458,26 @@ TEST(GCCallbacks) {
isolate->AddGCEpilogueCallback(EpilogueCallback);
CHECK_EQ(0, prologue_call_count);
CHECK_EQ(0, epilogue_call_count);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(1, prologue_call_count);
CHECK_EQ(1, epilogue_call_count);
isolate->AddGCPrologueCallback(PrologueCallbackSecond);
isolate->AddGCEpilogueCallback(EpilogueCallbackSecond);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(2, prologue_call_count);
CHECK_EQ(2, epilogue_call_count);
CHECK_EQ(1, prologue_call_count_second);
CHECK_EQ(1, epilogue_call_count_second);
isolate->RemoveGCPrologueCallback(PrologueCallback);
isolate->RemoveGCEpilogueCallback(EpilogueCallback);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(2, prologue_call_count);
CHECK_EQ(2, epilogue_call_count);
CHECK_EQ(2, prologue_call_count_second);
CHECK_EQ(2, epilogue_call_count_second);
isolate->RemoveGCPrologueCallback(PrologueCallbackSecond);
isolate->RemoveGCEpilogueCallback(EpilogueCallbackSecond);
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CHECK_EQ(2, prologue_call_count);
CHECK_EQ(2, epilogue_call_count);
CHECK_EQ(2, prologue_call_count_second);
@@ -19195,8 +19487,7 @@ TEST(GCCallbacks) {
CHECK_EQ(0, epilogue_call_count_alloc);
isolate->AddGCPrologueCallback(PrologueCallbackAlloc);
isolate->AddGCEpilogueCallback(EpilogueCallbackAlloc);
- CcTest::heap()->CollectAllGarbage(
- i::Heap::kAbortIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
CHECK_EQ(1, prologue_call_count_alloc);
CHECK_EQ(1, epilogue_call_count_alloc);
isolate->RemoveGCPrologueCallback(PrologueCallbackAlloc);
@@ -19374,7 +19665,7 @@ TEST(ContainsOnlyOneByte) {
void FailedAccessCheckCallbackGC(Local<v8::Object> target,
v8::AccessType type,
Local<v8::Value> data) {
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
CcTest::isolate()->ThrowException(
v8::Exception::Error(v8_str("cross context")));
}
@@ -19817,12 +20108,10 @@ class InitDefaultIsolateThread : public v8::base::Thread {
void Run() {
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
- const intptr_t pageSizeMult =
- v8::internal::Page::kPageSize / v8::internal::MB;
switch (testCase_) {
case SetResourceConstraints: {
- create_params.constraints.set_max_semi_space_size(1 * pageSizeMult);
- create_params.constraints.set_max_old_space_size(4 * pageSizeMult);
+ create_params.constraints.set_max_semi_space_size(1);
+ create_params.constraints.set_max_old_space_size(6);
break;
}
default:
@@ -19999,7 +20288,7 @@ TEST(DontDeleteCellLoadIC) {
"})()",
"ReferenceError: cell is not defined");
CompileRun("cell = \"new_second\";");
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
ExpectString("readCell()", "new_second");
ExpectString("readCell()", "new_second");
}
@@ -20069,8 +20358,8 @@ TEST(PersistentHandleInNewSpaceVisitor) {
object1.SetWrapperClassId(42);
CHECK_EQ(42, object1.WrapperClassId());
- CcTest::heap()->CollectAllGarbage();
- CcTest::heap()->CollectAllGarbage();
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
v8::Persistent<v8::Object> object2(isolate, v8::Object::New(isolate));
CHECK_EQ(0, object2.WrapperClassId());
@@ -20747,7 +21036,7 @@ THREADED_TEST(Regress1516) {
CHECK_LE(1, elements);
// We have to abort incremental marking here to abandon black pages.
- CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
+ CcTest::CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
CHECK_GT(elements, CountLiveMapsInMapCache(CcTest::i_isolate()->context()));
}
@@ -21488,12 +21777,15 @@ int* LookupCounter(const char* name) {
const char* kMegamorphicTestProgram =
"function CreateClass(name) {\n"
" var src = \n"
- " ` function ${name}() {};` +\n"
+ " ` function ${name}() { this.a = 0; };` +\n"
" ` ${name}.prototype.foo = function() {};` +\n"
" ` ${name};\\n`;\n"
" return (0, eval)(src);\n"
"}\n"
- "function fooify(obj) { obj.foo(); };\n"
+ "function trigger_ics(obj, v) {\n"
+ " obj.foo();\n"
+ " obj.a = v;\n"
+ "};\n"
"var objs = [];\n"
"for (var i = 0; i < 50; i++) {\n"
" var Class = CreateClass('Class' + i);\n"
@@ -21502,7 +21794,7 @@ const char* kMegamorphicTestProgram =
"}\n"
"for (var i = 0; i < 1000; i++) {\n"
" for (var obj of objs) {\n"
- " fooify(obj);\n"
+ " trigger_ics(obj, 1);\n"
" }\n"
"}\n";
@@ -21538,6 +21830,7 @@ void TestStubCache(bool primary) {
i::CodeStub::LoadICTF, i::CodeStub::LoadICTrampolineTF,
i::CodeStub::KeyedLoadIC, i::CodeStub::KeyedLoadICTrampoline,
i::CodeStub::StoreIC, i::CodeStub::StoreICTrampoline,
+ i::CodeStub::StoreICTF, i::CodeStub::StoreICTrampolineTF,
i::CodeStub::KeyedStoreIC, i::CodeStub::KeyedStoreICTrampoline,
};
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
@@ -21558,17 +21851,18 @@ void TestStubCache(bool primary) {
int updates = updates_counter - initial_updates;
const int kClassesCount = 50;
const int kIterationsCount = 1000;
- CHECK_LE(kClassesCount, updates);
+ const int kICKinds = 2; // LoadIC and StoreIC
+ CHECK_LE(kClassesCount * kICKinds, updates);
// Check that updates and misses counts are bounded.
// If there are too many updates then most likely the stub cache does not
// work properly.
- CHECK_LE(updates, kClassesCount * 2);
- CHECK_LE(1, misses);
- CHECK_LE(misses, kClassesCount * 2);
+ CHECK_LE(updates, kClassesCount * 2 * kICKinds);
+ CHECK_LE(kICKinds, misses);
+ CHECK_LE(misses, kClassesCount * 2 * kICKinds);
// 2 is for PREMONOMORPHIC and MONOMORPHIC states,
// 4 is for POLYMORPHIC states,
// and all the others probes are for MEGAMORPHIC state.
- CHECK_EQ(kIterationsCount * kClassesCount - 2 - 4, probes);
+ CHECK_EQ((kIterationsCount * kClassesCount - 2 - 4) * kICKinds, probes);
}
isolate->Dispose();
}
@@ -23339,6 +23633,140 @@ TEST(EventLogging) {
CHECK_EQ(1, last_event_status);
}
+TEST(PropertyDescriptor) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ { // empty descriptor
+ v8::PropertyDescriptor desc;
+ CHECK(!desc.has_value());
+ CHECK(!desc.has_set());
+ CHECK(!desc.has_get());
+ CHECK(!desc.has_enumerable());
+ CHECK(!desc.has_configurable());
+ CHECK(!desc.has_writable());
+ }
+ {
+ // data descriptor
+ v8::PropertyDescriptor desc(v8_num(42));
+ desc.set_enumerable(false);
+ CHECK(desc.value() == v8_num(42));
+ CHECK(desc.has_value());
+ CHECK(!desc.has_set());
+ CHECK(!desc.has_get());
+ CHECK(desc.has_enumerable());
+ CHECK(!desc.enumerable());
+ CHECK(!desc.has_configurable());
+ CHECK(!desc.has_writable());
+ }
+ {
+ // data descriptor
+ v8::PropertyDescriptor desc(v8_num(42));
+ desc.set_configurable(true);
+ CHECK(desc.value() == v8_num(42));
+ CHECK(desc.has_value());
+ CHECK(!desc.has_set());
+ CHECK(!desc.has_get());
+ CHECK(desc.has_configurable());
+ CHECK(desc.configurable());
+ CHECK(!desc.has_enumerable());
+ CHECK(!desc.has_writable());
+ }
+ {
+ // data descriptor
+ v8::PropertyDescriptor desc(v8_num(42));
+ desc.set_configurable(false);
+ CHECK(desc.value() == v8_num(42));
+ CHECK(desc.has_value());
+ CHECK(!desc.has_set());
+ CHECK(!desc.has_get());
+ CHECK(desc.has_configurable());
+ CHECK(!desc.configurable());
+ CHECK(!desc.has_enumerable());
+ CHECK(!desc.has_writable());
+ }
+ {
+ // data descriptor
+ v8::PropertyDescriptor desc(v8_num(42), false);
+ CHECK(desc.value() == v8_num(42));
+ CHECK(desc.has_value());
+ CHECK(!desc.has_set());
+ CHECK(!desc.has_get());
+ CHECK(!desc.has_enumerable());
+ CHECK(!desc.has_configurable());
+ CHECK(desc.has_writable());
+ CHECK(!desc.writable());
+ }
+ {
+ // data descriptor
+ v8::PropertyDescriptor desc(v8::Local<v8::Value>(), true);
+ CHECK(!desc.has_value());
+ CHECK(!desc.has_set());
+ CHECK(!desc.has_get());
+ CHECK(!desc.has_enumerable());
+ CHECK(!desc.has_configurable());
+ CHECK(desc.has_writable());
+ CHECK(desc.writable());
+ }
+ {
+ // accessor descriptor
+ CompileRun("var set = function() {return 43;};");
+
+ v8::Local<v8::Function> set =
+ v8::Local<v8::Function>::Cast(context->Global()
+ ->Get(context.local(), v8_str("set"))
+ .ToLocalChecked());
+ v8::PropertyDescriptor desc(v8::Undefined(isolate), set);
+ desc.set_configurable(false);
+ CHECK(!desc.has_value());
+ CHECK(desc.has_get());
+ CHECK(desc.get() == v8::Undefined(isolate));
+ CHECK(desc.has_set());
+ CHECK(desc.set() == set);
+ CHECK(!desc.has_enumerable());
+ CHECK(desc.has_configurable());
+ CHECK(!desc.configurable());
+ CHECK(!desc.has_writable());
+ }
+ {
+ // accessor descriptor with Proxy
+ CompileRun(
+ "var set = new Proxy(function() {}, {});"
+ "var get = undefined;");
+
+ v8::Local<v8::Value> get =
+ v8::Local<v8::Value>::Cast(context->Global()
+ ->Get(context.local(), v8_str("get"))
+ .ToLocalChecked());
+ v8::Local<v8::Function> set =
+ v8::Local<v8::Function>::Cast(context->Global()
+ ->Get(context.local(), v8_str("set"))
+ .ToLocalChecked());
+ v8::PropertyDescriptor desc(get, set);
+ desc.set_configurable(false);
+ CHECK(!desc.has_value());
+ CHECK(desc.get() == v8::Undefined(isolate));
+ CHECK(desc.has_get());
+ CHECK(desc.set() == set);
+ CHECK(desc.has_set());
+ CHECK(!desc.has_enumerable());
+ CHECK(desc.has_configurable());
+ CHECK(!desc.configurable());
+ CHECK(!desc.has_writable());
+ }
+ {
+ // accessor descriptor with empty function handle
+ v8::Local<v8::Function> get = v8::Local<v8::Function>();
+ v8::PropertyDescriptor desc(get, get);
+ CHECK(!desc.has_value());
+ CHECK(!desc.has_get());
+ CHECK(!desc.has_set());
+ CHECK(!desc.has_enumerable());
+ CHECK(!desc.has_configurable());
+ CHECK(!desc.has_writable());
+ }
+}
TEST(Promises) {
LocalContext context;
@@ -24141,7 +24569,7 @@ TEST(StreamingUtf8ScriptWithSplitCharactersValidEdgeCases) {
TEST(StreamingUtf8ScriptWithSplitCharactersInvalidEdgeCases) {
// Test cases where a UTF-8 character is split over several chunks. Those
// cases are not supported (the embedder should give the data in big enough
- // chunks), but we shouldn't crash, just produce a parse error.
+ // chunks), but we shouldn't crash and parse this just fine.
const char* reference = "\xec\x92\x81";
char chunk1[] =
"function foo() {\n"
@@ -24158,7 +24586,7 @@ TEST(StreamingUtf8ScriptWithSplitCharactersInvalidEdgeCases) {
chunk3[0] = reference[2];
const char* chunks[] = {chunk1, chunk2, chunk3, "foo();", NULL};
- RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, false);
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
}