| 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 1468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 | 1479 |
| 1480 // Clear references to functions so that one of them can die. | 1480 // Clear references to functions so that one of them can die. |
| 1481 { v8::HandleScope scope(CcTest::isolate()); | 1481 { v8::HandleScope scope(CcTest::isolate()); |
| 1482 CompileRun("foo = 0; bar = 0;"); | 1482 CompileRun("foo = 0; bar = 0;"); |
| 1483 } | 1483 } |
| 1484 | 1484 |
| 1485 // Bump the code age so that flushing is triggered while the function | 1485 // Bump the code age so that flushing is triggered while the function |
| 1486 // object is still located in new-space. | 1486 // object is still located in new-space. |
| 1487 const int kAgingThreshold = 6; | 1487 const int kAgingThreshold = 6; |
| 1488 for (int i = 0; i < kAgingThreshold; i++) { | 1488 for (int i = 0; i < kAgingThreshold; i++) { |
| 1489 function->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 1489 function->shared()->code()->MakeOlder(); |
| 1490 function2->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 1490 function2->shared()->code()->MakeOlder(); |
| 1491 } | 1491 } |
| 1492 | 1492 |
| 1493 // Simulate incremental marking so that the functions are enqueued as | 1493 // Simulate incremental marking so that the functions are enqueued as |
| 1494 // code flushing candidates. Then kill one of the functions. Finally | 1494 // code flushing candidates. Then kill one of the functions. Finally |
| 1495 // perform a scavenge while incremental marking is still running. | 1495 // perform a scavenge while incremental marking is still running. |
| 1496 heap::SimulateIncrementalMarking(CcTest::heap(), false); | 1496 heap::SimulateIncrementalMarking(CcTest::heap(), false); |
| 1497 *function2.location() = NULL; | 1497 *function2.location() = NULL; |
| 1498 CcTest::CollectGarbage(NEW_SPACE); | 1498 CcTest::CollectGarbage(NEW_SPACE); |
| 1499 | 1499 |
| 1500 // Simulate one final GC to make sure the candidate queue is sane. | 1500 // Simulate one final GC to make sure the candidate queue is sane. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1538 CHECK(function->shared()->is_compiled()); | 1538 CHECK(function->shared()->is_compiled()); |
| 1539 | 1539 |
| 1540 // The code will survive at least two GCs. | 1540 // The code will survive at least two GCs. |
| 1541 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1541 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
| 1542 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1542 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
| 1543 CHECK(function->shared()->is_compiled()); | 1543 CHECK(function->shared()->is_compiled()); |
| 1544 | 1544 |
| 1545 // Bump the code age so that flushing is triggered. | 1545 // Bump the code age so that flushing is triggered. |
| 1546 const int kAgingThreshold = 6; | 1546 const int kAgingThreshold = 6; |
| 1547 for (int i = 0; i < kAgingThreshold; i++) { | 1547 for (int i = 0; i < kAgingThreshold; i++) { |
| 1548 function->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 1548 function->shared()->code()->MakeOlder(); |
| 1549 } | 1549 } |
| 1550 | 1550 |
| 1551 // Simulate incremental marking so that the function is enqueued as | 1551 // Simulate incremental marking so that the function is enqueued as |
| 1552 // code flushing candidate. | 1552 // code flushing candidate. |
| 1553 heap::SimulateIncrementalMarking(heap); | 1553 heap::SimulateIncrementalMarking(heap); |
| 1554 | 1554 |
| 1555 // Enable the debugger and add a breakpoint while incremental marking | 1555 // Enable the debugger and add a breakpoint while incremental marking |
| 1556 // is running so that incremental marking aborts and code flushing is | 1556 // is running so that incremental marking aborts and code flushing is |
| 1557 // disabled. | 1557 // disabled. |
| 1558 int position = function->shared()->start_position(); | 1558 int position = function->shared()->start_position(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1657 if (!FLAG_optimize_for_size) { | 1657 if (!FLAG_optimize_for_size) { |
| 1658 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1658 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
| 1659 info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, | 1659 info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, |
| 1660 v8::ScriptOriginOptions(true, false), | 1660 v8::ScriptOriginOptions(true, false), |
| 1661 native_context, language_mode); | 1661 native_context, language_mode); |
| 1662 CHECK(!info.is_null()); | 1662 CHECK(!info.is_null()); |
| 1663 } | 1663 } |
| 1664 | 1664 |
| 1665 // Progress code age until it's old and ready for GC. | 1665 // Progress code age until it's old and ready for GC. |
| 1666 while (!info.ToHandleChecked()->code()->IsOld()) { | 1666 while (!info.ToHandleChecked()->code()->IsOld()) { |
| 1667 // To guarantee progress, we have to MakeOlder with different parities. | 1667 info.ToHandleChecked()->code()->MakeOlder(); |
| 1668 // We can't just use NO_MARKING_PARITY, since e.g. kExecutedOnceCodeAge is | |
| 1669 // always NO_MARKING_PARITY and the code age only progresses if the parity | |
| 1670 // is different. | |
| 1671 info.ToHandleChecked()->code()->MakeOlder(ODD_MARKING_PARITY); | |
| 1672 info.ToHandleChecked()->code()->MakeOlder(EVEN_MARKING_PARITY); | |
| 1673 } | 1668 } |
| 1674 | 1669 |
| 1675 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 1670 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
| 1676 // Ensure code aging cleared the entry from the cache. | 1671 // Ensure code aging cleared the entry from the cache. |
| 1677 info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, | 1672 info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, |
| 1678 v8::ScriptOriginOptions(true, false), | 1673 v8::ScriptOriginOptions(true, false), |
| 1679 native_context, language_mode); | 1674 native_context, language_mode); |
| 1680 CHECK(info.is_null()); | 1675 CHECK(info.is_null()); |
| 1681 } | 1676 } |
| 1682 | 1677 |
| (...skipping 2345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4028 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); | 4023 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); |
| 4029 CHECK(f->is_compiled()); | 4024 CHECK(f->is_compiled()); |
| 4030 CompileRun("f = null;"); | 4025 CompileRun("f = null;"); |
| 4031 | 4026 |
| 4032 Handle<JSFunction> g = Handle<JSFunction>::cast( | 4027 Handle<JSFunction> g = Handle<JSFunction>::cast( |
| 4033 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 4028 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4034 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); | 4029 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); |
| 4035 CHECK(g->is_compiled()); | 4030 CHECK(g->is_compiled()); |
| 4036 const int kAgingThreshold = 6; | 4031 const int kAgingThreshold = 6; |
| 4037 for (int i = 0; i < kAgingThreshold; i++) { | 4032 for (int i = 0; i < kAgingThreshold; i++) { |
| 4038 g->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 4033 g->code()->MakeOlder(); |
| 4039 } | 4034 } |
| 4040 | 4035 |
| 4041 code = inner_scope.CloseAndEscape(Handle<Code>(f->code())); | 4036 code = inner_scope.CloseAndEscape(Handle<Code>(f->code())); |
| 4042 } | 4037 } |
| 4043 | 4038 |
| 4044 // Simulate incremental marking so that the functions are enqueued as | 4039 // Simulate incremental marking so that the functions are enqueued as |
| 4045 // code flushing candidates. Then optimize one function. Finally | 4040 // code flushing candidates. Then optimize one function. Finally |
| 4046 // finish the GC to complete code flushing. | 4041 // finish the GC to complete code flushing. |
| 4047 heap::SimulateIncrementalMarking(heap); | 4042 heap::SimulateIncrementalMarking(heap); |
| 4048 CompileRun("%OptimizeFunctionOnNextCall(g); g(3);"); | 4043 CompileRun("%OptimizeFunctionOnNextCall(g); g(3);"); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 4076 "var f = mkClosure();" | 4071 "var f = mkClosure();" |
| 4077 "f(1); f(2);" | 4072 "f(1); f(2);" |
| 4078 "%OptimizeFunctionOnNextCall(f); f(3);"); | 4073 "%OptimizeFunctionOnNextCall(f); f(3);"); |
| 4079 | 4074 |
| 4080 Handle<JSFunction> f = Handle<JSFunction>::cast( | 4075 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 4081 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 4076 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4082 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); | 4077 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); |
| 4083 CHECK(f->is_compiled()); | 4078 CHECK(f->is_compiled()); |
| 4084 const int kAgingThreshold = 6; | 4079 const int kAgingThreshold = 6; |
| 4085 for (int i = 0; i < kAgingThreshold; i++) { | 4080 for (int i = 0; i < kAgingThreshold; i++) { |
| 4086 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 4081 f->shared()->code()->MakeOlder(); |
| 4087 } | 4082 } |
| 4088 | 4083 |
| 4089 CompileRun("f = null;"); | 4084 CompileRun("f = null;"); |
| 4090 } | 4085 } |
| 4091 | 4086 |
| 4092 // Simulate incremental marking so that unoptimized code is flushed | 4087 // Simulate incremental marking so that unoptimized code is flushed |
| 4093 // even though it still is cached in the optimized code map. | 4088 // even though it still is cached in the optimized code map. |
| 4094 heap::SimulateIncrementalMarking(heap); | 4089 heap::SimulateIncrementalMarking(heap); |
| 4095 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 4090 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
| 4096 | 4091 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4129 "g(false);" | 4124 "g(false);" |
| 4130 "%BaselineFunctionOnNextCall(g);" | 4125 "%BaselineFunctionOnNextCall(g);" |
| 4131 "g(false);"); | 4126 "g(false);"); |
| 4132 | 4127 |
| 4133 Handle<JSFunction> f = Handle<JSFunction>::cast( | 4128 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 4134 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 4129 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4135 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); | 4130 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); |
| 4136 CHECK(f->is_compiled()); | 4131 CHECK(f->is_compiled()); |
| 4137 const int kAgingThreshold = 6; | 4132 const int kAgingThreshold = 6; |
| 4138 for (int i = 0; i < kAgingThreshold; i++) { | 4133 for (int i = 0; i < kAgingThreshold; i++) { |
| 4139 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 4134 f->shared()->code()->MakeOlder(); |
| 4140 } | 4135 } |
| 4141 | 4136 |
| 4142 shared1 = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); | 4137 shared1 = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); |
| 4143 } | 4138 } |
| 4144 | 4139 |
| 4145 // Prepare a shared function info eligible for code flushing that will | 4140 // Prepare a shared function info eligible for code flushing that will |
| 4146 // represent the dangling tail of the candidate list. | 4141 // represent the dangling tail of the candidate list. |
| 4147 Handle<SharedFunctionInfo> shared2; | 4142 Handle<SharedFunctionInfo> shared2; |
| 4148 { | 4143 { |
| 4149 HandleScope inner_scope(isolate); | 4144 HandleScope inner_scope(isolate); |
| 4150 LocalContext env; | 4145 LocalContext env; |
| 4151 CompileRun( | 4146 CompileRun( |
| 4152 "function flushMe() { return 0; }" | 4147 "function flushMe() { return 0; }" |
| 4153 "flushMe(1);" | 4148 "flushMe(1);" |
| 4154 "%BaselineFunctionOnNextCall(flushMe);" | 4149 "%BaselineFunctionOnNextCall(flushMe);" |
| 4155 "flushMe(1);"); | 4150 "flushMe(1);"); |
| 4156 | 4151 |
| 4157 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4152 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( |
| 4158 *v8::Local<v8::Function>::Cast(CcTest::global() | 4153 *v8::Local<v8::Function>::Cast(CcTest::global() |
| 4159 ->Get(env.local(), v8_str("flushMe")) | 4154 ->Get(env.local(), v8_str("flushMe")) |
| 4160 .ToLocalChecked()))); | 4155 .ToLocalChecked()))); |
| 4161 CHECK(f->is_compiled()); | 4156 CHECK(f->is_compiled()); |
| 4162 const int kAgingThreshold = 6; | 4157 const int kAgingThreshold = 6; |
| 4163 for (int i = 0; i < kAgingThreshold; i++) { | 4158 for (int i = 0; i < kAgingThreshold; i++) { |
| 4164 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 4159 f->shared()->code()->MakeOlder(); |
| 4165 } | 4160 } |
| 4166 | 4161 |
| 4167 shared2 = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); | 4162 shared2 = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); |
| 4168 } | 4163 } |
| 4169 | 4164 |
| 4170 // Simulate incremental marking and collect code flushing candidates. | 4165 // Simulate incremental marking and collect code flushing candidates. |
| 4171 heap::SimulateIncrementalMarking(heap); | 4166 heap::SimulateIncrementalMarking(heap); |
| 4172 CHECK(shared1->code()->gc_metadata() != NULL); | 4167 CHECK(shared1->code()->gc_metadata() != NULL); |
| 4173 | 4168 |
| 4174 // Optimize function and make sure the unoptimized code is replaced. | 4169 // Optimize function and make sure the unoptimized code is replaced. |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4545 "f(1); f(2);" | 4540 "f(1); f(2);" |
| 4546 "%OptimizeFunctionOnNextCall(f); f(3);"); | 4541 "%OptimizeFunctionOnNextCall(f); f(3);"); |
| 4547 | 4542 |
| 4548 Handle<JSFunction> g = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4543 Handle<JSFunction> g = Handle<JSFunction>::cast(v8::Utils::OpenHandle( |
| 4549 *v8::Local<v8::Function>::Cast(CcTest::global() | 4544 *v8::Local<v8::Function>::Cast(CcTest::global() |
| 4550 ->Get(context.local(), v8_str("g")) | 4545 ->Get(context.local(), v8_str("g")) |
| 4551 .ToLocalChecked()))); | 4546 .ToLocalChecked()))); |
| 4552 CHECK(g->shared()->is_compiled()); | 4547 CHECK(g->shared()->is_compiled()); |
| 4553 const int kAgingThreshold = 6; | 4548 const int kAgingThreshold = 6; |
| 4554 for (int i = 0; i < kAgingThreshold; i++) { | 4549 for (int i = 0; i < kAgingThreshold; i++) { |
| 4555 g->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 4550 g->shared()->code()->MakeOlder(); |
| 4556 } | 4551 } |
| 4557 | 4552 |
| 4558 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4553 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( |
| 4559 *v8::Local<v8::Function>::Cast(CcTest::global() | 4554 *v8::Local<v8::Function>::Cast(CcTest::global() |
| 4560 ->Get(context.local(), v8_str("f")) | 4555 ->Get(context.local(), v8_str("f")) |
| 4561 .ToLocalChecked()))); | 4556 .ToLocalChecked()))); |
| 4562 CHECK(f->is_compiled()); | 4557 CHECK(f->is_compiled()); |
| 4563 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); | 4558 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); |
| 4564 CompileRun("f = null"); | 4559 CompileRun("f = null"); |
| 4565 } | 4560 } |
| (...skipping 2483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7049 SlotSet::FREE_EMPTY_BUCKETS); | 7044 SlotSet::FREE_EMPTY_BUCKETS); |
| 7050 slots[chunk->area_end() - kPointerSize] = false; | 7045 slots[chunk->area_end() - kPointerSize] = false; |
| 7051 RememberedSet<OLD_TO_NEW>::Iterate(chunk, [&slots](Address addr) { | 7046 RememberedSet<OLD_TO_NEW>::Iterate(chunk, [&slots](Address addr) { |
| 7052 CHECK(slots[addr]); | 7047 CHECK(slots[addr]); |
| 7053 return KEEP_SLOT; | 7048 return KEEP_SLOT; |
| 7054 }); | 7049 }); |
| 7055 } | 7050 } |
| 7056 | 7051 |
| 7057 } // namespace internal | 7052 } // namespace internal |
| 7058 } // namespace v8 | 7053 } // namespace v8 |
| OLD | NEW |