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 1416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 } | 1427 } |
1428 | 1428 |
1429 // If we aged the cache before caching the script, ensure that we didn't cache | 1429 // If we aged the cache before caching the script, ensure that we didn't cache |
1430 // on next compilation. | 1430 // on next compilation. |
1431 info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false, | 1431 info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false, |
1432 true, native_context, language_mode); | 1432 true, native_context, language_mode); |
1433 CHECK(info.is_null()); | 1433 CHECK(info.is_null()); |
1434 } | 1434 } |
1435 | 1435 |
1436 | 1436 |
| 1437 static void OptimizeEmptyFunction(const char* name) { |
| 1438 HandleScope scope(CcTest::i_isolate()); |
| 1439 EmbeddedVector<char, 256> source; |
| 1440 SNPrintF(source, |
| 1441 "function %s() { return 0; }" |
| 1442 "%s(); %s();" |
| 1443 "%%OptimizeFunctionOnNextCall(%s);" |
| 1444 "%s();", |
| 1445 name, name, name, name, name); |
| 1446 CompileRun(source.start()); |
| 1447 } |
| 1448 |
| 1449 |
1437 // Count the number of native contexts in the weak list of native contexts. | 1450 // Count the number of native contexts in the weak list of native contexts. |
1438 int CountNativeContexts() { | 1451 int CountNativeContexts() { |
1439 int count = 0; | 1452 int count = 0; |
1440 Object* object = CcTest::heap()->native_contexts_list(); | 1453 Object* object = CcTest::heap()->native_contexts_list(); |
1441 while (!object->IsUndefined()) { | 1454 while (!object->IsUndefined()) { |
1442 count++; | 1455 count++; |
1443 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); | 1456 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); |
1444 } | 1457 } |
1445 return count; | 1458 return count; |
1446 } | 1459 } |
1447 | 1460 |
1448 | 1461 |
1449 // Count the number of user functions in the weak list of optimized | 1462 // Count the number of user functions in the weak list of optimized |
1450 // functions attached to a native context. | 1463 // functions attached to a native context. |
1451 static int CountOptimizedUserFunctions(v8::Handle<v8::Context> context) { | 1464 static int CountOptimizedUserFunctions(v8::Handle<v8::Context> context) { |
1452 int count = 0; | 1465 int count = 0; |
1453 Handle<Context> icontext = v8::Utils::OpenHandle(*context); | 1466 Handle<Context> icontext = v8::Utils::OpenHandle(*context); |
1454 Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST); | 1467 Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST); |
1455 while (object->IsJSFunction() && !JSFunction::cast(object)->IsBuiltin()) { | 1468 while (object->IsJSFunction() && !JSFunction::cast(object)->IsBuiltin()) { |
1456 count++; | 1469 count++; |
1457 object = JSFunction::cast(object)->next_function_link(); | 1470 object = JSFunction::cast(object)->next_function_link(); |
1458 } | 1471 } |
1459 return count; | 1472 return count; |
1460 } | 1473 } |
1461 | 1474 |
1462 | 1475 |
1463 TEST(TestInternalWeakLists) { | 1476 TEST(TestInternalWeakLists) { |
| 1477 FLAG_always_opt = false; |
| 1478 FLAG_allow_natives_syntax = true; |
1464 v8::V8::Initialize(); | 1479 v8::V8::Initialize(); |
1465 | 1480 |
1466 // Some flags turn Scavenge collections into Mark-sweep collections | 1481 // Some flags turn Scavenge collections into Mark-sweep collections |
1467 // and hence are incompatible with this test case. | 1482 // and hence are incompatible with this test case. |
1468 if (FLAG_gc_global || FLAG_stress_compaction) return; | 1483 if (FLAG_gc_global || FLAG_stress_compaction) return; |
1469 FLAG_retain_maps_for_n_gc = 0; | 1484 FLAG_retain_maps_for_n_gc = 0; |
1470 | 1485 |
1471 static const int kNumTestContexts = 10; | 1486 static const int kNumTestContexts = 10; |
1472 | 1487 |
1473 Isolate* isolate = CcTest::i_isolate(); | 1488 Isolate* isolate = CcTest::i_isolate(); |
1474 Heap* heap = isolate->heap(); | 1489 Heap* heap = isolate->heap(); |
1475 HandleScope scope(isolate); | 1490 HandleScope scope(isolate); |
1476 v8::Handle<v8::Context> ctx[kNumTestContexts]; | 1491 v8::Handle<v8::Context> ctx[kNumTestContexts]; |
| 1492 if (!isolate->use_crankshaft()) return; |
1477 | 1493 |
1478 CHECK_EQ(0, CountNativeContexts()); | 1494 CHECK_EQ(0, CountNativeContexts()); |
1479 | 1495 |
1480 // Create a number of global contests which gets linked together. | 1496 // Create a number of global contests which gets linked together. |
1481 for (int i = 0; i < kNumTestContexts; i++) { | 1497 for (int i = 0; i < kNumTestContexts; i++) { |
1482 ctx[i] = v8::Context::New(CcTest::isolate()); | 1498 ctx[i] = v8::Context::New(CcTest::isolate()); |
1483 | 1499 |
1484 // Collect garbage that might have been created by one of the | 1500 // Collect garbage that might have been created by one of the |
1485 // installed extensions. | 1501 // installed extensions. |
1486 isolate->compilation_cache()->Clear(); | 1502 isolate->compilation_cache()->Clear(); |
1487 heap->CollectAllGarbage(Heap::kNoGCFlags); | 1503 heap->CollectAllGarbage(Heap::kNoGCFlags); |
1488 | 1504 |
1489 bool opt = (FLAG_always_opt && isolate->use_crankshaft()); | |
1490 | |
1491 CHECK_EQ(i + 1, CountNativeContexts()); | 1505 CHECK_EQ(i + 1, CountNativeContexts()); |
1492 | 1506 |
1493 ctx[i]->Enter(); | 1507 ctx[i]->Enter(); |
1494 | 1508 |
1495 // Create a handle scope so no function objects get stuch in the outer | 1509 // Create a handle scope so no function objects get stuck in the outer |
1496 // handle scope | 1510 // handle scope. |
1497 HandleScope scope(isolate); | 1511 HandleScope scope(isolate); |
1498 const char* source = "function f1() { };" | |
1499 "function f2() { };" | |
1500 "function f3() { };" | |
1501 "function f4() { };" | |
1502 "function f5() { };"; | |
1503 CompileRun(source); | |
1504 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i])); | 1512 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i])); |
1505 CompileRun("f1()"); | 1513 OptimizeEmptyFunction("f1"); |
1506 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[i])); | 1514 CHECK_EQ(1, CountOptimizedUserFunctions(ctx[i])); |
1507 CompileRun("f2()"); | 1515 OptimizeEmptyFunction("f2"); |
1508 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); | 1516 CHECK_EQ(2, CountOptimizedUserFunctions(ctx[i])); |
1509 CompileRun("f3()"); | 1517 OptimizeEmptyFunction("f3"); |
1510 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); | 1518 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i])); |
1511 CompileRun("f4()"); | 1519 OptimizeEmptyFunction("f4"); |
1512 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1520 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i])); |
1513 CompileRun("f5()"); | 1521 OptimizeEmptyFunction("f5"); |
1514 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); | 1522 CHECK_EQ(5, CountOptimizedUserFunctions(ctx[i])); |
1515 | 1523 |
1516 // Remove function f1, and | 1524 // Remove function f1, and |
1517 CompileRun("f1=null"); | 1525 CompileRun("f1=null"); |
1518 | 1526 |
1519 // Scavenge treats these references as strong. | 1527 // Scavenge treats these references as strong. |
1520 for (int j = 0; j < 10; j++) { | 1528 for (int j = 0; j < 10; j++) { |
1521 CcTest::heap()->CollectGarbage(NEW_SPACE); | 1529 CcTest::heap()->CollectGarbage(NEW_SPACE); |
1522 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); | 1530 CHECK_EQ(5, CountOptimizedUserFunctions(ctx[i])); |
1523 } | 1531 } |
1524 | 1532 |
1525 // Mark compact handles the weak references. | 1533 // Mark compact handles the weak references. |
1526 isolate->compilation_cache()->Clear(); | 1534 isolate->compilation_cache()->Clear(); |
1527 heap->CollectAllGarbage(Heap::kNoGCFlags); | 1535 heap->CollectAllGarbage(Heap::kNoGCFlags); |
1528 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1536 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i])); |
1529 | 1537 |
1530 // Get rid of f3 and f5 in the same way. | 1538 // Get rid of f3 and f5 in the same way. |
1531 CompileRun("f3=null"); | 1539 CompileRun("f3=null"); |
1532 for (int j = 0; j < 10; j++) { | 1540 for (int j = 0; j < 10; j++) { |
1533 CcTest::heap()->CollectGarbage(NEW_SPACE); | 1541 CcTest::heap()->CollectGarbage(NEW_SPACE); |
1534 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1542 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i])); |
1535 } | 1543 } |
1536 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1544 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1537 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); | 1545 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i])); |
1538 CompileRun("f5=null"); | 1546 CompileRun("f5=null"); |
1539 for (int j = 0; j < 10; j++) { | 1547 for (int j = 0; j < 10; j++) { |
1540 CcTest::heap()->CollectGarbage(NEW_SPACE); | 1548 CcTest::heap()->CollectGarbage(NEW_SPACE); |
1541 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); | 1549 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i])); |
1542 } | 1550 } |
1543 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1551 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1544 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); | 1552 CHECK_EQ(2, CountOptimizedUserFunctions(ctx[i])); |
1545 | 1553 |
1546 ctx[i]->Exit(); | 1554 ctx[i]->Exit(); |
1547 } | 1555 } |
1548 | 1556 |
1549 // Force compilation cache cleanup. | 1557 // Force compilation cache cleanup. |
1550 CcTest::heap()->NotifyContextDisposed(true); | 1558 CcTest::heap()->NotifyContextDisposed(true); |
1551 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1559 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1552 | 1560 |
1553 // Dispose the native contexts one by one. | 1561 // Dispose the native contexts one by one. |
1554 for (int i = 0; i < kNumTestContexts; i++) { | 1562 for (int i = 0; i < kNumTestContexts; i++) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1605 if (count == n) isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1613 if (count == n) isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1606 object = Handle<Object>( | 1614 object = Handle<Object>( |
1607 Object::cast(JSFunction::cast(*object)->next_function_link()), | 1615 Object::cast(JSFunction::cast(*object)->next_function_link()), |
1608 isolate); | 1616 isolate); |
1609 } | 1617 } |
1610 return count; | 1618 return count; |
1611 } | 1619 } |
1612 | 1620 |
1613 | 1621 |
1614 TEST(TestInternalWeakListsTraverseWithGC) { | 1622 TEST(TestInternalWeakListsTraverseWithGC) { |
| 1623 FLAG_always_opt = false; |
| 1624 FLAG_allow_natives_syntax = true; |
1615 v8::V8::Initialize(); | 1625 v8::V8::Initialize(); |
1616 Isolate* isolate = CcTest::i_isolate(); | |
1617 | 1626 |
1618 static const int kNumTestContexts = 10; | 1627 static const int kNumTestContexts = 10; |
1619 | 1628 |
| 1629 Isolate* isolate = CcTest::i_isolate(); |
1620 HandleScope scope(isolate); | 1630 HandleScope scope(isolate); |
1621 v8::Handle<v8::Context> ctx[kNumTestContexts]; | 1631 v8::Handle<v8::Context> ctx[kNumTestContexts]; |
| 1632 if (!isolate->use_crankshaft()) return; |
1622 | 1633 |
1623 CHECK_EQ(0, CountNativeContexts()); | 1634 CHECK_EQ(0, CountNativeContexts()); |
1624 | 1635 |
1625 // Create an number of contexts and check the length of the weak list both | 1636 // Create an number of contexts and check the length of the weak list both |
1626 // with and without GCs while iterating the list. | 1637 // with and without GCs while iterating the list. |
1627 for (int i = 0; i < kNumTestContexts; i++) { | 1638 for (int i = 0; i < kNumTestContexts; i++) { |
1628 ctx[i] = v8::Context::New(CcTest::isolate()); | 1639 ctx[i] = v8::Context::New(CcTest::isolate()); |
1629 CHECK_EQ(i + 1, CountNativeContexts()); | 1640 CHECK_EQ(i + 1, CountNativeContexts()); |
1630 CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); | 1641 CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); |
1631 } | 1642 } |
1632 | 1643 |
1633 bool opt = (FLAG_always_opt && isolate->use_crankshaft()); | 1644 ctx[0]->Enter(); |
1634 | 1645 |
1635 // Compile a number of functions the length of the weak list of optimized | 1646 // Compile a number of functions the length of the weak list of optimized |
1636 // functions both with and without GCs while iterating the list. | 1647 // functions both with and without GCs while iterating the list. |
1637 ctx[0]->Enter(); | |
1638 const char* source = "function f1() { };" | |
1639 "function f2() { };" | |
1640 "function f3() { };" | |
1641 "function f4() { };" | |
1642 "function f5() { };"; | |
1643 CompileRun(source); | |
1644 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[0])); | 1648 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[0])); |
1645 CompileRun("f1()"); | 1649 OptimizeEmptyFunction("f1"); |
1646 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[0])); | 1650 CHECK_EQ(1, CountOptimizedUserFunctions(ctx[0])); |
1647 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); | 1651 CHECK_EQ(1, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
1648 CompileRun("f2()"); | 1652 OptimizeEmptyFunction("f2"); |
1649 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[0])); | 1653 CHECK_EQ(2, CountOptimizedUserFunctions(ctx[0])); |
1650 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); | 1654 CHECK_EQ(2, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
1651 CompileRun("f3()"); | 1655 OptimizeEmptyFunction("f3"); |
1652 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[0])); | 1656 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[0])); |
1653 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); | 1657 CHECK_EQ(3, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
1654 CompileRun("f4()"); | 1658 OptimizeEmptyFunction("f4"); |
1655 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[0])); | 1659 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[0])); |
1656 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 2)); | 1660 CHECK_EQ(4, CountOptimizedUserFunctionsWithGC(ctx[0], 2)); |
1657 CompileRun("f5()"); | 1661 OptimizeEmptyFunction("f5"); |
1658 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0])); | 1662 CHECK_EQ(5, CountOptimizedUserFunctions(ctx[0])); |
1659 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4)); | 1663 CHECK_EQ(5, CountOptimizedUserFunctionsWithGC(ctx[0], 4)); |
1660 | 1664 |
1661 ctx[0]->Exit(); | 1665 ctx[0]->Exit(); |
1662 } | 1666 } |
1663 | 1667 |
1664 | 1668 |
1665 TEST(TestSizeOfRegExpCode) { | 1669 TEST(TestSizeOfRegExpCode) { |
1666 if (!FLAG_regexp_optimization) return; | 1670 if (!FLAG_regexp_optimization) return; |
1667 | 1671 |
1668 v8::V8::Initialize(); | 1672 v8::V8::Initialize(); |
1669 | 1673 |
(...skipping 2714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4384 int result = 0; | 4388 int result = 0; |
4385 while (code->next_code_link()->IsCode()) { | 4389 while (code->next_code_link()->IsCode()) { |
4386 result++; | 4390 result++; |
4387 code = Code::cast(code->next_code_link()); | 4391 code = Code::cast(code->next_code_link()); |
4388 } | 4392 } |
4389 return result; | 4393 return result; |
4390 } | 4394 } |
4391 | 4395 |
4392 | 4396 |
4393 TEST(NextCodeLinkIsWeak) { | 4397 TEST(NextCodeLinkIsWeak) { |
| 4398 i::FLAG_always_opt = false; |
4394 i::FLAG_allow_natives_syntax = true; | 4399 i::FLAG_allow_natives_syntax = true; |
4395 i::FLAG_turbo_deoptimization = true; | 4400 i::FLAG_turbo_deoptimization = true; |
4396 CcTest::InitializeVM(); | 4401 CcTest::InitializeVM(); |
4397 Isolate* isolate = CcTest::i_isolate(); | 4402 Isolate* isolate = CcTest::i_isolate(); |
4398 v8::internal::Heap* heap = CcTest::heap(); | 4403 v8::internal::Heap* heap = CcTest::heap(); |
4399 | 4404 |
4400 if (!isolate->use_crankshaft()) return; | 4405 if (!isolate->use_crankshaft()) return; |
4401 HandleScope outer_scope(heap->isolate()); | 4406 HandleScope outer_scope(heap->isolate()); |
4402 Handle<Code> code; | 4407 Handle<Code> code; |
4403 heap->CollectAllAvailableGarbage(); | 4408 heap->CollectAllAvailableGarbage(); |
(...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5354 TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 8, 6); | 5359 TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 8, 6); |
5355 TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 8 - 1, 6); | 5360 TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 8 - 1, 6); |
5356 | 5361 |
5357 // 32-bit cases. | 5362 // 32-bit cases. |
5358 TestRightTrimFixedTypedArray(v8::kExternalUint8Array, 16, 3); | 5363 TestRightTrimFixedTypedArray(v8::kExternalUint8Array, 16, 3); |
5359 TestRightTrimFixedTypedArray(v8::kExternalUint8Array, 16 - 3, 3); | 5364 TestRightTrimFixedTypedArray(v8::kExternalUint8Array, 16 - 3, 3); |
5360 TestRightTrimFixedTypedArray(v8::kExternalUint16Array, 8, 3); | 5365 TestRightTrimFixedTypedArray(v8::kExternalUint16Array, 8, 3); |
5361 TestRightTrimFixedTypedArray(v8::kExternalUint16Array, 8 - 1, 3); | 5366 TestRightTrimFixedTypedArray(v8::kExternalUint16Array, 8 - 1, 3); |
5362 TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 4, 3); | 5367 TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 4, 3); |
5363 } | 5368 } |
OLD | NEW |