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 1398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST); | 1409 Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST); |
1410 while (object->IsJSFunction() && !JSFunction::cast(object)->IsBuiltin()) { | 1410 while (object->IsJSFunction() && !JSFunction::cast(object)->IsBuiltin()) { |
1411 count++; | 1411 count++; |
1412 object = JSFunction::cast(object)->next_function_link(); | 1412 object = JSFunction::cast(object)->next_function_link(); |
1413 } | 1413 } |
1414 return count; | 1414 return count; |
1415 } | 1415 } |
1416 | 1416 |
1417 | 1417 |
1418 TEST(TestInternalWeakLists) { | 1418 TEST(TestInternalWeakLists) { |
1419 FLAG_allow_natives_syntax = true; | |
1420 v8::V8::Initialize(); | 1419 v8::V8::Initialize(); |
1421 Isolate* isolate = CcTest::i_isolate(); | |
1422 | |
1423 // TODO(mstarzinger): Test should be resilient against optimization decisions. | |
1424 if (i::FLAG_always_opt) return; | |
1425 if (!isolate->use_crankshaft()) return; | |
1426 | 1420 |
1427 // Some flags turn Scavenge collections into Mark-sweep collections | 1421 // Some flags turn Scavenge collections into Mark-sweep collections |
1428 // and hence are incompatible with this test case. | 1422 // and hence are incompatible with this test case. |
1429 if (FLAG_gc_global || FLAG_stress_compaction) return; | 1423 if (FLAG_gc_global || FLAG_stress_compaction) return; |
1430 | 1424 |
1431 static const int kNumTestContexts = 5; | 1425 static const int kNumTestContexts = 10; |
1432 static const int kNumTestCollections = 3; | |
1433 | 1426 |
| 1427 Isolate* isolate = CcTest::i_isolate(); |
| 1428 Heap* heap = isolate->heap(); |
1434 HandleScope scope(isolate); | 1429 HandleScope scope(isolate); |
1435 v8::Handle<v8::Context> ctx[kNumTestContexts]; | 1430 v8::Handle<v8::Context> ctx[kNumTestContexts]; |
1436 | 1431 |
1437 CHECK_EQ(0, CountNativeContexts()); | 1432 CHECK_EQ(0, CountNativeContexts()); |
1438 | 1433 |
1439 // Create a number of global contests which gets linked together. | 1434 // Create a number of global contests which gets linked together. |
1440 for (int i = 0; i < kNumTestContexts; i++) { | 1435 for (int i = 0; i < kNumTestContexts; i++) { |
1441 ctx[i] = v8::Context::New(CcTest::isolate()); | 1436 ctx[i] = v8::Context::New(CcTest::isolate()); |
1442 | 1437 |
1443 // Collect garbage that might have been created by one of the | 1438 // Collect garbage that might have been created by one of the |
1444 // installed extensions. | 1439 // installed extensions. |
1445 isolate->compilation_cache()->Clear(); | 1440 isolate->compilation_cache()->Clear(); |
1446 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1441 heap->CollectAllGarbage(Heap::kNoGCFlags); |
| 1442 |
| 1443 bool opt = (FLAG_always_opt && isolate->use_crankshaft()); |
1447 | 1444 |
1448 CHECK_EQ(i + 1, CountNativeContexts()); | 1445 CHECK_EQ(i + 1, CountNativeContexts()); |
1449 | 1446 |
1450 ctx[i]->Enter(); | 1447 ctx[i]->Enter(); |
1451 | 1448 |
1452 // Create a handle scope so no function objects get stuch in the outer | 1449 // Create a handle scope so no function objects get stuch in the outer |
1453 // handle scope | 1450 // handle scope |
1454 HandleScope scope(isolate); | 1451 HandleScope scope(isolate); |
1455 const char* source = "function f1() { };" | 1452 const char* source = "function f1() { };" |
1456 "function f2() { };" | 1453 "function f2() { };" |
1457 "function f3() { };" | 1454 "function f3() { };" |
1458 "function f4() { };" | 1455 "function f4() { };" |
1459 "function f5() { };"; | 1456 "function f5() { };"; |
1460 CompileRun(source); | 1457 CompileRun(source); |
1461 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i])); | 1458 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i])); |
1462 CompileRun("f1(); %OptimizeFunctionOnNextCall(f1); f1()"); | 1459 CompileRun("f1()"); |
1463 CHECK_EQ(1, CountOptimizedUserFunctions(ctx[i])); | 1460 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[i])); |
1464 CompileRun("f2(); %OptimizeFunctionOnNextCall(f2); f2()"); | 1461 CompileRun("f2()"); |
1465 CHECK_EQ(2, CountOptimizedUserFunctions(ctx[i])); | 1462 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); |
1466 CompileRun("f3(); %OptimizeFunctionOnNextCall(f3); f3()"); | 1463 CompileRun("f3()"); |
1467 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i])); | 1464 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); |
1468 CompileRun("f4(); %OptimizeFunctionOnNextCall(f4); f4()"); | 1465 CompileRun("f4()"); |
1469 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i])); | 1466 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
1470 CompileRun("f5(); %OptimizeFunctionOnNextCall(f5); f5()"); | 1467 CompileRun("f5()"); |
1471 CHECK_EQ(5, CountOptimizedUserFunctions(ctx[i])); | 1468 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); |
1472 | 1469 |
1473 // Remove function f1, and | 1470 // Remove function f1, and |
1474 CompileRun("f1=null"); | 1471 CompileRun("f1=null"); |
1475 | 1472 |
1476 // Scavenge treats these references as strong. | 1473 // Scavenge treats these references as strong. |
1477 for (int j = 0; j < kNumTestCollections; j++) { | 1474 for (int j = 0; j < 10; j++) { |
1478 CcTest::heap()->CollectGarbage(NEW_SPACE); | 1475 CcTest::heap()->CollectGarbage(NEW_SPACE); |
1479 CHECK_EQ(5, CountOptimizedUserFunctions(ctx[i])); | 1476 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); |
1480 } | 1477 } |
1481 | 1478 |
1482 // Mark compact handles the weak references. | 1479 // Mark compact handles the weak references. |
1483 isolate->compilation_cache()->Clear(); | 1480 isolate->compilation_cache()->Clear(); |
1484 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1481 heap->CollectAllGarbage(Heap::kNoGCFlags); |
1485 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i])); | 1482 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
1486 | 1483 |
1487 // Get rid of f3 and f5 in the same way. | 1484 // Get rid of f3 and f5 in the same way. |
1488 CompileRun("f3=null"); | 1485 CompileRun("f3=null"); |
1489 for (int j = 0; j < kNumTestCollections; j++) { | 1486 for (int j = 0; j < 10; j++) { |
1490 CcTest::heap()->CollectGarbage(NEW_SPACE); | 1487 CcTest::heap()->CollectGarbage(NEW_SPACE); |
1491 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i])); | 1488 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
1492 } | 1489 } |
1493 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1490 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1494 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i])); | 1491 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); |
1495 CompileRun("f5=null"); | 1492 CompileRun("f5=null"); |
1496 for (int j = 0; j < kNumTestCollections; j++) { | 1493 for (int j = 0; j < 10; j++) { |
1497 CcTest::heap()->CollectGarbage(NEW_SPACE); | 1494 CcTest::heap()->CollectGarbage(NEW_SPACE); |
1498 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i])); | 1495 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); |
1499 } | 1496 } |
1500 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1497 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1501 CHECK_EQ(2, CountOptimizedUserFunctions(ctx[i])); | 1498 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); |
1502 | 1499 |
1503 ctx[i]->Exit(); | 1500 ctx[i]->Exit(); |
1504 } | 1501 } |
1505 | 1502 |
1506 // Force compilation cache cleanup. | 1503 // Force compilation cache cleanup. |
1507 CcTest::heap()->NotifyContextDisposed(); | 1504 CcTest::heap()->NotifyContextDisposed(); |
1508 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1505 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1509 | 1506 |
1510 // Dispose the native contexts one by one. | 1507 // Dispose the native contexts one by one. |
1511 for (int i = 0; i < kNumTestContexts; i++) { | 1508 for (int i = 0; i < kNumTestContexts; i++) { |
1512 // TODO(dcarney): is there a better way to do this? | 1509 // TODO(dcarney): is there a better way to do this? |
1513 i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]); | 1510 i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]); |
1514 *unsafe = CcTest::heap()->undefined_value(); | 1511 *unsafe = CcTest::heap()->undefined_value(); |
1515 ctx[i].Clear(); | 1512 ctx[i].Clear(); |
1516 | 1513 |
1517 // Scavenge treats these references as strong. | 1514 // Scavenge treats these references as strong. |
1518 for (int j = 0; j < kNumTestCollections; j++) { | 1515 for (int j = 0; j < 10; j++) { |
1519 CcTest::heap()->CollectGarbage(i::NEW_SPACE); | 1516 CcTest::heap()->CollectGarbage(i::NEW_SPACE); |
1520 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); | 1517 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); |
1521 } | 1518 } |
1522 | 1519 |
1523 // Mark compact handles the weak references. | 1520 // Mark compact handles the weak references. |
1524 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1521 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1525 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); | 1522 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); |
1526 } | 1523 } |
1527 | 1524 |
1528 CHECK_EQ(0, CountNativeContexts()); | 1525 CHECK_EQ(0, CountNativeContexts()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1562 if (count == n) isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 1559 if (count == n) isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
1563 object = Handle<Object>( | 1560 object = Handle<Object>( |
1564 Object::cast(JSFunction::cast(*object)->next_function_link()), | 1561 Object::cast(JSFunction::cast(*object)->next_function_link()), |
1565 isolate); | 1562 isolate); |
1566 } | 1563 } |
1567 return count; | 1564 return count; |
1568 } | 1565 } |
1569 | 1566 |
1570 | 1567 |
1571 TEST(TestInternalWeakListsTraverseWithGC) { | 1568 TEST(TestInternalWeakListsTraverseWithGC) { |
1572 FLAG_allow_natives_syntax = true; | |
1573 v8::V8::Initialize(); | 1569 v8::V8::Initialize(); |
1574 Isolate* isolate = CcTest::i_isolate(); | 1570 Isolate* isolate = CcTest::i_isolate(); |
1575 | 1571 |
1576 // TODO(mstarzinger): Test should be resilient against optimization decisions. | 1572 static const int kNumTestContexts = 10; |
1577 if (i::FLAG_always_opt) return; | |
1578 if (!isolate->use_crankshaft()) return; | |
1579 | |
1580 static const int kNumTestContexts = 5; | |
1581 | 1573 |
1582 HandleScope scope(isolate); | 1574 HandleScope scope(isolate); |
1583 v8::Handle<v8::Context> ctx[kNumTestContexts]; | 1575 v8::Handle<v8::Context> ctx[kNumTestContexts]; |
1584 | 1576 |
1585 CHECK_EQ(0, CountNativeContexts()); | 1577 CHECK_EQ(0, CountNativeContexts()); |
1586 | 1578 |
1587 // Create an number of contexts and check the length of the weak list both | 1579 // Create an number of contexts and check the length of the weak list both |
1588 // with and without GCs while iterating the list. | 1580 // with and without GCs while iterating the list. |
1589 for (int i = 0; i < kNumTestContexts; i++) { | 1581 for (int i = 0; i < kNumTestContexts; i++) { |
1590 ctx[i] = v8::Context::New(CcTest::isolate()); | 1582 ctx[i] = v8::Context::New(CcTest::isolate()); |
1591 CHECK_EQ(i + 1, CountNativeContexts()); | 1583 CHECK_EQ(i + 1, CountNativeContexts()); |
1592 CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); | 1584 CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); |
1593 } | 1585 } |
1594 | 1586 |
| 1587 bool opt = (FLAG_always_opt && isolate->use_crankshaft()); |
| 1588 |
1595 // Compile a number of functions the length of the weak list of optimized | 1589 // Compile a number of functions the length of the weak list of optimized |
1596 // functions both with and without GCs while iterating the list. | 1590 // functions both with and without GCs while iterating the list. |
1597 ctx[0]->Enter(); | 1591 ctx[0]->Enter(); |
1598 const char* source = "function f1() { };" | 1592 const char* source = "function f1() { };" |
1599 "function f2() { };" | 1593 "function f2() { };" |
1600 "function f3() { };" | 1594 "function f3() { };" |
1601 "function f4() { };" | 1595 "function f4() { };" |
1602 "function f5() { };"; | 1596 "function f5() { };"; |
1603 CompileRun(source); | 1597 CompileRun(source); |
1604 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[0])); | 1598 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[0])); |
1605 CompileRun("f1(); %OptimizeFunctionOnNextCall(f1); f1()"); | 1599 CompileRun("f1()"); |
1606 CHECK_EQ(1, CountOptimizedUserFunctions(ctx[0])); | 1600 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[0])); |
1607 CHECK_EQ(1, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); | 1601 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
1608 CompileRun("f2(); %OptimizeFunctionOnNextCall(f2); f2()"); | 1602 CompileRun("f2()"); |
1609 CHECK_EQ(2, CountOptimizedUserFunctions(ctx[0])); | 1603 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[0])); |
1610 CHECK_EQ(2, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); | 1604 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
1611 CompileRun("f3(); %OptimizeFunctionOnNextCall(f3); f3()"); | 1605 CompileRun("f3()"); |
1612 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[0])); | 1606 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[0])); |
1613 CHECK_EQ(3, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); | 1607 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
1614 CompileRun("f4(); %OptimizeFunctionOnNextCall(f4); f4()"); | 1608 CompileRun("f4()"); |
1615 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[0])); | 1609 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[0])); |
1616 CHECK_EQ(4, CountOptimizedUserFunctionsWithGC(ctx[0], 2)); | 1610 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 2)); |
1617 CompileRun("f5(); %OptimizeFunctionOnNextCall(f5); f5()"); | 1611 CompileRun("f5()"); |
1618 CHECK_EQ(5, CountOptimizedUserFunctions(ctx[0])); | 1612 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0])); |
1619 CHECK_EQ(5, CountOptimizedUserFunctionsWithGC(ctx[0], 4)); | 1613 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4)); |
1620 | 1614 |
1621 ctx[0]->Exit(); | 1615 ctx[0]->Exit(); |
1622 } | 1616 } |
1623 | 1617 |
1624 | 1618 |
1625 TEST(TestSizeOfObjects) { | 1619 TEST(TestSizeOfObjects) { |
1626 v8::V8::Initialize(); | 1620 v8::V8::Initialize(); |
1627 | 1621 |
1628 // Get initial heap size after several full GCs, which will stabilize | 1622 // Get initial heap size after several full GCs, which will stabilize |
1629 // the heap size and return with sweeping finished completely. | 1623 // the heap size and return with sweeping finished completely. |
(...skipping 2441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4071 return result; | 4065 return result; |
4072 } | 4066 } |
4073 | 4067 |
4074 | 4068 |
4075 TEST(NextCodeLinkIsWeak) { | 4069 TEST(NextCodeLinkIsWeak) { |
4076 i::FLAG_allow_natives_syntax = true; | 4070 i::FLAG_allow_natives_syntax = true; |
4077 CcTest::InitializeVM(); | 4071 CcTest::InitializeVM(); |
4078 Isolate* isolate = CcTest::i_isolate(); | 4072 Isolate* isolate = CcTest::i_isolate(); |
4079 v8::internal::Heap* heap = CcTest::heap(); | 4073 v8::internal::Heap* heap = CcTest::heap(); |
4080 | 4074 |
4081 // TODO(titzer): Test should be resilient against optimization decisions. | |
4082 if (i::FLAG_always_opt) return; | |
4083 if (!isolate->use_crankshaft()) return; | 4075 if (!isolate->use_crankshaft()) return; |
4084 | |
4085 HandleScope outer_scope(heap->isolate()); | 4076 HandleScope outer_scope(heap->isolate()); |
4086 Handle<Code> code; | 4077 Handle<Code> code; |
4087 heap->CollectAllAvailableGarbage(); | 4078 heap->CollectAllAvailableGarbage(); |
4088 int code_chain_length_before, code_chain_length_after; | 4079 int code_chain_length_before, code_chain_length_after; |
4089 { | 4080 { |
4090 HandleScope scope(heap->isolate()); | 4081 HandleScope scope(heap->isolate()); |
4091 Handle<JSFunction> mortal = OptimizeDummyFunction("mortal"); | 4082 Handle<JSFunction> mortal = OptimizeDummyFunction("mortal"); |
4092 Handle<JSFunction> immortal = OptimizeDummyFunction("immortal"); | 4083 Handle<JSFunction> immortal = OptimizeDummyFunction("immortal"); |
4093 CHECK_EQ(immortal->code()->next_code_link(), mortal->code()); | 4084 CHECK_EQ(immortal->code()->next_code_link(), mortal->code()); |
4094 code_chain_length_before = GetCodeChainLength(immortal->code()); | 4085 code_chain_length_before = GetCodeChainLength(immortal->code()); |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4505 #ifdef DEBUG | 4496 #ifdef DEBUG |
4506 TEST(PathTracer) { | 4497 TEST(PathTracer) { |
4507 CcTest::InitializeVM(); | 4498 CcTest::InitializeVM(); |
4508 v8::HandleScope scope(CcTest::isolate()); | 4499 v8::HandleScope scope(CcTest::isolate()); |
4509 | 4500 |
4510 v8::Local<v8::Value> result = CompileRun("'abc'"); | 4501 v8::Local<v8::Value> result = CompileRun("'abc'"); |
4511 Handle<Object> o = v8::Utils::OpenHandle(*result); | 4502 Handle<Object> o = v8::Utils::OpenHandle(*result); |
4512 CcTest::i_isolate()->heap()->TracePathToObject(*o); | 4503 CcTest::i_isolate()->heap()->TracePathToObject(*o); |
4513 } | 4504 } |
4514 #endif // DEBUG | 4505 #endif // DEBUG |
OLD | NEW |