Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: test/cctest/test-heap.cc

Issue 11140025: Enable incremental code flushing. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Prevent recording a flushing candidate twice. Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 2
3 #include <stdlib.h> 3 #include <stdlib.h>
4 4
5 #include "v8.h" 5 #include "v8.h"
6 6
7 #include "compilation-cache.h" 7 #include "compilation-cache.h"
8 #include "execution.h" 8 #include "execution.h"
9 #include "factory.h" 9 #include "factory.h"
10 #include "macro-assembler.h" 10 #include "macro-assembler.h"
11 #include "global-handles.h" 11 #include "global-handles.h"
12 #include "stub-cache.h" 12 #include "stub-cache.h"
13 #include "cctest.h" 13 #include "cctest.h"
14 14
15 using namespace v8::internal; 15 using namespace v8::internal;
16 16
17 static v8::Persistent<v8::Context> env; 17 static v8::Persistent<v8::Context> env;
18 18
19 static void InitializeVM() { 19 static void InitializeVM() {
20 if (env.IsEmpty()) env = v8::Context::New(); 20 if (env.IsEmpty()) env = v8::Context::New();
21 v8::HandleScope scope; 21 v8::HandleScope scope;
22 env->Enter(); 22 env->Enter();
23 } 23 }
24 24
25 25
26 // Go through all incremental marking steps in one swoop.
27 static void SimulateIncrementalMarking() {
28 IncrementalMarking* marking = HEAP->incremental_marking();
29 CHECK(marking->IsStopped());
30 marking->Start();
31 CHECK(marking->IsMarking());
32 while (!marking->IsComplete()) {
33 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
34 }
35 CHECK(marking->IsComplete());
36 }
37
38
26 static void CheckMap(Map* map, int type, int instance_size) { 39 static void CheckMap(Map* map, int type, int instance_size) {
27 CHECK(map->IsHeapObject()); 40 CHECK(map->IsHeapObject());
28 #ifdef DEBUG 41 #ifdef DEBUG
29 CHECK(HEAP->Contains(map)); 42 CHECK(HEAP->Contains(map));
30 #endif 43 #endif
31 CHECK_EQ(HEAP->meta_map(), map->map()); 44 CHECK_EQ(HEAP->meta_map(), map->map());
32 CHECK_EQ(type, map->instance_type()); 45 CHECK_EQ(type, map->instance_type());
33 CHECK_EQ(instance_size, map->instance_size()); 46 CHECK_EQ(instance_size, map->instance_size());
34 } 47 }
35 48
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 JSObject* clone = JSObject::cast(clone_obj); 948 JSObject* clone = JSObject::cast(clone_obj);
936 if (clone->address() != old_pointer_space_top) { 949 if (clone->address() != old_pointer_space_top) {
937 // Alas, got allocated from free list, we cannot do checks. 950 // Alas, got allocated from free list, we cannot do checks.
938 return; 951 return;
939 } 952 }
940 CHECK(HEAP->old_pointer_space()->Contains(clone->address())); 953 CHECK(HEAP->old_pointer_space()->Contains(clone->address()));
941 } 954 }
942 955
943 956
944 TEST(TestCodeFlushing) { 957 TEST(TestCodeFlushing) {
945 i::FLAG_allow_natives_syntax = true;
946 // If we do not flush code this test is invalid. 958 // If we do not flush code this test is invalid.
947 if (!FLAG_flush_code) return; 959 if (!FLAG_flush_code) return;
960 i::FLAG_allow_natives_syntax = true;
948 InitializeVM(); 961 InitializeVM();
949 v8::HandleScope scope; 962 v8::HandleScope scope;
950 const char* source = "function foo() {" 963 const char* source = "function foo() {"
951 " var x = 42;" 964 " var x = 42;"
952 " var y = 42;" 965 " var y = 42;"
953 " var z = x + y;" 966 " var z = x + y;"
954 "};" 967 "};"
955 "foo()"; 968 "foo()";
956 Handle<String> foo_name = FACTORY->LookupAsciiSymbol("foo"); 969 Handle<String> foo_name = FACTORY->LookupAsciiSymbol("foo");
957 970
958 // This compile will add the code to the compilation cache. 971 // This compile will add the code to the compilation cache.
959 { v8::HandleScope scope; 972 { v8::HandleScope scope;
960 CompileRun(source); 973 CompileRun(source);
961 } 974 }
962 975
963 // Check function is compiled. 976 // Check function is compiled.
964 Object* func_value = Isolate::Current()->context()->global_object()-> 977 Object* func_value = Isolate::Current()->context()->global_object()->
965 GetProperty(*foo_name)->ToObjectChecked(); 978 GetProperty(*foo_name)->ToObjectChecked();
966 CHECK(func_value->IsJSFunction()); 979 CHECK(func_value->IsJSFunction());
967 Handle<JSFunction> function(JSFunction::cast(func_value)); 980 Handle<JSFunction> function(JSFunction::cast(func_value));
968 CHECK(function->shared()->is_compiled()); 981 CHECK(function->shared()->is_compiled());
969 982
970 // TODO(1609) Currently incremental marker does not support code flushing. 983 // The code will survive at least two GCs.
971 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 984 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
972 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 985 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
973
974 CHECK(function->shared()->is_compiled()); 986 CHECK(function->shared()->is_compiled());
975 987
976 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 988 // Simulate several GCs that use full marking.
977 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 989 const int kAgingThreshold = 6;
978 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 990 for (int i = 0; i < kAgingThreshold; i++) {
979 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 991 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
980 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 992 }
981 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
982 993
983 // foo should no longer be in the compilation cache 994 // foo should no longer be in the compilation cache
984 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); 995 CHECK(!function->shared()->is_compiled() || function->IsOptimized());
985 CHECK(!function->is_compiled() || function->IsOptimized()); 996 CHECK(!function->is_compiled() || function->IsOptimized());
986 // Call foo to get it recompiled. 997 // Call foo to get it recompiled.
987 CompileRun("foo()"); 998 CompileRun("foo()");
988 CHECK(function->shared()->is_compiled()); 999 CHECK(function->shared()->is_compiled());
989 CHECK(function->is_compiled()); 1000 CHECK(function->is_compiled());
990 } 1001 }
991 1002
992 1003
1004 TEST(TestCodeFlushingIncremental) {
1005 // If we do not flush code this test is invalid.
1006 if (!FLAG_flush_code) return;
1007 i::FLAG_allow_natives_syntax = true;
1008 InitializeVM();
1009 v8::HandleScope scope;
1010 const char* source = "function foo() {"
1011 " var x = 42;"
1012 " var y = 42;"
1013 " var z = x + y;"
1014 "};"
1015 "foo()";
1016 Handle<String> foo_name = FACTORY->LookupAsciiSymbol("foo");
1017
1018 // This compile will add the code to the compilation cache.
1019 { v8::HandleScope scope;
1020 CompileRun(source);
1021 }
1022
1023 // Check function is compiled.
1024 Object* func_value = Isolate::Current()->context()->global_object()->
1025 GetProperty(*foo_name)->ToObjectChecked();
1026 CHECK(func_value->IsJSFunction());
1027 Handle<JSFunction> function(JSFunction::cast(func_value));
1028 CHECK(function->shared()->is_compiled());
1029
1030 // The code will survive at least two GCs.
1031 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1032 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1033 CHECK(function->shared()->is_compiled());
1034
1035 // Simulate several GCs that use incremental marking.
1036 const int kAgingThreshold = 6;
1037 for (int i = 0; i < kAgingThreshold; i++) {
1038 HEAP->incremental_marking()->Abort();
1039 SimulateIncrementalMarking();
1040 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1041 }
1042 CHECK(!function->shared()->is_compiled() || function->IsOptimized());
1043 CHECK(!function->is_compiled() || function->IsOptimized());
1044
1045 // This compile will compile the function again.
1046 { v8::HandleScope scope;
1047 CompileRun("foo();");
1048 }
1049
1050 // Simulate several GCs that use incremental marking but make sure
1051 // the loop breaks once the function is enqueued as a candidate.
1052 for (int i = 0; i < kAgingThreshold; i++) {
1053 HEAP->incremental_marking()->Abort();
1054 SimulateIncrementalMarking();
1055 if (!function->next_function_link()->IsUndefined()) break;
1056 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1057 }
1058
1059 // Force optimization while incremental marking is active and while
1060 // the function is enqueued as a candidate.
1061 { v8::HandleScope scope;
1062 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();");
1063 }
1064
1065 // Simulate one final GC to make sure the candidate queue is sane.
1066 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1067 CHECK(function->shared()->is_compiled() || !function->IsOptimized());
1068 CHECK(function->is_compiled() || !function->IsOptimized());
1069 }
1070
1071
993 // Count the number of native contexts in the weak list of native contexts. 1072 // Count the number of native contexts in the weak list of native contexts.
994 int CountNativeContexts() { 1073 int CountNativeContexts() {
995 int count = 0; 1074 int count = 0;
996 Object* object = HEAP->native_contexts_list(); 1075 Object* object = HEAP->native_contexts_list();
997 while (!object->IsUndefined()) { 1076 while (!object->IsUndefined()) {
998 count++; 1077 count++;
999 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); 1078 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK);
1000 } 1079 }
1001 return count; 1080 return count;
1002 } 1081 }
(...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 1839
1761 CHECK(HEAP->InNewSpace(*o)); 1840 CHECK(HEAP->InNewSpace(*o));
1762 } 1841 }
1763 1842
1764 1843
1765 static int CountMapTransitions(Map* map) { 1844 static int CountMapTransitions(Map* map) {
1766 return map->transitions()->number_of_transitions(); 1845 return map->transitions()->number_of_transitions();
1767 } 1846 }
1768 1847
1769 1848
1770 // Go through all incremental marking steps in one swoop.
1771 static void SimulateIncrementalMarking() {
1772 IncrementalMarking* marking = HEAP->incremental_marking();
1773 CHECK(marking->IsStopped());
1774 marking->Start();
1775 CHECK(marking->IsMarking());
1776 while (!marking->IsComplete()) {
1777 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
1778 }
1779 CHECK(marking->IsComplete());
1780 }
1781
1782
1783 // Test that map transitions are cleared and maps are collected with 1849 // Test that map transitions are cleared and maps are collected with
1784 // incremental marking as well. 1850 // incremental marking as well.
1785 TEST(Regress1465) { 1851 TEST(Regress1465) {
1786 i::FLAG_allow_natives_syntax = true; 1852 i::FLAG_allow_natives_syntax = true;
1787 i::FLAG_trace_incremental_marking = true; 1853 i::FLAG_trace_incremental_marking = true;
1788 InitializeVM(); 1854 InitializeVM();
1789 v8::HandleScope scope; 1855 v8::HandleScope scope;
1790 static const int transitions_count = 256; 1856 static const int transitions_count = 256;
1791 1857
1792 { 1858 {
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after
2304 Handle<Object> call_function(call); 2370 Handle<Object> call_function(call);
2305 2371
2306 // Now we are ready to mess up the heap. 2372 // Now we are ready to mess up the heap.
2307 HEAP->CollectAllGarbage(Heap::kReduceMemoryFootprintMask); 2373 HEAP->CollectAllGarbage(Heap::kReduceMemoryFootprintMask);
2308 2374
2309 // Either heap verification caught the problem already or we go kaboom once 2375 // Either heap verification caught the problem already or we go kaboom once
2310 // the CallIC is executed the next time. 2376 // the CallIC is executed the next time.
2311 USE(global->SetProperty(*name, *call_function, NONE, kNonStrictMode)); 2377 USE(global->SetProperty(*name, *call_function, NONE, kNonStrictMode));
2312 CompileRun("call();"); 2378 CompileRun("call();");
2313 } 2379 }
OLDNEW
« no previous file with comments | « src/runtime.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698