15 using namespace v8::internal;
19 static void InitializeVM() {
26 static void CheckMap(
Map* map,
int type,
int instance_size) {
27 CHECK(map->IsHeapObject());
46 static void CheckOddball(
Object* obj,
const char*
string) {
47 CHECK(obj->IsOddball());
54 static void CheckSmi(
int value,
const char*
string) {
62 static void CheckNumber(
double value,
const char*
string) {
63 Object* obj =
HEAP->NumberFromDouble(value)->ToObjectChecked();
64 CHECK(obj->IsNumber());
71 static void CheckFindCodeObject() {
85 CHECK(code->IsCode());
88 Address obj_addr = obj->address();
91 Object* found =
HEAP->FindCodeObject(obj_addr + i);
99 CHECK(copy->IsCode());
101 Object* not_right =
HEAP->FindCodeObject(obj_copy->address() +
102 obj_copy->Size() / 2);
103 CHECK(not_right != code);
111 Object* value =
HEAP->NumberFromDouble(1.000123)->ToObjectChecked();
112 CHECK(value->IsHeapNumber());
113 CHECK(value->IsNumber());
116 value =
HEAP->NumberFromDouble(1.0)->ToObjectChecked();
117 CHECK(value->IsSmi());
118 CHECK(value->IsNumber());
121 value =
HEAP->NumberFromInt32(1024)->ToObjectChecked();
122 CHECK(value->IsSmi());
123 CHECK(value->IsNumber());
127 CHECK(value->IsSmi());
128 CHECK(value->IsNumber());
132 CHECK(value->IsSmi());
133 CHECK(value->IsNumber());
136 #ifndef V8_TARGET_ARCH_X64
139 CHECK(value->IsHeapNumber());
140 CHECK(value->IsNumber());
144 MaybeObject* maybe_value =
146 value = maybe_value->ToObjectChecked();
147 CHECK(value->IsHeapNumber());
148 CHECK(value->IsNumber());
157 CHECK(s->IsString());
162 Isolate::Current()->context()->global_object()->HasLocalProperty(
166 CheckOddball(
HEAP->true_value(),
"true");
167 CheckOddball(
HEAP->false_value(),
"false");
168 CheckOddball(
HEAP->null_value(),
"null");
169 CheckOddball(
HEAP->undefined_value(),
"undefined");
174 CheckSmi(-42,
"-42");
177 CheckNumber(1.1,
"1.1");
179 CheckFindCodeObject();
218 function->set_initial_map(*initial_map);
219 Isolate::Current()->context()->global_object()->SetProperty(
235 CHECK(Isolate::Current()->context()->global_object()->
236 HasLocalProperty(*name));
238 Object* func_value = Isolate::Current()->context()->global_object()->
240 CHECK(func_value->IsJSFunction());
247 Isolate::Current()->context()->global_object()->SetProperty(
256 CHECK(Isolate::Current()->context()->global_object()->
257 HasLocalProperty(*obj_name));
258 CHECK(Isolate::Current()->context()->global_object()->
259 GetProperty(*obj_name)->ToObjectChecked()->IsJSObject());
260 Object* obj = Isolate::Current()->context()->global_object()->
267 static void VerifyStringAllocation(
const char*
string) {
271 for (
int index = 0; index < s->length(); index++) {
272 CHECK_EQ(static_cast<uint16_t>(
string[index]), s->Get(index));
280 VerifyStringAllocation(
"a");
281 VerifyStringAllocation(
"ab");
282 VerifyStringAllocation(
"abc");
283 VerifyStringAllocation(
"abcd");
284 VerifyStringAllocation(
"fiskerdrengen er paa havet");
292 const char* name =
"Kasper the spunky";
300 GlobalHandles* global_handles = Isolate::Current()->global_handles();
313 h1 = global_handles->
Create(*i);
314 h2 = global_handles->
Create(*u);
315 h3 = global_handles->
Create(*i);
316 h4 = global_handles->
Create(*u);
322 CHECK((*h1)->IsString());
323 CHECK((*h2)->IsHeapNumber());
324 CHECK((*h3)->IsString());
325 CHECK((*h4)->IsHeapNumber());
337 static bool WeakPointerCleared =
false;
341 if (1234 == reinterpret_cast<intptr_t>(
id)) WeakPointerCleared =
true;
346 TEST(WeakGlobalHandlesScavenge) {
348 GlobalHandles* global_handles = Isolate::Current()->global_handles();
350 WeakPointerCleared =
false;
361 h1 = global_handles->
Create(*i);
362 h2 = global_handles->
Create(*u);
366 reinterpret_cast<void*
>(1234),
367 &TestWeakGlobalHandleCallback);
370 HEAP->PerformScavenge();
372 CHECK((*h1)->IsString());
373 CHECK((*h2)->IsHeapNumber());
375 CHECK(!WeakPointerCleared);
386 GlobalHandles* global_handles = Isolate::Current()->global_handles();
388 WeakPointerCleared =
false;
399 h1 = global_handles->
Create(*i);
400 h2 = global_handles->
Create(*u);
408 reinterpret_cast<void*
>(1234),
409 &TestWeakGlobalHandleCallback);
415 CHECK((*h1)->IsString());
417 CHECK(WeakPointerCleared);
426 GlobalHandles* global_handles = Isolate::Current()->global_handles();
428 WeakPointerCleared =
false;
436 h = global_handles->
Create(*i);
440 reinterpret_cast<void*
>(1234),
441 &TestWeakGlobalHandleCallback);
444 HEAP->PerformScavenge();
446 CHECK(!WeakPointerCleared);
451 CHECK(WeakPointerCleared);
455 static const char* not_so_random_string_table[] = {
519 static void CheckSymbols(
const char** strings) {
520 for (
const char*
string = *strings; *strings != 0;
string = *strings++) {
522 MaybeObject* maybe_a =
HEAP->LookupAsciiSymbol(
string);
524 if (!maybe_a->ToObject(&a))
continue;
525 CHECK(a->IsSymbol());
527 MaybeObject* maybe_b =
HEAP->LookupAsciiSymbol(
string);
528 if (!maybe_b->ToObject(&b))
continue;
538 CheckSymbols(not_so_random_string_table);
539 CheckSymbols(not_so_random_string_table);
552 function->set_initial_map(*initial_map);
560 function->SetProperty(
571 Object* raw_object = Isolate::Current()->context()->global_object()->
580 CHECK(!obj->HasLocalProperty(*first));
585 CHECK(obj->HasLocalProperty(*first));
589 CHECK(!obj->HasLocalProperty(*first));
596 CHECK(obj->HasLocalProperty(*first));
597 CHECK(obj->HasLocalProperty(*second));
601 CHECK(obj->HasLocalProperty(*second));
603 CHECK(!obj->HasLocalProperty(*first));
604 CHECK(!obj->HasLocalProperty(*second));
611 CHECK(obj->HasLocalProperty(*first));
612 CHECK(obj->HasLocalProperty(*second));
616 CHECK(obj->HasLocalProperty(*first));
618 CHECK(!obj->HasLocalProperty(*first));
619 CHECK(!obj->HasLocalProperty(*second));
622 const char* string1 =
"fisk";
627 CHECK(obj->HasLocalProperty(*s1_symbol));
630 const char* string2 =
"fugl";
635 CHECK(obj->HasLocalProperty(*s2));
648 function->set_initial_map(*initial_map);
659 CHECK(*initial_map != obj->map());
668 Object* raw_object = Isolate::Current()->context()->global_object()->
677 array->Initialize(0)->ToObjectChecked();
680 array->SetElementsLength(
Smi::FromInt(0))->ToObjectChecked();
683 CHECK(array->HasFastSmiOrObjectElements());
688 CHECK_EQ(array->GetElement(0), *name);
693 array->SetElementsLength(*length)->ToObjectChecked();
695 uint32_t int_length = 0;
696 CHECK(length->ToArrayIndex(&int_length));
698 CHECK(array->HasDictionaryElements());
702 uint32_t new_int_length = 0;
703 CHECK(array->length()->ToArrayIndex(&new_int_length));
704 CHECK_EQ(static_cast<double>(int_length), new_int_length - 1);
705 CHECK_EQ(array->GetElement(int_length), *name);
706 CHECK_EQ(array->GetElement(0), *name);
715 Object* raw_object = Isolate::Current()->context()->global_object()->
735 CHECK_EQ(obj->GetElement(0), clone->GetElement(0));
736 CHECK_EQ(obj->GetElement(1), clone->GetElement(1));
738 CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*first));
739 CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*second));
750 CHECK_EQ(obj->GetElement(1), clone->GetElement(0));
751 CHECK_EQ(obj->GetElement(0), clone->GetElement(1));
753 CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*first));
754 CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*second));
762 const unsigned char chars[] = { 0xe5, 0xa4, 0xa7 };
763 for (
int length = 0; length < 100; length++) {
765 char* non_ascii = NewArray<char>(3 * length + 1);
766 char* ascii = NewArray<char>(length + 1);
767 non_ascii[3 * length] = 0;
769 for (
int i = 0; i < length; i++) {
771 non_ascii[3 * i] = chars[0];
772 non_ascii[3 * i + 1] = chars[1];
773 non_ascii[3 * i + 2] = chars[2];
777 CHECK_EQ(length, non_ascii_sym->length());
780 CHECK_EQ(length, ascii_sym->length());
783 non_ascii_str->Hash();
784 CHECK_EQ(length, non_ascii_str->length());
788 CHECK_EQ(length, ascii_str->length());
798 HeapIterator iterator;
799 for (
HeapObject* obj = iterator.next(); obj !=
NULL; obj = iterator.next()) {
800 for (
int i = 0; i < size; i++) {
801 if (*objs[i] == obj) {
815 const int objs_count = 6;
817 int next_objs_index = 0;
820 objs[next_objs_index++] =
FACTORY->NewJSArray(10);
821 objs[next_objs_index++] =
FACTORY->NewJSArray(10,
826 objs[next_objs_index++] =
828 objs[next_objs_index++] =
833 char* str =
new char[large_size];
834 for (
int i = 0; i < large_size - 1; ++i) str[i] =
'a';
835 str[large_size - 1] =
'\0';
836 objs[next_objs_index++] =
843 CHECK_EQ(objs_count, next_objs_index);
844 CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count));
864 static int LenFromSize(
int size) {
884 Isolate::Current()->native_context()->object_function());
885 CHECK(object_ctor->has_initial_map());
886 Handle<Map> object_map(object_ctor->initial_map());
889 int n_properties = my_map->inobject_properties();
892 int object_size = my_map->instance_size();
898 HEAP->MaxObjectSizeInNewSpace());
899 int allocation_len = LenFromSize(allocation_amount);
903 while ((*limit_addr - *top_addr) > allocation_amount) {
905 Object* array =
HEAP->AllocateFixedArray(allocation_len)->ToObjectChecked();
906 CHECK(!array->IsFailure());
911 int to_fill =
static_cast<int>(*limit_addr - *top_addr - object_size);
912 int fixed_array_len = LenFromSize(to_fill);
916 Object* array =
HEAP->AllocateFixedArray(fixed_array_len)->ToObjectChecked();
917 CHECK(!array->IsFailure());
920 Object*
object =
HEAP->AllocateJSObjectFromMap(*my_map)->ToObjectChecked();
924 CHECK_EQ(0, jsobject->properties()->length());
926 jsobject->FastPropertyAtPut(-1, array);
928 CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr));
932 Address old_pointer_space_top =
HEAP->old_pointer_space()->top();
934 Object* clone_obj =
HEAP->CopyJSObject(jsobject)->ToObjectChecked();
936 if (clone->
address() != old_pointer_space_top) {
945 i::FLAG_allow_natives_syntax =
true;
947 if (!FLAG_flush_code)
return;
950 const char* source =
"function foo() {"
964 Object* func_value = Isolate::Current()->context()->global_object()->
966 CHECK(func_value->IsJSFunction());
968 CHECK(function->shared()->is_compiled());
974 CHECK(function->shared()->is_compiled());
984 CHECK(!function->shared()->is_compiled() ||
function->IsOptimized());
985 CHECK(!function->is_compiled() ||
function->IsOptimized());
988 CHECK(function->shared()->is_compiled());
989 CHECK(function->is_compiled());
996 Object*
object =
HEAP->native_contexts_list();
997 while (!object->IsUndefined()) {
1022 static const int kNumTestContexts = 10;
1030 for (
int i = 0; i < kNumTestContexts; i++) {
1042 const char* source =
"function f1() { };"
1043 "function f2() { };"
1044 "function f3() { };"
1045 "function f4() { };"
1046 "function f5() { };";
1048 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i]));
1050 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[i]));
1052 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i]));
1054 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
1056 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
1058 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i]));
1061 CompileRun(
"f1=null");
1064 for (
int j = 0; j < 10; j++) {
1065 HEAP->PerformScavenge();
1066 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i]));
1070 ISOLATE->compilation_cache()->Clear();
1072 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
1075 CompileRun(
"f3=null");
1076 for (
int j = 0; j < 10; j++) {
1077 HEAP->PerformScavenge();
1078 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
1081 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
1082 CompileRun(
"f5=null");
1083 for (
int j = 0; j < 10; j++) {
1084 HEAP->PerformScavenge();
1085 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
1088 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i]));
1097 for (
int i = 0; i < kNumTestContexts; i++) {
1102 for (
int j = 0; j < 10; j++) {
1103 HEAP->PerformScavenge();
1118 static int CountNativeContextsWithGC(
int n) {
1121 while (!object->IsUndefined()) {
1139 while (object->IsJSFunction() &&
1150 TEST(TestInternalWeakListsTraverseWithGC) {
1153 static const int kNumTestContexts = 10;
1162 for (
int i = 0; i < kNumTestContexts; i++) {
1165 CHECK_EQ(i + 1, CountNativeContextsWithGC(i / 2 + 1));
1173 const char* source =
"function f1() { };"
1174 "function f2() { };"
1175 "function f3() { };"
1176 "function f4() { };"
1177 "function f5() { };";
1179 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[0]));
1181 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[0]));
1182 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1));
1184 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[0]));
1185 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1));
1187 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[0]));
1188 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1));
1190 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[0]));
1191 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 2));
1193 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0]));
1194 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4));
1210 CHECK(
HEAP->old_pointer_space()->IsSweepingComplete());
1211 int initial_size =
static_cast<int>(
HEAP->SizeOfObjects());
1218 for (
int i = 1; i <= 100; i++) {
1219 HEAP->AllocateFixedArray(8192,
TENURED)->ToObjectChecked();
1220 CHECK_EQ(initial_size + i * filler_size,
1221 static_cast<int>(
HEAP->SizeOfObjects()));
1231 CHECK_EQ(initial_size, static_cast<int>(
HEAP->SizeOfObjects()));
1234 while (!
HEAP->old_pointer_space()->IsSweepingComplete()) {
1235 HEAP->old_pointer_space()->AdvanceSweeper(
KB);
1236 CHECK_EQ(initial_size, static_cast<int>(
HEAP->SizeOfObjects()));
1241 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
1243 HEAP->EnsureHeapIsIterable();
1244 intptr_t size_of_objects_1 =
HEAP->SizeOfObjects();
1245 HeapIterator iterator;
1246 intptr_t size_of_objects_2 = 0;
1249 obj = iterator.next()) {
1250 if (!obj->IsFreeSpace()) {
1251 size_of_objects_2 += obj->Size();
1258 if (size_of_objects_1 > size_of_objects_2) {
1259 intptr_t delta = size_of_objects_1 - size_of_objects_2;
1263 size_of_objects_1, size_of_objects_2, delta);
1264 CHECK_GT(size_of_objects_1 / 20, delta);
1266 intptr_t delta = size_of_objects_2 - size_of_objects_1;
1270 size_of_objects_1, size_of_objects_2, delta);
1271 CHECK_GT(size_of_objects_2 / 20, delta);
1276 static void FillUpNewSpace(
NewSpace* new_space) {
1283 for (intptr_t i = 0; i < number_of_fillers; i++) {
1293 if (
HEAP->ReservedSemiSpaceSize() ==
HEAP->InitialSemiSpaceSize() ||
1294 HEAP->MaxSemiSpaceSize() ==
HEAP->InitialSemiSpaceSize()) {
1302 intptr_t old_capacity, new_capacity;
1303 old_capacity = new_space->
Capacity();
1305 new_capacity = new_space->
Capacity();
1306 CHECK(2 * old_capacity == new_capacity);
1308 old_capacity = new_space->
Capacity();
1309 FillUpNewSpace(new_space);
1310 new_capacity = new_space->
Capacity();
1311 CHECK(old_capacity == new_capacity);
1314 old_capacity = new_space->
Capacity();
1316 new_capacity = new_space->
Capacity();
1317 CHECK(old_capacity == new_capacity);
1324 old_capacity = new_space->
Capacity();
1326 new_capacity = new_space->
Capacity();
1327 CHECK(old_capacity == 2 * new_capacity);
1330 old_capacity = new_space->
Capacity();
1334 new_capacity = new_space->
Capacity();
1335 CHECK(old_capacity == new_capacity);
1339 TEST(CollectingAllAvailableGarbageShrinksNewSpace) {
1342 if (
HEAP->ReservedSemiSpaceSize() ==
HEAP->InitialSemiSpaceSize() ||
1343 HEAP->MaxSemiSpaceSize() ==
HEAP->InitialSemiSpaceSize()) {
1352 intptr_t old_capacity, new_capacity;
1353 old_capacity = new_space->
Capacity();
1355 new_capacity = new_space->
Capacity();
1356 CHECK(2 * old_capacity == new_capacity);
1357 FillUpNewSpace(new_space);
1358 HEAP->CollectAllAvailableGarbage();
1359 new_capacity = new_space->
Capacity();
1360 CHECK(old_capacity == new_capacity);
1364 static int NumberOfGlobalObjects() {
1366 HeapIterator iterator;
1367 for (
HeapObject* obj = iterator.next(); obj !=
NULL; obj = iterator.next()) {
1368 if (obj->IsGlobalObject()) count++;
1377 i::FLAG_allow_natives_syntax =
true;
1383 HEAP->CollectAllAvailableGarbage();
1384 CHECK_EQ(4, NumberOfGlobalObjects());
1388 CompileRun(
"var v = {x: 42}");
1391 ctx2->Global()->Set(v8_str(
"o"), v);
1393 "function f() { return o.x; }"
1394 "for (var i = 0; i < 10; ++i) f();"
1395 "%OptimizeFunctionOnNextCall(f);"
1404 HEAP->CollectAllAvailableGarbage();
1405 CHECK_EQ(2, NumberOfGlobalObjects());
1407 HEAP->CollectAllAvailableGarbage();
1408 CHECK_EQ(0, NumberOfGlobalObjects());
1414 TEST(LeakNativeContextViaFunction) {
1415 i::FLAG_allow_natives_syntax =
true;
1421 HEAP->CollectAllAvailableGarbage();
1422 CHECK_EQ(4, NumberOfGlobalObjects());
1426 CompileRun(
"var v = function() { return 42; }");
1429 ctx2->Global()->Set(v8_str(
"o"), v);
1431 "function f(x) { return x(); }"
1432 "for (var i = 0; i < 10; ++i) f(o);"
1433 "%OptimizeFunctionOnNextCall(f);"
1442 HEAP->CollectAllAvailableGarbage();
1443 CHECK_EQ(2, NumberOfGlobalObjects());
1445 HEAP->CollectAllAvailableGarbage();
1446 CHECK_EQ(0, NumberOfGlobalObjects());
1450 TEST(LeakNativeContextViaMapKeyed) {
1451 i::FLAG_allow_natives_syntax =
true;
1457 HEAP->CollectAllAvailableGarbage();
1458 CHECK_EQ(4, NumberOfGlobalObjects());
1462 CompileRun(
"var v = [42, 43]");
1465 ctx2->Global()->Set(v8_str(
"o"), v);
1467 "function f() { return o[0]; }"
1468 "for (var i = 0; i < 10; ++i) f();"
1469 "%OptimizeFunctionOnNextCall(f);"
1478 HEAP->CollectAllAvailableGarbage();
1479 CHECK_EQ(2, NumberOfGlobalObjects());
1481 HEAP->CollectAllAvailableGarbage();
1482 CHECK_EQ(0, NumberOfGlobalObjects());
1486 TEST(LeakNativeContextViaMapProto) {
1487 i::FLAG_allow_natives_syntax =
true;
1493 HEAP->CollectAllAvailableGarbage();
1494 CHECK_EQ(4, NumberOfGlobalObjects());
1498 CompileRun(
"var v = { y: 42}");
1501 ctx2->Global()->Set(v8_str(
"o"), v);
1508 "for (var i = 0; i < 10; ++i) f();"
1509 "%OptimizeFunctionOnNextCall(f);"
1518 HEAP->CollectAllAvailableGarbage();
1519 CHECK_EQ(2, NumberOfGlobalObjects());
1521 HEAP->CollectAllAvailableGarbage();
1522 CHECK_EQ(0, NumberOfGlobalObjects());
1527 i::FLAG_allow_natives_syntax =
true;
1529 i::FLAG_verify_heap =
true;
1539 "function foo () { }"
1540 "function mkbar () { return new (new Function(\"\")) (); }"
1541 "function f (x) { return (x instanceof foo); }"
1542 "function g () { f(mkbar()); }"
1543 "f(new foo()); f(new foo());"
1544 "%OptimizeFunctionOnNextCall(f);"
1545 "f(new foo()); g();");
1553 v8::Utils::OpenHandle(
1557 CHECK(f->IsOptimized());
1566 CHECK(marking->IsMarking());
1576 HEAP->incremental_marking()->set_should_hurry(
true);
1581 TEST(PrototypeTransitionClearing) {
1588 "for (var i = 0; i < 10; i++) {"
1590 " var prototype = {};"
1591 " object.__proto__ = prototype;"
1592 " if (i >= 3) live.push(object, prototype);"
1596 v8::Utils::OpenHandle(
1601 CHECK_EQ(10, baseObject->map()->NumberOfProtoTransitions());
1603 const int transitions = 10 - 3;
1604 CHECK_EQ(transitions, baseObject->map()->NumberOfProtoTransitions());
1607 FixedArray* trans = baseObject->map()->GetPrototypeTransitions();
1608 for (
int i = 0; i < transitions; i++) {
1613 CHECK(proto->IsTheHole() || proto->IsJSObject());
1626 i::FLAG_always_compact =
true;
1631 baseObject->SetPrototype(*prototype,
false)->ToObjectChecked();
1638 TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) {
1639 i::FLAG_allow_natives_syntax =
true;
1641 i::FLAG_verify_heap =
true;
1653 " for (var i = 0; i < 100; i++) s += i;"
1657 "%OptimizeFunctionOnNextCall(f);"
1661 v8::Utils::OpenHandle(
1664 CHECK(f->IsOptimized());
1671 const int kLongIdlePauseInMs = 1000;
1675 while (!marking->IsStopped() && !marking->IsComplete()) {
1678 if (!marking->IsStopped() || marking->should_hurry()) {
1685 "Test finalizing incremental mark-sweep");
1688 CHECK_EQ(
HEAP->global_ic_age(), f->shared()->ic_age());
1689 CHECK_EQ(0, f->shared()->opt_count());
1690 CHECK_EQ(0, f->shared()->code()->profiler_ticks());
1694 TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) {
1695 i::FLAG_allow_natives_syntax =
true;
1697 i::FLAG_verify_heap =
true;
1709 " for (var i = 0; i < 100; i++) s += i;"
1713 "%OptimizeFunctionOnNextCall(f);"
1717 v8::Utils::OpenHandle(
1720 CHECK(f->IsOptimized());
1722 HEAP->incremental_marking()->Abort();
1726 const int kLongIdlePauseInMs = 1000;
1730 CHECK_EQ(
HEAP->global_ic_age(), f->shared()->ic_age());
1731 CHECK_EQ(0, f->shared()->opt_count());
1732 CHECK_EQ(0, f->shared()->code()->profiler_ticks());
1737 TEST(OptimizedAllocationAlwaysInNewSpace) {
1738 i::FLAG_allow_natives_syntax =
true;
1743 FillUpNewSpace(
HEAP->new_space());
1748 " for (var i = 0; i < 32; i++) {"
1749 " this['x' + i] = x;"
1752 "function f(x) { return new c(x); };"
1754 "%OptimizeFunctionOnNextCall(f);"
1756 CHECK_EQ(4, res->
ToObject()->GetRealNamedProperty(v8_str(
"x"))->Int32Value());
1765 static int CountMapTransitions(
Map* map) {
1766 return map->transitions()->number_of_transitions();
1771 static void SimulateIncrementalMarking() {
1775 CHECK(marking->IsMarking());
1786 i::FLAG_allow_natives_syntax =
true;
1787 i::FLAG_trace_incremental_marking =
true;
1790 static const int transitions_count = 256;
1794 for (
int i = 0; i < transitions_count; i++) {
1796 OS::SNPrintF(buffer,
"var o = new Object; o.prop%d = %d;", i, i);
1797 CompileRun(buffer.
start());
1799 CompileRun(
"var root = new Object;");
1803 v8::Utils::OpenHandle(
1808 int transitions_before = CountMapTransitions(root->map());
1809 CompileRun(
"%DebugPrint(root);");
1810 CHECK_EQ(transitions_count, transitions_before);
1812 SimulateIncrementalMarking();
1817 int transitions_after = CountMapTransitions(root->map());
1818 CompileRun(
"%DebugPrint(root);");
1824 i::FLAG_collect_maps =
true;
1825 i::FLAG_incremental_marking =
true;
1831 CompileRun(
"var root = new Object;"
1833 "root = new Object;");
1835 SimulateIncrementalMarking();
1840 CompileRun(
"function f(o) {"
1847 HEAP->AgeInlineCaches();
1853 v8::Utils::OpenHandle(
1858 CHECK(root->IsJSObject());
1859 CHECK(root->map()->IsMap());
1864 i::FLAG_collect_maps =
true;
1865 i::FLAG_incremental_marking =
true;
1866 i::FLAG_allow_natives_syntax =
true;
1872 CompileRun(
"var root = new Object;"
1874 "root = new Object;");
1876 SimulateIncrementalMarking();
1881 CompileRun(
"function f(o) {"
1886 "%OptimizeFunctionOnNextCall(f);"
1888 "%DeoptimizeFunction(f);");
1891 HEAP->AgeInlineCaches();
1897 v8::Utils::OpenHandle(
1902 CHECK(root->IsJSObject());
1903 CHECK(root->map()->IsMap());
1912 i::FLAG_trace_gc =
true;
1914 i::FLAG_crankshaft =
false;
1915 i::FLAG_always_opt =
false;
1918 static const int number_of_test_pages = 20;
1923 for (
int i = 0; i < number_of_test_pages; i++) {
1949 HEAP->CollectAllAvailableGarbage(
"triggered really hard");
1962 const char* c =
"This text is long enough to trigger sliced strings.";
1964 CHECK(s->IsSeqAsciiString());
1969 FillUpNewSpace(
HEAP->new_space());
1974 for (
int i = 0; i < 16; i++) {
1975 t =
FACTORY->NewProperSubString(s, 5, 35);
1977 CHECK(t->IsSlicedString());
1989 TEST(PrintSharedFunctionInfo) {
1992 const char* source =
"f = function() { return 987654321; }\n"
1993 "g = function() { return 123456789; }\n";
1996 v8::Utils::OpenHandle(
2001 g->shared()->PrintLn();
2003 #endif // OBJECT_PRINT
2012 Heap* heap = Isolate::Current()->heap();
2014 for (
int i = 0; i < 2; i++) {
2018 CHECK(internal_obj->HasFastProperties());
2023 MaybeObject* maybe_obj = internal_obj->SetIdentityHash(hash,
2025 CHECK(!maybe_obj->IsFailure());
2030 internal_obj->GetHiddenProperty(heap->identity_hash_symbol()));
2034 DescriptorArray* descriptors = internal_obj->map()->instance_descriptors();
2036 internal_obj->FastPropertyAt(descriptors->
GetFieldIndex(0)));
2043 TEST(IncrementalMarkingClearsTypeFeedbackCells) {
2044 if (i::FLAG_always_opt)
return;
2051 CompileRun(
"function fun() {};");
2052 fun1 = env->
Global()->Get(v8_str(
"fun"));
2057 CompileRun(
"function fun() {};");
2058 fun2 = env->
Global()->Get(v8_str(
"fun"));
2065 CompileRun(
"function f(a, b) { a(); b(); } f(fun1, fun2);");
2067 v8::Utils::OpenHandle(
2071 f->shared()->code()->type_feedback_info())->type_feedback_cells());
2074 CHECK(cells->Cell(0)->value()->IsJSFunction());
2075 CHECK(cells->Cell(1)->value()->IsJSFunction());
2077 SimulateIncrementalMarking();
2081 CHECK(cells->Cell(0)->value()->IsTheHole());
2082 CHECK(cells->Cell(1)->value()->IsTheHole());
2087 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
2088 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) |
2089 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) |
2090 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT);
2092 RelocInfo* info = it.rinfo();
2102 TEST(IncrementalMarkingPreservesMonomorhpicIC) {
2103 if (i::FLAG_always_opt)
return;
2109 CompileRun(
"function fun() { this.x = 1; }; var obj = new fun();"
2110 "function f(o) { return o.x; } f(obj); f(obj);");
2112 v8::Utils::OpenHandle(
2116 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
2119 SimulateIncrementalMarking();
2122 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
2127 TEST(IncrementalMarkingClearsMonomorhpicIC) {
2128 if (i::FLAG_always_opt)
return;
2135 CompileRun(
"function fun() { this.x = 1; }; var obj = new fun();");
2136 obj1 = env->
Global()->Get(v8_str(
"obj"));
2142 CompileRun(
"function f(o) { return o.x; } f(obj1); f(obj1);");
2144 v8::Utils::OpenHandle(
2148 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
2153 SimulateIncrementalMarking();
2156 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
2161 TEST(IncrementalMarkingClearsPolymorhpicIC) {
2162 if (i::FLAG_always_opt)
return;
2169 CompileRun(
"function fun() { this.x = 1; }; var obj = new fun();");
2170 obj1 = env->
Global()->Get(v8_str(
"obj"));
2175 CompileRun(
"function fun() { this.x = 2; }; var obj = new fun();");
2176 obj2 = env->
Global()->Get(v8_str(
"obj"));
2183 CompileRun(
"function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);");
2185 v8::Utils::OpenHandle(
2189 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
2194 SimulateIncrementalMarking();
2197 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
2205 : data_(data), length_(strlen(data)) { }
2212 const char*
data()
const {
return data_; }
2231 static const char* source =
"var error = 1; "
2233 " throw new Error(); "
2244 HEAP->CollectAllAvailableGarbage();
2248 CompileRun(
"error.stack; error.stack;");
2249 HEAP->CollectAllAvailableGarbage();
2267 ISOLATE->stub_cache()->ComputeCallInitialize(9, RelocInfo::CODE_TARGET);
2276 CompileRun(
"var o = { f:function(a,b,c,d,e,f,g,h,i) {}};"
2277 "function call() { o.f(1,2,3,4,5,6,7,8,9); };"
2286 CompileRun(
"for (var i = 0; i < 2000; i++) {"
2287 " eval('function f' + i + '() { return ' + i +'; };' +"
2288 " 'f' + i + '();');"
2298 MaybeObject* maybe_call = global->GetProperty(*name);
2301 ISOLATE->compilation_cache()->Clear();
2302 call->shared()->set_ic_age(
HEAP->global_ic_age() + 1);
2312 CompileRun(
"call();");
static bool IsBlack(MarkBit mark_bit)
static Local< Context > GetCurrent()
static const int kMaxLength
void Destroy(Object **location)
static Local< Script > Compile(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *pre_data=NULL, Handle< String > script_data=Handle< String >())
#define CHECK_EQ(expected, value)
bool Contains(Address addr)
void PrintF(const char *format,...)
static TypeFeedbackInfo * cast(Object *obj)
static String * cast(Object *obj)
static bool UseCrankshaft()
V8EXPORT Local< Value > Get(Handle< Value > key)
static Smi * FromInt(int value)
static HeapObject * cast(Object *obj)
static Handle< T > cast(Handle< S > that)
static const int kProtoTransitionElementsPerEntry
const int kVariableSizeSentinel
bool is_identical_to(const Handle< T > other) const
const char * data() const
Address * allocation_top_address()
V8EXPORT Local< Value > GetHiddenValue(Handle< String > key)
static bool IsNearDeath(Object **location)
static Failure * Exception()
static Handle< T > Cast(Handle< S > that)
V8EXPORT Local< Value > Call(Handle< Object > recv, int argc, Handle< Value > argv[])
Map * GetPrototypeTransition(Object *prototype)
void Step(intptr_t allocated, CompletionAction action)
static const int kReduceMemoryFootprintMask
static Context * cast(Object *context)
Handle< Object > GetProperty(Handle< JSReceiver > obj, const char *name)
static const int kMaxSize
intptr_t EffectiveCapacity()
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if available(X64 only)") DEFINE_bool(enable_vfp3
V8EXPORT bool Equals(Handle< Value > that) const
static Smi * cast(Object *object)
static MarkBit MarkBitFrom(Address addr)
static SlicedString * cast(Object *obj)
static const int kProtoTransitionMapOffset
Handle< Object > Create(Object *value)
static Failure * RetryAfterGC()
static const int kMinValue
static const int kNoGCFlags
int GetFieldIndex(int descriptor_number)
static int ContextDisposedNotification()
V8EXPORT int32_t Int32Value() const
SourceResource(const char *data)
void SimulateFullSpace(PagedSpace *space)
static Flags ComputeFlags(Kind kind, InlineCacheState ic_state=UNINITIALIZED, ExtraICState extra_ic_state=kNoExtraICState, StubType type=NORMAL, int argc=-1, InlineCacheHolderFlag holder=OWN_MAP)
static Code * GetCodeFromTargetAddress(Address address)
bool is_inline_cache_stub()
V8EXPORT bool SetHiddenValue(Handle< String > key, Handle< Value > value)
static const int kMaxNonCodeHeapObjectSize
InlineCacheState ic_state()
static const int kAbortIncrementalMarkingMask
Vector< const char > CStrVector(const char *data)
int StrLength(const char *string)
static int SizeFor(int length)
static const int kProtoTransitionHeaderSize
static const int kHeaderSize
static int SNPrintF(Vector< char > str, const char *format,...)
static ObjectHashTable * cast(Object *obj)
#define OBJECT_POINTER_ALIGN(value)
static Object * cast(Object *value)
Handle< T > EscapeFrom(v8::HandleScope *scope)
static const int kProtoTransitionPrototypeOffset
MUST_USE_RESULT MaybeObject * GetProperty(String *key)
InstanceType instance_type()
static V8EXPORT Local< Integer > New(int32_t value)
static FixedArray * cast(Object *obj)
static const int kHeaderSize
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
static Handle< Object > ToString(Handle< Object > obj, bool *exc)
static Persistent< Context > New(ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
V8EXPORT Local< Object > ToObject() const
char * StrDup(const char *str)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
Address * allocation_limit_address()
void MakeWeak(Object **location, void *parameter, WeakReferenceCallback callback)
static V8EXPORT Local< String > NewExternal(ExternalStringResource *resource)
void DeleteArray(T *array)
static const int kMaxValue
FixedArray * GetPrototypeTransitions()
static JSObject * cast(Object *obj)
static V8EXPORT Local< Object > New()
int CountNativeContexts()
Handle< JSObject > Copy(Handle< JSObject > obj)
static bool IdleNotification(int hint=1000)
static JSFunction * cast(Object *obj)