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

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

Issue 6639024: Get rid of distinction between below- and above-watermark in page allocation.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 9 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
OLDNEW
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 766 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 DeleteArray(non_ascii); 777 DeleteArray(non_ascii);
778 DeleteArray(ascii); 778 DeleteArray(ascii);
779 } 779 }
780 } 780 }
781 781
782 782
783 static int ObjectsFoundInHeap(Handle<Object> objs[], int size) { 783 static int ObjectsFoundInHeap(Handle<Object> objs[], int size) {
784 // Count the number of objects found in the heap. 784 // Count the number of objects found in the heap.
785 int found_count = 0; 785 int found_count = 0;
786 HeapIterator iterator; 786 HeapIterator iterator;
787 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 787 for (HeapObject* obj = iterator.Next(); obj != NULL; obj = iterator.Next()) {
788 for (int i = 0; i < size; i++) { 788 for (int i = 0; i < size; i++) {
789 if (*objs[i] == obj) { 789 if (*objs[i] == obj) {
790 found_count++; 790 found_count++;
791 } 791 }
792 } 792 }
793 } 793 }
794 return found_count; 794 return found_count;
795 } 795 }
796 796
797 797
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 static int LenFromSize(int size) { 850 static int LenFromSize(int size) {
851 return (size - FixedArray::kHeaderSize) / kPointerSize; 851 return (size - FixedArray::kHeaderSize) / kPointerSize;
852 } 852 }
853 853
854 854
855 TEST(Regression39128) { 855 TEST(Regression39128) {
856 // Test case for crbug.com/39128. 856 // Test case for crbug.com/39128.
857 InitializeVM(); 857 InitializeVM();
858 858
859 // Increase the chance of 'bump-the-pointer' allocation in old space. 859 // Increase the chance of 'bump-the-pointer' allocation in old space.
860 bool force_compaction = true; 860 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
861 Heap::CollectAllGarbage(force_compaction);
862 861
863 v8::HandleScope scope; 862 v8::HandleScope scope;
864 863
865 // The plan: create JSObject which references objects in new space. 864 // The plan: create JSObject which references objects in new space.
866 // Then clone this object (forcing it to go into old space) and check 865 // Then clone this object (forcing it to go into old space) and check
867 // that region dirty marks are updated correctly. 866 // that region dirty marks are updated correctly.
868 867
869 // Step 1: prepare a map for the object. We add 1 inobject property to it. 868 // Step 1: prepare a map for the object. We add 1 inobject property to it.
870 Handle<JSFunction> object_ctor(Top::global_context()->object_function()); 869 Handle<JSFunction> object_ctor(Top::global_context()->object_function());
871 CHECK(object_ctor->has_initial_map()); 870 CHECK(object_ctor->has_initial_map());
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 CompileRun(source); 945 CompileRun(source);
947 } 946 }
948 947
949 // Check function is compiled. 948 // Check function is compiled.
950 Object* func_value = 949 Object* func_value =
951 Top::context()->global()->GetProperty(*foo_name)->ToObjectChecked(); 950 Top::context()->global()->GetProperty(*foo_name)->ToObjectChecked();
952 CHECK(func_value->IsJSFunction()); 951 CHECK(func_value->IsJSFunction());
953 Handle<JSFunction> function(JSFunction::cast(func_value)); 952 Handle<JSFunction> function(JSFunction::cast(func_value));
954 CHECK(function->shared()->is_compiled()); 953 CHECK(function->shared()->is_compiled());
955 954
956 Heap::CollectAllGarbage(true); 955 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
957 Heap::CollectAllGarbage(true); 956 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
958 957
959 CHECK(function->shared()->is_compiled()); 958 CHECK(function->shared()->is_compiled());
960 959
961 Heap::CollectAllGarbage(true); 960 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
962 Heap::CollectAllGarbage(true); 961 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
963 Heap::CollectAllGarbage(true); 962 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
964 Heap::CollectAllGarbage(true); 963 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
965 Heap::CollectAllGarbage(true); 964 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
966 Heap::CollectAllGarbage(true); 965 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
967 966
968 // foo should no longer be in the compilation cache 967 // foo should no longer be in the compilation cache
969 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); 968 CHECK(!function->shared()->is_compiled() || function->IsOptimized());
970 CHECK(!function->is_compiled() || function->IsOptimized()); 969 CHECK(!function->is_compiled() || function->IsOptimized());
971 // Call foo to get it recompiled. 970 // Call foo to get it recompiled.
972 CompileRun("foo()"); 971 CompileRun("foo()");
973 CHECK(function->shared()->is_compiled()); 972 CHECK(function->shared()->is_compiled());
974 CHECK(function->is_compiled()); 973 CHECK(function->is_compiled());
975 } 974 }
976 975
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 // Remove function f1, and 1042 // Remove function f1, and
1044 CompileRun("f1=null"); 1043 CompileRun("f1=null");
1045 1044
1046 // Scavenge treats these references as strong. 1045 // Scavenge treats these references as strong.
1047 for (int j = 0; j < 10; j++) { 1046 for (int j = 0; j < 10; j++) {
1048 Heap::PerformScavenge(); 1047 Heap::PerformScavenge();
1049 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); 1048 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i]));
1050 } 1049 }
1051 1050
1052 // Mark compact handles the weak references. 1051 // Mark compact handles the weak references.
1053 Heap::CollectAllGarbage(true); 1052 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1054 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); 1053 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
1055 1054
1056 // Get rid of f3 and f5 in the same way. 1055 // Get rid of f3 and f5 in the same way.
1057 CompileRun("f3=null"); 1056 CompileRun("f3=null");
1058 for (int j = 0; j < 10; j++) { 1057 for (int j = 0; j < 10; j++) {
1059 Heap::PerformScavenge(); 1058 Heap::PerformScavenge();
1060 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); 1059 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
1061 } 1060 }
1062 Heap::CollectAllGarbage(true); 1061 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1063 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); 1062 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
1064 CompileRun("f5=null"); 1063 CompileRun("f5=null");
1065 for (int j = 0; j < 10; j++) { 1064 for (int j = 0; j < 10; j++) {
1066 Heap::PerformScavenge(); 1065 Heap::PerformScavenge();
1067 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); 1066 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
1068 } 1067 }
1069 Heap::CollectAllGarbage(true); 1068 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1070 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); 1069 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i]));
1071 1070
1072 ctx[i]->Exit(); 1071 ctx[i]->Exit();
1073 } 1072 }
1074 1073
1075 // Force compilation cache cleanup. 1074 // Force compilation cache cleanup.
1076 Heap::CollectAllGarbage(true); 1075 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1077 1076
1078 // Dispose the global contexts one by one. 1077 // Dispose the global contexts one by one.
1079 for (int i = 0; i < kNumTestContexts; i++) { 1078 for (int i = 0; i < kNumTestContexts; i++) {
1080 ctx[i].Dispose(); 1079 ctx[i].Dispose();
1081 ctx[i].Clear(); 1080 ctx[i].Clear();
1082 1081
1083 // Scavenge treats these references as strong. 1082 // Scavenge treats these references as strong.
1084 for (int j = 0; j < 10; j++) { 1083 for (int j = 0; j < 10; j++) {
1085 Heap::PerformScavenge(); 1084 Heap::PerformScavenge();
1086 CHECK_EQ(kNumTestContexts - i, CountGlobalContexts()); 1085 CHECK_EQ(kNumTestContexts - i, CountGlobalContexts());
1087 } 1086 }
1088 1087
1089 // Mark compact handles the weak references. 1088 // Mark compact handles the weak references.
1090 Heap::CollectAllGarbage(true); 1089 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1091 CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts()); 1090 CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts());
1092 } 1091 }
1093 1092
1094 CHECK_EQ(0, CountGlobalContexts()); 1093 CHECK_EQ(0, CountGlobalContexts());
1095 } 1094 }
1096 1095
1097 1096
1098 // Count the number of global contexts in the weak list of global contexts 1097 // Count the number of global contexts in the weak list of global contexts
1099 // causing a GC after the specified number of elements. 1098 // causing a GC after the specified number of elements.
1100 static int CountGlobalContextsWithGC(int n) { 1099 static int CountGlobalContextsWithGC(int n) {
1101 int count = 0; 1100 int count = 0;
1102 Handle<Object> object(Heap::global_contexts_list()); 1101 Handle<Object> object(Heap::global_contexts_list());
1103 while (!object->IsUndefined()) { 1102 while (!object->IsUndefined()) {
1104 count++; 1103 count++;
1105 if (count == n) Heap::CollectAllGarbage(true); 1104 if (count == n) Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1106 object = 1105 object =
1107 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK)); 1106 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK));
1108 } 1107 }
1109 return count; 1108 return count;
1110 } 1109 }
1111 1110
1112 1111
1113 // Count the number of user functions in the weak list of optimized 1112 // Count the number of user functions in the weak list of optimized
1114 // functions attached to a global context causing a GC after the 1113 // functions attached to a global context causing a GC after the
1115 // specified number of elements. 1114 // specified number of elements.
1116 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, 1115 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context,
1117 int n) { 1116 int n) {
1118 int count = 0; 1117 int count = 0;
1119 Handle<Context> icontext = v8::Utils::OpenHandle(*context); 1118 Handle<Context> icontext = v8::Utils::OpenHandle(*context);
1120 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST)); 1119 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST));
1121 while (object->IsJSFunction() && 1120 while (object->IsJSFunction() &&
1122 !Handle<JSFunction>::cast(object)->IsBuiltin()) { 1121 !Handle<JSFunction>::cast(object)->IsBuiltin()) {
1123 count++; 1122 count++;
1124 if (count == n) Heap::CollectAllGarbage(true); 1123 if (count == n) Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1125 object = Handle<Object>( 1124 object = Handle<Object>(
1126 Object::cast(JSFunction::cast(*object)->next_function_link())); 1125 Object::cast(JSFunction::cast(*object)->next_function_link()));
1127 } 1126 }
1128 return count; 1127 return count;
1129 } 1128 }
1130 1129
1131 1130
1132 TEST(TestInternalWeakListsTraverseWithGC) { 1131 TEST(TestInternalWeakListsTraverseWithGC) {
1133 static const int kNumTestContexts = 10; 1132 static const int kNumTestContexts = 10;
1134 1133
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 CompileRun("f5()"); 1171 CompileRun("f5()");
1173 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0])); 1172 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0]));
1174 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4)); 1173 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4));
1175 1174
1176 ctx[0]->Exit(); 1175 ctx[0]->Exit();
1177 } 1176 }
1178 1177
1179 1178
1180 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) { 1179 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
1181 InitializeVM(); 1180 InitializeVM();
1181 Heap::EnsureHeapIsIterable();
1182 intptr_t size_of_objects_1 = Heap::SizeOfObjects(); 1182 intptr_t size_of_objects_1 = Heap::SizeOfObjects();
1183 HeapIterator iterator(HeapIterator::kFilterFreeListNodes); 1183 HeapIterator iterator;
1184 intptr_t size_of_objects_2 = 0; 1184 intptr_t size_of_objects_2 = 0;
1185 for (HeapObject* obj = iterator.next(); 1185 for (HeapObject* obj = iterator.Next();
1186 obj != NULL; 1186 obj != NULL;
1187 obj = iterator.next()) { 1187 obj = iterator.Next()) {
1188 size_of_objects_2 += obj->Size(); 1188 size_of_objects_2 += obj->Size();
1189 } 1189 }
1190 // Delta must be within 1% of the larger result. 1190 // Delta must be within 5% of the larger result.
1191 // TODO(gc): Tighten this up by distinguishing between byte
1192 // arrays that are real and those that merely mark free space
1193 // on the heap.
1191 if (size_of_objects_1 > size_of_objects_2) { 1194 if (size_of_objects_1 > size_of_objects_2) {
1192 intptr_t delta = size_of_objects_1 - size_of_objects_2; 1195 intptr_t delta = size_of_objects_1 - size_of_objects_2;
1193 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, " 1196 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, "
1194 "Iterator: %" V8_PTR_PREFIX "d, " 1197 "Iterator: %" V8_PTR_PREFIX "d, "
1195 "delta: %" V8_PTR_PREFIX "d\n", 1198 "delta: %" V8_PTR_PREFIX "d\n",
1196 size_of_objects_1, size_of_objects_2, delta); 1199 size_of_objects_1, size_of_objects_2, delta);
1197 CHECK_GT(size_of_objects_1 / 100, delta); 1200 CHECK_GT(size_of_objects_1 / 20, delta);
1198 } else { 1201 } else {
1199 intptr_t delta = size_of_objects_2 - size_of_objects_1; 1202 intptr_t delta = size_of_objects_2 - size_of_objects_1;
1200 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, " 1203 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, "
1201 "Iterator: %" V8_PTR_PREFIX "d, " 1204 "Iterator: %" V8_PTR_PREFIX "d, "
1202 "delta: %" V8_PTR_PREFIX "d\n", 1205 "delta: %" V8_PTR_PREFIX "d\n",
1203 size_of_objects_1, size_of_objects_2, delta); 1206 size_of_objects_1, size_of_objects_2, delta);
1204 CHECK_GT(size_of_objects_2 / 100, delta); 1207 CHECK_GT(size_of_objects_2 / 20, delta);
1205 } 1208 }
1206 } 1209 }
1207 1210
1208 1211
1209 class HeapIteratorTestHelper { 1212 class HeapIteratorTestHelper {
1210 public: 1213 public:
1211 HeapIteratorTestHelper(Object* a, Object* b) 1214 HeapIteratorTestHelper(Object* a, Object* b)
1212 : a_(a), b_(b), a_found_(false), b_found_(false) {} 1215 : a_(a), b_(b), a_found_(false), b_found_(false) {}
1213 bool a_found() { return a_found_; } 1216 bool a_found() { return a_found_; }
1214 bool b_found() { return b_found_; } 1217 bool b_found() { return b_found_; }
1215 void IterateHeap(HeapIterator::HeapObjectsFiltering mode) { 1218 void IterateHeap() {
1216 HeapIterator iterator(mode); 1219 HeapIterator iterator;
1217 for (HeapObject* obj = iterator.next(); 1220 for (HeapObject* obj = iterator.Next();
1218 obj != NULL; 1221 obj != NULL;
1219 obj = iterator.next()) { 1222 obj = iterator.Next()) {
1220 if (obj == a_) 1223 if (obj == a_)
1221 a_found_ = true; 1224 a_found_ = true;
1222 else if (obj == b_) 1225 else if (obj == b_)
1223 b_found_ = true; 1226 b_found_ = true;
1224 } 1227 }
1225 } 1228 }
1226 private: 1229 private:
1227 Object* a_; 1230 Object* a_;
1228 Object* b_; 1231 Object* b_;
1229 bool a_found_; 1232 bool a_found_;
1230 bool b_found_; 1233 bool b_found_;
1231 }; 1234 };
1232 1235
1233 TEST(HeapIteratorFilterUnreachable) {
1234 InitializeVM();
1235 v8::HandleScope scope;
1236 CompileRun("a = {}; b = {};");
1237 v8::Handle<Object> a(Top::context()->global()->GetProperty(
1238 *Factory::LookupAsciiSymbol("a"))->ToObjectChecked());
1239 v8::Handle<Object> b(Top::context()->global()->GetProperty(
1240 *Factory::LookupAsciiSymbol("b"))->ToObjectChecked());
1241 CHECK_NE(*a, *b);
1242 {
1243 HeapIteratorTestHelper helper(*a, *b);
1244 helper.IterateHeap(HeapIterator::kFilterUnreachable);
1245 CHECK(helper.a_found());
1246 CHECK(helper.b_found());
1247 }
1248 CHECK(Top::context()->global()->DeleteProperty(
1249 *Factory::LookupAsciiSymbol("a"), JSObject::FORCE_DELETION));
1250 // We ensure that GC will not happen, so our raw pointer stays valid.
1251 AssertNoAllocation no_alloc;
1252 Object* a_saved = *a;
1253 a.Clear();
1254 // Verify that "a" object still resides in the heap...
1255 {
1256 HeapIteratorTestHelper helper(a_saved, *b);
1257 helper.IterateHeap(HeapIterator::kNoFiltering);
1258 CHECK(helper.a_found());
1259 CHECK(helper.b_found());
1260 }
1261 // ...but is now unreachable.
1262 {
1263 HeapIteratorTestHelper helper(a_saved, *b);
1264 helper.IterateHeap(HeapIterator::kFilterUnreachable);
1265 CHECK(!helper.a_found());
1266 CHECK(helper.b_found());
1267 }
1268 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698