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

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 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 DeleteArray(non_ascii); 764 DeleteArray(non_ascii);
765 DeleteArray(ascii); 765 DeleteArray(ascii);
766 } 766 }
767 } 767 }
768 768
769 769
770 static int ObjectsFoundInHeap(Handle<Object> objs[], int size) { 770 static int ObjectsFoundInHeap(Handle<Object> objs[], int size) {
771 // Count the number of objects found in the heap. 771 // Count the number of objects found in the heap.
772 int found_count = 0; 772 int found_count = 0;
773 HeapIterator iterator; 773 HeapIterator iterator;
774 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 774 for (HeapObject* obj = iterator.Next(); obj != NULL; obj = iterator.Next()) {
775 for (int i = 0; i < size; i++) { 775 for (int i = 0; i < size; i++) {
776 if (*objs[i] == obj) { 776 if (*objs[i] == obj) {
777 found_count++; 777 found_count++;
778 } 778 }
779 } 779 }
780 } 780 }
781 return found_count; 781 return found_count;
782 } 782 }
783 783
784 784
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 static int LenFromSize(int size) { 837 static int LenFromSize(int size) {
838 return (size - FixedArray::kHeaderSize) / kPointerSize; 838 return (size - FixedArray::kHeaderSize) / kPointerSize;
839 } 839 }
840 840
841 841
842 TEST(Regression39128) { 842 TEST(Regression39128) {
843 // Test case for crbug.com/39128. 843 // Test case for crbug.com/39128.
844 InitializeVM(); 844 InitializeVM();
845 845
846 // Increase the chance of 'bump-the-pointer' allocation in old space. 846 // Increase the chance of 'bump-the-pointer' allocation in old space.
847 bool force_compaction = true; 847 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
848 Heap::CollectAllGarbage(force_compaction);
849 848
850 v8::HandleScope scope; 849 v8::HandleScope scope;
851 850
852 // The plan: create JSObject which references objects in new space. 851 // The plan: create JSObject which references objects in new space.
853 // Then clone this object (forcing it to go into old space) and check 852 // Then clone this object (forcing it to go into old space) and check
854 // that region dirty marks are updated correctly. 853 // that region dirty marks are updated correctly.
855 854
856 // Step 1: prepare a map for the object. We add 1 inobject property to it. 855 // Step 1: prepare a map for the object. We add 1 inobject property to it.
857 Handle<JSFunction> object_ctor(Top::global_context()->object_function()); 856 Handle<JSFunction> object_ctor(Top::global_context()->object_function());
858 CHECK(object_ctor->has_initial_map()); 857 CHECK(object_ctor->has_initial_map());
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 CompileRun(source); 932 CompileRun(source);
934 } 933 }
935 934
936 // Check function is compiled. 935 // Check function is compiled.
937 Object* func_value = 936 Object* func_value =
938 Top::context()->global()->GetProperty(*foo_name)->ToObjectChecked(); 937 Top::context()->global()->GetProperty(*foo_name)->ToObjectChecked();
939 CHECK(func_value->IsJSFunction()); 938 CHECK(func_value->IsJSFunction());
940 Handle<JSFunction> function(JSFunction::cast(func_value)); 939 Handle<JSFunction> function(JSFunction::cast(func_value));
941 CHECK(function->shared()->is_compiled()); 940 CHECK(function->shared()->is_compiled());
942 941
943 Heap::CollectAllGarbage(true); 942 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
944 Heap::CollectAllGarbage(true); 943 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
945 944
946 CHECK(function->shared()->is_compiled()); 945 CHECK(function->shared()->is_compiled());
947 946
948 Heap::CollectAllGarbage(true); 947 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
949 Heap::CollectAllGarbage(true); 948 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
950 Heap::CollectAllGarbage(true); 949 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
951 Heap::CollectAllGarbage(true); 950 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
952 Heap::CollectAllGarbage(true); 951 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
953 Heap::CollectAllGarbage(true); 952 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
954 953
955 // foo should no longer be in the compilation cache 954 // foo should no longer be in the compilation cache
956 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); 955 CHECK(!function->shared()->is_compiled() || function->IsOptimized());
957 CHECK(!function->is_compiled() || function->IsOptimized()); 956 CHECK(!function->is_compiled() || function->IsOptimized());
958 // Call foo to get it recompiled. 957 // Call foo to get it recompiled.
959 CompileRun("foo()"); 958 CompileRun("foo()");
960 CHECK(function->shared()->is_compiled()); 959 CHECK(function->shared()->is_compiled());
961 CHECK(function->is_compiled()); 960 CHECK(function->is_compiled());
962 } 961 }
963 962
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 // Remove function f1, and 1029 // Remove function f1, and
1031 CompileRun("f1=null"); 1030 CompileRun("f1=null");
1032 1031
1033 // Scavenge treats these references as strong. 1032 // Scavenge treats these references as strong.
1034 for (int j = 0; j < 10; j++) { 1033 for (int j = 0; j < 10; j++) {
1035 Heap::PerformScavenge(); 1034 Heap::PerformScavenge();
1036 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); 1035 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i]));
1037 } 1036 }
1038 1037
1039 // Mark compact handles the weak references. 1038 // Mark compact handles the weak references.
1040 Heap::CollectAllGarbage(true); 1039 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1041 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); 1040 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
1042 1041
1043 // Get rid of f3 and f5 in the same way. 1042 // Get rid of f3 and f5 in the same way.
1044 CompileRun("f3=null"); 1043 CompileRun("f3=null");
1045 for (int j = 0; j < 10; j++) { 1044 for (int j = 0; j < 10; j++) {
1046 Heap::PerformScavenge(); 1045 Heap::PerformScavenge();
1047 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); 1046 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
1048 } 1047 }
1049 Heap::CollectAllGarbage(true); 1048 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1050 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); 1049 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
1051 CompileRun("f5=null"); 1050 CompileRun("f5=null");
1052 for (int j = 0; j < 10; j++) { 1051 for (int j = 0; j < 10; j++) {
1053 Heap::PerformScavenge(); 1052 Heap::PerformScavenge();
1054 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); 1053 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
1055 } 1054 }
1056 Heap::CollectAllGarbage(true); 1055 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1057 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); 1056 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i]));
1058 1057
1059 ctx[i]->Exit(); 1058 ctx[i]->Exit();
1060 } 1059 }
1061 1060
1062 // Force compilation cache cleanup. 1061 // Force compilation cache cleanup.
1063 Heap::CollectAllGarbage(true); 1062 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1064 1063
1065 // Dispose the global contexts one by one. 1064 // Dispose the global contexts one by one.
1066 for (int i = 0; i < kNumTestContexts; i++) { 1065 for (int i = 0; i < kNumTestContexts; i++) {
1067 ctx[i].Dispose(); 1066 ctx[i].Dispose();
1068 ctx[i].Clear(); 1067 ctx[i].Clear();
1069 1068
1070 // Scavenge treats these references as strong. 1069 // Scavenge treats these references as strong.
1071 for (int j = 0; j < 10; j++) { 1070 for (int j = 0; j < 10; j++) {
1072 Heap::PerformScavenge(); 1071 Heap::PerformScavenge();
1073 CHECK_EQ(kNumTestContexts - i, CountGlobalContexts()); 1072 CHECK_EQ(kNumTestContexts - i, CountGlobalContexts());
1074 } 1073 }
1075 1074
1076 // Mark compact handles the weak references. 1075 // Mark compact handles the weak references.
1077 Heap::CollectAllGarbage(true); 1076 Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1078 CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts()); 1077 CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts());
1079 } 1078 }
1080 1079
1081 CHECK_EQ(0, CountGlobalContexts()); 1080 CHECK_EQ(0, CountGlobalContexts());
1082 } 1081 }
1083 1082
1084 1083
1085 // Count the number of global contexts in the weak list of global contexts 1084 // Count the number of global contexts in the weak list of global contexts
1086 // causing a GC after the specified number of elements. 1085 // causing a GC after the specified number of elements.
1087 static int CountGlobalContextsWithGC(int n) { 1086 static int CountGlobalContextsWithGC(int n) {
1088 int count = 0; 1087 int count = 0;
1089 Handle<Object> object(Heap::global_contexts_list()); 1088 Handle<Object> object(Heap::global_contexts_list());
1090 while (!object->IsUndefined()) { 1089 while (!object->IsUndefined()) {
1091 count++; 1090 count++;
1092 if (count == n) Heap::CollectAllGarbage(true); 1091 if (count == n) Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1093 object = 1092 object =
1094 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK)); 1093 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK));
1095 } 1094 }
1096 return count; 1095 return count;
1097 } 1096 }
1098 1097
1099 1098
1100 // Count the number of user functions in the weak list of optimized 1099 // Count the number of user functions in the weak list of optimized
1101 // functions attached to a global context causing a GC after the 1100 // functions attached to a global context causing a GC after the
1102 // specified number of elements. 1101 // specified number of elements.
1103 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, 1102 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context,
1104 int n) { 1103 int n) {
1105 int count = 0; 1104 int count = 0;
1106 Handle<Context> icontext = v8::Utils::OpenHandle(*context); 1105 Handle<Context> icontext = v8::Utils::OpenHandle(*context);
1107 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST)); 1106 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST));
1108 while (object->IsJSFunction() && 1107 while (object->IsJSFunction() &&
1109 !Handle<JSFunction>::cast(object)->IsBuiltin()) { 1108 !Handle<JSFunction>::cast(object)->IsBuiltin()) {
1110 count++; 1109 count++;
1111 if (count == n) Heap::CollectAllGarbage(true); 1110 if (count == n) Heap::CollectAllGarbage(Heap::kForceCompactionMask);
1112 object = Handle<Object>( 1111 object = Handle<Object>(
1113 Object::cast(JSFunction::cast(*object)->next_function_link())); 1112 Object::cast(JSFunction::cast(*object)->next_function_link()));
1114 } 1113 }
1115 return count; 1114 return count;
1116 } 1115 }
1117 1116
1118 1117
1119 TEST(TestInternalWeakListsTraverseWithGC) { 1118 TEST(TestInternalWeakListsTraverseWithGC) {
1120 static const int kNumTestContexts = 10; 1119 static const int kNumTestContexts = 10;
1121 1120
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 CompileRun("f5()"); 1158 CompileRun("f5()");
1160 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0])); 1159 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0]));
1161 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4)); 1160 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4));
1162 1161
1163 ctx[0]->Exit(); 1162 ctx[0]->Exit();
1164 } 1163 }
1165 1164
1166 1165
1167 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) { 1166 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
1168 InitializeVM(); 1167 InitializeVM();
1168 Heap::EnsureHeapIsIterable();
1169 intptr_t size_of_objects_1 = Heap::SizeOfObjects(); 1169 intptr_t size_of_objects_1 = Heap::SizeOfObjects();
1170 HeapIterator iterator(HeapIterator::kFilterFreeListNodes); 1170 HeapIterator iterator;
1171 intptr_t size_of_objects_2 = 0; 1171 intptr_t size_of_objects_2 = 0;
1172 for (HeapObject* obj = iterator.next(); 1172 for (HeapObject* obj = iterator.Next();
1173 obj != NULL; 1173 obj != NULL;
1174 obj = iterator.next()) { 1174 obj = iterator.Next()) {
1175 size_of_objects_2 += obj->Size(); 1175 size_of_objects_2 += obj->Size();
1176 } 1176 }
1177 // Delta must be within 1% of the larger result. 1177 // Delta must be within 5% of the larger result.
1178 // TODO(gc): Tighten this up by distinguishing between byte
1179 // arrays that are real and those that merely mark free space
1180 // on the heap.
1178 if (size_of_objects_1 > size_of_objects_2) { 1181 if (size_of_objects_1 > size_of_objects_2) {
1179 intptr_t delta = size_of_objects_1 - size_of_objects_2; 1182 intptr_t delta = size_of_objects_1 - size_of_objects_2;
1180 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, " 1183 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, "
1181 "Iterator: %" V8_PTR_PREFIX "d, " 1184 "Iterator: %" V8_PTR_PREFIX "d, "
1182 "delta: %" V8_PTR_PREFIX "d\n", 1185 "delta: %" V8_PTR_PREFIX "d\n",
1183 size_of_objects_1, size_of_objects_2, delta); 1186 size_of_objects_1, size_of_objects_2, delta);
1184 CHECK_GT(size_of_objects_1 / 100, delta); 1187 CHECK_GT(size_of_objects_1 / 20, delta);
1185 } else { 1188 } else {
1186 intptr_t delta = size_of_objects_2 - size_of_objects_1; 1189 intptr_t delta = size_of_objects_2 - size_of_objects_1;
1187 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, " 1190 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, "
1188 "Iterator: %" V8_PTR_PREFIX "d, " 1191 "Iterator: %" V8_PTR_PREFIX "d, "
1189 "delta: %" V8_PTR_PREFIX "d\n", 1192 "delta: %" V8_PTR_PREFIX "d\n",
1190 size_of_objects_1, size_of_objects_2, delta); 1193 size_of_objects_1, size_of_objects_2, delta);
1191 CHECK_GT(size_of_objects_2 / 100, delta); 1194 CHECK_GT(size_of_objects_2 / 20, delta);
1192 } 1195 }
1193 } 1196 }
1194 1197
1195 1198
1196 class HeapIteratorTestHelper { 1199 class HeapIteratorTestHelper {
1197 public: 1200 public:
1198 HeapIteratorTestHelper(Object* a, Object* b) 1201 HeapIteratorTestHelper(Object* a, Object* b)
1199 : a_(a), b_(b), a_found_(false), b_found_(false) {} 1202 : a_(a), b_(b), a_found_(false), b_found_(false) {}
1200 bool a_found() { return a_found_; } 1203 bool a_found() { return a_found_; }
1201 bool b_found() { return b_found_; } 1204 bool b_found() { return b_found_; }
1202 void IterateHeap(HeapIterator::HeapObjectsFiltering mode) { 1205 void IterateHeap() {
1203 HeapIterator iterator(mode); 1206 HeapIterator iterator;
1204 for (HeapObject* obj = iterator.next(); 1207 for (HeapObject* obj = iterator.Next();
1205 obj != NULL; 1208 obj != NULL;
1206 obj = iterator.next()) { 1209 obj = iterator.Next()) {
1207 if (obj == a_) 1210 if (obj == a_)
1208 a_found_ = true; 1211 a_found_ = true;
1209 else if (obj == b_) 1212 else if (obj == b_)
1210 b_found_ = true; 1213 b_found_ = true;
1211 } 1214 }
1212 } 1215 }
1213 private: 1216 private:
1214 Object* a_; 1217 Object* a_;
1215 Object* b_; 1218 Object* b_;
1216 bool a_found_; 1219 bool a_found_;
1217 bool b_found_; 1220 bool b_found_;
1218 }; 1221 };
1219 1222
1220 TEST(HeapIteratorFilterUnreachable) {
1221 InitializeVM();
1222 v8::HandleScope scope;
1223 CompileRun("a = {}; b = {};");
1224 v8::Handle<Object> a(Top::context()->global()->GetProperty(
1225 *Factory::LookupAsciiSymbol("a"))->ToObjectChecked());
1226 v8::Handle<Object> b(Top::context()->global()->GetProperty(
1227 *Factory::LookupAsciiSymbol("b"))->ToObjectChecked());
1228 CHECK_NE(*a, *b);
1229 {
1230 HeapIteratorTestHelper helper(*a, *b);
1231 helper.IterateHeap(HeapIterator::kFilterUnreachable);
1232 CHECK(helper.a_found());
1233 CHECK(helper.b_found());
1234 }
1235 CHECK(Top::context()->global()->DeleteProperty(
1236 *Factory::LookupAsciiSymbol("a"), JSObject::FORCE_DELETION));
1237 // We ensure that GC will not happen, so our raw pointer stays valid.
1238 AssertNoAllocation no_alloc;
1239 Object* a_saved = *a;
1240 a.Clear();
1241 // Verify that "a" object still resides in the heap...
1242 {
1243 HeapIteratorTestHelper helper(a_saved, *b);
1244 helper.IterateHeap(HeapIterator::kNoFiltering);
1245 CHECK(helper.a_found());
1246 CHECK(helper.b_found());
1247 }
1248 // ...but is now unreachable.
1249 {
1250 HeapIteratorTestHelper helper(a_saved, *b);
1251 helper.IterateHeap(HeapIterator::kFilterUnreachable);
1252 CHECK(!helper.a_found());
1253 CHECK(helper.b_found());
1254 }
1255 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698