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 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1272 | 1272 |
1273 // Simulate several GCs that use full marking. | 1273 // Simulate several GCs that use full marking. |
1274 const int kAgingThreshold = 6; | 1274 const int kAgingThreshold = 6; |
1275 for (int i = 0; i < kAgingThreshold; i++) { | 1275 for (int i = 0; i < kAgingThreshold; i++) { |
1276 i_isolate->heap()->CollectAllGarbage( | 1276 i_isolate->heap()->CollectAllGarbage( |
1277 i::Heap::kFinalizeIncrementalMarkingMask, | 1277 i::Heap::kFinalizeIncrementalMarkingMask, |
1278 i::GarbageCollectionReason::kTesting); | 1278 i::GarbageCollectionReason::kTesting); |
1279 } | 1279 } |
1280 | 1280 |
1281 // foo should no longer be in the compilation cache | 1281 // foo should no longer be in the compilation cache |
1282 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 1282 CHECK(!function->shared()->is_compiled() || function->IsOptimized() || |
1283 CHECK(!function->is_compiled() || function->IsOptimized()); | 1283 function->IsInterpreted()); |
| 1284 CHECK(!function->is_compiled() || function->IsOptimized() || |
| 1285 function->IsInterpreted()); |
1284 // Call foo to get it recompiled. | 1286 // Call foo to get it recompiled. |
1285 CompileRun("foo()"); | 1287 CompileRun("foo()"); |
1286 CHECK(function->shared()->is_compiled()); | 1288 CHECK(function->shared()->is_compiled()); |
1287 CHECK(function->is_compiled()); | 1289 CHECK(function->is_compiled()); |
1288 } | 1290 } |
1289 isolate->Exit(); | 1291 isolate->Exit(); |
1290 isolate->Dispose(); | 1292 isolate->Dispose(); |
1291 } | 1293 } |
1292 | 1294 |
1293 | 1295 |
(...skipping 26 matching lines...) Expand all Loading... |
1320 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value); | 1322 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value); |
1321 CHECK(function->shared()->is_compiled()); | 1323 CHECK(function->shared()->is_compiled()); |
1322 | 1324 |
1323 // The code has been run so will survive at least one GC. | 1325 // The code has been run so will survive at least one GC. |
1324 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1326 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
1325 CHECK(function->shared()->is_compiled()); | 1327 CHECK(function->shared()->is_compiled()); |
1326 | 1328 |
1327 // The code was only run once, so it should be pre-aged and collected on the | 1329 // The code was only run once, so it should be pre-aged and collected on the |
1328 // next GC. | 1330 // next GC. |
1329 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1331 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
1330 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 1332 CHECK(!function->shared()->is_compiled() || function->IsOptimized() || |
| 1333 function->IsInterpreted()); |
1331 | 1334 |
1332 // Execute the function again twice, and ensure it is reset to the young age. | 1335 // Execute the function again twice, and ensure it is reset to the young age. |
1333 { v8::HandleScope scope(CcTest::isolate()); | 1336 { v8::HandleScope scope(CcTest::isolate()); |
1334 CompileRun("foo();" | 1337 CompileRun("foo();" |
1335 "foo();"); | 1338 "foo();"); |
1336 } | 1339 } |
1337 | 1340 |
1338 // The code will survive at least two GC now that it is young again. | 1341 // The code will survive at least two GC now that it is young again. |
1339 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1342 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
1340 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1343 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
1341 CHECK(function->shared()->is_compiled()); | 1344 CHECK(function->shared()->is_compiled()); |
1342 | 1345 |
1343 // Simulate several GCs that use full marking. | 1346 // Simulate several GCs that use full marking. |
1344 const int kAgingThreshold = 6; | 1347 const int kAgingThreshold = 6; |
1345 for (int i = 0; i < kAgingThreshold; i++) { | 1348 for (int i = 0; i < kAgingThreshold; i++) { |
1346 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1349 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
1347 } | 1350 } |
1348 | 1351 |
1349 // foo should no longer be in the compilation cache | 1352 // foo should no longer be in the compilation cache |
1350 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 1353 CHECK(!function->shared()->is_compiled() || function->IsOptimized() || |
1351 CHECK(!function->is_compiled() || function->IsOptimized()); | 1354 function->IsInterpreted()); |
| 1355 CHECK(!function->is_compiled() || function->IsOptimized() || |
| 1356 function->IsInterpreted()); |
1352 // Call foo to get it recompiled. | 1357 // Call foo to get it recompiled. |
1353 CompileRun("foo()"); | 1358 CompileRun("foo()"); |
1354 CHECK(function->shared()->is_compiled()); | 1359 CHECK(function->shared()->is_compiled()); |
1355 CHECK(function->is_compiled()); | 1360 CHECK(function->is_compiled()); |
1356 } | 1361 } |
1357 | 1362 |
1358 | 1363 |
1359 TEST(TestCodeFlushingIncremental) { | 1364 TEST(TestCodeFlushingIncremental) { |
1360 // If we do not flush code this test is invalid. | 1365 // If we do not flush code this test is invalid. |
1361 if (!FLAG_flush_code) return; | 1366 if (!FLAG_flush_code) return; |
(...skipping 27 matching lines...) Expand all Loading... |
1389 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1394 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
1390 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1395 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
1391 CHECK(function->shared()->is_compiled()); | 1396 CHECK(function->shared()->is_compiled()); |
1392 | 1397 |
1393 // Simulate several GCs that use incremental marking. | 1398 // Simulate several GCs that use incremental marking. |
1394 const int kAgingThreshold = 6; | 1399 const int kAgingThreshold = 6; |
1395 for (int i = 0; i < kAgingThreshold; i++) { | 1400 for (int i = 0; i < kAgingThreshold; i++) { |
1396 heap::SimulateIncrementalMarking(CcTest::heap()); | 1401 heap::SimulateIncrementalMarking(CcTest::heap()); |
1397 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1402 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
1398 } | 1403 } |
1399 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 1404 CHECK(!function->shared()->is_compiled() || function->IsOptimized() || |
1400 CHECK(!function->is_compiled() || function->IsOptimized()); | 1405 function->IsInterpreted()); |
| 1406 CHECK(!function->is_compiled() || function->IsOptimized() || |
| 1407 function->IsInterpreted()); |
1401 | 1408 |
1402 // This compile will compile the function again. | 1409 // This compile will compile the function again. |
1403 { v8::HandleScope scope(CcTest::isolate()); | 1410 { v8::HandleScope scope(CcTest::isolate()); |
1404 CompileRun("foo();"); | 1411 CompileRun("foo();"); |
1405 } | 1412 } |
1406 | 1413 |
1407 // Simulate several GCs that use incremental marking but make sure | 1414 // Simulate several GCs that use incremental marking but make sure |
1408 // the loop breaks once the function is enqueued as a candidate. | 1415 // the loop breaks once the function is enqueued as a candidate. |
1409 for (int i = 0; i < kAgingThreshold; i++) { | 1416 for (int i = 0; i < kAgingThreshold; i++) { |
1410 heap::SimulateIncrementalMarking(CcTest::heap()); | 1417 heap::SimulateIncrementalMarking(CcTest::heap()); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 | 1490 |
1484 // Simulate incremental marking so that the functions are enqueued as | 1491 // Simulate incremental marking so that the functions are enqueued as |
1485 // code flushing candidates. Then kill one of the functions. Finally | 1492 // code flushing candidates. Then kill one of the functions. Finally |
1486 // perform a scavenge while incremental marking is still running. | 1493 // perform a scavenge while incremental marking is still running. |
1487 heap::SimulateIncrementalMarking(CcTest::heap(), false); | 1494 heap::SimulateIncrementalMarking(CcTest::heap(), false); |
1488 *function2.location() = NULL; | 1495 *function2.location() = NULL; |
1489 CcTest::CollectGarbage(NEW_SPACE); | 1496 CcTest::CollectGarbage(NEW_SPACE); |
1490 | 1497 |
1491 // Simulate one final GC to make sure the candidate queue is sane. | 1498 // Simulate one final GC to make sure the candidate queue is sane. |
1492 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1499 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
1493 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 1500 CHECK(!function->shared()->is_compiled() || function->IsOptimized() || |
1494 CHECK(!function->is_compiled() || function->IsOptimized()); | 1501 function->IsInterpreted()); |
| 1502 CHECK(!function->is_compiled() || function->IsOptimized() || |
| 1503 function->IsInterpreted()); |
1495 } | 1504 } |
1496 | 1505 |
1497 | 1506 |
1498 TEST(TestCodeFlushingIncrementalAbort) { | 1507 TEST(TestCodeFlushingIncrementalAbort) { |
1499 // If we do not flush code this test is invalid. | 1508 // If we do not flush code this test is invalid. |
1500 if (!FLAG_flush_code) return; | 1509 if (!FLAG_flush_code) return; |
1501 i::FLAG_allow_natives_syntax = true; | 1510 i::FLAG_allow_natives_syntax = true; |
1502 i::FLAG_optimize_for_size = false; | 1511 i::FLAG_optimize_for_size = false; |
1503 CcTest::InitializeVM(); | 1512 CcTest::InitializeVM(); |
1504 Isolate* isolate = CcTest::i_isolate(); | 1513 Isolate* isolate = CcTest::i_isolate(); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1599 // g should now have available an optimized function, unmarked by gc. The | 1608 // g should now have available an optimized function, unmarked by gc. The |
1600 // CompileLazy built-in will discover it and install it in the closure, and | 1609 // CompileLazy built-in will discover it and install it in the closure, and |
1601 // the incremental write barrier should be used. | 1610 // the incremental write barrier should be used. |
1602 CompileRun("g();"); | 1611 CompileRun("g();"); |
1603 CHECK(g_function->is_compiled()); | 1612 CHECK(g_function->is_compiled()); |
1604 } | 1613 } |
1605 | 1614 |
1606 TEST(CompilationCacheCachingBehavior) { | 1615 TEST(CompilationCacheCachingBehavior) { |
1607 // If we do not flush code, or have the compilation cache turned off, this | 1616 // If we do not flush code, or have the compilation cache turned off, this |
1608 // test is invalid. | 1617 // test is invalid. |
| 1618 i::FLAG_allow_natives_syntax = true; |
1609 if (!FLAG_flush_code || !FLAG_compilation_cache) { | 1619 if (!FLAG_flush_code || !FLAG_compilation_cache) { |
1610 return; | 1620 return; |
1611 } | 1621 } |
1612 CcTest::InitializeVM(); | 1622 CcTest::InitializeVM(); |
1613 Isolate* isolate = CcTest::i_isolate(); | 1623 Isolate* isolate = CcTest::i_isolate(); |
1614 Factory* factory = isolate->factory(); | 1624 Factory* factory = isolate->factory(); |
1615 CompilationCache* compilation_cache = isolate->compilation_cache(); | 1625 CompilationCache* compilation_cache = isolate->compilation_cache(); |
1616 LanguageMode language_mode = construct_language_mode(FLAG_use_strict); | 1626 LanguageMode language_mode = construct_language_mode(FLAG_use_strict); |
1617 | 1627 |
1618 v8::HandleScope scope(CcTest::isolate()); | 1628 v8::HandleScope scope(CcTest::isolate()); |
1619 const char* raw_source = | 1629 const char* raw_source = |
1620 "function foo() {" | 1630 "function foo() {" |
1621 " var x = 42;" | 1631 " var x = 42;" |
1622 " var y = 42;" | 1632 " var y = 42;" |
1623 " var z = x + y;" | 1633 " var z = x + y;" |
1624 "};" | 1634 "};" |
1625 "foo()"; | 1635 "foo();"; |
1626 Handle<String> source = factory->InternalizeUtf8String(raw_source); | 1636 Handle<String> source = factory->InternalizeUtf8String(raw_source); |
1627 Handle<Context> native_context = isolate->native_context(); | 1637 Handle<Context> native_context = isolate->native_context(); |
1628 | 1638 |
1629 { | 1639 { |
1630 v8::HandleScope scope(CcTest::isolate()); | 1640 v8::HandleScope scope(CcTest::isolate()); |
1631 CompileRun(raw_source); | 1641 CompileRun(raw_source); |
1632 } | 1642 } |
1633 | 1643 |
1634 // The script should be in the cache now. | 1644 // The script should be in the cache now. |
1635 MaybeHandle<SharedFunctionInfo> info = compilation_cache->LookupScript( | 1645 MaybeHandle<SharedFunctionInfo> info = compilation_cache->LookupScript( |
(...skipping 2435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4071 heap::SimulateIncrementalMarking(heap); | 4081 heap::SimulateIncrementalMarking(heap); |
4072 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 4082 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
4073 | 4083 |
4074 // Make a new closure that will get code installed from the code map. | 4084 // Make a new closure that will get code installed from the code map. |
4075 // Unoptimized code is missing and the deoptimizer will go ballistic. | 4085 // Unoptimized code is missing and the deoptimizer will go ballistic. |
4076 CompileRun("var g = mkClosure(); g('bozo');"); | 4086 CompileRun("var g = mkClosure(); g('bozo');"); |
4077 } | 4087 } |
4078 | 4088 |
4079 | 4089 |
4080 TEST(Regress169209) { | 4090 TEST(Regress169209) { |
| 4091 i::FLAG_always_opt = false; |
4081 i::FLAG_stress_compaction = false; | 4092 i::FLAG_stress_compaction = false; |
4082 i::FLAG_allow_natives_syntax = true; | 4093 i::FLAG_allow_natives_syntax = true; |
4083 | 4094 |
4084 CcTest::InitializeVM(); | 4095 CcTest::InitializeVM(); |
4085 Isolate* isolate = CcTest::i_isolate(); | 4096 Isolate* isolate = CcTest::i_isolate(); |
4086 Heap* heap = isolate->heap(); | 4097 Heap* heap = isolate->heap(); |
4087 HandleScope scope(isolate); | 4098 HandleScope scope(isolate); |
4088 | 4099 |
4089 // Perform one initial GC to enable code flushing. | 4100 // Perform one initial GC to enable code flushing. |
4090 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 4101 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
4091 | 4102 |
4092 // Prepare a shared function info eligible for code flushing for which | 4103 // Prepare a shared function info eligible for code flushing for which |
4093 // the unoptimized code will be replaced during optimization. | 4104 // the unoptimized code will be replaced during optimization. |
4094 Handle<SharedFunctionInfo> shared1; | 4105 Handle<SharedFunctionInfo> shared1; |
4095 { | 4106 { |
4096 HandleScope inner_scope(isolate); | 4107 HandleScope inner_scope(isolate); |
4097 LocalContext env; | 4108 LocalContext env; |
4098 CompileRun("function f() { return 'foobar'; }" | 4109 CompileRun( |
4099 "function g(x) { if (x) f(); }" | 4110 "function f() { return 'foobar'; }" |
4100 "f();" | 4111 "function g(x) { if (x) f(); }" |
4101 "g(false);" | 4112 "f();" |
4102 "g(false);"); | 4113 "%BaselineFunctionOnNextCall(f);" |
| 4114 "f();" |
| 4115 "g(false);" |
| 4116 "%BaselineFunctionOnNextCall(g);" |
| 4117 "g(false);"); |
4103 | 4118 |
4104 Handle<JSFunction> f = Handle<JSFunction>::cast( | 4119 Handle<JSFunction> f = Handle<JSFunction>::cast( |
4105 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 4120 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
4106 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); | 4121 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); |
4107 CHECK(f->is_compiled()); | 4122 CHECK(f->is_compiled()); |
4108 const int kAgingThreshold = 6; | 4123 const int kAgingThreshold = 6; |
4109 for (int i = 0; i < kAgingThreshold; i++) { | 4124 for (int i = 0; i < kAgingThreshold; i++) { |
4110 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 4125 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); |
4111 } | 4126 } |
4112 | 4127 |
4113 shared1 = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); | 4128 shared1 = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); |
4114 } | 4129 } |
4115 | 4130 |
4116 // Prepare a shared function info eligible for code flushing that will | 4131 // Prepare a shared function info eligible for code flushing that will |
4117 // represent the dangling tail of the candidate list. | 4132 // represent the dangling tail of the candidate list. |
4118 Handle<SharedFunctionInfo> shared2; | 4133 Handle<SharedFunctionInfo> shared2; |
4119 { | 4134 { |
4120 HandleScope inner_scope(isolate); | 4135 HandleScope inner_scope(isolate); |
4121 LocalContext env; | 4136 LocalContext env; |
4122 CompileRun("function flushMe() { return 0; }" | 4137 CompileRun( |
4123 "flushMe(1);"); | 4138 "function flushMe() { return 0; }" |
| 4139 "flushMe(1);" |
| 4140 "%BaselineFunctionOnNextCall(flushMe);" |
| 4141 "flushMe(1);"); |
4124 | 4142 |
4125 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4143 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( |
4126 *v8::Local<v8::Function>::Cast(CcTest::global() | 4144 *v8::Local<v8::Function>::Cast(CcTest::global() |
4127 ->Get(env.local(), v8_str("flushMe")) | 4145 ->Get(env.local(), v8_str("flushMe")) |
4128 .ToLocalChecked()))); | 4146 .ToLocalChecked()))); |
4129 CHECK(f->is_compiled()); | 4147 CHECK(f->is_compiled()); |
4130 const int kAgingThreshold = 6; | 4148 const int kAgingThreshold = 6; |
4131 for (int i = 0; i < kAgingThreshold; i++) { | 4149 for (int i = 0; i < kAgingThreshold; i++) { |
4132 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 4150 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); |
4133 } | 4151 } |
(...skipping 2866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7000 SlotSet::FREE_EMPTY_BUCKETS); | 7018 SlotSet::FREE_EMPTY_BUCKETS); |
7001 slots[chunk->area_end() - kPointerSize] = false; | 7019 slots[chunk->area_end() - kPointerSize] = false; |
7002 RememberedSet<OLD_TO_NEW>::Iterate(chunk, [&slots](Address addr) { | 7020 RememberedSet<OLD_TO_NEW>::Iterate(chunk, [&slots](Address addr) { |
7003 CHECK(slots[addr]); | 7021 CHECK(slots[addr]); |
7004 return KEEP_SLOT; | 7022 return KEEP_SLOT; |
7005 }); | 7023 }); |
7006 } | 7024 } |
7007 | 7025 |
7008 } // namespace internal | 7026 } // namespace internal |
7009 } // namespace v8 | 7027 } // namespace v8 |
OLD | NEW |