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

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

Issue 1099783003: Reland Force full GCwhenever CollectAllGarbage is meant to trigger a full GC. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 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
« no previous file with comments | « test/cctest/test-feedback-vector.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 CHECK(!heap->InNewSpace(*h1) && !heap->InNewSpace(*h2)); 445 CHECK(!heap->InNewSpace(*h1) && !heap->InNewSpace(*h2));
446 446
447 std::pair<Handle<Object>*, int> handle_and_id(&h2, 1234); 447 std::pair<Handle<Object>*, int> handle_and_id(&h2, 1234);
448 GlobalHandles::MakeWeak(h2.location(), 448 GlobalHandles::MakeWeak(h2.location(),
449 reinterpret_cast<void*>(&handle_and_id), 449 reinterpret_cast<void*>(&handle_and_id),
450 &TestWeakGlobalHandleCallback); 450 &TestWeakGlobalHandleCallback);
451 CHECK(!GlobalHandles::IsNearDeath(h1.location())); 451 CHECK(!GlobalHandles::IsNearDeath(h1.location()));
452 CHECK(!GlobalHandles::IsNearDeath(h2.location())); 452 CHECK(!GlobalHandles::IsNearDeath(h2.location()));
453 453
454 // Incremental marking potentially marked handles before they turned weak. 454 // Incremental marking potentially marked handles before they turned weak.
455 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 455 heap->CollectAllGarbage();
456 456
457 CHECK((*h1)->IsString()); 457 CHECK((*h1)->IsString());
458 458
459 CHECK(WeakPointerCleared); 459 CHECK(WeakPointerCleared);
460 CHECK(!GlobalHandles::IsNearDeath(h1.location())); 460 CHECK(!GlobalHandles::IsNearDeath(h1.location()));
461 461
462 GlobalHandles::Destroy(h1.location()); 462 GlobalHandles::Destroy(h1.location());
463 } 463 }
464 464
465 465
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 } 940 }
941 941
942 942
943 TEST(Regression39128) { 943 TEST(Regression39128) {
944 // Test case for crbug.com/39128. 944 // Test case for crbug.com/39128.
945 CcTest::InitializeVM(); 945 CcTest::InitializeVM();
946 Isolate* isolate = CcTest::i_isolate(); 946 Isolate* isolate = CcTest::i_isolate();
947 TestHeap* heap = CcTest::test_heap(); 947 TestHeap* heap = CcTest::test_heap();
948 948
949 // Increase the chance of 'bump-the-pointer' allocation in old space. 949 // Increase the chance of 'bump-the-pointer' allocation in old space.
950 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 950 heap->CollectAllGarbage();
951 951
952 v8::HandleScope scope(CcTest::isolate()); 952 v8::HandleScope scope(CcTest::isolate());
953 953
954 // The plan: create JSObject which references objects in new space. 954 // The plan: create JSObject which references objects in new space.
955 // Then clone this object (forcing it to go into old space) and check 955 // Then clone this object (forcing it to go into old space) and check
956 // that region dirty marks are updated correctly. 956 // that region dirty marks are updated correctly.
957 957
958 // Step 1: prepare a map for the object. We add 1 inobject property to it. 958 // Step 1: prepare a map for the object. We add 1 inobject property to it.
959 // Create a map with single inobject property. 959 // Create a map with single inobject property.
960 Handle<Map> my_map = Map::Create(CcTest::i_isolate(), 1); 960 Handle<Map> my_map = Map::Create(CcTest::i_isolate(), 1);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 } 1041 }
1042 1042
1043 // Check function is compiled. 1043 // Check function is compiled.
1044 Handle<Object> func_value = Object::GetProperty(i_isolate->global_object(), 1044 Handle<Object> func_value = Object::GetProperty(i_isolate->global_object(),
1045 foo_name).ToHandleChecked(); 1045 foo_name).ToHandleChecked();
1046 CHECK(func_value->IsJSFunction()); 1046 CHECK(func_value->IsJSFunction());
1047 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value); 1047 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value);
1048 CHECK(function->shared()->is_compiled()); 1048 CHECK(function->shared()->is_compiled());
1049 1049
1050 // The code will survive at least two GCs. 1050 // The code will survive at least two GCs.
1051 i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1051 i_isolate->heap()->CollectAllGarbage();
1052 i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1052 i_isolate->heap()->CollectAllGarbage();
1053 CHECK(function->shared()->is_compiled()); 1053 CHECK(function->shared()->is_compiled());
1054 1054
1055 // Simulate several GCs that use full marking. 1055 // Simulate several GCs that use full marking.
1056 const int kAgingThreshold = 6; 1056 const int kAgingThreshold = 6;
1057 for (int i = 0; i < kAgingThreshold; i++) { 1057 for (int i = 0; i < kAgingThreshold; i++) {
1058 i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1058 i_isolate->heap()->CollectAllGarbage();
1059 } 1059 }
1060 1060
1061 // foo should no longer be in the compilation cache 1061 // foo should no longer be in the compilation cache
1062 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); 1062 CHECK(!function->shared()->is_compiled() || function->IsOptimized());
1063 CHECK(!function->is_compiled() || function->IsOptimized()); 1063 CHECK(!function->is_compiled() || function->IsOptimized());
1064 // Call foo to get it recompiled. 1064 // Call foo to get it recompiled.
1065 CompileRun("foo()"); 1065 CompileRun("foo()");
1066 CHECK(function->shared()->is_compiled()); 1066 CHECK(function->shared()->is_compiled());
1067 CHECK(function->is_compiled()); 1067 CHECK(function->is_compiled());
1068 } 1068 }
(...skipping 25 matching lines...) Expand all
1094 } 1094 }
1095 1095
1096 // Check function is compiled. 1096 // Check function is compiled.
1097 Handle<Object> func_value = 1097 Handle<Object> func_value =
1098 Object::GetProperty(isolate->global_object(), foo_name).ToHandleChecked(); 1098 Object::GetProperty(isolate->global_object(), foo_name).ToHandleChecked();
1099 CHECK(func_value->IsJSFunction()); 1099 CHECK(func_value->IsJSFunction());
1100 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value); 1100 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value);
1101 CHECK(function->shared()->is_compiled()); 1101 CHECK(function->shared()->is_compiled());
1102 1102
1103 // The code has been run so will survive at least one GC. 1103 // The code has been run so will survive at least one GC.
1104 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1104 CcTest::heap()->CollectAllGarbage();
1105 CHECK(function->shared()->is_compiled()); 1105 CHECK(function->shared()->is_compiled());
1106 1106
1107 // The code was only run once, so it should be pre-aged and collected on the 1107 // The code was only run once, so it should be pre-aged and collected on the
1108 // next GC. 1108 // next GC.
1109 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1109 CcTest::heap()->CollectAllGarbage();
1110 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); 1110 CHECK(!function->shared()->is_compiled() || function->IsOptimized());
1111 1111
1112 // Execute the function again twice, and ensure it is reset to the young age. 1112 // Execute the function again twice, and ensure it is reset to the young age.
1113 { v8::HandleScope scope(CcTest::isolate()); 1113 { v8::HandleScope scope(CcTest::isolate());
1114 CompileRun("foo();" 1114 CompileRun("foo();"
1115 "foo();"); 1115 "foo();");
1116 } 1116 }
1117 1117
1118 // The code will survive at least two GC now that it is young again. 1118 // The code will survive at least two GC now that it is young again.
1119 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1119 CcTest::heap()->CollectAllGarbage();
1120 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1120 CcTest::heap()->CollectAllGarbage();
1121 CHECK(function->shared()->is_compiled()); 1121 CHECK(function->shared()->is_compiled());
1122 1122
1123 // Simulate several GCs that use full marking. 1123 // Simulate several GCs that use full marking.
1124 const int kAgingThreshold = 6; 1124 const int kAgingThreshold = 6;
1125 for (int i = 0; i < kAgingThreshold; i++) { 1125 for (int i = 0; i < kAgingThreshold; i++) {
1126 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1126 CcTest::heap()->CollectAllGarbage();
1127 } 1127 }
1128 1128
1129 // foo should no longer be in the compilation cache 1129 // foo should no longer be in the compilation cache
1130 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); 1130 CHECK(!function->shared()->is_compiled() || function->IsOptimized());
1131 CHECK(!function->is_compiled() || function->IsOptimized()); 1131 CHECK(!function->is_compiled() || function->IsOptimized());
1132 // Call foo to get it recompiled. 1132 // Call foo to get it recompiled.
1133 CompileRun("foo()"); 1133 CompileRun("foo()");
1134 CHECK(function->shared()->is_compiled()); 1134 CHECK(function->shared()->is_compiled());
1135 CHECK(function->is_compiled()); 1135 CHECK(function->is_compiled());
1136 } 1136 }
(...skipping 22 matching lines...) Expand all
1159 } 1159 }
1160 1160
1161 // Check function is compiled. 1161 // Check function is compiled.
1162 Handle<Object> func_value = 1162 Handle<Object> func_value =
1163 Object::GetProperty(isolate->global_object(), foo_name).ToHandleChecked(); 1163 Object::GetProperty(isolate->global_object(), foo_name).ToHandleChecked();
1164 CHECK(func_value->IsJSFunction()); 1164 CHECK(func_value->IsJSFunction());
1165 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value); 1165 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value);
1166 CHECK(function->shared()->is_compiled()); 1166 CHECK(function->shared()->is_compiled());
1167 1167
1168 // The code will survive at least two GCs. 1168 // The code will survive at least two GCs.
1169 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1169 CcTest::heap()->CollectAllGarbage();
1170 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1170 CcTest::heap()->CollectAllGarbage();
1171 CHECK(function->shared()->is_compiled()); 1171 CHECK(function->shared()->is_compiled());
1172 1172
1173 // Simulate several GCs that use incremental marking. 1173 // Simulate several GCs that use incremental marking.
1174 const int kAgingThreshold = 6; 1174 const int kAgingThreshold = 6;
1175 for (int i = 0; i < kAgingThreshold; i++) { 1175 for (int i = 0; i < kAgingThreshold; i++) {
1176 SimulateIncrementalMarking(CcTest::heap()); 1176 SimulateIncrementalMarking(CcTest::heap());
1177 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1177 CcTest::heap()->CollectAllGarbage();
1178 } 1178 }
1179 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); 1179 CHECK(!function->shared()->is_compiled() || function->IsOptimized());
1180 CHECK(!function->is_compiled() || function->IsOptimized()); 1180 CHECK(!function->is_compiled() || function->IsOptimized());
1181 1181
1182 // This compile will compile the function again. 1182 // This compile will compile the function again.
1183 { v8::HandleScope scope(CcTest::isolate()); 1183 { v8::HandleScope scope(CcTest::isolate());
1184 CompileRun("foo();"); 1184 CompileRun("foo();");
1185 } 1185 }
1186 1186
1187 // Simulate several GCs that use incremental marking but make sure 1187 // Simulate several GCs that use incremental marking but make sure
1188 // the loop breaks once the function is enqueued as a candidate. 1188 // the loop breaks once the function is enqueued as a candidate.
1189 for (int i = 0; i < kAgingThreshold; i++) { 1189 for (int i = 0; i < kAgingThreshold; i++) {
1190 SimulateIncrementalMarking(CcTest::heap()); 1190 SimulateIncrementalMarking(CcTest::heap());
1191 if (!function->next_function_link()->IsUndefined()) break; 1191 if (!function->next_function_link()->IsUndefined()) break;
1192 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1192 CcTest::heap()->CollectAllGarbage();
1193 } 1193 }
1194 1194
1195 // Force optimization while incremental marking is active and while 1195 // Force optimization while incremental marking is active and while
1196 // the function is enqueued as a candidate. 1196 // the function is enqueued as a candidate.
1197 { v8::HandleScope scope(CcTest::isolate()); 1197 { v8::HandleScope scope(CcTest::isolate());
1198 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();"); 1198 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();");
1199 } 1199 }
1200 1200
1201 // Simulate one final GC to make sure the candidate queue is sane. 1201 // Simulate one final GC to make sure the candidate queue is sane.
1202 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1202 CcTest::heap()->CollectAllGarbage();
1203 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); 1203 CHECK(function->shared()->is_compiled() || !function->IsOptimized());
1204 CHECK(function->is_compiled() || !function->IsOptimized()); 1204 CHECK(function->is_compiled() || !function->IsOptimized());
1205 } 1205 }
1206 1206
1207 1207
1208 TEST(TestCodeFlushingIncrementalScavenge) { 1208 TEST(TestCodeFlushingIncrementalScavenge) {
1209 // If we do not flush code this test is invalid. 1209 // If we do not flush code this test is invalid.
1210 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; 1210 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return;
1211 i::FLAG_allow_natives_syntax = true; 1211 i::FLAG_allow_natives_syntax = true;
1212 i::FLAG_optimize_for_size = false; 1212 i::FLAG_optimize_for_size = false;
1213 CcTest::InitializeVM(); 1213 CcTest::InitializeVM();
1214 Isolate* isolate = CcTest::i_isolate(); 1214 Isolate* isolate = CcTest::i_isolate();
1215 Factory* factory = isolate->factory(); 1215 Factory* factory = isolate->factory();
1216 v8::HandleScope scope(CcTest::isolate()); 1216 v8::HandleScope scope(CcTest::isolate());
1217 const char* source = "var foo = function() {" 1217 const char* source = "var foo = function() {"
1218 " var x = 42;" 1218 " var x = 42;"
1219 " var y = 42;" 1219 " var y = 42;"
1220 " var z = x + y;" 1220 " var z = x + y;"
1221 "};" 1221 "};"
1222 "foo();" 1222 "foo();"
1223 "var bar = function() {" 1223 "var bar = function() {"
1224 " var x = 23;" 1224 " var x = 23;"
1225 "};" 1225 "};"
1226 "bar();"; 1226 "bar();";
1227 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); 1227 Handle<String> foo_name = factory->InternalizeUtf8String("foo");
1228 Handle<String> bar_name = factory->InternalizeUtf8String("bar"); 1228 Handle<String> bar_name = factory->InternalizeUtf8String("bar");
1229 1229
1230 // Perfrom one initial GC to enable code flushing. 1230 // Perfrom one initial GC to enable code flushing.
1231 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1231 CcTest::heap()->CollectAllGarbage();
1232 1232
1233 // This compile will add the code to the compilation cache. 1233 // This compile will add the code to the compilation cache.
1234 { v8::HandleScope scope(CcTest::isolate()); 1234 { v8::HandleScope scope(CcTest::isolate());
1235 CompileRun(source); 1235 CompileRun(source);
1236 } 1236 }
1237 1237
1238 // Check functions are compiled. 1238 // Check functions are compiled.
1239 Handle<Object> func_value = 1239 Handle<Object> func_value =
1240 Object::GetProperty(isolate->global_object(), foo_name).ToHandleChecked(); 1240 Object::GetProperty(isolate->global_object(), foo_name).ToHandleChecked();
1241 CHECK(func_value->IsJSFunction()); 1241 CHECK(func_value->IsJSFunction());
(...skipping 19 matching lines...) Expand all
1261 } 1261 }
1262 1262
1263 // Simulate incremental marking so that the functions are enqueued as 1263 // Simulate incremental marking so that the functions are enqueued as
1264 // code flushing candidates. Then kill one of the functions. Finally 1264 // code flushing candidates. Then kill one of the functions. Finally
1265 // perform a scavenge while incremental marking is still running. 1265 // perform a scavenge while incremental marking is still running.
1266 SimulateIncrementalMarking(CcTest::heap()); 1266 SimulateIncrementalMarking(CcTest::heap());
1267 *function2.location() = NULL; 1267 *function2.location() = NULL;
1268 CcTest::heap()->CollectGarbage(NEW_SPACE, "test scavenge while marking"); 1268 CcTest::heap()->CollectGarbage(NEW_SPACE, "test scavenge while marking");
1269 1269
1270 // Simulate one final GC to make sure the candidate queue is sane. 1270 // Simulate one final GC to make sure the candidate queue is sane.
1271 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1271 CcTest::heap()->CollectAllGarbage();
1272 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); 1272 CHECK(!function->shared()->is_compiled() || function->IsOptimized());
1273 CHECK(!function->is_compiled() || function->IsOptimized()); 1273 CHECK(!function->is_compiled() || function->IsOptimized());
1274 } 1274 }
1275 1275
1276 1276
1277 TEST(TestCodeFlushingIncrementalAbort) { 1277 TEST(TestCodeFlushingIncrementalAbort) {
1278 // If we do not flush code this test is invalid. 1278 // If we do not flush code this test is invalid.
1279 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return; 1279 if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return;
1280 i::FLAG_allow_natives_syntax = true; 1280 i::FLAG_allow_natives_syntax = true;
1281 i::FLAG_optimize_for_size = false; 1281 i::FLAG_optimize_for_size = false;
(...skipping 16 matching lines...) Expand all
1298 } 1298 }
1299 1299
1300 // Check function is compiled. 1300 // Check function is compiled.
1301 Handle<Object> func_value = 1301 Handle<Object> func_value =
1302 Object::GetProperty(isolate->global_object(), foo_name).ToHandleChecked(); 1302 Object::GetProperty(isolate->global_object(), foo_name).ToHandleChecked();
1303 CHECK(func_value->IsJSFunction()); 1303 CHECK(func_value->IsJSFunction());
1304 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value); 1304 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value);
1305 CHECK(function->shared()->is_compiled()); 1305 CHECK(function->shared()->is_compiled());
1306 1306
1307 // The code will survive at least two GCs. 1307 // The code will survive at least two GCs.
1308 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1308 heap->CollectAllGarbage();
1309 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 1309 heap->CollectAllGarbage();
1310 CHECK(function->shared()->is_compiled()); 1310 CHECK(function->shared()->is_compiled());
1311 1311
1312 // Bump the code age so that flushing is triggered. 1312 // Bump the code age so that flushing is triggered.
1313 const int kAgingThreshold = 6; 1313 const int kAgingThreshold = 6;
1314 for (int i = 0; i < kAgingThreshold; i++) { 1314 for (int i = 0; i < kAgingThreshold; i++) {
1315 function->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); 1315 function->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
1316 } 1316 }
1317 1317
1318 // Simulate incremental marking so that the function is enqueued as 1318 // Simulate incremental marking so that the function is enqueued as
1319 // code flushing candidate. 1319 // code flushing candidate.
1320 SimulateIncrementalMarking(heap); 1320 SimulateIncrementalMarking(heap);
1321 1321
1322 // Enable the debugger and add a breakpoint while incremental marking 1322 // Enable the debugger and add a breakpoint while incremental marking
1323 // is running so that incremental marking aborts and code flushing is 1323 // is running so that incremental marking aborts and code flushing is
1324 // disabled. 1324 // disabled.
1325 int position = 0; 1325 int position = 0;
1326 Handle<Object> breakpoint_object(Smi::FromInt(0), isolate); 1326 Handle<Object> breakpoint_object(Smi::FromInt(0), isolate);
1327 isolate->debug()->SetBreakPoint(function, breakpoint_object, &position); 1327 isolate->debug()->SetBreakPoint(function, breakpoint_object, &position);
1328 isolate->debug()->ClearAllBreakPoints(); 1328 isolate->debug()->ClearAllBreakPoints();
1329 1329
1330 // Force optimization now that code flushing is disabled. 1330 // Force optimization now that code flushing is disabled.
1331 { v8::HandleScope scope(CcTest::isolate()); 1331 { v8::HandleScope scope(CcTest::isolate());
1332 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();"); 1332 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();");
1333 } 1333 }
1334 1334
1335 // Simulate one final GC to make sure the candidate queue is sane. 1335 // Simulate one final GC to make sure the candidate queue is sane.
1336 heap->CollectAllGarbage(Heap::kNoGCFlags); 1336 heap->CollectAllGarbage();
1337 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); 1337 CHECK(function->shared()->is_compiled() || !function->IsOptimized());
1338 CHECK(function->is_compiled() || !function->IsOptimized()); 1338 CHECK(function->is_compiled() || !function->IsOptimized());
1339 } 1339 }
1340 1340
1341 1341
1342 TEST(CompilationCacheCachingBehavior) { 1342 TEST(CompilationCacheCachingBehavior) {
1343 // If we do not flush code, or have the compilation cache turned off, this 1343 // If we do not flush code, or have the compilation cache turned off, this
1344 // test is invalid. 1344 // test is invalid.
1345 if (!FLAG_flush_code || !FLAG_flush_code_incrementally || 1345 if (!FLAG_flush_code || !FLAG_flush_code_incrementally ||
1346 !FLAG_compilation_cache) { 1346 !FLAG_compilation_cache) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1381 v8::HandleScope scope(CcTest::isolate()); 1381 v8::HandleScope scope(CcTest::isolate());
1382 CompileRun(raw_source); 1382 CompileRun(raw_source);
1383 } 1383 }
1384 1384
1385 // On second compilation, the hash is replaced by a real cache entry mapping 1385 // On second compilation, the hash is replaced by a real cache entry mapping
1386 // the source to the shared function info containing the code. 1386 // the source to the shared function info containing the code.
1387 info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false, 1387 info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
1388 true, native_context, language_mode); 1388 true, native_context, language_mode);
1389 CHECK(!info.is_null()); 1389 CHECK(!info.is_null());
1390 1390
1391 heap->CollectAllGarbage(Heap::kNoGCFlags); 1391 heap->CollectAllGarbage();
1392 1392
1393 // On second compilation, the hash is replaced by a real cache entry mapping 1393 // On second compilation, the hash is replaced by a real cache entry mapping
1394 // the source to the shared function info containing the code. 1394 // the source to the shared function info containing the code.
1395 info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false, 1395 info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
1396 true, native_context, language_mode); 1396 true, native_context, language_mode);
1397 CHECK(!info.is_null()); 1397 CHECK(!info.is_null());
1398 1398
1399 while (!info.ToHandleChecked()->code()->IsOld()) { 1399 while (!info.ToHandleChecked()->code()->IsOld()) {
1400 info.ToHandleChecked()->code()->MakeOlder(NO_MARKING_PARITY); 1400 info.ToHandleChecked()->code()->MakeOlder(NO_MARKING_PARITY);
1401 } 1401 }
1402 1402
1403 heap->CollectAllGarbage(Heap::kNoGCFlags); 1403 heap->CollectAllGarbage();
1404 // Ensure code aging cleared the entry from the cache. 1404 // Ensure code aging cleared the entry from the cache.
1405 info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false, 1405 info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
1406 true, native_context, language_mode); 1406 true, native_context, language_mode);
1407 CHECK(info.is_null()); 1407 CHECK(info.is_null());
1408 1408
1409 { 1409 {
1410 v8::HandleScope scope(CcTest::isolate()); 1410 v8::HandleScope scope(CcTest::isolate());
1411 CompileRun(raw_source); 1411 CompileRun(raw_source);
1412 } 1412 }
1413 1413
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 1493
1494 CHECK_EQ(0, CountNativeContexts()); 1494 CHECK_EQ(0, CountNativeContexts());
1495 1495
1496 // Create a number of global contests which gets linked together. 1496 // Create a number of global contests which gets linked together.
1497 for (int i = 0; i < kNumTestContexts; i++) { 1497 for (int i = 0; i < kNumTestContexts; i++) {
1498 ctx[i] = v8::Context::New(CcTest::isolate()); 1498 ctx[i] = v8::Context::New(CcTest::isolate());
1499 1499
1500 // Collect garbage that might have been created by one of the 1500 // Collect garbage that might have been created by one of the
1501 // installed extensions. 1501 // installed extensions.
1502 isolate->compilation_cache()->Clear(); 1502 isolate->compilation_cache()->Clear();
1503 heap->CollectAllGarbage(Heap::kNoGCFlags); 1503 heap->CollectAllGarbage();
1504 1504
1505 CHECK_EQ(i + 1, CountNativeContexts()); 1505 CHECK_EQ(i + 1, CountNativeContexts());
1506 1506
1507 ctx[i]->Enter(); 1507 ctx[i]->Enter();
1508 1508
1509 // Create a handle scope so no function objects get stuck in the outer 1509 // Create a handle scope so no function objects get stuck in the outer
1510 // handle scope. 1510 // handle scope.
1511 HandleScope scope(isolate); 1511 HandleScope scope(isolate);
1512 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i])); 1512 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i]));
1513 OptimizeEmptyFunction("f1"); 1513 OptimizeEmptyFunction("f1");
(...skipping 11 matching lines...) Expand all
1525 CompileRun("f1=null"); 1525 CompileRun("f1=null");
1526 1526
1527 // Scavenge treats these references as strong. 1527 // Scavenge treats these references as strong.
1528 for (int j = 0; j < 10; j++) { 1528 for (int j = 0; j < 10; j++) {
1529 CcTest::heap()->CollectGarbage(NEW_SPACE); 1529 CcTest::heap()->CollectGarbage(NEW_SPACE);
1530 CHECK_EQ(5, CountOptimizedUserFunctions(ctx[i])); 1530 CHECK_EQ(5, CountOptimizedUserFunctions(ctx[i]));
1531 } 1531 }
1532 1532
1533 // Mark compact handles the weak references. 1533 // Mark compact handles the weak references.
1534 isolate->compilation_cache()->Clear(); 1534 isolate->compilation_cache()->Clear();
1535 heap->CollectAllGarbage(Heap::kNoGCFlags); 1535 heap->CollectAllGarbage();
1536 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i])); 1536 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i]));
1537 1537
1538 // Get rid of f3 and f5 in the same way. 1538 // Get rid of f3 and f5 in the same way.
1539 CompileRun("f3=null"); 1539 CompileRun("f3=null");
1540 for (int j = 0; j < 10; j++) { 1540 for (int j = 0; j < 10; j++) {
1541 CcTest::heap()->CollectGarbage(NEW_SPACE); 1541 CcTest::heap()->CollectGarbage(NEW_SPACE);
1542 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i])); 1542 CHECK_EQ(4, CountOptimizedUserFunctions(ctx[i]));
1543 } 1543 }
1544 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1544 CcTest::heap()->CollectAllGarbage();
1545 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i])); 1545 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i]));
1546 CompileRun("f5=null"); 1546 CompileRun("f5=null");
1547 for (int j = 0; j < 10; j++) { 1547 for (int j = 0; j < 10; j++) {
1548 CcTest::heap()->CollectGarbage(NEW_SPACE); 1548 CcTest::heap()->CollectGarbage(NEW_SPACE);
1549 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i])); 1549 CHECK_EQ(3, CountOptimizedUserFunctions(ctx[i]));
1550 } 1550 }
1551 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1551 CcTest::heap()->CollectAllGarbage();
1552 CHECK_EQ(2, CountOptimizedUserFunctions(ctx[i])); 1552 CHECK_EQ(2, CountOptimizedUserFunctions(ctx[i]));
1553 1553
1554 ctx[i]->Exit(); 1554 ctx[i]->Exit();
1555 } 1555 }
1556 1556
1557 // Force compilation cache cleanup. 1557 // Force compilation cache cleanup.
1558 CcTest::heap()->NotifyContextDisposed(true); 1558 CcTest::heap()->NotifyContextDisposed(true);
1559 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1559 CcTest::heap()->CollectAllGarbage();
1560 1560
1561 // Dispose the native contexts one by one. 1561 // Dispose the native contexts one by one.
1562 for (int i = 0; i < kNumTestContexts; i++) { 1562 for (int i = 0; i < kNumTestContexts; i++) {
1563 // TODO(dcarney): is there a better way to do this? 1563 // TODO(dcarney): is there a better way to do this?
1564 i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]); 1564 i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]);
1565 *unsafe = CcTest::heap()->undefined_value(); 1565 *unsafe = CcTest::heap()->undefined_value();
1566 ctx[i].Clear(); 1566 ctx[i].Clear();
1567 1567
1568 // Scavenge treats these references as strong. 1568 // Scavenge treats these references as strong.
1569 for (int j = 0; j < 10; j++) { 1569 for (int j = 0; j < 10; j++) {
1570 CcTest::heap()->CollectGarbage(i::NEW_SPACE); 1570 CcTest::heap()->CollectGarbage(i::NEW_SPACE);
1571 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); 1571 CHECK_EQ(kNumTestContexts - i, CountNativeContexts());
1572 } 1572 }
1573 1573
1574 // Mark compact handles the weak references. 1574 // Mark compact handles the weak references.
1575 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1575 CcTest::heap()->CollectAllGarbage();
1576 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); 1576 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts());
1577 } 1577 }
1578 1578
1579 CHECK_EQ(0, CountNativeContexts()); 1579 CHECK_EQ(0, CountNativeContexts());
1580 } 1580 }
1581 1581
1582 1582
1583 // Count the number of native contexts in the weak list of native contexts 1583 // Count the number of native contexts in the weak list of native contexts
1584 // causing a GC after the specified number of elements. 1584 // causing a GC after the specified number of elements.
1585 static int CountNativeContextsWithGC(Isolate* isolate, int n) { 1585 static int CountNativeContextsWithGC(Isolate* isolate, int n) {
1586 Heap* heap = isolate->heap(); 1586 Heap* heap = isolate->heap();
1587 int count = 0; 1587 int count = 0;
1588 Handle<Object> object(heap->native_contexts_list(), isolate); 1588 Handle<Object> object(heap->native_contexts_list(), isolate);
1589 while (!object->IsUndefined()) { 1589 while (!object->IsUndefined()) {
1590 count++; 1590 count++;
1591 if (count == n) heap->CollectAllGarbage(Heap::kNoGCFlags); 1591 if (count == n) heap->CollectAllGarbage();
1592 object = 1592 object =
1593 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK), 1593 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK),
1594 isolate); 1594 isolate);
1595 } 1595 }
1596 return count; 1596 return count;
1597 } 1597 }
1598 1598
1599 1599
1600 // Count the number of user functions in the weak list of optimized 1600 // Count the number of user functions in the weak list of optimized
1601 // functions attached to a native context causing a GC after the 1601 // functions attached to a native context causing a GC after the
1602 // specified number of elements. 1602 // specified number of elements.
1603 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, 1603 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context,
1604 int n) { 1604 int n) {
1605 int count = 0; 1605 int count = 0;
1606 Handle<Context> icontext = v8::Utils::OpenHandle(*context); 1606 Handle<Context> icontext = v8::Utils::OpenHandle(*context);
1607 Isolate* isolate = icontext->GetIsolate(); 1607 Isolate* isolate = icontext->GetIsolate();
1608 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST), 1608 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST),
1609 isolate); 1609 isolate);
1610 while (object->IsJSFunction() && 1610 while (object->IsJSFunction() &&
1611 !Handle<JSFunction>::cast(object)->IsBuiltin()) { 1611 !Handle<JSFunction>::cast(object)->IsBuiltin()) {
1612 count++; 1612 count++;
1613 if (count == n) isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); 1613 if (count == n) isolate->heap()->CollectAllGarbage();
1614 object = Handle<Object>( 1614 object = Handle<Object>(
1615 Object::cast(JSFunction::cast(*object)->next_function_link()), 1615 Object::cast(JSFunction::cast(*object)->next_function_link()),
1616 isolate); 1616 isolate);
1617 } 1617 }
1618 return count; 1618 return count;
1619 } 1619 }
1620 1620
1621 1621
1622 TEST(TestInternalWeakListsTraverseWithGC) { 1622 TEST(TestInternalWeakListsTraverseWithGC) {
1623 FLAG_always_opt = false; 1623 FLAG_always_opt = false;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 "var half_size_reg_exp;" 1686 "var half_size_reg_exp;"
1687 "while (reg_exp_source.length < 10 * 1024) {" 1687 "while (reg_exp_source.length < 10 * 1024) {"
1688 " half_size_reg_exp = reg_exp_source;" 1688 " half_size_reg_exp = reg_exp_source;"
1689 " reg_exp_source = reg_exp_source + reg_exp_source;" 1689 " reg_exp_source = reg_exp_source + reg_exp_source;"
1690 "}" 1690 "}"
1691 // Flatten string. 1691 // Flatten string.
1692 "reg_exp_source.match(/f/);"); 1692 "reg_exp_source.match(/f/);");
1693 1693
1694 // Get initial heap size after several full GCs, which will stabilize 1694 // Get initial heap size after several full GCs, which will stabilize
1695 // the heap size and return with sweeping finished completely. 1695 // the heap size and return with sweeping finished completely.
1696 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1696 CcTest::heap()->CollectAllGarbage();
1697 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1697 CcTest::heap()->CollectAllGarbage();
1698 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1698 CcTest::heap()->CollectAllGarbage();
1699 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1699 CcTest::heap()->CollectAllGarbage();
1700 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1700 CcTest::heap()->CollectAllGarbage();
1701 MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector(); 1701 MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
1702 if (collector->sweeping_in_progress()) { 1702 if (collector->sweeping_in_progress()) {
1703 collector->EnsureSweepingCompleted(); 1703 collector->EnsureSweepingCompleted();
1704 } 1704 }
1705 int initial_size = static_cast<int>(CcTest::heap()->SizeOfObjects()); 1705 int initial_size = static_cast<int>(CcTest::heap()->SizeOfObjects());
1706 1706
1707 CompileRun("'foo'.match(reg_exp_source);"); 1707 CompileRun("'foo'.match(reg_exp_source);");
1708 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1708 CcTest::heap()->CollectAllGarbage();
1709 int size_with_regexp = static_cast<int>(CcTest::heap()->SizeOfObjects()); 1709 int size_with_regexp = static_cast<int>(CcTest::heap()->SizeOfObjects());
1710 1710
1711 CompileRun("'foo'.match(half_size_reg_exp);"); 1711 CompileRun("'foo'.match(half_size_reg_exp);");
1712 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1712 CcTest::heap()->CollectAllGarbage();
1713 int size_with_optimized_regexp = 1713 int size_with_optimized_regexp =
1714 static_cast<int>(CcTest::heap()->SizeOfObjects()); 1714 static_cast<int>(CcTest::heap()->SizeOfObjects());
1715 1715
1716 int size_of_regexp_code = size_with_regexp - initial_size; 1716 int size_of_regexp_code = size_with_regexp - initial_size;
1717 1717
1718 CHECK_LE(size_of_regexp_code, 1 * MB); 1718 CHECK_LE(size_of_regexp_code, 1 * MB);
1719 1719
1720 // Small regexp is half the size, but compiles to more than twice the code 1720 // Small regexp is half the size, but compiles to more than twice the code
1721 // due to the optimization steps. 1721 // due to the optimization steps.
1722 CHECK_GE(size_with_optimized_regexp, 1722 CHECK_GE(size_with_optimized_regexp,
1723 size_with_regexp + size_of_regexp_code * 2); 1723 size_with_regexp + size_of_regexp_code * 2);
1724 } 1724 }
1725 1725
1726 1726
1727 TEST(TestSizeOfObjects) { 1727 TEST(TestSizeOfObjects) {
1728 v8::V8::Initialize(); 1728 v8::V8::Initialize();
1729 1729
1730 // Get initial heap size after several full GCs, which will stabilize 1730 // Get initial heap size after several full GCs, which will stabilize
1731 // the heap size and return with sweeping finished completely. 1731 // the heap size and return with sweeping finished completely.
1732 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1732 CcTest::heap()->CollectAllGarbage();
1733 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1733 CcTest::heap()->CollectAllGarbage();
1734 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1734 CcTest::heap()->CollectAllGarbage();
1735 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1735 CcTest::heap()->CollectAllGarbage();
1736 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1736 CcTest::heap()->CollectAllGarbage();
1737 MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector(); 1737 MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
1738 if (collector->sweeping_in_progress()) { 1738 if (collector->sweeping_in_progress()) {
1739 collector->EnsureSweepingCompleted(); 1739 collector->EnsureSweepingCompleted();
1740 } 1740 }
1741 int initial_size = static_cast<int>(CcTest::heap()->SizeOfObjects()); 1741 int initial_size = static_cast<int>(CcTest::heap()->SizeOfObjects());
1742 1742
1743 { 1743 {
1744 // Allocate objects on several different old-space pages so that 1744 // Allocate objects on several different old-space pages so that
1745 // concurrent sweeper threads will be busy sweeping the old space on 1745 // concurrent sweeper threads will be busy sweeping the old space on
1746 // subsequent GC runs. 1746 // subsequent GC runs.
1747 AlwaysAllocateScope always_allocate(CcTest::i_isolate()); 1747 AlwaysAllocateScope always_allocate(CcTest::i_isolate());
1748 int filler_size = static_cast<int>(FixedArray::SizeFor(8192)); 1748 int filler_size = static_cast<int>(FixedArray::SizeFor(8192));
1749 for (int i = 1; i <= 100; i++) { 1749 for (int i = 1; i <= 100; i++) {
1750 CcTest::test_heap()->AllocateFixedArray(8192, TENURED).ToObjectChecked(); 1750 CcTest::test_heap()->AllocateFixedArray(8192, TENURED).ToObjectChecked();
1751 CHECK_EQ(initial_size + i * filler_size, 1751 CHECK_EQ(initial_size + i * filler_size,
1752 static_cast<int>(CcTest::heap()->SizeOfObjects())); 1752 static_cast<int>(CcTest::heap()->SizeOfObjects()));
1753 } 1753 }
1754 } 1754 }
1755 1755
1756 // The heap size should go back to initial size after a full GC, even 1756 // The heap size should go back to initial size after a full GC, even
1757 // though sweeping didn't finish yet. 1757 // though sweeping didn't finish yet.
1758 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1758 CcTest::heap()->CollectAllGarbage();
1759 1759
1760 // Normally sweeping would not be complete here, but no guarantees. 1760 // Normally sweeping would not be complete here, but no guarantees.
1761 1761
1762 CHECK_EQ(initial_size, static_cast<int>(CcTest::heap()->SizeOfObjects())); 1762 CHECK_EQ(initial_size, static_cast<int>(CcTest::heap()->SizeOfObjects()));
1763 1763
1764 // Waiting for sweeper threads should not change heap size. 1764 // Waiting for sweeper threads should not change heap size.
1765 if (collector->sweeping_in_progress()) { 1765 if (collector->sweeping_in_progress()) {
1766 collector->EnsureSweepingCompleted(); 1766 collector->EnsureSweepingCompleted();
1767 } 1767 }
1768 CHECK_EQ(initial_size, static_cast<int>(CcTest::heap()->SizeOfObjects())); 1768 CHECK_EQ(initial_size, static_cast<int>(CcTest::heap()->SizeOfObjects()));
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
2170 "for (var i = 0; i < 10; i++) {" 2170 "for (var i = 0; i < 10; i++) {"
2171 " var object = {};" 2171 " var object = {};"
2172 " var prototype = {};" 2172 " var prototype = {};"
2173 " object.__proto__ = prototype;" 2173 " object.__proto__ = prototype;"
2174 " if (i >= 3) live.push(object, prototype);" 2174 " if (i >= 3) live.push(object, prototype);"
2175 "}"); 2175 "}");
2176 2176
2177 // Verify that only dead prototype transitions are cleared. 2177 // Verify that only dead prototype transitions are cleared.
2178 CHECK_EQ(initialTransitions + 10, 2178 CHECK_EQ(initialTransitions + 10,
2179 NumberOfProtoTransitions(baseObject->map())); 2179 NumberOfProtoTransitions(baseObject->map()));
2180 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 2180 CcTest::heap()->CollectAllGarbage();
2181 const int transitions = 10 - 3; 2181 const int transitions = 10 - 3;
2182 CHECK_EQ(initialTransitions + transitions, 2182 CHECK_EQ(initialTransitions + transitions,
2183 NumberOfProtoTransitions(baseObject->map())); 2183 NumberOfProtoTransitions(baseObject->map()));
2184 2184
2185 // Verify that prototype transitions array was compacted. 2185 // Verify that prototype transitions array was compacted.
2186 FixedArray* trans = 2186 FixedArray* trans =
2187 TransitionArray::GetPrototypeTransitions(baseObject->map()); 2187 TransitionArray::GetPrototypeTransitions(baseObject->map());
2188 for (int i = initialTransitions; i < initialTransitions + transitions; i++) { 2188 for (int i = initialTransitions; i < initialTransitions + transitions; i++) {
2189 int j = TransitionArray::kProtoTransitionHeaderSize + i; 2189 int j = TransitionArray::kProtoTransitionHeaderSize + i;
2190 CHECK(trans->get(j)->IsMap()); 2190 CHECK(trans->get(j)->IsMap());
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2252 2252
2253 while (!marking->IsStopped() && !marking->IsComplete()) { 2253 while (!marking->IsStopped() && !marking->IsComplete()) {
2254 marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); 2254 marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
2255 } 2255 }
2256 if (!marking->IsStopped() || marking->should_hurry()) { 2256 if (!marking->IsStopped() || marking->should_hurry()) {
2257 // We don't normally finish a GC via Step(), we normally finish by 2257 // We don't normally finish a GC via Step(), we normally finish by
2258 // setting the stack guard and then do the final steps in the stack 2258 // setting the stack guard and then do the final steps in the stack
2259 // guard interrupt. But here we didn't ask for that, and there is no 2259 // guard interrupt. But here we didn't ask for that, and there is no
2260 // JS code running to trigger the interrupt, so we explicitly finalize 2260 // JS code running to trigger the interrupt, so we explicitly finalize
2261 // here. 2261 // here.
2262 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags, 2262 CcTest::heap()->CollectAllGarbage(Heap::kFinalizeIncrementalMarkingMask,
2263 "Test finalizing incremental mark-sweep"); 2263 "Test finalizing incremental mark-sweep");
2264 } 2264 }
2265 2265
2266 CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age()); 2266 CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age());
2267 CHECK_EQ(0, f->shared()->opt_count()); 2267 CHECK_EQ(0, f->shared()->opt_count());
2268 CHECK_EQ(0, f->shared()->code()->profiler_ticks()); 2268 CHECK_EQ(0, f->shared()->code()->profiler_ticks());
2269 } 2269 }
2270 2270
2271 2271
2272 TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { 2272 TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) {
2273 i::FLAG_stress_compaction = false; 2273 i::FLAG_stress_compaction = false;
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
2926 v8::Utils::OpenHandle( 2926 v8::Utils::OpenHandle(
2927 *v8::Handle<v8::Object>::Cast( 2927 *v8::Handle<v8::Object>::Cast(
2928 CcTest::global()->Get(v8_str("root")))); 2928 CcTest::global()->Get(v8_str("root"))));
2929 2929
2930 // Count number of live transitions before marking. 2930 // Count number of live transitions before marking.
2931 int transitions_before = CountMapTransitions(root->map()); 2931 int transitions_before = CountMapTransitions(root->map());
2932 CompileRun("%DebugPrint(root);"); 2932 CompileRun("%DebugPrint(root);");
2933 CHECK_EQ(transitions_count, transitions_before); 2933 CHECK_EQ(transitions_count, transitions_before);
2934 2934
2935 SimulateIncrementalMarking(CcTest::heap()); 2935 SimulateIncrementalMarking(CcTest::heap());
2936 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 2936 CcTest::heap()->CollectAllGarbage();
2937 2937
2938 // Count number of live transitions after marking. Note that one transition 2938 // Count number of live transitions after marking. Note that one transition
2939 // is left, because 'o' still holds an instance of one transition target. 2939 // is left, because 'o' still holds an instance of one transition target.
2940 int transitions_after = CountMapTransitions(root->map()); 2940 int transitions_after = CountMapTransitions(root->map());
2941 CompileRun("%DebugPrint(root);"); 2941 CompileRun("%DebugPrint(root);");
2942 CHECK_EQ(1, transitions_after); 2942 CHECK_EQ(1, transitions_after);
2943 } 2943 }
2944 2944
2945 2945
2946 #ifdef DEBUG 2946 #ifdef DEBUG
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
3109 CompileRun("function f(o) {" 3109 CompileRun("function f(o) {"
3110 " o.foo = 0;" 3110 " o.foo = 0;"
3111 "}" 3111 "}"
3112 "f(new Object);" 3112 "f(new Object);"
3113 "f(root);"); 3113 "f(root);");
3114 3114
3115 // This bug only triggers with aggressive IC clearing. 3115 // This bug only triggers with aggressive IC clearing.
3116 CcTest::heap()->AgeInlineCaches(); 3116 CcTest::heap()->AgeInlineCaches();
3117 3117
3118 // Explicitly request GC to perform final marking step and sweeping. 3118 // Explicitly request GC to perform final marking step and sweeping.
3119 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3119 CcTest::heap()->CollectAllGarbage();
3120 3120
3121 Handle<JSObject> root = 3121 Handle<JSObject> root =
3122 v8::Utils::OpenHandle( 3122 v8::Utils::OpenHandle(
3123 *v8::Handle<v8::Object>::Cast( 3123 *v8::Handle<v8::Object>::Cast(
3124 CcTest::global()->Get(v8_str("root")))); 3124 CcTest::global()->Get(v8_str("root"))));
3125 3125
3126 // The root object should be in a sane state. 3126 // The root object should be in a sane state.
3127 CHECK(root->IsJSObject()); 3127 CHECK(root->IsJSObject());
3128 CHECK(root->map()->IsMap()); 3128 CHECK(root->map()->IsMap());
3129 } 3129 }
(...skipping 23 matching lines...) Expand all
3153 "f(new Object);" 3153 "f(new Object);"
3154 "f(new Object);" 3154 "f(new Object);"
3155 "%OptimizeFunctionOnNextCall(f);" 3155 "%OptimizeFunctionOnNextCall(f);"
3156 "f(root);" 3156 "f(root);"
3157 "%DeoptimizeFunction(f);"); 3157 "%DeoptimizeFunction(f);");
3158 3158
3159 // This bug only triggers with aggressive IC clearing. 3159 // This bug only triggers with aggressive IC clearing.
3160 CcTest::heap()->AgeInlineCaches(); 3160 CcTest::heap()->AgeInlineCaches();
3161 3161
3162 // Explicitly request GC to perform final marking step and sweeping. 3162 // Explicitly request GC to perform final marking step and sweeping.
3163 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3163 CcTest::heap()->CollectAllGarbage();
3164 3164
3165 Handle<JSObject> root = 3165 Handle<JSObject> root =
3166 v8::Utils::OpenHandle( 3166 v8::Utils::OpenHandle(
3167 *v8::Handle<v8::Object>::Cast( 3167 *v8::Handle<v8::Object>::Cast(
3168 CcTest::global()->Get(v8_str("root")))); 3168 CcTest::global()->Get(v8_str("root"))));
3169 3169
3170 // The root object should be in a sane state. 3170 // The root object should be in a sane state.
3171 CHECK(root->IsJSObject()); 3171 CHECK(root->IsJSObject());
3172 CHECK(root->map()->IsMap()); 3172 CHECK(root->map()->IsMap());
3173 } 3173 }
(...skipping 17 matching lines...) Expand all
3191 CHECK_EQ(1, old_space->CountTotalPages()); 3191 CHECK_EQ(1, old_space->CountTotalPages());
3192 for (int i = 0; i < number_of_test_pages; i++) { 3192 for (int i = 0; i < number_of_test_pages; i++) {
3193 AlwaysAllocateScope always_allocate(isolate); 3193 AlwaysAllocateScope always_allocate(isolate);
3194 SimulateFullSpace(old_space); 3194 SimulateFullSpace(old_space);
3195 factory->NewFixedArray(1, TENURED); 3195 factory->NewFixedArray(1, TENURED);
3196 } 3196 }
3197 CHECK_EQ(number_of_test_pages + 1, old_space->CountTotalPages()); 3197 CHECK_EQ(number_of_test_pages + 1, old_space->CountTotalPages());
3198 3198
3199 // Triggering one GC will cause a lot of garbage to be discovered but 3199 // Triggering one GC will cause a lot of garbage to be discovered but
3200 // even spread across all allocated pages. 3200 // even spread across all allocated pages.
3201 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask, 3201 heap->CollectAllGarbage(Heap::kFinalizeIncrementalMarkingMask,
3202 "triggered for preparation"); 3202 "triggered for preparation");
3203 CHECK_GE(number_of_test_pages + 1, old_space->CountTotalPages()); 3203 CHECK_GE(number_of_test_pages + 1, old_space->CountTotalPages());
3204 3204
3205 // Triggering subsequent GCs should cause at least half of the pages 3205 // Triggering subsequent GCs should cause at least half of the pages
3206 // to be released to the OS after at most two cycles. 3206 // to be released to the OS after at most two cycles.
3207 heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 1"); 3207 heap->CollectAllGarbage(Heap::kFinalizeIncrementalMarkingMask,
3208 "triggered by test 1");
3208 CHECK_GE(number_of_test_pages + 1, old_space->CountTotalPages()); 3209 CHECK_GE(number_of_test_pages + 1, old_space->CountTotalPages());
3209 heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 2"); 3210 heap->CollectAllGarbage(Heap::kFinalizeIncrementalMarkingMask,
3211 "triggered by test 2");
3210 CHECK_GE(number_of_test_pages + 1, old_space->CountTotalPages() * 2); 3212 CHECK_GE(number_of_test_pages + 1, old_space->CountTotalPages() * 2);
3211 3213
3212 // Triggering a last-resort GC should cause all pages to be released to the 3214 // Triggering a last-resort GC should cause all pages to be released to the
3213 // OS so that other processes can seize the memory. If we get a failure here 3215 // OS so that other processes can seize the memory. If we get a failure here
3214 // where there are 2 pages left instead of 1, then we should increase the 3216 // where there are 2 pages left instead of 1, then we should increase the
3215 // size of the first page a little in SizeOfFirstPage in spaces.cc. The 3217 // size of the first page a little in SizeOfFirstPage in spaces.cc. The
3216 // first page should be small in order to reduce memory used when the VM 3218 // first page should be small in order to reduce memory used when the VM
3217 // boots, but if the 20 small arrays don't fit on the first page then that's 3219 // boots, but if the 20 small arrays don't fit on the first page then that's
3218 // an indication that it is too small. 3220 // an indication that it is too small.
3219 heap->CollectAllAvailableGarbage("triggered really hard"); 3221 heap->CollectAllAvailableGarbage("triggered really hard");
(...skipping 21 matching lines...) Expand all
3241 // lives in old-space. 3243 // lives in old-space.
3242 SimulateFullSpace(CcTest::heap()->new_space()); 3244 SimulateFullSpace(CcTest::heap()->new_space());
3243 AlwaysAllocateScope always_allocate(isolate); 3245 AlwaysAllocateScope always_allocate(isolate);
3244 Handle<String> t = factory->NewProperSubString(s, 5, 35); 3246 Handle<String> t = factory->NewProperSubString(s, 5, 35);
3245 CHECK(t->IsSlicedString()); 3247 CHECK(t->IsSlicedString());
3246 CHECK(!CcTest::heap()->InNewSpace(*t)); 3248 CHECK(!CcTest::heap()->InNewSpace(*t));
3247 *slice.location() = *t.location(); 3249 *slice.location() = *t.location();
3248 } 3250 }
3249 3251
3250 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); 3252 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString());
3251 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3253 CcTest::heap()->CollectAllGarbage();
3252 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); 3254 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString());
3253 } 3255 }
3254 3256
3255 3257
3256 #ifdef OBJECT_PRINT 3258 #ifdef OBJECT_PRINT
3257 TEST(PrintSharedFunctionInfo) { 3259 TEST(PrintSharedFunctionInfo) {
3258 CcTest::InitializeVM(); 3260 CcTest::InitializeVM();
3259 v8::HandleScope scope(CcTest::isolate()); 3261 v8::HandleScope scope(CcTest::isolate());
3260 const char* source = "f = function() { return 987654321; }\n" 3262 const char* source = "f = function() { return 987654321; }\n"
3261 "g = function() { return 123456789; }\n"; 3263 "g = function() { return 123456789; }\n";
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3339 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); 3341 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector());
3340 3342
3341 int expected_slots = 2; 3343 int expected_slots = 2;
3342 CHECK_EQ(expected_slots, feedback_vector->ICSlots()); 3344 CHECK_EQ(expected_slots, feedback_vector->ICSlots());
3343 int slot1 = 0; 3345 int slot1 = 0;
3344 int slot2 = 1; 3346 int slot2 = 1;
3345 CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot1))->IsWeakCell()); 3347 CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot1))->IsWeakCell());
3346 CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot2))->IsWeakCell()); 3348 CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot2))->IsWeakCell());
3347 3349
3348 SimulateIncrementalMarking(CcTest::heap()); 3350 SimulateIncrementalMarking(CcTest::heap());
3349 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3351 CcTest::heap()->CollectAllGarbage();
3350 3352
3351 CHECK(!WeakCell::cast(feedback_vector->Get(FeedbackVectorICSlot(slot1))) 3353 CHECK(!WeakCell::cast(feedback_vector->Get(FeedbackVectorICSlot(slot1)))
3352 ->cleared()); 3354 ->cleared());
3353 CHECK(!WeakCell::cast(feedback_vector->Get(FeedbackVectorICSlot(slot2))) 3355 CHECK(!WeakCell::cast(feedback_vector->Get(FeedbackVectorICSlot(slot2)))
3354 ->cleared()); 3356 ->cleared());
3355 } 3357 }
3356 3358
3357 3359
3358 static Code* FindFirstIC(Code* code, Code::Kind kind) { 3360 static Code* FindFirstIC(Code* code, Code::Kind kind) {
3359 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | 3361 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3400 "function fun() { this.x = 1; };" 3402 "function fun() { this.x = 1; };"
3401 "function f(o) { return new o(); } f(fun); f(fun);"); 3403 "function f(o) { return new o(); } f(fun); f(fun);");
3402 Handle<JSFunction> f = v8::Utils::OpenHandle( 3404 Handle<JSFunction> f = v8::Utils::OpenHandle(
3403 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f")))); 3405 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
3404 3406
3405 3407
3406 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector()); 3408 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector());
3407 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); 3409 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell());
3408 3410
3409 SimulateIncrementalMarking(CcTest::heap()); 3411 SimulateIncrementalMarking(CcTest::heap());
3410 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3412 CcTest::heap()->CollectAllGarbage();
3411 3413
3412 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); 3414 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell());
3413 } 3415 }
3414 3416
3415 3417
3416 TEST(IncrementalMarkingClearsMonomorphicConstructor) { 3418 TEST(IncrementalMarkingClearsMonomorphicConstructor) {
3417 if (i::FLAG_always_opt) return; 3419 if (i::FLAG_always_opt) return;
3418 CcTest::InitializeVM(); 3420 CcTest::InitializeVM();
3419 Isolate* isolate = CcTest::i_isolate(); 3421 Isolate* isolate = CcTest::i_isolate();
3420 v8::HandleScope scope(CcTest::isolate()); 3422 v8::HandleScope scope(CcTest::isolate());
(...skipping 14 matching lines...) Expand all
3435 Handle<JSFunction> f = v8::Utils::OpenHandle( 3437 Handle<JSFunction> f = v8::Utils::OpenHandle(
3436 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f")))); 3438 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
3437 3439
3438 3440
3439 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector()); 3441 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector());
3440 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); 3442 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell());
3441 3443
3442 // Fire context dispose notification. 3444 // Fire context dispose notification.
3443 CcTest::isolate()->ContextDisposedNotification(); 3445 CcTest::isolate()->ContextDisposedNotification();
3444 SimulateIncrementalMarking(CcTest::heap()); 3446 SimulateIncrementalMarking(CcTest::heap());
3445 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3447 CcTest::heap()->CollectAllGarbage();
3446 3448
3447 CHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(isolate), 3449 CHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(isolate),
3448 vector->Get(FeedbackVectorSlot(0))); 3450 vector->Get(FeedbackVectorSlot(0)));
3449 } 3451 }
3450 3452
3451 3453
3452 TEST(IncrementalMarkingPreservesMonomorphicIC) { 3454 TEST(IncrementalMarkingPreservesMonomorphicIC) {
3453 if (i::FLAG_always_opt) return; 3455 if (i::FLAG_always_opt) return;
3454 CcTest::InitializeVM(); 3456 CcTest::InitializeVM();
3455 v8::HandleScope scope(CcTest::isolate()); 3457 v8::HandleScope scope(CcTest::isolate());
3456 3458
3457 // Prepare function f that contains a monomorphic IC for object 3459 // Prepare function f that contains a monomorphic IC for object
3458 // originating from the same native context. 3460 // originating from the same native context.
3459 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" 3461 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"
3460 "function f(o) { return o.x; } f(obj); f(obj);"); 3462 "function f(o) { return o.x; } f(obj); f(obj);");
3461 Handle<JSFunction> f = 3463 Handle<JSFunction> f =
3462 v8::Utils::OpenHandle( 3464 v8::Utils::OpenHandle(
3463 *v8::Handle<v8::Function>::Cast( 3465 *v8::Handle<v8::Function>::Cast(
3464 CcTest::global()->Get(v8_str("f")))); 3466 CcTest::global()->Get(v8_str("f"))));
3465 3467
3466 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3468 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3467 if (FLAG_vector_ics) { 3469 if (FLAG_vector_ics) {
3468 CheckVectorIC(f, 0, MONOMORPHIC); 3470 CheckVectorIC(f, 0, MONOMORPHIC);
3469 CHECK(ic_before->ic_state() == DEFAULT); 3471 CHECK(ic_before->ic_state() == DEFAULT);
3470 } else { 3472 } else {
3471 CHECK(ic_before->ic_state() == MONOMORPHIC); 3473 CHECK(ic_before->ic_state() == MONOMORPHIC);
3472 } 3474 }
3473 3475
3474 SimulateIncrementalMarking(CcTest::heap()); 3476 SimulateIncrementalMarking(CcTest::heap());
3475 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3477 CcTest::heap()->CollectAllGarbage();
3476 3478
3477 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3479 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3478 if (FLAG_vector_ics) { 3480 if (FLAG_vector_ics) {
3479 CheckVectorIC(f, 0, MONOMORPHIC); 3481 CheckVectorIC(f, 0, MONOMORPHIC);
3480 CHECK(ic_after->ic_state() == DEFAULT); 3482 CHECK(ic_after->ic_state() == DEFAULT);
3481 } else { 3483 } else {
3482 CHECK(ic_after->ic_state() == MONOMORPHIC); 3484 CHECK(ic_after->ic_state() == MONOMORPHIC);
3483 } 3485 }
3484 } 3486 }
3485 3487
(...skipping 21 matching lines...) Expand all
3507 if (FLAG_vector_ics) { 3509 if (FLAG_vector_ics) {
3508 CheckVectorIC(f, 0, MONOMORPHIC); 3510 CheckVectorIC(f, 0, MONOMORPHIC);
3509 CHECK(ic_before->ic_state() == DEFAULT); 3511 CHECK(ic_before->ic_state() == DEFAULT);
3510 } else { 3512 } else {
3511 CHECK(ic_before->ic_state() == MONOMORPHIC); 3513 CHECK(ic_before->ic_state() == MONOMORPHIC);
3512 } 3514 }
3513 3515
3514 // Fire context dispose notification. 3516 // Fire context dispose notification.
3515 CcTest::isolate()->ContextDisposedNotification(); 3517 CcTest::isolate()->ContextDisposedNotification();
3516 SimulateIncrementalMarking(CcTest::heap()); 3518 SimulateIncrementalMarking(CcTest::heap());
3517 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3519 CcTest::heap()->CollectAllGarbage();
3518 3520
3519 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3521 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3520 if (FLAG_vector_ics) { 3522 if (FLAG_vector_ics) {
3521 CheckVectorICCleared(f, 0); 3523 CheckVectorICCleared(f, 0);
3522 CHECK(ic_after->ic_state() == DEFAULT); 3524 CHECK(ic_after->ic_state() == DEFAULT);
3523 } else { 3525 } else {
3524 CHECK(IC::IsCleared(ic_after)); 3526 CHECK(IC::IsCleared(ic_after));
3525 } 3527 }
3526 } 3528 }
3527 3529
(...skipping 27 matching lines...) Expand all
3555 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3557 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3556 if (FLAG_vector_ics) { 3558 if (FLAG_vector_ics) {
3557 CheckVectorIC(f, 0, POLYMORPHIC); 3559 CheckVectorIC(f, 0, POLYMORPHIC);
3558 CHECK(ic_before->ic_state() == DEFAULT); 3560 CHECK(ic_before->ic_state() == DEFAULT);
3559 } else { 3561 } else {
3560 CHECK(ic_before->ic_state() == POLYMORPHIC); 3562 CHECK(ic_before->ic_state() == POLYMORPHIC);
3561 } 3563 }
3562 3564
3563 // Fire context dispose notification. 3565 // Fire context dispose notification.
3564 SimulateIncrementalMarking(CcTest::heap()); 3566 SimulateIncrementalMarking(CcTest::heap());
3565 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3567 CcTest::heap()->CollectAllGarbage();
3566 3568
3567 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3569 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3568 if (FLAG_vector_ics) { 3570 if (FLAG_vector_ics) {
3569 CheckVectorIC(f, 0, POLYMORPHIC); 3571 CheckVectorIC(f, 0, POLYMORPHIC);
3570 CHECK(ic_after->ic_state() == DEFAULT); 3572 CHECK(ic_after->ic_state() == DEFAULT);
3571 } else { 3573 } else {
3572 CHECK(ic_after->ic_state() == POLYMORPHIC); 3574 CHECK(ic_after->ic_state() == POLYMORPHIC);
3573 } 3575 }
3574 } 3576 }
3575 3577
(...skipping 28 matching lines...) Expand all
3604 if (FLAG_vector_ics) { 3606 if (FLAG_vector_ics) {
3605 CheckVectorIC(f, 0, POLYMORPHIC); 3607 CheckVectorIC(f, 0, POLYMORPHIC);
3606 CHECK(ic_before->ic_state() == DEFAULT); 3608 CHECK(ic_before->ic_state() == DEFAULT);
3607 } else { 3609 } else {
3608 CHECK(ic_before->ic_state() == POLYMORPHIC); 3610 CHECK(ic_before->ic_state() == POLYMORPHIC);
3609 } 3611 }
3610 3612
3611 // Fire context dispose notification. 3613 // Fire context dispose notification.
3612 CcTest::isolate()->ContextDisposedNotification(); 3614 CcTest::isolate()->ContextDisposedNotification();
3613 SimulateIncrementalMarking(CcTest::heap()); 3615 SimulateIncrementalMarking(CcTest::heap());
3614 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3616 CcTest::heap()->CollectAllGarbage();
3615 3617
3616 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3618 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3617 if (FLAG_vector_ics) { 3619 if (FLAG_vector_ics) {
3618 CheckVectorICCleared(f, 0); 3620 CheckVectorICCleared(f, 0);
3619 CHECK(ic_before->ic_state() == DEFAULT); 3621 CHECK(ic_before->ic_state() == DEFAULT);
3620 } else { 3622 } else {
3621 CHECK(IC::IsCleared(ic_after)); 3623 CHECK(IC::IsCleared(ic_after));
3622 } 3624 }
3623 } 3625 }
3624 3626
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
3733 3735
3734 TEST(Regress159140) { 3736 TEST(Regress159140) {
3735 i::FLAG_allow_natives_syntax = true; 3737 i::FLAG_allow_natives_syntax = true;
3736 i::FLAG_flush_code_incrementally = true; 3738 i::FLAG_flush_code_incrementally = true;
3737 CcTest::InitializeVM(); 3739 CcTest::InitializeVM();
3738 Isolate* isolate = CcTest::i_isolate(); 3740 Isolate* isolate = CcTest::i_isolate();
3739 Heap* heap = isolate->heap(); 3741 Heap* heap = isolate->heap();
3740 HandleScope scope(isolate); 3742 HandleScope scope(isolate);
3741 3743
3742 // Perform one initial GC to enable code flushing. 3744 // Perform one initial GC to enable code flushing.
3743 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 3745 heap->CollectAllGarbage();
3744 3746
3745 // Prepare several closures that are all eligible for code flushing 3747 // Prepare several closures that are all eligible for code flushing
3746 // because all reachable ones are not optimized. Make sure that the 3748 // because all reachable ones are not optimized. Make sure that the
3747 // optimized code object is directly reachable through a handle so 3749 // optimized code object is directly reachable through a handle so
3748 // that it is marked black during incremental marking. 3750 // that it is marked black during incremental marking.
3749 Handle<Code> code; 3751 Handle<Code> code;
3750 { 3752 {
3751 HandleScope inner_scope(isolate); 3753 HandleScope inner_scope(isolate);
3752 CompileRun("function h(x) {}" 3754 CompileRun("function h(x) {}"
3753 "function mkClosure() {" 3755 "function mkClosure() {"
(...skipping 25 matching lines...) Expand all
3779 } 3781 }
3780 3782
3781 code = inner_scope.CloseAndEscape(Handle<Code>(f->code())); 3783 code = inner_scope.CloseAndEscape(Handle<Code>(f->code()));
3782 } 3784 }
3783 3785
3784 // Simulate incremental marking so that the functions are enqueued as 3786 // Simulate incremental marking so that the functions are enqueued as
3785 // code flushing candidates. Then optimize one function. Finally 3787 // code flushing candidates. Then optimize one function. Finally
3786 // finish the GC to complete code flushing. 3788 // finish the GC to complete code flushing.
3787 SimulateIncrementalMarking(heap); 3789 SimulateIncrementalMarking(heap);
3788 CompileRun("%OptimizeFunctionOnNextCall(g); g(3);"); 3790 CompileRun("%OptimizeFunctionOnNextCall(g); g(3);");
3789 heap->CollectAllGarbage(Heap::kNoGCFlags); 3791 heap->CollectAllGarbage();
3790 3792
3791 // Unoptimized code is missing and the deoptimizer will go ballistic. 3793 // Unoptimized code is missing and the deoptimizer will go ballistic.
3792 CompileRun("g('bozo');"); 3794 CompileRun("g('bozo');");
3793 } 3795 }
3794 3796
3795 3797
3796 TEST(Regress165495) { 3798 TEST(Regress165495) {
3797 i::FLAG_allow_natives_syntax = true; 3799 i::FLAG_allow_natives_syntax = true;
3798 i::FLAG_flush_code_incrementally = true; 3800 i::FLAG_flush_code_incrementally = true;
3799 CcTest::InitializeVM(); 3801 CcTest::InitializeVM();
3800 Isolate* isolate = CcTest::i_isolate(); 3802 Isolate* isolate = CcTest::i_isolate();
3801 Heap* heap = isolate->heap(); 3803 Heap* heap = isolate->heap();
3802 HandleScope scope(isolate); 3804 HandleScope scope(isolate);
3803 3805
3804 // Perform one initial GC to enable code flushing. 3806 // Perform one initial GC to enable code flushing.
3805 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 3807 heap->CollectAllGarbage();
3806 3808
3807 // Prepare an optimized closure that the optimized code map will get 3809 // Prepare an optimized closure that the optimized code map will get
3808 // populated. Then age the unoptimized code to trigger code flushing 3810 // populated. Then age the unoptimized code to trigger code flushing
3809 // but make sure the optimized code is unreachable. 3811 // but make sure the optimized code is unreachable.
3810 { 3812 {
3811 HandleScope inner_scope(isolate); 3813 HandleScope inner_scope(isolate);
3812 CompileRun("function mkClosure() {" 3814 CompileRun("function mkClosure() {"
3813 " return function(x) { return x + 1; };" 3815 " return function(x) { return x + 1; };"
3814 "}" 3816 "}"
3815 "var f = mkClosure();" 3817 "var f = mkClosure();"
3816 "f(1); f(2);" 3818 "f(1); f(2);"
3817 "%OptimizeFunctionOnNextCall(f); f(3);"); 3819 "%OptimizeFunctionOnNextCall(f); f(3);");
3818 3820
3819 Handle<JSFunction> f = 3821 Handle<JSFunction> f =
3820 v8::Utils::OpenHandle( 3822 v8::Utils::OpenHandle(
3821 *v8::Handle<v8::Function>::Cast( 3823 *v8::Handle<v8::Function>::Cast(
3822 CcTest::global()->Get(v8_str("f")))); 3824 CcTest::global()->Get(v8_str("f"))));
3823 CHECK(f->is_compiled()); 3825 CHECK(f->is_compiled());
3824 const int kAgingThreshold = 6; 3826 const int kAgingThreshold = 6;
3825 for (int i = 0; i < kAgingThreshold; i++) { 3827 for (int i = 0; i < kAgingThreshold; i++) {
3826 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); 3828 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
3827 } 3829 }
3828 3830
3829 CompileRun("f = null;"); 3831 CompileRun("f = null;");
3830 } 3832 }
3831 3833
3832 // Simulate incremental marking so that unoptimized code is flushed 3834 // Simulate incremental marking so that unoptimized code is flushed
3833 // even though it still is cached in the optimized code map. 3835 // even though it still is cached in the optimized code map.
3834 SimulateIncrementalMarking(heap); 3836 SimulateIncrementalMarking(heap);
3835 heap->CollectAllGarbage(Heap::kNoGCFlags); 3837 heap->CollectAllGarbage();
3836 3838
3837 // Make a new closure that will get code installed from the code map. 3839 // Make a new closure that will get code installed from the code map.
3838 // Unoptimized code is missing and the deoptimizer will go ballistic. 3840 // Unoptimized code is missing and the deoptimizer will go ballistic.
3839 CompileRun("var g = mkClosure(); g('bozo');"); 3841 CompileRun("var g = mkClosure(); g('bozo');");
3840 } 3842 }
3841 3843
3842 3844
3843 TEST(Regress169209) { 3845 TEST(Regress169209) {
3844 i::FLAG_stress_compaction = false; 3846 i::FLAG_stress_compaction = false;
3845 i::FLAG_allow_natives_syntax = true; 3847 i::FLAG_allow_natives_syntax = true;
3846 i::FLAG_flush_code_incrementally = true; 3848 i::FLAG_flush_code_incrementally = true;
3847 3849
3848 CcTest::InitializeVM(); 3850 CcTest::InitializeVM();
3849 Isolate* isolate = CcTest::i_isolate(); 3851 Isolate* isolate = CcTest::i_isolate();
3850 Heap* heap = isolate->heap(); 3852 Heap* heap = isolate->heap();
3851 HandleScope scope(isolate); 3853 HandleScope scope(isolate);
3852 3854
3853 // Perform one initial GC to enable code flushing. 3855 // Perform one initial GC to enable code flushing.
3854 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 3856 heap->CollectAllGarbage();
3855 3857
3856 // Prepare a shared function info eligible for code flushing for which 3858 // Prepare a shared function info eligible for code flushing for which
3857 // the unoptimized code will be replaced during optimization. 3859 // the unoptimized code will be replaced during optimization.
3858 Handle<SharedFunctionInfo> shared1; 3860 Handle<SharedFunctionInfo> shared1;
3859 { 3861 {
3860 HandleScope inner_scope(isolate); 3862 HandleScope inner_scope(isolate);
3861 CompileRun("function f() { return 'foobar'; }" 3863 CompileRun("function f() { return 'foobar'; }"
3862 "function g(x) { if (x) f(); }" 3864 "function g(x) { if (x) f(); }"
3863 "f();" 3865 "f();"
3864 "g(false);" 3866 "g(false);"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3903 CHECK(shared1->code()->gc_metadata() != NULL); 3905 CHECK(shared1->code()->gc_metadata() != NULL);
3904 3906
3905 // Optimize function and make sure the unoptimized code is replaced. 3907 // Optimize function and make sure the unoptimized code is replaced.
3906 #ifdef DEBUG 3908 #ifdef DEBUG
3907 FLAG_stop_at = "f"; 3909 FLAG_stop_at = "f";
3908 #endif 3910 #endif
3909 CompileRun("%OptimizeFunctionOnNextCall(g);" 3911 CompileRun("%OptimizeFunctionOnNextCall(g);"
3910 "g(false);"); 3912 "g(false);");
3911 3913
3912 // Finish garbage collection cycle. 3914 // Finish garbage collection cycle.
3913 heap->CollectAllGarbage(Heap::kNoGCFlags); 3915 heap->CollectAllGarbage();
3914 CHECK(shared1->code()->gc_metadata() == NULL); 3916 CHECK(shared1->code()->gc_metadata() == NULL);
3915 } 3917 }
3916 3918
3917 3919
3918 TEST(Regress169928) { 3920 TEST(Regress169928) {
3919 i::FLAG_allow_natives_syntax = true; 3921 i::FLAG_allow_natives_syntax = true;
3920 i::FLAG_crankshaft = false; 3922 i::FLAG_crankshaft = false;
3921 CcTest::InitializeVM(); 3923 CcTest::InitializeVM();
3922 Isolate* isolate = CcTest::i_isolate(); 3924 Isolate* isolate = CcTest::i_isolate();
3923 Factory* factory = isolate->factory(); 3925 Factory* factory = isolate->factory();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3992 i::FLAG_always_compact = true; 3994 i::FLAG_always_compact = true;
3993 i::FLAG_cache_optimized_code = false; 3995 i::FLAG_cache_optimized_code = false;
3994 i::FLAG_allow_natives_syntax = true; 3996 i::FLAG_allow_natives_syntax = true;
3995 i::FLAG_flush_code_incrementally = true; 3997 i::FLAG_flush_code_incrementally = true;
3996 CcTest::InitializeVM(); 3998 CcTest::InitializeVM();
3997 Isolate* isolate = CcTest::i_isolate(); 3999 Isolate* isolate = CcTest::i_isolate();
3998 Heap* heap = isolate->heap(); 4000 Heap* heap = isolate->heap();
3999 HandleScope scope(isolate); 4001 HandleScope scope(isolate);
4000 4002
4001 // Perform one initial GC to enable code flushing. 4003 // Perform one initial GC to enable code flushing.
4002 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4004 heap->CollectAllGarbage();
4003 4005
4004 // Ensure the code ends up on an evacuation candidate. 4006 // Ensure the code ends up on an evacuation candidate.
4005 SimulateFullSpace(heap->code_space()); 4007 SimulateFullSpace(heap->code_space());
4006 4008
4007 // Prepare an unoptimized function that is eligible for code flushing. 4009 // Prepare an unoptimized function that is eligible for code flushing.
4008 Handle<JSFunction> function; 4010 Handle<JSFunction> function;
4009 { 4011 {
4010 HandleScope inner_scope(isolate); 4012 HandleScope inner_scope(isolate);
4011 CompileRun("function mkClosure() {" 4013 CompileRun("function mkClosure() {"
4012 " return function(x) { return x + 1; };" 4014 " return function(x) { return x + 1; };"
(...skipping 19 matching lines...) Expand all
4032 // explicitly enqueued. 4034 // explicitly enqueued.
4033 SimulateIncrementalMarking(heap); 4035 SimulateIncrementalMarking(heap);
4034 4036
4035 // Now optimize the function so that it is taken off the candidate list. 4037 // Now optimize the function so that it is taken off the candidate list.
4036 { 4038 {
4037 HandleScope inner_scope(isolate); 4039 HandleScope inner_scope(isolate);
4038 CompileRun("%OptimizeFunctionOnNextCall(f); f(3);"); 4040 CompileRun("%OptimizeFunctionOnNextCall(f); f(3);");
4039 } 4041 }
4040 4042
4041 // This cycle will bust the heap and subsequent cycles will go ballistic. 4043 // This cycle will bust the heap and subsequent cycles will go ballistic.
4042 heap->CollectAllGarbage(Heap::kNoGCFlags); 4044 heap->CollectAllGarbage();
4043 heap->CollectAllGarbage(Heap::kNoGCFlags); 4045 heap->CollectAllGarbage();
4044 } 4046 }
4045 4047
4046 4048
4047 TEST(Regress173458) { 4049 TEST(Regress173458) {
4048 if (i::FLAG_never_compact) return; 4050 if (i::FLAG_never_compact) return;
4049 i::FLAG_always_compact = true; 4051 i::FLAG_always_compact = true;
4050 i::FLAG_cache_optimized_code = false; 4052 i::FLAG_cache_optimized_code = false;
4051 i::FLAG_allow_natives_syntax = true; 4053 i::FLAG_allow_natives_syntax = true;
4052 i::FLAG_flush_code_incrementally = true; 4054 i::FLAG_flush_code_incrementally = true;
4053 CcTest::InitializeVM(); 4055 CcTest::InitializeVM();
4054 Isolate* isolate = CcTest::i_isolate(); 4056 Isolate* isolate = CcTest::i_isolate();
4055 Heap* heap = isolate->heap(); 4057 Heap* heap = isolate->heap();
4056 HandleScope scope(isolate); 4058 HandleScope scope(isolate);
4057 4059
4058 // Perform one initial GC to enable code flushing. 4060 // Perform one initial GC to enable code flushing.
4059 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4061 heap->CollectAllGarbage();
4060 4062
4061 // Ensure the code ends up on an evacuation candidate. 4063 // Ensure the code ends up on an evacuation candidate.
4062 SimulateFullSpace(heap->code_space()); 4064 SimulateFullSpace(heap->code_space());
4063 4065
4064 // Prepare an unoptimized function that is eligible for code flushing. 4066 // Prepare an unoptimized function that is eligible for code flushing.
4065 Handle<JSFunction> function; 4067 Handle<JSFunction> function;
4066 { 4068 {
4067 HandleScope inner_scope(isolate); 4069 HandleScope inner_scope(isolate);
4068 CompileRun("function mkClosure() {" 4070 CompileRun("function mkClosure() {"
4069 " return function(x) { return x + 1; };" 4071 " return function(x) { return x + 1; };"
(...skipping 16 matching lines...) Expand all
4086 4088
4087 // Simulate incremental marking so that unoptimized function is enqueued as a 4089 // Simulate incremental marking so that unoptimized function is enqueued as a
4088 // candidate for code flushing. The shared function info however will not be 4090 // candidate for code flushing. The shared function info however will not be
4089 // explicitly enqueued. 4091 // explicitly enqueued.
4090 SimulateIncrementalMarking(heap); 4092 SimulateIncrementalMarking(heap);
4091 4093
4092 // Now enable the debugger which in turn will disable code flushing. 4094 // Now enable the debugger which in turn will disable code flushing.
4093 CHECK(isolate->debug()->Load()); 4095 CHECK(isolate->debug()->Load());
4094 4096
4095 // This cycle will bust the heap and subsequent cycles will go ballistic. 4097 // This cycle will bust the heap and subsequent cycles will go ballistic.
4096 heap->CollectAllGarbage(Heap::kNoGCFlags); 4098 heap->CollectAllGarbage();
4097 heap->CollectAllGarbage(Heap::kNoGCFlags); 4099 heap->CollectAllGarbage();
4098 } 4100 }
4099 4101
4100 4102
4101 class DummyVisitor : public ObjectVisitor { 4103 class DummyVisitor : public ObjectVisitor {
4102 public: 4104 public:
4103 void VisitPointers(Object** start, Object** end) { } 4105 void VisitPointers(Object** start, Object** end) { }
4104 }; 4106 };
4105 4107
4106 4108
4107 TEST(DeferredHandles) { 4109 TEST(DeferredHandles) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
4222 Handle<JSFunction> bar_handle = 4224 Handle<JSFunction> bar_handle =
4223 v8::Utils::OpenHandle( 4225 v8::Utils::OpenHandle(
4224 *v8::Handle<v8::Function>::Cast( 4226 *v8::Handle<v8::Function>::Cast(
4225 CcTest::global()->Get(v8_str("bar")))); 4227 CcTest::global()->Get(v8_str("bar"))));
4226 CHECK_EQ(bar_handle->code(), function_bar); 4228 CHECK_EQ(bar_handle->code(), function_bar);
4227 } 4229 }
4228 4230
4229 // Now make sure that a gc should get rid of the function, even though we 4231 // Now make sure that a gc should get rid of the function, even though we
4230 // still have the allocation site alive. 4232 // still have the allocation site alive.
4231 for (int i = 0; i < 4; i++) { 4233 for (int i = 0; i < 4; i++) {
4232 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4234 heap->CollectAllGarbage();
4233 } 4235 }
4234 4236
4235 // The site still exists because of our global handle, but the code is no 4237 // The site still exists because of our global handle, but the code is no
4236 // longer referred to by dependent_code(). 4238 // longer referred to by dependent_code().
4237 DependentCode::GroupStartIndexes starts(site->dependent_code()); 4239 DependentCode::GroupStartIndexes starts(site->dependent_code());
4238 int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); 4240 int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup);
4239 CHECK(site->dependent_code()->object_at(index)->IsWeakCell() && 4241 CHECK(site->dependent_code()->object_at(index)->IsWeakCell() &&
4240 WeakCell::cast(site->dependent_code()->object_at(index))->cleared()); 4242 WeakCell::cast(site->dependent_code()->object_at(index))->cleared());
4241 } 4243 }
4242 4244
(...skipping 27 matching lines...) Expand all
4270 4272
4271 Handle<JSFunction> bar = 4273 Handle<JSFunction> bar =
4272 v8::Utils::OpenHandle( 4274 v8::Utils::OpenHandle(
4273 *v8::Handle<v8::Function>::Cast( 4275 *v8::Handle<v8::Function>::Cast(
4274 CcTest::global()->Get(v8_str("bar")))); 4276 CcTest::global()->Get(v8_str("bar"))));
4275 code = scope.CloseAndEscape(Handle<Code>(bar->code())); 4277 code = scope.CloseAndEscape(Handle<Code>(bar->code()));
4276 } 4278 }
4277 4279
4278 // Now make sure that a gc should get rid of the function 4280 // Now make sure that a gc should get rid of the function
4279 for (int i = 0; i < 4; i++) { 4281 for (int i = 0; i < 4; i++) {
4280 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4282 heap->CollectAllGarbage();
4281 } 4283 }
4282 4284
4283 DCHECK(code->marked_for_deoptimization()); 4285 DCHECK(code->marked_for_deoptimization());
4284 } 4286 }
4285 4287
4286 4288
4287 TEST(ObjectsInOptimizedCodeAreWeak) { 4289 TEST(ObjectsInOptimizedCodeAreWeak) {
4288 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; 4290 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
4289 i::FLAG_weak_embedded_objects_in_optimized_code = true; 4291 i::FLAG_weak_embedded_objects_in_optimized_code = true;
4290 i::FLAG_allow_natives_syntax = true; 4292 i::FLAG_allow_natives_syntax = true;
(...skipping 20 matching lines...) Expand all
4311 4313
4312 Handle<JSFunction> bar = 4314 Handle<JSFunction> bar =
4313 v8::Utils::OpenHandle( 4315 v8::Utils::OpenHandle(
4314 *v8::Handle<v8::Function>::Cast( 4316 *v8::Handle<v8::Function>::Cast(
4315 CcTest::global()->Get(v8_str("bar")))); 4317 CcTest::global()->Get(v8_str("bar"))));
4316 code = scope.CloseAndEscape(Handle<Code>(bar->code())); 4318 code = scope.CloseAndEscape(Handle<Code>(bar->code()));
4317 } 4319 }
4318 4320
4319 // Now make sure that a gc should get rid of the function 4321 // Now make sure that a gc should get rid of the function
4320 for (int i = 0; i < 4; i++) { 4322 for (int i = 0; i < 4; i++) {
4321 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4323 heap->CollectAllGarbage();
4322 } 4324 }
4323 4325
4324 DCHECK(code->marked_for_deoptimization()); 4326 DCHECK(code->marked_for_deoptimization());
4325 } 4327 }
4326 4328
4327 4329
4328 TEST(NoWeakHashTableLeakWithIncrementalMarking) { 4330 TEST(NoWeakHashTableLeakWithIncrementalMarking) {
4329 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; 4331 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
4330 if (!i::FLAG_incremental_marking) return; 4332 if (!i::FLAG_incremental_marking) return;
4331 i::FLAG_weak_embedded_objects_in_optimized_code = true; 4333 i::FLAG_weak_embedded_objects_in_optimized_code = true;
(...skipping 18 matching lines...) Expand all
4350 "};" 4352 "};"
4351 "function foo%d(x) { with (x) { return 1 + x; } };" 4353 "function foo%d(x) { with (x) { return 1 + x; } };"
4352 "bar%d();" 4354 "bar%d();"
4353 "bar%d();" 4355 "bar%d();"
4354 "bar%d();" 4356 "bar%d();"
4355 "%%OptimizeFwunctionOnNextCall(bar%d);" 4357 "%%OptimizeFwunctionOnNextCall(bar%d);"
4356 "bar%d();", 4358 "bar%d();",
4357 i, i, i, i, i, i, i, i); 4359 i, i, i, i, i, i, i, i);
4358 CompileRun(source.start()); 4360 CompileRun(source.start());
4359 } 4361 }
4360 heap->CollectAllGarbage(i::Heap::kNoGCFlags); 4362 heap->CollectAllGarbage();
4361 } 4363 }
4362 int elements = 0; 4364 int elements = 0;
4363 if (heap->weak_object_to_code_table()->IsHashTable()) { 4365 if (heap->weak_object_to_code_table()->IsHashTable()) {
4364 WeakHashTable* t = WeakHashTable::cast(heap->weak_object_to_code_table()); 4366 WeakHashTable* t = WeakHashTable::cast(heap->weak_object_to_code_table());
4365 elements = t->NumberOfElements(); 4367 elements = t->NumberOfElements();
4366 } 4368 }
4367 CHECK_EQ(0, elements); 4369 CHECK_EQ(0, elements);
4368 } 4370 }
4369 4371
4370 4372
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4500 " function hat() { this.x = 5; }" 4502 " function hat() { this.x = 5; }"
4501 " createObj(hat);" 4503 " createObj(hat);"
4502 " createObj(hat);" 4504 " createObj(hat);"
4503 " return hat;" 4505 " return hat;"
4504 " })();"; 4506 " })();";
4505 garbage.Reset(isolate, CompileRun(source)->ToObject(isolate)); 4507 garbage.Reset(isolate, CompileRun(source)->ToObject(isolate));
4506 } 4508 }
4507 weak_ic_cleared = false; 4509 weak_ic_cleared = false;
4508 garbage.SetWeak(static_cast<void*>(&garbage), &ClearWeakIC); 4510 garbage.SetWeak(static_cast<void*>(&garbage), &ClearWeakIC);
4509 Heap* heap = CcTest::i_isolate()->heap(); 4511 Heap* heap = CcTest::i_isolate()->heap();
4510 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4512 heap->CollectAllGarbage();
4511 CHECK(weak_ic_cleared); 4513 CHECK(weak_ic_cleared);
4512 4514
4513 // We've determined the constructor in createObj has had it's weak cell 4515 // We've determined the constructor in createObj has had it's weak cell
4514 // cleared. Now, verify that one additional call with a new function 4516 // cleared. Now, verify that one additional call with a new function
4515 // allows monomorphicity. 4517 // allows monomorphicity.
4516 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>( 4518 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>(
4517 createObj->shared()->feedback_vector(), CcTest::i_isolate()); 4519 createObj->shared()->feedback_vector(), CcTest::i_isolate());
4518 for (int i = 0; i < 20; i++) { 4520 for (int i = 0; i < 20; i++) {
4519 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); 4521 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0));
4520 CHECK(slot_value->IsWeakCell()); 4522 CHECK(slot_value->IsWeakCell());
4521 if (WeakCell::cast(slot_value)->cleared()) break; 4523 if (WeakCell::cast(slot_value)->cleared()) break;
4522 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4524 heap->CollectAllGarbage();
4523 } 4525 }
4524 4526
4525 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); 4527 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0));
4526 CHECK(slot_value->IsWeakCell() && WeakCell::cast(slot_value)->cleared()); 4528 CHECK(slot_value->IsWeakCell() && WeakCell::cast(slot_value)->cleared());
4527 CompileRun( 4529 CompileRun(
4528 "function coat() { this.x = 6; }" 4530 "function coat() { this.x = 6; }"
4529 "createObj(coat);"); 4531 "createObj(coat);");
4530 slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); 4532 slot_value = feedback_vector->Get(FeedbackVectorSlot(0));
4531 CHECK(slot_value->IsWeakCell() && !WeakCell::cast(slot_value)->cleared()); 4533 CHECK(slot_value->IsWeakCell() && !WeakCell::cast(slot_value)->cleared());
4532 } 4534 }
4533 4535
4534 4536
4535 // Checks that the value returned by execution of the source is weak. 4537 // Checks that the value returned by execution of the source is weak.
4536 void CheckWeakness(const char* source) { 4538 void CheckWeakness(const char* source) {
4537 i::FLAG_stress_compaction = false; 4539 i::FLAG_stress_compaction = false;
4538 CcTest::InitializeVM(); 4540 CcTest::InitializeVM();
4539 v8::Isolate* isolate = CcTest::isolate(); 4541 v8::Isolate* isolate = CcTest::isolate();
4540 v8::HandleScope scope(isolate); 4542 v8::HandleScope scope(isolate);
4541 v8::Persistent<v8::Object> garbage; 4543 v8::Persistent<v8::Object> garbage;
4542 { 4544 {
4543 v8::HandleScope scope(isolate); 4545 v8::HandleScope scope(isolate);
4544 garbage.Reset(isolate, CompileRun(source)->ToObject(isolate)); 4546 garbage.Reset(isolate, CompileRun(source)->ToObject(isolate));
4545 } 4547 }
4546 weak_ic_cleared = false; 4548 weak_ic_cleared = false;
4547 garbage.SetWeak(static_cast<void*>(&garbage), &ClearWeakIC); 4549 garbage.SetWeak(static_cast<void*>(&garbage), &ClearWeakIC);
4548 Heap* heap = CcTest::i_isolate()->heap(); 4550 Heap* heap = CcTest::i_isolate()->heap();
4549 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4551 heap->CollectAllGarbage();
4550 CHECK(weak_ic_cleared); 4552 CHECK(weak_ic_cleared);
4551 } 4553 }
4552 4554
4553 4555
4554 // Each of the following "weak IC" tests creates an IC that embeds a map with 4556 // Each of the following "weak IC" tests creates an IC that embeds a map with
4555 // the prototype pointing to _proto_ and checks that the _proto_ dies on GC. 4557 // the prototype pointing to _proto_ and checks that the _proto_ dies on GC.
4556 TEST(WeakMapInMonomorphicLoadIC) { 4558 TEST(WeakMapInMonomorphicLoadIC) {
4557 CheckWeakness("function loadIC(obj) {" 4559 CheckWeakness("function loadIC(obj) {"
4558 " return obj.name;" 4560 " return obj.name;"
4559 "}" 4561 "}"
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
4753 " loadIC(obj);" 4755 " loadIC(obj);"
4754 " loadIC(obj);" 4756 " loadIC(obj);"
4755 " loadIC(obj);" 4757 " loadIC(obj);"
4756 " return proto;" 4758 " return proto;"
4757 "};"); 4759 "};");
4758 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC"); 4760 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC");
4759 { 4761 {
4760 v8::HandleScope scope(CcTest::isolate()); 4762 v8::HandleScope scope(CcTest::isolate());
4761 CompileRun("(testIC())"); 4763 CompileRun("(testIC())");
4762 } 4764 }
4763 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4765 heap->CollectAllGarbage();
4764 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC); 4766 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC);
4765 { 4767 {
4766 v8::HandleScope scope(CcTest::isolate()); 4768 v8::HandleScope scope(CcTest::isolate());
4767 CompileRun("(testIC())"); 4769 CompileRun("(testIC())");
4768 } 4770 }
4769 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC); 4771 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC);
4770 } 4772 }
4771 4773
4772 4774
4773 TEST(PolymorphicStaysPolymorphicAfterGC) { 4775 TEST(PolymorphicStaysPolymorphicAfterGC) {
(...skipping 15 matching lines...) Expand all
4789 " var poly = Object.create(proto);" 4791 " var poly = Object.create(proto);"
4790 " poly.x = true;" 4792 " poly.x = true;"
4791 " loadIC(poly);" 4793 " loadIC(poly);"
4792 " return proto;" 4794 " return proto;"
4793 "};"); 4795 "};");
4794 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC"); 4796 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC");
4795 { 4797 {
4796 v8::HandleScope scope(CcTest::isolate()); 4798 v8::HandleScope scope(CcTest::isolate());
4797 CompileRun("(testIC())"); 4799 CompileRun("(testIC())");
4798 } 4800 }
4799 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4801 heap->CollectAllGarbage();
4800 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC); 4802 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC);
4801 { 4803 {
4802 v8::HandleScope scope(CcTest::isolate()); 4804 v8::HandleScope scope(CcTest::isolate());
4803 CompileRun("(testIC())"); 4805 CompileRun("(testIC())");
4804 } 4806 }
4805 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC); 4807 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC);
4806 } 4808 }
4807 4809
4808 4810
4809 TEST(WeakCell) { 4811 TEST(WeakCell) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4857 i == 0 ? survivor : factory->NewFixedArray(1, NOT_TENURED); 4859 i == 0 ? survivor : factory->NewFixedArray(1, NOT_TENURED);
4858 Handle<WeakCell> weak_cell = factory->NewWeakCell(value); 4860 Handle<WeakCell> weak_cell = factory->NewWeakCell(value);
4859 CHECK(weak_cell->value()->IsFixedArray()); 4861 CHECK(weak_cell->value()->IsFixedArray());
4860 IncrementalMarking* marking = heap->incremental_marking(); 4862 IncrementalMarking* marking = heap->incremental_marking();
4861 if (marking->IsStopped()) marking->Start(); 4863 if (marking->IsStopped()) marking->Start();
4862 marking->Step(128, IncrementalMarking::NO_GC_VIA_STACK_GUARD); 4864 marking->Step(128, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
4863 heap->CollectGarbage(NEW_SPACE); 4865 heap->CollectGarbage(NEW_SPACE);
4864 CHECK(weak_cell->value()->IsFixedArray()); 4866 CHECK(weak_cell->value()->IsFixedArray());
4865 weak_cells[i] = inner_scope.CloseAndEscape(weak_cell); 4867 weak_cells[i] = inner_scope.CloseAndEscape(weak_cell);
4866 } 4868 }
4867 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4869 heap->CollectAllGarbage();
4868 CHECK_EQ(*survivor, weak_cells[0]->value()); 4870 CHECK_EQ(*survivor, weak_cells[0]->value());
4869 for (int i = 1; i < N; i++) { 4871 for (int i = 1; i < N; i++) {
4870 CHECK(weak_cells[i]->cleared()); 4872 CHECK(weak_cells[i]->cleared());
4871 } 4873 }
4872 } 4874 }
4873 4875
4874 4876
4875 #ifdef DEBUG 4877 #ifdef DEBUG
4876 TEST(AddInstructionChangesNewSpacePromotion) { 4878 TEST(AddInstructionChangesNewSpacePromotion) {
4877 i::FLAG_allow_natives_syntax = true; 4879 i::FLAG_allow_natives_syntax = true;
(...skipping 26 matching lines...) Expand all
4904 "%OptimizeFunctionOnNextCall(crash);" 4906 "%OptimizeFunctionOnNextCall(crash);"
4905 "crash(1);"); 4907 "crash(1);");
4906 4908
4907 v8::Handle<v8::Object> global = CcTest::global(); 4909 v8::Handle<v8::Object> global = CcTest::global();
4908 v8::Handle<v8::Function> g = 4910 v8::Handle<v8::Function> g =
4909 v8::Handle<v8::Function>::Cast(global->Get(v8_str("crash"))); 4911 v8::Handle<v8::Function>::Cast(global->Get(v8_str("crash")));
4910 v8::Handle<v8::Value> args1[] = { v8_num(1) }; 4912 v8::Handle<v8::Value> args1[] = { v8_num(1) };
4911 heap->DisableInlineAllocation(); 4913 heap->DisableInlineAllocation();
4912 heap->set_allocation_timeout(1); 4914 heap->set_allocation_timeout(1);
4913 g->Call(global, 1, args1); 4915 g->Call(global, 1, args1);
4914 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4916 heap->CollectAllGarbage();
4915 } 4917 }
4916 4918
4917 4919
4918 void OnFatalErrorExpectOOM(const char* location, const char* message) { 4920 void OnFatalErrorExpectOOM(const char* location, const char* message) {
4919 // Exit with 0 if the location matches our expectation. 4921 // Exit with 0 if the location matches our expectation.
4920 exit(strcmp(location, "CALL_AND_RETRY_LAST")); 4922 exit(strcmp(location, "CALL_AND_RETRY_LAST"));
4921 } 4923 }
4922 4924
4923 4925
4924 TEST(CEntryStubOOM) { 4926 TEST(CEntryStubOOM) {
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
5215 Handle<JSObject> proto = 5217 Handle<JSObject> proto =
5216 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result)); 5218 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result));
5217 weak_prototype = inner_scope.CloseAndEscape(factory->NewWeakCell(proto)); 5219 weak_prototype = inner_scope.CloseAndEscape(factory->NewWeakCell(proto));
5218 } 5220 }
5219 CHECK(!weak_prototype->cleared()); 5221 CHECK(!weak_prototype->cleared());
5220 CompileRun( 5222 CompileRun(
5221 "var a = { };" 5223 "var a = { };"
5222 "a.x = new cls();" 5224 "a.x = new cls();"
5223 "cls.prototype = null;"); 5225 "cls.prototype = null;");
5224 for (int i = 0; i < 4; i++) { 5226 for (int i = 0; i < 4; i++) {
5225 heap->CollectAllGarbage(Heap::kNoGCFlags); 5227 heap->CollectAllGarbage();
5226 } 5228 }
5227 // The map of a.x keeps prototype alive 5229 // The map of a.x keeps prototype alive
5228 CHECK(!weak_prototype->cleared()); 5230 CHECK(!weak_prototype->cleared());
5229 // Change the map of a.x and make the previous map garbage collectable. 5231 // Change the map of a.x and make the previous map garbage collectable.
5230 CompileRun("a.x.__proto__ = {};"); 5232 CompileRun("a.x.__proto__ = {};");
5231 for (int i = 0; i < 4; i++) { 5233 for (int i = 0; i < 4; i++) {
5232 heap->CollectAllGarbage(Heap::kNoGCFlags); 5234 heap->CollectAllGarbage();
5233 } 5235 }
5234 CHECK(weak_prototype->cleared()); 5236 CHECK(weak_prototype->cleared());
5235 } 5237 }
5236 5238
5237 5239
5238 Handle<WeakCell> AddRetainedMap(Isolate* isolate, Heap* heap) { 5240 Handle<WeakCell> AddRetainedMap(Isolate* isolate, Heap* heap) {
5239 HandleScope inner_scope(isolate); 5241 HandleScope inner_scope(isolate);
5240 Handle<Map> map = Map::Create(isolate, 1); 5242 Handle<Map> map = Map::Create(isolate, 1);
5241 v8::Local<v8::Value> result = 5243 v8::Local<v8::Value> result =
5242 CompileRun("(function () { return {x : 10}; })();"); 5244 CompileRun("(function () { return {x : 10}; })();");
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
5360 TestRightTrimFixedTypedArray(i::kExternalUint32Array, 8, 6); 5362 TestRightTrimFixedTypedArray(i::kExternalUint32Array, 8, 6);
5361 TestRightTrimFixedTypedArray(i::kExternalUint32Array, 8 - 1, 6); 5363 TestRightTrimFixedTypedArray(i::kExternalUint32Array, 8 - 1, 6);
5362 5364
5363 // 32-bit cases. 5365 // 32-bit cases.
5364 TestRightTrimFixedTypedArray(i::kExternalUint8Array, 16, 3); 5366 TestRightTrimFixedTypedArray(i::kExternalUint8Array, 16, 3);
5365 TestRightTrimFixedTypedArray(i::kExternalUint8Array, 16 - 3, 3); 5367 TestRightTrimFixedTypedArray(i::kExternalUint8Array, 16 - 3, 3);
5366 TestRightTrimFixedTypedArray(i::kExternalUint16Array, 8, 3); 5368 TestRightTrimFixedTypedArray(i::kExternalUint16Array, 8, 3);
5367 TestRightTrimFixedTypedArray(i::kExternalUint16Array, 8 - 1, 3); 5369 TestRightTrimFixedTypedArray(i::kExternalUint16Array, 8 - 1, 3);
5368 TestRightTrimFixedTypedArray(i::kExternalUint32Array, 4, 3); 5370 TestRightTrimFixedTypedArray(i::kExternalUint32Array, 4, 3);
5369 } 5371 }
OLDNEW
« no previous file with comments | « test/cctest/test-feedback-vector.cc ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698