Index: test/cctest/test-heap.cc |
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc |
index 2ccc9d41e69c4b795742eba362033998b1ad2f8b..696dc864430d2c72250a8ac60be5411080c7c94f 100644 |
--- a/test/cctest/test-heap.cc |
+++ b/test/cctest/test-heap.cc |
@@ -1069,6 +1069,70 @@ TEST(TestCodeFlushingIncremental) { |
} |
+TEST(TestCodeFlushingIncrementalScavenge) { |
+ // If we do not flush code this test is invalid. |
+ if (!FLAG_flush_code) return; |
+ i::FLAG_allow_natives_syntax = true; |
+ InitializeVM(); |
+ v8::HandleScope scope; |
+ const char* source = "var foo = function() {" |
+ " var x = 42;" |
+ " var y = 42;" |
+ " var z = x + y;" |
+ "};" |
+ "foo();" |
+ "var bar = function() {" |
+ " var x = 23;" |
+ "};" |
+ "bar();"; |
+ Handle<String> foo_name = FACTORY->LookupAsciiSymbol("foo"); |
+ Handle<String> bar_name = FACTORY->LookupAsciiSymbol("bar"); |
+ |
+ // Perfrom one initial GC to enable code flushing. |
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
+ |
+ // This compile will add the code to the compilation cache. |
+ { v8::HandleScope scope; |
+ CompileRun(source); |
+ } |
+ |
+ // Check functions are compiled. |
+ Object* func_value = Isolate::Current()->context()->global_object()-> |
+ GetProperty(*foo_name)->ToObjectChecked(); |
+ CHECK(func_value->IsJSFunction()); |
+ Handle<JSFunction> function(JSFunction::cast(func_value)); |
+ CHECK(function->shared()->is_compiled()); |
+ Object* func_value2 = Isolate::Current()->context()->global_object()-> |
+ GetProperty(*bar_name)->ToObjectChecked(); |
+ CHECK(func_value2->IsJSFunction()); |
+ Handle<JSFunction> function2(JSFunction::cast(func_value2)); |
+ CHECK(function2->shared()->is_compiled()); |
+ |
+ // Clear references to functions so that one of them can die. |
+ { v8::HandleScope scope; |
+ CompileRun("foo = 0; bar = 0;"); |
+ } |
+ |
+ // Bump the code age so that flushing is triggered while the function |
+ // object is still located in new-space. |
+ const int kAgingThreshold = 6; |
+ function->shared()->set_code_age(kAgingThreshold); |
+ function2->shared()->set_code_age(kAgingThreshold); |
+ |
+ // Simulate incremental marking so that the functions are enqueued as |
+ // code flushing candidates. Then kill one of the functions. Finally |
+ // perform a scavenge while incremental marking is still running. |
+ SimulateIncrementalMarking(); |
+ *function2.location() = NULL; |
+ HEAP->CollectGarbage(NEW_SPACE, "test scavenge while marking"); |
+ |
+ // Simulate one final GC to make sure the candidate queue is sane. |
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
+ CHECK(!function->shared()->is_compiled() || function->IsOptimized()); |
+ CHECK(!function->is_compiled() || function->IsOptimized()); |
+} |
+ |
+ |
// Count the number of native contexts in the weak list of native contexts. |
int CountNativeContexts() { |
int count = 0; |