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

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

Issue 7945009: Merge experimental/gc branch to the bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 3 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 | « test/cctest/test-disasm-ia32.cc ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2011 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"
11 #include "cctest.h" 11 #include "cctest.h"
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 delete[] str; 831 delete[] str;
832 832
833 // Add a Map object to look for. 833 // Add a Map object to look for.
834 objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); 834 objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map());
835 835
836 CHECK_EQ(objs_count, next_objs_index); 836 CHECK_EQ(objs_count, next_objs_index);
837 CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count)); 837 CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count));
838 } 838 }
839 839
840 840
841 TEST(LargeObjectSpaceContains) {
842 InitializeVM();
843
844 HEAP->CollectGarbage(NEW_SPACE);
845
846 Address current_top = HEAP->new_space()->top();
847 Page* page = Page::FromAddress(current_top);
848 Address current_page = page->address();
849 Address next_page = current_page + Page::kPageSize;
850 int bytes_to_page = static_cast<int>(next_page - current_top);
851 if (bytes_to_page <= FixedArray::kHeaderSize) {
852 // Alas, need to cross another page to be able to
853 // put desired value.
854 next_page += Page::kPageSize;
855 bytes_to_page = static_cast<int>(next_page - current_top);
856 }
857 CHECK(bytes_to_page > FixedArray::kHeaderSize);
858
859 intptr_t* flags_ptr = &Page::FromAddress(next_page)->flags_;
860 Address flags_addr = reinterpret_cast<Address>(flags_ptr);
861
862 int bytes_to_allocate =
863 static_cast<int>(flags_addr - current_top) + kPointerSize;
864
865 int n_elements = (bytes_to_allocate - FixedArray::kHeaderSize) /
866 kPointerSize;
867 CHECK_EQ(bytes_to_allocate, FixedArray::SizeFor(n_elements));
868 FixedArray* array = FixedArray::cast(
869 HEAP->AllocateFixedArray(n_elements)->ToObjectChecked());
870
871 int index = n_elements - 1;
872 CHECK_EQ(flags_ptr,
873 HeapObject::RawField(array, FixedArray::OffsetOfElementAt(index)));
874 array->set(index, Smi::FromInt(0));
875 // This chould have turned next page into LargeObjectPage:
876 // CHECK(Page::FromAddress(next_page)->IsLargeObjectPage());
877
878 HeapObject* addr = HeapObject::FromAddress(next_page + 2 * kPointerSize);
879 CHECK(HEAP->new_space()->Contains(addr));
880 CHECK(!HEAP->lo_space()->Contains(addr));
881 }
882
883
884 TEST(EmptyHandleEscapeFrom) { 841 TEST(EmptyHandleEscapeFrom) {
885 InitializeVM(); 842 InitializeVM();
886 843
887 v8::HandleScope scope; 844 v8::HandleScope scope;
888 Handle<JSObject> runaway; 845 Handle<JSObject> runaway;
889 846
890 { 847 {
891 v8::HandleScope nested; 848 v8::HandleScope nested;
892 Handle<JSObject> empty; 849 Handle<JSObject> empty;
893 runaway = empty.EscapeFrom(&nested); 850 runaway = empty.EscapeFrom(&nested);
894 } 851 }
895 852
896 CHECK(runaway.is_null()); 853 CHECK(runaway.is_null());
897 } 854 }
898 855
899 856
900 static int LenFromSize(int size) { 857 static int LenFromSize(int size) {
901 return (size - FixedArray::kHeaderSize) / kPointerSize; 858 return (size - FixedArray::kHeaderSize) / kPointerSize;
902 } 859 }
903 860
904 861
905 TEST(Regression39128) { 862 TEST(Regression39128) {
906 // Test case for crbug.com/39128. 863 // Test case for crbug.com/39128.
907 InitializeVM(); 864 InitializeVM();
908 865
909 // Increase the chance of 'bump-the-pointer' allocation in old space. 866 // Increase the chance of 'bump-the-pointer' allocation in old space.
910 bool force_compaction = true; 867 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
911 HEAP->CollectAllGarbage(force_compaction);
912 868
913 v8::HandleScope scope; 869 v8::HandleScope scope;
914 870
915 // The plan: create JSObject which references objects in new space. 871 // The plan: create JSObject which references objects in new space.
916 // Then clone this object (forcing it to go into old space) and check 872 // Then clone this object (forcing it to go into old space) and check
917 // that region dirty marks are updated correctly. 873 // that region dirty marks are updated correctly.
918 874
919 // Step 1: prepare a map for the object. We add 1 inobject property to it. 875 // Step 1: prepare a map for the object. We add 1 inobject property to it.
920 Handle<JSFunction> object_ctor( 876 Handle<JSFunction> object_ctor(
921 Isolate::Current()->global_context()->object_function()); 877 Isolate::Current()->global_context()->object_function());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 // in old pointer space. 924 // in old pointer space.
969 Address old_pointer_space_top = HEAP->old_pointer_space()->top(); 925 Address old_pointer_space_top = HEAP->old_pointer_space()->top();
970 AlwaysAllocateScope aa_scope; 926 AlwaysAllocateScope aa_scope;
971 Object* clone_obj = HEAP->CopyJSObject(jsobject)->ToObjectChecked(); 927 Object* clone_obj = HEAP->CopyJSObject(jsobject)->ToObjectChecked();
972 JSObject* clone = JSObject::cast(clone_obj); 928 JSObject* clone = JSObject::cast(clone_obj);
973 if (clone->address() != old_pointer_space_top) { 929 if (clone->address() != old_pointer_space_top) {
974 // Alas, got allocated from free list, we cannot do checks. 930 // Alas, got allocated from free list, we cannot do checks.
975 return; 931 return;
976 } 932 }
977 CHECK(HEAP->old_pointer_space()->Contains(clone->address())); 933 CHECK(HEAP->old_pointer_space()->Contains(clone->address()));
978
979 // Step 5: verify validity of region dirty marks.
980 Address clone_addr = clone->address();
981 Page* page = Page::FromAddress(clone_addr);
982 // Check that region covering inobject property 1 is marked dirty.
983 CHECK(page->IsRegionDirty(clone_addr + (object_size - kPointerSize)));
984 } 934 }
985 935
986 936
987 TEST(TestCodeFlushing) { 937 TEST(TestCodeFlushing) {
988 i::FLAG_allow_natives_syntax = true; 938 i::FLAG_allow_natives_syntax = true;
989 // If we do not flush code this test is invalid. 939 // If we do not flush code this test is invalid.
990 if (!FLAG_flush_code) return; 940 if (!FLAG_flush_code) return;
991 InitializeVM(); 941 InitializeVM();
992 v8::HandleScope scope; 942 v8::HandleScope scope;
993 const char* source = "function foo() {" 943 const char* source = "function foo() {"
994 " var x = 42;" 944 " var x = 42;"
995 " var y = 42;" 945 " var y = 42;"
996 " var z = x + y;" 946 " var z = x + y;"
997 "};" 947 "};"
998 "foo()"; 948 "foo()";
999 Handle<String> foo_name = FACTORY->LookupAsciiSymbol("foo"); 949 Handle<String> foo_name = FACTORY->LookupAsciiSymbol("foo");
1000 950
1001 // This compile will add the code to the compilation cache. 951 // This compile will add the code to the compilation cache.
1002 { v8::HandleScope scope; 952 { v8::HandleScope scope;
1003 CompileRun(source); 953 CompileRun(source);
1004 } 954 }
1005 955
1006 // Check function is compiled. 956 // Check function is compiled.
1007 Object* func_value = Isolate::Current()->context()->global()-> 957 Object* func_value = Isolate::Current()->context()->global()->
1008 GetProperty(*foo_name)->ToObjectChecked(); 958 GetProperty(*foo_name)->ToObjectChecked();
1009 CHECK(func_value->IsJSFunction()); 959 CHECK(func_value->IsJSFunction());
1010 Handle<JSFunction> function(JSFunction::cast(func_value)); 960 Handle<JSFunction> function(JSFunction::cast(func_value));
1011 CHECK(function->shared()->is_compiled()); 961 CHECK(function->shared()->is_compiled());
1012 962
1013 HEAP->CollectAllGarbage(true); 963 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1014 HEAP->CollectAllGarbage(true); 964 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1015 965
1016 CHECK(function->shared()->is_compiled()); 966 CHECK(function->shared()->is_compiled());
1017 967
1018 HEAP->CollectAllGarbage(true); 968 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1019 HEAP->CollectAllGarbage(true); 969 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1020 HEAP->CollectAllGarbage(true); 970 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1021 HEAP->CollectAllGarbage(true); 971 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1022 HEAP->CollectAllGarbage(true); 972 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1023 HEAP->CollectAllGarbage(true); 973 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1024 974
1025 // foo should no longer be in the compilation cache 975 // foo should no longer be in the compilation cache
1026 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); 976 CHECK(!function->shared()->is_compiled() || function->IsOptimized());
1027 CHECK(!function->is_compiled() || function->IsOptimized()); 977 CHECK(!function->is_compiled() || function->IsOptimized());
1028 // Call foo to get it recompiled. 978 // Call foo to get it recompiled.
1029 CompileRun("foo()"); 979 CompileRun("foo()");
1030 CHECK(function->shared()->is_compiled()); 980 CHECK(function->shared()->is_compiled());
1031 CHECK(function->is_compiled()); 981 CHECK(function->is_compiled());
1032 } 982 }
1033 983
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 // Remove function f1, and 1052 // Remove function f1, and
1103 CompileRun("f1=null"); 1053 CompileRun("f1=null");
1104 1054
1105 // Scavenge treats these references as strong. 1055 // Scavenge treats these references as strong.
1106 for (int j = 0; j < 10; j++) { 1056 for (int j = 0; j < 10; j++) {
1107 HEAP->PerformScavenge(); 1057 HEAP->PerformScavenge();
1108 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); 1058 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i]));
1109 } 1059 }
1110 1060
1111 // Mark compact handles the weak references. 1061 // Mark compact handles the weak references.
1112 HEAP->CollectAllGarbage(true); 1062 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1113 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); 1063 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
1114 1064
1115 // Get rid of f3 and f5 in the same way. 1065 // Get rid of f3 and f5 in the same way.
1116 CompileRun("f3=null"); 1066 CompileRun("f3=null");
1117 for (int j = 0; j < 10; j++) { 1067 for (int j = 0; j < 10; j++) {
1118 HEAP->PerformScavenge(); 1068 HEAP->PerformScavenge();
1119 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); 1069 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
1120 } 1070 }
1121 HEAP->CollectAllGarbage(true); 1071 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1122 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); 1072 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
1123 CompileRun("f5=null"); 1073 CompileRun("f5=null");
1124 for (int j = 0; j < 10; j++) { 1074 for (int j = 0; j < 10; j++) {
1125 HEAP->PerformScavenge(); 1075 HEAP->PerformScavenge();
1126 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); 1076 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
1127 } 1077 }
1128 HEAP->CollectAllGarbage(true); 1078 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1129 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); 1079 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i]));
1130 1080
1131 ctx[i]->Exit(); 1081 ctx[i]->Exit();
1132 } 1082 }
1133 1083
1134 // Force compilation cache cleanup. 1084 // Force compilation cache cleanup.
1135 HEAP->CollectAllGarbage(true); 1085 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1136 1086
1137 // Dispose the global contexts one by one. 1087 // Dispose the global contexts one by one.
1138 for (int i = 0; i < kNumTestContexts; i++) { 1088 for (int i = 0; i < kNumTestContexts; i++) {
1139 ctx[i].Dispose(); 1089 ctx[i].Dispose();
1140 ctx[i].Clear(); 1090 ctx[i].Clear();
1141 1091
1142 // Scavenge treats these references as strong. 1092 // Scavenge treats these references as strong.
1143 for (int j = 0; j < 10; j++) { 1093 for (int j = 0; j < 10; j++) {
1144 HEAP->PerformScavenge(); 1094 HEAP->PerformScavenge();
1145 CHECK_EQ(kNumTestContexts - i, CountGlobalContexts()); 1095 CHECK_EQ(kNumTestContexts - i, CountGlobalContexts());
1146 } 1096 }
1147 1097
1148 // Mark compact handles the weak references. 1098 // Mark compact handles the weak references.
1149 HEAP->CollectAllGarbage(true); 1099 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1150 CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts()); 1100 CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts());
1151 } 1101 }
1152 1102
1153 CHECK_EQ(0, CountGlobalContexts()); 1103 CHECK_EQ(0, CountGlobalContexts());
1154 } 1104 }
1155 1105
1156 1106
1157 // Count the number of global contexts in the weak list of global contexts 1107 // Count the number of global contexts in the weak list of global contexts
1158 // causing a GC after the specified number of elements. 1108 // causing a GC after the specified number of elements.
1159 static int CountGlobalContextsWithGC(int n) { 1109 static int CountGlobalContextsWithGC(int n) {
1160 int count = 0; 1110 int count = 0;
1161 Handle<Object> object(HEAP->global_contexts_list()); 1111 Handle<Object> object(HEAP->global_contexts_list());
1162 while (!object->IsUndefined()) { 1112 while (!object->IsUndefined()) {
1163 count++; 1113 count++;
1164 if (count == n) HEAP->CollectAllGarbage(true); 1114 if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1165 object = 1115 object =
1166 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK)); 1116 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK));
1167 } 1117 }
1168 return count; 1118 return count;
1169 } 1119 }
1170 1120
1171 1121
1172 // Count the number of user functions in the weak list of optimized 1122 // Count the number of user functions in the weak list of optimized
1173 // functions attached to a global context causing a GC after the 1123 // functions attached to a global context causing a GC after the
1174 // specified number of elements. 1124 // specified number of elements.
1175 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, 1125 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context,
1176 int n) { 1126 int n) {
1177 int count = 0; 1127 int count = 0;
1178 Handle<Context> icontext = v8::Utils::OpenHandle(*context); 1128 Handle<Context> icontext = v8::Utils::OpenHandle(*context);
1179 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST)); 1129 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST));
1180 while (object->IsJSFunction() && 1130 while (object->IsJSFunction() &&
1181 !Handle<JSFunction>::cast(object)->IsBuiltin()) { 1131 !Handle<JSFunction>::cast(object)->IsBuiltin()) {
1182 count++; 1132 count++;
1183 if (count == n) HEAP->CollectAllGarbage(true); 1133 if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1184 object = Handle<Object>( 1134 object = Handle<Object>(
1185 Object::cast(JSFunction::cast(*object)->next_function_link())); 1135 Object::cast(JSFunction::cast(*object)->next_function_link()));
1186 } 1136 }
1187 return count; 1137 return count;
1188 } 1138 }
1189 1139
1190 1140
1191 TEST(TestInternalWeakListsTraverseWithGC) { 1141 TEST(TestInternalWeakListsTraverseWithGC) {
1192 v8::V8::Initialize(); 1142 v8::V8::Initialize();
1193 1143
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 CompileRun("f5()"); 1183 CompileRun("f5()");
1234 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0])); 1184 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0]));
1235 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4)); 1185 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4));
1236 1186
1237 ctx[0]->Exit(); 1187 ctx[0]->Exit();
1238 } 1188 }
1239 1189
1240 1190
1241 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) { 1191 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
1242 InitializeVM(); 1192 InitializeVM();
1193 HEAP->EnsureHeapIsIterable();
1243 intptr_t size_of_objects_1 = HEAP->SizeOfObjects(); 1194 intptr_t size_of_objects_1 = HEAP->SizeOfObjects();
1244 HeapIterator iterator(HeapIterator::kFilterFreeListNodes); 1195 HeapIterator iterator;
1245 intptr_t size_of_objects_2 = 0; 1196 intptr_t size_of_objects_2 = 0;
1246 for (HeapObject* obj = iterator.next(); 1197 for (HeapObject* obj = iterator.next();
1247 obj != NULL; 1198 obj != NULL;
1248 obj = iterator.next()) { 1199 obj = iterator.next()) {
1249 size_of_objects_2 += obj->Size(); 1200 size_of_objects_2 += obj->Size();
1250 } 1201 }
1251 // Delta must be within 1% of the larger result. 1202 // Delta must be within 5% of the larger result.
1203 // TODO(gc): Tighten this up by distinguishing between byte
1204 // arrays that are real and those that merely mark free space
1205 // on the heap.
1252 if (size_of_objects_1 > size_of_objects_2) { 1206 if (size_of_objects_1 > size_of_objects_2) {
1253 intptr_t delta = size_of_objects_1 - size_of_objects_2; 1207 intptr_t delta = size_of_objects_1 - size_of_objects_2;
1254 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, " 1208 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, "
1255 "Iterator: %" V8_PTR_PREFIX "d, " 1209 "Iterator: %" V8_PTR_PREFIX "d, "
1256 "delta: %" V8_PTR_PREFIX "d\n", 1210 "delta: %" V8_PTR_PREFIX "d\n",
1257 size_of_objects_1, size_of_objects_2, delta); 1211 size_of_objects_1, size_of_objects_2, delta);
1258 CHECK_GT(size_of_objects_1 / 100, delta); 1212 CHECK_GT(size_of_objects_1 / 20, delta);
1259 } else { 1213 } else {
1260 intptr_t delta = size_of_objects_2 - size_of_objects_1; 1214 intptr_t delta = size_of_objects_2 - size_of_objects_1;
1261 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, " 1215 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, "
1262 "Iterator: %" V8_PTR_PREFIX "d, " 1216 "Iterator: %" V8_PTR_PREFIX "d, "
1263 "delta: %" V8_PTR_PREFIX "d\n", 1217 "delta: %" V8_PTR_PREFIX "d\n",
1264 size_of_objects_1, size_of_objects_2, delta); 1218 size_of_objects_1, size_of_objects_2, delta);
1265 CHECK_GT(size_of_objects_2 / 100, delta); 1219 CHECK_GT(size_of_objects_2 / 20, delta);
1266 } 1220 }
1267 } 1221 }
1268 1222
1269 1223
1270 class HeapIteratorTestHelper { 1224 class HeapIteratorTestHelper {
1271 public: 1225 public:
1272 HeapIteratorTestHelper(Object* a, Object* b) 1226 HeapIteratorTestHelper(Object* a, Object* b)
1273 : a_(a), b_(b), a_found_(false), b_found_(false) {} 1227 : a_(a), b_(b), a_found_(false), b_found_(false) {}
1274 bool a_found() { return a_found_; } 1228 bool a_found() { return a_found_; }
1275 bool b_found() { return b_found_; } 1229 bool b_found() { return b_found_; }
1276 void IterateHeap(HeapIterator::HeapObjectsFiltering mode) { 1230 void IterateHeap() {
1277 HeapIterator iterator(mode); 1231 HeapIterator iterator;
1278 for (HeapObject* obj = iterator.next(); 1232 for (HeapObject* obj = iterator.next();
1279 obj != NULL; 1233 obj != NULL;
1280 obj = iterator.next()) { 1234 obj = iterator.next()) {
1281 if (obj == a_) 1235 if (obj == a_)
1282 a_found_ = true; 1236 a_found_ = true;
1283 else if (obj == b_) 1237 else if (obj == b_)
1284 b_found_ = true; 1238 b_found_ = true;
1285 } 1239 }
1286 } 1240 }
1287 private: 1241 private:
1288 Object* a_; 1242 Object* a_;
1289 Object* b_; 1243 Object* b_;
1290 bool a_found_; 1244 bool a_found_;
1291 bool b_found_; 1245 bool b_found_;
1292 }; 1246 };
1293
1294 TEST(HeapIteratorFilterUnreachable) {
1295 InitializeVM();
1296 v8::HandleScope scope;
1297 CompileRun("a = {}; b = {};");
1298 v8::Handle<Object> a(ISOLATE->context()->global()->GetProperty(
1299 *FACTORY->LookupAsciiSymbol("a"))->ToObjectChecked());
1300 v8::Handle<Object> b(ISOLATE->context()->global()->GetProperty(
1301 *FACTORY->LookupAsciiSymbol("b"))->ToObjectChecked());
1302 CHECK_NE(*a, *b);
1303 {
1304 HeapIteratorTestHelper helper(*a, *b);
1305 helper.IterateHeap(HeapIterator::kFilterUnreachable);
1306 CHECK(helper.a_found());
1307 CHECK(helper.b_found());
1308 }
1309 CHECK(ISOLATE->context()->global()->DeleteProperty(
1310 *FACTORY->LookupAsciiSymbol("a"), JSObject::FORCE_DELETION));
1311 // We ensure that GC will not happen, so our raw pointer stays valid.
1312 AssertNoAllocation no_alloc;
1313 Object* a_saved = *a;
1314 a.Clear();
1315 // Verify that "a" object still resides in the heap...
1316 {
1317 HeapIteratorTestHelper helper(a_saved, *b);
1318 helper.IterateHeap(HeapIterator::kNoFiltering);
1319 CHECK(helper.a_found());
1320 CHECK(helper.b_found());
1321 }
1322 // ...but is now unreachable.
1323 {
1324 HeapIteratorTestHelper helper(a_saved, *b);
1325 helper.IterateHeap(HeapIterator::kFilterUnreachable);
1326 CHECK(!helper.a_found());
1327 CHECK(helper.b_found());
1328 }
1329 }
OLDNEW
« no previous file with comments | « test/cctest/test-disasm-ia32.cc ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698