OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST); | 1373 Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST); |
1374 while (object->IsJSFunction() && !JSFunction::cast(object)->IsBuiltin()) { | 1374 while (object->IsJSFunction() && !JSFunction::cast(object)->IsBuiltin()) { |
1375 count++; | 1375 count++; |
1376 object = JSFunction::cast(object)->next_function_link(); | 1376 object = JSFunction::cast(object)->next_function_link(); |
1377 } | 1377 } |
1378 return count; | 1378 return count; |
1379 } | 1379 } |
1380 | 1380 |
1381 | 1381 |
1382 TEST(TestInternalWeakLists) { | 1382 TEST(TestInternalWeakLists) { |
| 1383 FLAG_allow_natives_syntax = true; |
1383 v8::V8::Initialize(); | 1384 v8::V8::Initialize(); |
| 1385 Isolate* isolate = CcTest::i_isolate(); |
| 1386 |
| 1387 // TODO(mstarzinger): Test should be resilient against optimization decisions. |
| 1388 if (i::FLAG_always_opt) return; |
| 1389 if (!isolate->use_crankshaft()) return; |
1384 | 1390 |
1385 // Some flags turn Scavenge collections into Mark-sweep collections | 1391 // Some flags turn Scavenge collections into Mark-sweep collections |
1386 // and hence are incompatible with this test case. | 1392 // and hence are incompatible with this test case. |
1387 if (FLAG_gc_global || FLAG_stress_compaction) return; | 1393 if (FLAG_gc_global || FLAG_stress_compaction) return; |
1388 | 1394 |
1389 static const int kNumTestContexts = 10; | 1395 static const int kNumTestContexts = 5; |
| 1396 static const int kNumTestCollections = 3; |
1390 | 1397 |
1391 Isolate* isolate = CcTest::i_isolate(); | |
1392 Heap* heap = isolate->heap(); | |
1393 HandleScope scope(isolate); | 1398 HandleScope scope(isolate); |
1394 v8::Handle<v8::Context> ctx[kNumTestContexts]; | 1399 v8::Handle<v8::Context> ctx[kNumTestContexts]; |
1395 | 1400 |
1396 CHECK_EQ(0, CountNativeContexts()); | 1401 CHECK_EQ(0, CountNativeContexts()); |
1397 | 1402 |
1398 // Create a number of global contests which gets linked together. | 1403 // Create a number of global contests which gets linked together. |
1399 for (int i = 0; i < kNumTestContexts; i++) { | 1404 for (int i = 0; i < kNumTestContexts; i++) { |
1400 ctx[i] = v8::Context::New(CcTest::isolate()); | 1405 ctx[i] = v8::Context::New(CcTest::isolate()); |
1401 | 1406 |
1402 // Collect garbage that might have been created by one of the | 1407 // Collect garbage that might have been created by one of the |
1403 // installed extensions. | 1408 // installed extensions. |
1404 isolate->compilation_cache()->Clear(); | 1409 isolate->compilation_cache()->Clear(); |
1405 heap->CollectAllGarbage(Heap::kNoGCFlags); | 1410 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1406 | |
1407 bool opt = (FLAG_always_opt && isolate->use_crankshaft()); | |
1408 | 1411 |
1409 CHECK_EQ(i + 1, CountNativeContexts()); | 1412 CHECK_EQ(i + 1, CountNativeContexts()); |
1410 | 1413 |
1411 ctx[i]->Enter(); | 1414 ctx[i]->Enter(); |
1412 | 1415 |
1413 // Create a handle scope so no function objects get stuch in the outer | 1416 // Create a handle scope so no function objects get stuch in the outer |
1414 // handle scope | 1417 // handle scope |
1415 HandleScope scope(isolate); | 1418 HandleScope scope(isolate); |
1416 const char* source = "function f1() { };" | 1419 const char* source = "function f1() { };" |
1417 "function f2() { };" | 1420 "function f2() { };" |
1418 "function f3() { };" | 1421 "function f3() { };" |
1419 "function f4() { };" | 1422 "function f4() { };" |
1420 "function f5() { };"; | 1423 "function f5() { };"; |
1421 CompileRun(source); | 1424 CompileRun(source); |
1422 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i])); | 1425 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i])); |
1423 CompileRun("f1()"); | 1426 CompileRun("f1(); %OptimizeFunctionOnNextCall(f1); f1()"); |
1424 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[i])); | 1427 CHECK_EQ(1, CountOptimizedUserFunctions(ctx[i])); |
1425 CompileRun("f2()"); | 1428 CompileRun("f2(); %OptimizeFunctionOnNextCall(f2); f2()"); |
1426 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); | 1429 CHECK_EQ(2, CountOptimizedUserFunctions(ctx[i])); |
1427 CompileRun("f3()"); | 1430 CompileRun("f3(); %OptimizeFunctionOnNextCall(f3); f3()"); |
1428 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); | 1431 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i])); |
1429 CompileRun("f4()"); | 1432 CompileRun("f4(); %OptimizeFunctionOnNextCall(f4); f4()"); |
1430 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1433 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i])); |
1431 CompileRun("f5()"); | 1434 CompileRun("f5(); %OptimizeFunctionOnNextCall(f5); f5()"); |
1432 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); | 1435 CHECK_EQ(5, CountOptimizedUserFunctions(ctx[i])); |
1433 | 1436 |
1434 // Remove function f1, and | 1437 // Remove function f1, and |
1435 CompileRun("f1=null"); | 1438 CompileRun("f1=null"); |
1436 | 1439 |
1437 // Scavenge treats these references as strong. | 1440 // Scavenge treats these references as strong. |
1438 for (int j = 0; j < 10; j++) { | 1441 for (int j = 0; j < kNumTestCollections; j++) { |
1439 CcTest::heap()->CollectGarbage(NEW_SPACE); | 1442 CcTest::heap()->CollectGarbage(NEW_SPACE); |
1440 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); | 1443 CHECK_EQ(5, CountOptimizedUserFunctions(ctx[i])); |
1441 } | 1444 } |
1442 | 1445 |
1443 // Mark compact handles the weak references. | 1446 // Mark compact handles the weak references. |
1444 isolate->compilation_cache()->Clear(); | 1447 isolate->compilation_cache()->Clear(); |
1445 heap->CollectAllGarbage(Heap::kNoGCFlags); | 1448 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1446 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1449 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i])); |
1447 | 1450 |
1448 // Get rid of f3 and f5 in the same way. | 1451 // Get rid of f3 and f5 in the same way. |
1449 CompileRun("f3=null"); | 1452 CompileRun("f3=null"); |
1450 for (int j = 0; j < 10; j++) { | 1453 for (int j = 0; j < kNumTestCollections; j++) { |
1451 CcTest::heap()->CollectGarbage(NEW_SPACE); | 1454 CcTest::heap()->CollectGarbage(NEW_SPACE); |
1452 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1455 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i])); |
1453 } | 1456 } |
1454 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1457 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1455 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); | 1458 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i])); |
1456 CompileRun("f5=null"); | 1459 CompileRun("f5=null"); |
1457 for (int j = 0; j < 10; j++) { | 1460 for (int j = 0; j < kNumTestCollections; j++) { |
1458 CcTest::heap()->CollectGarbage(NEW_SPACE); | 1461 CcTest::heap()->CollectGarbage(NEW_SPACE); |
1459 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); | 1462 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i])); |
1460 } | 1463 } |
1461 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1464 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1462 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); | 1465 CHECK_EQ(2, CountOptimizedUserFunctions(ctx[i])); |
1463 | 1466 |
1464 ctx[i]->Exit(); | 1467 ctx[i]->Exit(); |
1465 } | 1468 } |
1466 | 1469 |
1467 // Force compilation cache cleanup. | 1470 // Force compilation cache cleanup. |
1468 CcTest::heap()->NotifyContextDisposed(); | 1471 CcTest::heap()->NotifyContextDisposed(); |
1469 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1472 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1470 | 1473 |
1471 // Dispose the native contexts one by one. | 1474 // Dispose the native contexts one by one. |
1472 for (int i = 0; i < kNumTestContexts; i++) { | 1475 for (int i = 0; i < kNumTestContexts; i++) { |
1473 // TODO(dcarney): is there a better way to do this? | 1476 // TODO(dcarney): is there a better way to do this? |
1474 i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]); | 1477 i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]); |
1475 *unsafe = CcTest::heap()->undefined_value(); | 1478 *unsafe = CcTest::heap()->undefined_value(); |
1476 ctx[i].Clear(); | 1479 ctx[i].Clear(); |
1477 | 1480 |
1478 // Scavenge treats these references as strong. | 1481 // Scavenge treats these references as strong. |
1479 for (int j = 0; j < 10; j++) { | 1482 for (int j = 0; j < kNumTestCollections; j++) { |
1480 CcTest::heap()->CollectGarbage(i::NEW_SPACE); | 1483 CcTest::heap()->CollectGarbage(i::NEW_SPACE); |
1481 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); | 1484 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); |
1482 } | 1485 } |
1483 | 1486 |
1484 // Mark compact handles the weak references. | 1487 // Mark compact handles the weak references. |
1485 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1488 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1486 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); | 1489 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); |
1487 } | 1490 } |
1488 | 1491 |
1489 CHECK_EQ(0, CountNativeContexts()); | 1492 CHECK_EQ(0, CountNativeContexts()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1523 if (count == n) isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1526 if (count == n) isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1524 object = Handle<Object>( | 1527 object = Handle<Object>( |
1525 Object::cast(JSFunction::cast(*object)->next_function_link()), | 1528 Object::cast(JSFunction::cast(*object)->next_function_link()), |
1526 isolate); | 1529 isolate); |
1527 } | 1530 } |
1528 return count; | 1531 return count; |
1529 } | 1532 } |
1530 | 1533 |
1531 | 1534 |
1532 TEST(TestInternalWeakListsTraverseWithGC) { | 1535 TEST(TestInternalWeakListsTraverseWithGC) { |
| 1536 FLAG_allow_natives_syntax = true; |
1533 v8::V8::Initialize(); | 1537 v8::V8::Initialize(); |
1534 Isolate* isolate = CcTest::i_isolate(); | 1538 Isolate* isolate = CcTest::i_isolate(); |
1535 | 1539 |
1536 static const int kNumTestContexts = 10; | 1540 // TODO(mstarzinger): Test should be resilient against optimization decisions. |
| 1541 if (i::FLAG_always_opt) return; |
| 1542 if (!isolate->use_crankshaft()) return; |
| 1543 |
| 1544 static const int kNumTestContexts = 5; |
1537 | 1545 |
1538 HandleScope scope(isolate); | 1546 HandleScope scope(isolate); |
1539 v8::Handle<v8::Context> ctx[kNumTestContexts]; | 1547 v8::Handle<v8::Context> ctx[kNumTestContexts]; |
1540 | 1548 |
1541 CHECK_EQ(0, CountNativeContexts()); | 1549 CHECK_EQ(0, CountNativeContexts()); |
1542 | 1550 |
1543 // Create an number of contexts and check the length of the weak list both | 1551 // Create an number of contexts and check the length of the weak list both |
1544 // with and without GCs while iterating the list. | 1552 // with and without GCs while iterating the list. |
1545 for (int i = 0; i < kNumTestContexts; i++) { | 1553 for (int i = 0; i < kNumTestContexts; i++) { |
1546 ctx[i] = v8::Context::New(CcTest::isolate()); | 1554 ctx[i] = v8::Context::New(CcTest::isolate()); |
1547 CHECK_EQ(i + 1, CountNativeContexts()); | 1555 CHECK_EQ(i + 1, CountNativeContexts()); |
1548 CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); | 1556 CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); |
1549 } | 1557 } |
1550 | 1558 |
1551 bool opt = (FLAG_always_opt && isolate->use_crankshaft()); | |
1552 | |
1553 // Compile a number of functions the length of the weak list of optimized | 1559 // Compile a number of functions the length of the weak list of optimized |
1554 // functions both with and without GCs while iterating the list. | 1560 // functions both with and without GCs while iterating the list. |
1555 ctx[0]->Enter(); | 1561 ctx[0]->Enter(); |
1556 const char* source = "function f1() { };" | 1562 const char* source = "function f1() { };" |
1557 "function f2() { };" | 1563 "function f2() { };" |
1558 "function f3() { };" | 1564 "function f3() { };" |
1559 "function f4() { };" | 1565 "function f4() { };" |
1560 "function f5() { };"; | 1566 "function f5() { };"; |
1561 CompileRun(source); | 1567 CompileRun(source); |
1562 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[0])); | 1568 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[0])); |
1563 CompileRun("f1()"); | 1569 CompileRun("f1(); %OptimizeFunctionOnNextCall(f1); f1()"); |
1564 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[0])); | 1570 CHECK_EQ(1, CountOptimizedUserFunctions(ctx[0])); |
1565 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); | 1571 CHECK_EQ(1, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
1566 CompileRun("f2()"); | 1572 CompileRun("f2(); %OptimizeFunctionOnNextCall(f2); f2()"); |
1567 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[0])); | 1573 CHECK_EQ(2, CountOptimizedUserFunctions(ctx[0])); |
1568 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); | 1574 CHECK_EQ(2, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
1569 CompileRun("f3()"); | 1575 CompileRun("f3(); %OptimizeFunctionOnNextCall(f3); f3()"); |
1570 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[0])); | 1576 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[0])); |
1571 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); | 1577 CHECK_EQ(3, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
1572 CompileRun("f4()"); | 1578 CompileRun("f4(); %OptimizeFunctionOnNextCall(f4); f4()"); |
1573 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[0])); | 1579 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[0])); |
1574 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 2)); | 1580 CHECK_EQ(4, CountOptimizedUserFunctionsWithGC(ctx[0], 2)); |
1575 CompileRun("f5()"); | 1581 CompileRun("f5(); %OptimizeFunctionOnNextCall(f5); f5()"); |
1576 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0])); | 1582 CHECK_EQ(5, CountOptimizedUserFunctions(ctx[0])); |
1577 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4)); | 1583 CHECK_EQ(5, CountOptimizedUserFunctionsWithGC(ctx[0], 4)); |
1578 | 1584 |
1579 ctx[0]->Exit(); | 1585 ctx[0]->Exit(); |
1580 } | 1586 } |
1581 | 1587 |
1582 | 1588 |
1583 TEST(TestSizeOfObjects) { | 1589 TEST(TestSizeOfObjects) { |
1584 v8::V8::Initialize(); | 1590 v8::V8::Initialize(); |
1585 | 1591 |
1586 // Get initial heap size after several full GCs, which will stabilize | 1592 // Get initial heap size after several full GCs, which will stabilize |
1587 // the heap size and return with sweeping finished completely. | 1593 // the heap size and return with sweeping finished completely. |
(...skipping 2441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4029 return result; | 4035 return result; |
4030 } | 4036 } |
4031 | 4037 |
4032 | 4038 |
4033 TEST(NextCodeLinkIsWeak) { | 4039 TEST(NextCodeLinkIsWeak) { |
4034 i::FLAG_allow_natives_syntax = true; | 4040 i::FLAG_allow_natives_syntax = true; |
4035 CcTest::InitializeVM(); | 4041 CcTest::InitializeVM(); |
4036 Isolate* isolate = CcTest::i_isolate(); | 4042 Isolate* isolate = CcTest::i_isolate(); |
4037 v8::internal::Heap* heap = CcTest::heap(); | 4043 v8::internal::Heap* heap = CcTest::heap(); |
4038 | 4044 |
| 4045 // TODO(titzer): Test should be resilient against optimization decisions. |
| 4046 if (i::FLAG_always_opt) return; |
4039 if (!isolate->use_crankshaft()) return; | 4047 if (!isolate->use_crankshaft()) return; |
| 4048 |
4040 HandleScope outer_scope(heap->isolate()); | 4049 HandleScope outer_scope(heap->isolate()); |
4041 Handle<Code> code; | 4050 Handle<Code> code; |
4042 heap->CollectAllAvailableGarbage(); | 4051 heap->CollectAllAvailableGarbage(); |
4043 int code_chain_length_before, code_chain_length_after; | 4052 int code_chain_length_before, code_chain_length_after; |
4044 { | 4053 { |
4045 HandleScope scope(heap->isolate()); | 4054 HandleScope scope(heap->isolate()); |
4046 Handle<JSFunction> mortal = OptimizeDummyFunction("mortal"); | 4055 Handle<JSFunction> mortal = OptimizeDummyFunction("mortal"); |
4047 Handle<JSFunction> immortal = OptimizeDummyFunction("immortal"); | 4056 Handle<JSFunction> immortal = OptimizeDummyFunction("immortal"); |
4048 CHECK_EQ(immortal->code()->next_code_link(), mortal->code()); | 4057 CHECK_EQ(immortal->code()->next_code_link(), mortal->code()); |
4049 code_chain_length_before = GetCodeChainLength(immortal->code()); | 4058 code_chain_length_before = GetCodeChainLength(immortal->code()); |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4408 #ifdef DEBUG | 4417 #ifdef DEBUG |
4409 TEST(PathTracer) { | 4418 TEST(PathTracer) { |
4410 CcTest::InitializeVM(); | 4419 CcTest::InitializeVM(); |
4411 v8::HandleScope scope(CcTest::isolate()); | 4420 v8::HandleScope scope(CcTest::isolate()); |
4412 | 4421 |
4413 v8::Local<v8::Value> result = CompileRun("'abc'"); | 4422 v8::Local<v8::Value> result = CompileRun("'abc'"); |
4414 Handle<Object> o = v8::Utils::OpenHandle(*result); | 4423 Handle<Object> o = v8::Utils::OpenHandle(*result); |
4415 CcTest::i_isolate()->heap()->TracePathToObject(*o); | 4424 CcTest::i_isolate()->heap()->TracePathToObject(*o); |
4416 } | 4425 } |
4417 #endif // DEBUG | 4426 #endif // DEBUG |
OLD | NEW |