OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 "execution.h" | 7 #include "execution.h" |
8 #include "factory.h" | 8 #include "factory.h" |
9 #include "macro-assembler.h" | 9 #include "macro-assembler.h" |
10 #include "global-handles.h" | 10 #include "global-handles.h" |
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 } | 951 } |
952 CHECK(Heap::old_pointer_space()->Contains(clone->address())); | 952 CHECK(Heap::old_pointer_space()->Contains(clone->address())); |
953 | 953 |
954 // Step 5: verify validity of region dirty marks. | 954 // Step 5: verify validity of region dirty marks. |
955 Address clone_addr = clone->address(); | 955 Address clone_addr = clone->address(); |
956 Page* page = Page::FromAddress(clone_addr); | 956 Page* page = Page::FromAddress(clone_addr); |
957 // Check that region covering inobject property 1 is marked dirty. | 957 // Check that region covering inobject property 1 is marked dirty. |
958 CHECK(page->IsRegionDirty(clone_addr + (object_size - kPointerSize))); | 958 CHECK(page->IsRegionDirty(clone_addr + (object_size - kPointerSize))); |
959 } | 959 } |
960 | 960 |
| 961 |
961 TEST(TestCodeFlushing) { | 962 TEST(TestCodeFlushing) { |
962 i::FLAG_allow_natives_syntax = true; | 963 i::FLAG_allow_natives_syntax = true; |
963 // If we do not flush code this test is invalid. | 964 // If we do not flush code this test is invalid. |
964 if (!FLAG_flush_code) return; | 965 if (!FLAG_flush_code) return; |
965 InitializeVM(); | 966 InitializeVM(); |
966 v8::HandleScope scope; | 967 v8::HandleScope scope; |
967 const char* source = "function foo() {" | 968 const char* source = "function foo() {" |
968 " var x = 42;" | 969 " var x = 42;" |
969 " var y = 42;" | 970 " var y = 42;" |
970 " var z = x + y;" | 971 " var z = x + y;" |
(...skipping 23 matching lines...) Expand all Loading... |
994 Heap::CollectAllGarbage(true); | 995 Heap::CollectAllGarbage(true); |
995 | 996 |
996 // foo should no longer be in the compilation cache | 997 // foo should no longer be in the compilation cache |
997 CHECK(!function->shared()->is_compiled()); | 998 CHECK(!function->shared()->is_compiled()); |
998 CHECK(!function->is_compiled()); | 999 CHECK(!function->is_compiled()); |
999 // Call foo to get it recompiled. | 1000 // Call foo to get it recompiled. |
1000 CompileRun("foo()"); | 1001 CompileRun("foo()"); |
1001 CHECK(function->shared()->is_compiled()); | 1002 CHECK(function->shared()->is_compiled()); |
1002 CHECK(function->is_compiled()); | 1003 CHECK(function->is_compiled()); |
1003 } | 1004 } |
| 1005 |
| 1006 |
| 1007 // Count the number of global contexts in the weak list of global contexts. |
| 1008 static int CountGlobalContexts() { |
| 1009 int count = 0; |
| 1010 Object* object = Heap::global_contexts_list(); |
| 1011 while (!object->IsUndefined()) { |
| 1012 count++; |
| 1013 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); |
| 1014 } |
| 1015 return count; |
| 1016 } |
| 1017 |
| 1018 |
| 1019 TEST(TestInternalWeakLists) { |
| 1020 static const int kNumTestContexts = 10; |
| 1021 |
| 1022 v8::HandleScope scope; |
| 1023 v8::Persistent<v8::Context> ctx[kNumTestContexts]; |
| 1024 |
| 1025 CHECK_EQ(0, CountGlobalContexts()); |
| 1026 |
| 1027 // Create a number of global contests which gets linked together. |
| 1028 for (int i = 0; i < kNumTestContexts; i++) { |
| 1029 ctx[i] = v8::Context::New(); |
| 1030 CHECK_EQ(i + 1, CountGlobalContexts()); |
| 1031 |
| 1032 ctx[i]->Enter(); |
| 1033 ctx[i]->Exit(); |
| 1034 } |
| 1035 |
| 1036 // Dispose the global contexts one by one. |
| 1037 for (int i = 0; i < kNumTestContexts; i++) { |
| 1038 ctx[i].Dispose(); |
| 1039 ctx[i].Clear(); |
| 1040 |
| 1041 // Scavenge treats these references as strong. |
| 1042 for (int j = 0; j < 10; j++) { |
| 1043 Heap::PerformScavenge(); |
| 1044 CHECK_EQ(kNumTestContexts - i, CountGlobalContexts()); |
| 1045 } |
| 1046 |
| 1047 // Mark compact handles the weak references. |
| 1048 Heap::CollectAllGarbage(true); |
| 1049 CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts()); |
| 1050 } |
| 1051 |
| 1052 CHECK_EQ(0, CountGlobalContexts()); |
| 1053 } |
| 1054 |
| 1055 |
| 1056 // Count the number of global contexts in the weak list of global contexts |
| 1057 // causing a GC after the specified number of elements. |
| 1058 static int CountGlobalContextsWithGC(int n) { |
| 1059 int count = 0; |
| 1060 Handle<Object> object(Heap::global_contexts_list()); |
| 1061 while (!object->IsUndefined()) { |
| 1062 count++; |
| 1063 if (count == n) Heap::CollectAllGarbage(true); |
| 1064 object = |
| 1065 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK)); |
| 1066 } |
| 1067 return count; |
| 1068 } |
| 1069 |
| 1070 |
| 1071 TEST(TestInternalWeakListsTraverseWithGC) { |
| 1072 static const int kNumTestContexts = 10; |
| 1073 |
| 1074 v8::HandleScope scope; |
| 1075 v8::Persistent<v8::Context> ctx[kNumTestContexts]; |
| 1076 |
| 1077 CHECK_EQ(0, CountGlobalContexts()); |
| 1078 |
| 1079 // Create an number of contexts and check the length of the weak list both |
| 1080 // with and without GCs while iterating the list. |
| 1081 for (int i = 0; i < kNumTestContexts; i++) { |
| 1082 ctx[i] = v8::Context::New(); |
| 1083 CHECK_EQ(i + 1, CountGlobalContexts()); |
| 1084 CHECK_EQ(i + 1, CountGlobalContextsWithGC(i / 2 + 1)); |
| 1085 |
| 1086 ctx[i]->Enter(); |
| 1087 ctx[i]->Exit(); |
| 1088 } |
| 1089 } |
OLD | NEW |