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

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

Issue 1088083002: Revert of 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(); 455 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
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(); 950 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
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(); 1051 i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
1052 i_isolate->heap()->CollectAllGarbage(); 1052 i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
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(); 1058 i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
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(); 1104 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
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(); 1109 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
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(); 1119 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
1120 CcTest::heap()->CollectAllGarbage(); 1120 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
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(); 1126 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
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(); 1169 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
1170 CcTest::heap()->CollectAllGarbage(); 1170 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
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(); 1177 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1192 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1202 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1231 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
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(); 1271 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1308 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
1309 heap->CollectAllGarbage(); 1309 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
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(); 1336 heap->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1391 heap->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1403 heap->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1503 heap->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1535 heap->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1544 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1551 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1559 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1575 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1591 if (count == n) heap->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1613 if (count == n) isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1696 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
1697 CcTest::heap()->CollectAllGarbage(); 1697 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
1698 CcTest::heap()->CollectAllGarbage(); 1698 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
1699 CcTest::heap()->CollectAllGarbage(); 1699 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
1700 CcTest::heap()->CollectAllGarbage(); 1700 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1708 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1712 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1732 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
1733 CcTest::heap()->CollectAllGarbage(); 1733 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
1734 CcTest::heap()->CollectAllGarbage(); 1734 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
1735 CcTest::heap()->CollectAllGarbage(); 1735 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
1736 CcTest::heap()->CollectAllGarbage(); 1736 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 1758 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 2180 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
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::kFinalizeIncrementalMarkingMask, 2262 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags,
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(); 2936 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 3119 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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(); 3163 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
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::kFinalizeIncrementalMarkingMask, 3201 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask,
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::kFinalizeIncrementalMarkingMask, 3207 heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 1");
3208 "triggered by test 1");
3209 CHECK_GE(number_of_test_pages + 1, old_space->CountTotalPages()); 3208 CHECK_GE(number_of_test_pages + 1, old_space->CountTotalPages());
3210 heap->CollectAllGarbage(Heap::kFinalizeIncrementalMarkingMask, 3209 heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered by test 2");
3211 "triggered by test 2");
3212 CHECK_GE(number_of_test_pages + 1, old_space->CountTotalPages() * 2); 3210 CHECK_GE(number_of_test_pages + 1, old_space->CountTotalPages() * 2);
3213 3211
3214 // Triggering a last-resort GC should cause all pages to be released to the 3212 // Triggering a last-resort GC should cause all pages to be released to the
3215 // OS so that other processes can seize the memory. If we get a failure here 3213 // OS so that other processes can seize the memory. If we get a failure here
3216 // where there are 2 pages left instead of 1, then we should increase the 3214 // where there are 2 pages left instead of 1, then we should increase the
3217 // size of the first page a little in SizeOfFirstPage in spaces.cc. The 3215 // size of the first page a little in SizeOfFirstPage in spaces.cc. The
3218 // first page should be small in order to reduce memory used when the VM 3216 // first page should be small in order to reduce memory used when the VM
3219 // boots, but if the 20 small arrays don't fit on the first page then that's 3217 // boots, but if the 20 small arrays don't fit on the first page then that's
3220 // an indication that it is too small. 3218 // an indication that it is too small.
3221 heap->CollectAllAvailableGarbage("triggered really hard"); 3219 heap->CollectAllAvailableGarbage("triggered really hard");
(...skipping 21 matching lines...) Expand all
3243 // lives in old-space. 3241 // lives in old-space.
3244 SimulateFullSpace(CcTest::heap()->new_space()); 3242 SimulateFullSpace(CcTest::heap()->new_space());
3245 AlwaysAllocateScope always_allocate(isolate); 3243 AlwaysAllocateScope always_allocate(isolate);
3246 Handle<String> t = factory->NewProperSubString(s, 5, 35); 3244 Handle<String> t = factory->NewProperSubString(s, 5, 35);
3247 CHECK(t->IsSlicedString()); 3245 CHECK(t->IsSlicedString());
3248 CHECK(!CcTest::heap()->InNewSpace(*t)); 3246 CHECK(!CcTest::heap()->InNewSpace(*t));
3249 *slice.location() = *t.location(); 3247 *slice.location() = *t.location();
3250 } 3248 }
3251 3249
3252 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); 3250 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString());
3253 CcTest::heap()->CollectAllGarbage(); 3251 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
3254 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString()); 3252 CHECK(SlicedString::cast(*slice)->parent()->IsSeqOneByteString());
3255 } 3253 }
3256 3254
3257 3255
3258 #ifdef OBJECT_PRINT 3256 #ifdef OBJECT_PRINT
3259 TEST(PrintSharedFunctionInfo) { 3257 TEST(PrintSharedFunctionInfo) {
3260 CcTest::InitializeVM(); 3258 CcTest::InitializeVM();
3261 v8::HandleScope scope(CcTest::isolate()); 3259 v8::HandleScope scope(CcTest::isolate());
3262 const char* source = "f = function() { return 987654321; }\n" 3260 const char* source = "f = function() { return 987654321; }\n"
3263 "g = function() { return 123456789; }\n"; 3261 "g = function() { return 123456789; }\n";
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3341 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); 3339 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector());
3342 3340
3343 int expected_slots = 2; 3341 int expected_slots = 2;
3344 CHECK_EQ(expected_slots, feedback_vector->ICSlots()); 3342 CHECK_EQ(expected_slots, feedback_vector->ICSlots());
3345 int slot1 = 0; 3343 int slot1 = 0;
3346 int slot2 = 1; 3344 int slot2 = 1;
3347 CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot1))->IsWeakCell()); 3345 CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot1))->IsWeakCell());
3348 CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot2))->IsWeakCell()); 3346 CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot2))->IsWeakCell());
3349 3347
3350 SimulateIncrementalMarking(CcTest::heap()); 3348 SimulateIncrementalMarking(CcTest::heap());
3351 CcTest::heap()->CollectAllGarbage(); 3349 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
3352 3350
3353 CHECK(!WeakCell::cast(feedback_vector->Get(FeedbackVectorICSlot(slot1))) 3351 CHECK(!WeakCell::cast(feedback_vector->Get(FeedbackVectorICSlot(slot1)))
3354 ->cleared()); 3352 ->cleared());
3355 CHECK(!WeakCell::cast(feedback_vector->Get(FeedbackVectorICSlot(slot2))) 3353 CHECK(!WeakCell::cast(feedback_vector->Get(FeedbackVectorICSlot(slot2)))
3356 ->cleared()); 3354 ->cleared());
3357 } 3355 }
3358 3356
3359 3357
3360 static Code* FindFirstIC(Code* code, Code::Kind kind) { 3358 static Code* FindFirstIC(Code* code, Code::Kind kind) {
3361 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | 3359 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3402 "function fun() { this.x = 1; };" 3400 "function fun() { this.x = 1; };"
3403 "function f(o) { return new o(); } f(fun); f(fun);"); 3401 "function f(o) { return new o(); } f(fun); f(fun);");
3404 Handle<JSFunction> f = v8::Utils::OpenHandle( 3402 Handle<JSFunction> f = v8::Utils::OpenHandle(
3405 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f")))); 3403 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
3406 3404
3407 3405
3408 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector()); 3406 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector());
3409 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); 3407 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell());
3410 3408
3411 SimulateIncrementalMarking(CcTest::heap()); 3409 SimulateIncrementalMarking(CcTest::heap());
3412 CcTest::heap()->CollectAllGarbage(); 3410 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
3413 3411
3414 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); 3412 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell());
3415 } 3413 }
3416 3414
3417 3415
3418 TEST(IncrementalMarkingClearsMonomorphicConstructor) { 3416 TEST(IncrementalMarkingClearsMonomorphicConstructor) {
3419 if (i::FLAG_always_opt) return; 3417 if (i::FLAG_always_opt) return;
3420 CcTest::InitializeVM(); 3418 CcTest::InitializeVM();
3421 Isolate* isolate = CcTest::i_isolate(); 3419 Isolate* isolate = CcTest::i_isolate();
3422 v8::HandleScope scope(CcTest::isolate()); 3420 v8::HandleScope scope(CcTest::isolate());
(...skipping 14 matching lines...) Expand all
3437 Handle<JSFunction> f = v8::Utils::OpenHandle( 3435 Handle<JSFunction> f = v8::Utils::OpenHandle(
3438 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f")))); 3436 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
3439 3437
3440 3438
3441 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector()); 3439 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector());
3442 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); 3440 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell());
3443 3441
3444 // Fire context dispose notification. 3442 // Fire context dispose notification.
3445 CcTest::isolate()->ContextDisposedNotification(); 3443 CcTest::isolate()->ContextDisposedNotification();
3446 SimulateIncrementalMarking(CcTest::heap()); 3444 SimulateIncrementalMarking(CcTest::heap());
3447 CcTest::heap()->CollectAllGarbage(); 3445 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
3448 3446
3449 CHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(isolate), 3447 CHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(isolate),
3450 vector->Get(FeedbackVectorSlot(0))); 3448 vector->Get(FeedbackVectorSlot(0)));
3451 } 3449 }
3452 3450
3453 3451
3454 TEST(IncrementalMarkingPreservesMonomorphicIC) { 3452 TEST(IncrementalMarkingPreservesMonomorphicIC) {
3455 if (i::FLAG_always_opt) return; 3453 if (i::FLAG_always_opt) return;
3456 CcTest::InitializeVM(); 3454 CcTest::InitializeVM();
3457 v8::HandleScope scope(CcTest::isolate()); 3455 v8::HandleScope scope(CcTest::isolate());
3458 3456
3459 // Prepare function f that contains a monomorphic IC for object 3457 // Prepare function f that contains a monomorphic IC for object
3460 // originating from the same native context. 3458 // originating from the same native context.
3461 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" 3459 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"
3462 "function f(o) { return o.x; } f(obj); f(obj);"); 3460 "function f(o) { return o.x; } f(obj); f(obj);");
3463 Handle<JSFunction> f = 3461 Handle<JSFunction> f =
3464 v8::Utils::OpenHandle( 3462 v8::Utils::OpenHandle(
3465 *v8::Handle<v8::Function>::Cast( 3463 *v8::Handle<v8::Function>::Cast(
3466 CcTest::global()->Get(v8_str("f")))); 3464 CcTest::global()->Get(v8_str("f"))));
3467 3465
3468 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3466 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3469 if (FLAG_vector_ics) { 3467 if (FLAG_vector_ics) {
3470 CheckVectorIC(f, 0, MONOMORPHIC); 3468 CheckVectorIC(f, 0, MONOMORPHIC);
3471 CHECK(ic_before->ic_state() == DEFAULT); 3469 CHECK(ic_before->ic_state() == DEFAULT);
3472 } else { 3470 } else {
3473 CHECK(ic_before->ic_state() == MONOMORPHIC); 3471 CHECK(ic_before->ic_state() == MONOMORPHIC);
3474 } 3472 }
3475 3473
3476 SimulateIncrementalMarking(CcTest::heap()); 3474 SimulateIncrementalMarking(CcTest::heap());
3477 CcTest::heap()->CollectAllGarbage(); 3475 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
3478 3476
3479 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3477 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3480 if (FLAG_vector_ics) { 3478 if (FLAG_vector_ics) {
3481 CheckVectorIC(f, 0, MONOMORPHIC); 3479 CheckVectorIC(f, 0, MONOMORPHIC);
3482 CHECK(ic_after->ic_state() == DEFAULT); 3480 CHECK(ic_after->ic_state() == DEFAULT);
3483 } else { 3481 } else {
3484 CHECK(ic_after->ic_state() == MONOMORPHIC); 3482 CHECK(ic_after->ic_state() == MONOMORPHIC);
3485 } 3483 }
3486 } 3484 }
3487 3485
(...skipping 21 matching lines...) Expand all
3509 if (FLAG_vector_ics) { 3507 if (FLAG_vector_ics) {
3510 CheckVectorIC(f, 0, MONOMORPHIC); 3508 CheckVectorIC(f, 0, MONOMORPHIC);
3511 CHECK(ic_before->ic_state() == DEFAULT); 3509 CHECK(ic_before->ic_state() == DEFAULT);
3512 } else { 3510 } else {
3513 CHECK(ic_before->ic_state() == MONOMORPHIC); 3511 CHECK(ic_before->ic_state() == MONOMORPHIC);
3514 } 3512 }
3515 3513
3516 // Fire context dispose notification. 3514 // Fire context dispose notification.
3517 CcTest::isolate()->ContextDisposedNotification(); 3515 CcTest::isolate()->ContextDisposedNotification();
3518 SimulateIncrementalMarking(CcTest::heap()); 3516 SimulateIncrementalMarking(CcTest::heap());
3519 CcTest::heap()->CollectAllGarbage(); 3517 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
3520 3518
3521 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3519 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3522 if (FLAG_vector_ics) { 3520 if (FLAG_vector_ics) {
3523 CheckVectorICCleared(f, 0); 3521 CheckVectorICCleared(f, 0);
3524 CHECK(ic_after->ic_state() == DEFAULT); 3522 CHECK(ic_after->ic_state() == DEFAULT);
3525 } else { 3523 } else {
3526 CHECK(IC::IsCleared(ic_after)); 3524 CHECK(IC::IsCleared(ic_after));
3527 } 3525 }
3528 } 3526 }
3529 3527
(...skipping 27 matching lines...) Expand all
3557 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3555 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3558 if (FLAG_vector_ics) { 3556 if (FLAG_vector_ics) {
3559 CheckVectorIC(f, 0, POLYMORPHIC); 3557 CheckVectorIC(f, 0, POLYMORPHIC);
3560 CHECK(ic_before->ic_state() == DEFAULT); 3558 CHECK(ic_before->ic_state() == DEFAULT);
3561 } else { 3559 } else {
3562 CHECK(ic_before->ic_state() == POLYMORPHIC); 3560 CHECK(ic_before->ic_state() == POLYMORPHIC);
3563 } 3561 }
3564 3562
3565 // Fire context dispose notification. 3563 // Fire context dispose notification.
3566 SimulateIncrementalMarking(CcTest::heap()); 3564 SimulateIncrementalMarking(CcTest::heap());
3567 CcTest::heap()->CollectAllGarbage(); 3565 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
3568 3566
3569 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3567 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3570 if (FLAG_vector_ics) { 3568 if (FLAG_vector_ics) {
3571 CheckVectorIC(f, 0, POLYMORPHIC); 3569 CheckVectorIC(f, 0, POLYMORPHIC);
3572 CHECK(ic_after->ic_state() == DEFAULT); 3570 CHECK(ic_after->ic_state() == DEFAULT);
3573 } else { 3571 } else {
3574 CHECK(ic_after->ic_state() == POLYMORPHIC); 3572 CHECK(ic_after->ic_state() == POLYMORPHIC);
3575 } 3573 }
3576 } 3574 }
3577 3575
(...skipping 28 matching lines...) Expand all
3606 if (FLAG_vector_ics) { 3604 if (FLAG_vector_ics) {
3607 CheckVectorIC(f, 0, POLYMORPHIC); 3605 CheckVectorIC(f, 0, POLYMORPHIC);
3608 CHECK(ic_before->ic_state() == DEFAULT); 3606 CHECK(ic_before->ic_state() == DEFAULT);
3609 } else { 3607 } else {
3610 CHECK(ic_before->ic_state() == POLYMORPHIC); 3608 CHECK(ic_before->ic_state() == POLYMORPHIC);
3611 } 3609 }
3612 3610
3613 // Fire context dispose notification. 3611 // Fire context dispose notification.
3614 CcTest::isolate()->ContextDisposedNotification(); 3612 CcTest::isolate()->ContextDisposedNotification();
3615 SimulateIncrementalMarking(CcTest::heap()); 3613 SimulateIncrementalMarking(CcTest::heap());
3616 CcTest::heap()->CollectAllGarbage(); 3614 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
3617 3615
3618 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3616 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3619 if (FLAG_vector_ics) { 3617 if (FLAG_vector_ics) {
3620 CheckVectorICCleared(f, 0); 3618 CheckVectorICCleared(f, 0);
3621 CHECK(ic_before->ic_state() == DEFAULT); 3619 CHECK(ic_before->ic_state() == DEFAULT);
3622 } else { 3620 } else {
3623 CHECK(IC::IsCleared(ic_after)); 3621 CHECK(IC::IsCleared(ic_after));
3624 } 3622 }
3625 } 3623 }
3626 3624
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
3735 3733
3736 TEST(Regress159140) { 3734 TEST(Regress159140) {
3737 i::FLAG_allow_natives_syntax = true; 3735 i::FLAG_allow_natives_syntax = true;
3738 i::FLAG_flush_code_incrementally = true; 3736 i::FLAG_flush_code_incrementally = true;
3739 CcTest::InitializeVM(); 3737 CcTest::InitializeVM();
3740 Isolate* isolate = CcTest::i_isolate(); 3738 Isolate* isolate = CcTest::i_isolate();
3741 Heap* heap = isolate->heap(); 3739 Heap* heap = isolate->heap();
3742 HandleScope scope(isolate); 3740 HandleScope scope(isolate);
3743 3741
3744 // Perform one initial GC to enable code flushing. 3742 // Perform one initial GC to enable code flushing.
3745 heap->CollectAllGarbage(); 3743 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
3746 3744
3747 // Prepare several closures that are all eligible for code flushing 3745 // Prepare several closures that are all eligible for code flushing
3748 // because all reachable ones are not optimized. Make sure that the 3746 // because all reachable ones are not optimized. Make sure that the
3749 // optimized code object is directly reachable through a handle so 3747 // optimized code object is directly reachable through a handle so
3750 // that it is marked black during incremental marking. 3748 // that it is marked black during incremental marking.
3751 Handle<Code> code; 3749 Handle<Code> code;
3752 { 3750 {
3753 HandleScope inner_scope(isolate); 3751 HandleScope inner_scope(isolate);
3754 CompileRun("function h(x) {}" 3752 CompileRun("function h(x) {}"
3755 "function mkClosure() {" 3753 "function mkClosure() {"
(...skipping 25 matching lines...) Expand all
3781 } 3779 }
3782 3780
3783 code = inner_scope.CloseAndEscape(Handle<Code>(f->code())); 3781 code = inner_scope.CloseAndEscape(Handle<Code>(f->code()));
3784 } 3782 }
3785 3783
3786 // Simulate incremental marking so that the functions are enqueued as 3784 // Simulate incremental marking so that the functions are enqueued as
3787 // code flushing candidates. Then optimize one function. Finally 3785 // code flushing candidates. Then optimize one function. Finally
3788 // finish the GC to complete code flushing. 3786 // finish the GC to complete code flushing.
3789 SimulateIncrementalMarking(heap); 3787 SimulateIncrementalMarking(heap);
3790 CompileRun("%OptimizeFunctionOnNextCall(g); g(3);"); 3788 CompileRun("%OptimizeFunctionOnNextCall(g); g(3);");
3791 heap->CollectAllGarbage(); 3789 heap->CollectAllGarbage(Heap::kNoGCFlags);
3792 3790
3793 // Unoptimized code is missing and the deoptimizer will go ballistic. 3791 // Unoptimized code is missing and the deoptimizer will go ballistic.
3794 CompileRun("g('bozo');"); 3792 CompileRun("g('bozo');");
3795 } 3793 }
3796 3794
3797 3795
3798 TEST(Regress165495) { 3796 TEST(Regress165495) {
3799 i::FLAG_allow_natives_syntax = true; 3797 i::FLAG_allow_natives_syntax = true;
3800 i::FLAG_flush_code_incrementally = true; 3798 i::FLAG_flush_code_incrementally = true;
3801 CcTest::InitializeVM(); 3799 CcTest::InitializeVM();
3802 Isolate* isolate = CcTest::i_isolate(); 3800 Isolate* isolate = CcTest::i_isolate();
3803 Heap* heap = isolate->heap(); 3801 Heap* heap = isolate->heap();
3804 HandleScope scope(isolate); 3802 HandleScope scope(isolate);
3805 3803
3806 // Perform one initial GC to enable code flushing. 3804 // Perform one initial GC to enable code flushing.
3807 heap->CollectAllGarbage(); 3805 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
3808 3806
3809 // Prepare an optimized closure that the optimized code map will get 3807 // Prepare an optimized closure that the optimized code map will get
3810 // populated. Then age the unoptimized code to trigger code flushing 3808 // populated. Then age the unoptimized code to trigger code flushing
3811 // but make sure the optimized code is unreachable. 3809 // but make sure the optimized code is unreachable.
3812 { 3810 {
3813 HandleScope inner_scope(isolate); 3811 HandleScope inner_scope(isolate);
3814 CompileRun("function mkClosure() {" 3812 CompileRun("function mkClosure() {"
3815 " return function(x) { return x + 1; };" 3813 " return function(x) { return x + 1; };"
3816 "}" 3814 "}"
3817 "var f = mkClosure();" 3815 "var f = mkClosure();"
3818 "f(1); f(2);" 3816 "f(1); f(2);"
3819 "%OptimizeFunctionOnNextCall(f); f(3);"); 3817 "%OptimizeFunctionOnNextCall(f); f(3);");
3820 3818
3821 Handle<JSFunction> f = 3819 Handle<JSFunction> f =
3822 v8::Utils::OpenHandle( 3820 v8::Utils::OpenHandle(
3823 *v8::Handle<v8::Function>::Cast( 3821 *v8::Handle<v8::Function>::Cast(
3824 CcTest::global()->Get(v8_str("f")))); 3822 CcTest::global()->Get(v8_str("f"))));
3825 CHECK(f->is_compiled()); 3823 CHECK(f->is_compiled());
3826 const int kAgingThreshold = 6; 3824 const int kAgingThreshold = 6;
3827 for (int i = 0; i < kAgingThreshold; i++) { 3825 for (int i = 0; i < kAgingThreshold; i++) {
3828 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); 3826 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
3829 } 3827 }
3830 3828
3831 CompileRun("f = null;"); 3829 CompileRun("f = null;");
3832 } 3830 }
3833 3831
3834 // Simulate incremental marking so that unoptimized code is flushed 3832 // Simulate incremental marking so that unoptimized code is flushed
3835 // even though it still is cached in the optimized code map. 3833 // even though it still is cached in the optimized code map.
3836 SimulateIncrementalMarking(heap); 3834 SimulateIncrementalMarking(heap);
3837 heap->CollectAllGarbage(); 3835 heap->CollectAllGarbage(Heap::kNoGCFlags);
3838 3836
3839 // Make a new closure that will get code installed from the code map. 3837 // Make a new closure that will get code installed from the code map.
3840 // Unoptimized code is missing and the deoptimizer will go ballistic. 3838 // Unoptimized code is missing and the deoptimizer will go ballistic.
3841 CompileRun("var g = mkClosure(); g('bozo');"); 3839 CompileRun("var g = mkClosure(); g('bozo');");
3842 } 3840 }
3843 3841
3844 3842
3845 TEST(Regress169209) { 3843 TEST(Regress169209) {
3846 i::FLAG_stress_compaction = false; 3844 i::FLAG_stress_compaction = false;
3847 i::FLAG_allow_natives_syntax = true; 3845 i::FLAG_allow_natives_syntax = true;
3848 i::FLAG_flush_code_incrementally = true; 3846 i::FLAG_flush_code_incrementally = true;
3849 3847
3850 CcTest::InitializeVM(); 3848 CcTest::InitializeVM();
3851 Isolate* isolate = CcTest::i_isolate(); 3849 Isolate* isolate = CcTest::i_isolate();
3852 Heap* heap = isolate->heap(); 3850 Heap* heap = isolate->heap();
3853 HandleScope scope(isolate); 3851 HandleScope scope(isolate);
3854 3852
3855 // Perform one initial GC to enable code flushing. 3853 // Perform one initial GC to enable code flushing.
3856 heap->CollectAllGarbage(); 3854 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
3857 3855
3858 // Prepare a shared function info eligible for code flushing for which 3856 // Prepare a shared function info eligible for code flushing for which
3859 // the unoptimized code will be replaced during optimization. 3857 // the unoptimized code will be replaced during optimization.
3860 Handle<SharedFunctionInfo> shared1; 3858 Handle<SharedFunctionInfo> shared1;
3861 { 3859 {
3862 HandleScope inner_scope(isolate); 3860 HandleScope inner_scope(isolate);
3863 CompileRun("function f() { return 'foobar'; }" 3861 CompileRun("function f() { return 'foobar'; }"
3864 "function g(x) { if (x) f(); }" 3862 "function g(x) { if (x) f(); }"
3865 "f();" 3863 "f();"
3866 "g(false);" 3864 "g(false);"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3905 CHECK(shared1->code()->gc_metadata() != NULL); 3903 CHECK(shared1->code()->gc_metadata() != NULL);
3906 3904
3907 // Optimize function and make sure the unoptimized code is replaced. 3905 // Optimize function and make sure the unoptimized code is replaced.
3908 #ifdef DEBUG 3906 #ifdef DEBUG
3909 FLAG_stop_at = "f"; 3907 FLAG_stop_at = "f";
3910 #endif 3908 #endif
3911 CompileRun("%OptimizeFunctionOnNextCall(g);" 3909 CompileRun("%OptimizeFunctionOnNextCall(g);"
3912 "g(false);"); 3910 "g(false);");
3913 3911
3914 // Finish garbage collection cycle. 3912 // Finish garbage collection cycle.
3915 heap->CollectAllGarbage(); 3913 heap->CollectAllGarbage(Heap::kNoGCFlags);
3916 CHECK(shared1->code()->gc_metadata() == NULL); 3914 CHECK(shared1->code()->gc_metadata() == NULL);
3917 } 3915 }
3918 3916
3919 3917
3920 TEST(Regress169928) { 3918 TEST(Regress169928) {
3921 i::FLAG_allow_natives_syntax = true; 3919 i::FLAG_allow_natives_syntax = true;
3922 i::FLAG_crankshaft = false; 3920 i::FLAG_crankshaft = false;
3923 CcTest::InitializeVM(); 3921 CcTest::InitializeVM();
3924 Isolate* isolate = CcTest::i_isolate(); 3922 Isolate* isolate = CcTest::i_isolate();
3925 Factory* factory = isolate->factory(); 3923 Factory* factory = isolate->factory();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3994 i::FLAG_always_compact = true; 3992 i::FLAG_always_compact = true;
3995 i::FLAG_cache_optimized_code = false; 3993 i::FLAG_cache_optimized_code = false;
3996 i::FLAG_allow_natives_syntax = true; 3994 i::FLAG_allow_natives_syntax = true;
3997 i::FLAG_flush_code_incrementally = true; 3995 i::FLAG_flush_code_incrementally = true;
3998 CcTest::InitializeVM(); 3996 CcTest::InitializeVM();
3999 Isolate* isolate = CcTest::i_isolate(); 3997 Isolate* isolate = CcTest::i_isolate();
4000 Heap* heap = isolate->heap(); 3998 Heap* heap = isolate->heap();
4001 HandleScope scope(isolate); 3999 HandleScope scope(isolate);
4002 4000
4003 // Perform one initial GC to enable code flushing. 4001 // Perform one initial GC to enable code flushing.
4004 heap->CollectAllGarbage(); 4002 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
4005 4003
4006 // Ensure the code ends up on an evacuation candidate. 4004 // Ensure the code ends up on an evacuation candidate.
4007 SimulateFullSpace(heap->code_space()); 4005 SimulateFullSpace(heap->code_space());
4008 4006
4009 // Prepare an unoptimized function that is eligible for code flushing. 4007 // Prepare an unoptimized function that is eligible for code flushing.
4010 Handle<JSFunction> function; 4008 Handle<JSFunction> function;
4011 { 4009 {
4012 HandleScope inner_scope(isolate); 4010 HandleScope inner_scope(isolate);
4013 CompileRun("function mkClosure() {" 4011 CompileRun("function mkClosure() {"
4014 " return function(x) { return x + 1; };" 4012 " return function(x) { return x + 1; };"
(...skipping 19 matching lines...) Expand all
4034 // explicitly enqueued. 4032 // explicitly enqueued.
4035 SimulateIncrementalMarking(heap); 4033 SimulateIncrementalMarking(heap);
4036 4034
4037 // Now optimize the function so that it is taken off the candidate list. 4035 // Now optimize the function so that it is taken off the candidate list.
4038 { 4036 {
4039 HandleScope inner_scope(isolate); 4037 HandleScope inner_scope(isolate);
4040 CompileRun("%OptimizeFunctionOnNextCall(f); f(3);"); 4038 CompileRun("%OptimizeFunctionOnNextCall(f); f(3);");
4041 } 4039 }
4042 4040
4043 // This cycle will bust the heap and subsequent cycles will go ballistic. 4041 // This cycle will bust the heap and subsequent cycles will go ballistic.
4044 heap->CollectAllGarbage(); 4042 heap->CollectAllGarbage(Heap::kNoGCFlags);
4045 heap->CollectAllGarbage(); 4043 heap->CollectAllGarbage(Heap::kNoGCFlags);
4046 } 4044 }
4047 4045
4048 4046
4049 TEST(Regress173458) { 4047 TEST(Regress173458) {
4050 if (i::FLAG_never_compact) return; 4048 if (i::FLAG_never_compact) return;
4051 i::FLAG_always_compact = true; 4049 i::FLAG_always_compact = true;
4052 i::FLAG_cache_optimized_code = false; 4050 i::FLAG_cache_optimized_code = false;
4053 i::FLAG_allow_natives_syntax = true; 4051 i::FLAG_allow_natives_syntax = true;
4054 i::FLAG_flush_code_incrementally = true; 4052 i::FLAG_flush_code_incrementally = true;
4055 CcTest::InitializeVM(); 4053 CcTest::InitializeVM();
4056 Isolate* isolate = CcTest::i_isolate(); 4054 Isolate* isolate = CcTest::i_isolate();
4057 Heap* heap = isolate->heap(); 4055 Heap* heap = isolate->heap();
4058 HandleScope scope(isolate); 4056 HandleScope scope(isolate);
4059 4057
4060 // Perform one initial GC to enable code flushing. 4058 // Perform one initial GC to enable code flushing.
4061 heap->CollectAllGarbage(); 4059 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
4062 4060
4063 // Ensure the code ends up on an evacuation candidate. 4061 // Ensure the code ends up on an evacuation candidate.
4064 SimulateFullSpace(heap->code_space()); 4062 SimulateFullSpace(heap->code_space());
4065 4063
4066 // Prepare an unoptimized function that is eligible for code flushing. 4064 // Prepare an unoptimized function that is eligible for code flushing.
4067 Handle<JSFunction> function; 4065 Handle<JSFunction> function;
4068 { 4066 {
4069 HandleScope inner_scope(isolate); 4067 HandleScope inner_scope(isolate);
4070 CompileRun("function mkClosure() {" 4068 CompileRun("function mkClosure() {"
4071 " return function(x) { return x + 1; };" 4069 " return function(x) { return x + 1; };"
(...skipping 16 matching lines...) Expand all
4088 4086
4089 // Simulate incremental marking so that unoptimized function is enqueued as a 4087 // Simulate incremental marking so that unoptimized function is enqueued as a
4090 // candidate for code flushing. The shared function info however will not be 4088 // candidate for code flushing. The shared function info however will not be
4091 // explicitly enqueued. 4089 // explicitly enqueued.
4092 SimulateIncrementalMarking(heap); 4090 SimulateIncrementalMarking(heap);
4093 4091
4094 // Now enable the debugger which in turn will disable code flushing. 4092 // Now enable the debugger which in turn will disable code flushing.
4095 CHECK(isolate->debug()->Load()); 4093 CHECK(isolate->debug()->Load());
4096 4094
4097 // This cycle will bust the heap and subsequent cycles will go ballistic. 4095 // This cycle will bust the heap and subsequent cycles will go ballistic.
4098 heap->CollectAllGarbage(); 4096 heap->CollectAllGarbage(Heap::kNoGCFlags);
4099 heap->CollectAllGarbage(); 4097 heap->CollectAllGarbage(Heap::kNoGCFlags);
4100 } 4098 }
4101 4099
4102 4100
4103 class DummyVisitor : public ObjectVisitor { 4101 class DummyVisitor : public ObjectVisitor {
4104 public: 4102 public:
4105 void VisitPointers(Object** start, Object** end) { } 4103 void VisitPointers(Object** start, Object** end) { }
4106 }; 4104 };
4107 4105
4108 4106
4109 TEST(DeferredHandles) { 4107 TEST(DeferredHandles) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
4224 Handle<JSFunction> bar_handle = 4222 Handle<JSFunction> bar_handle =
4225 v8::Utils::OpenHandle( 4223 v8::Utils::OpenHandle(
4226 *v8::Handle<v8::Function>::Cast( 4224 *v8::Handle<v8::Function>::Cast(
4227 CcTest::global()->Get(v8_str("bar")))); 4225 CcTest::global()->Get(v8_str("bar"))));
4228 CHECK_EQ(bar_handle->code(), function_bar); 4226 CHECK_EQ(bar_handle->code(), function_bar);
4229 } 4227 }
4230 4228
4231 // Now make sure that a gc should get rid of the function, even though we 4229 // Now make sure that a gc should get rid of the function, even though we
4232 // still have the allocation site alive. 4230 // still have the allocation site alive.
4233 for (int i = 0; i < 4; i++) { 4231 for (int i = 0; i < 4; i++) {
4234 heap->CollectAllGarbage(); 4232 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
4235 } 4233 }
4236 4234
4237 // The site still exists because of our global handle, but the code is no 4235 // The site still exists because of our global handle, but the code is no
4238 // longer referred to by dependent_code(). 4236 // longer referred to by dependent_code().
4239 DependentCode::GroupStartIndexes starts(site->dependent_code()); 4237 DependentCode::GroupStartIndexes starts(site->dependent_code());
4240 int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); 4238 int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup);
4241 CHECK(site->dependent_code()->object_at(index)->IsWeakCell() && 4239 CHECK(site->dependent_code()->object_at(index)->IsWeakCell() &&
4242 WeakCell::cast(site->dependent_code()->object_at(index))->cleared()); 4240 WeakCell::cast(site->dependent_code()->object_at(index))->cleared());
4243 } 4241 }
4244 4242
(...skipping 27 matching lines...) Expand all
4272 4270
4273 Handle<JSFunction> bar = 4271 Handle<JSFunction> bar =
4274 v8::Utils::OpenHandle( 4272 v8::Utils::OpenHandle(
4275 *v8::Handle<v8::Function>::Cast( 4273 *v8::Handle<v8::Function>::Cast(
4276 CcTest::global()->Get(v8_str("bar")))); 4274 CcTest::global()->Get(v8_str("bar"))));
4277 code = scope.CloseAndEscape(Handle<Code>(bar->code())); 4275 code = scope.CloseAndEscape(Handle<Code>(bar->code()));
4278 } 4276 }
4279 4277
4280 // Now make sure that a gc should get rid of the function 4278 // Now make sure that a gc should get rid of the function
4281 for (int i = 0; i < 4; i++) { 4279 for (int i = 0; i < 4; i++) {
4282 heap->CollectAllGarbage(); 4280 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
4283 } 4281 }
4284 4282
4285 DCHECK(code->marked_for_deoptimization()); 4283 DCHECK(code->marked_for_deoptimization());
4286 } 4284 }
4287 4285
4288 4286
4289 TEST(ObjectsInOptimizedCodeAreWeak) { 4287 TEST(ObjectsInOptimizedCodeAreWeak) {
4290 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; 4288 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
4291 i::FLAG_weak_embedded_objects_in_optimized_code = true; 4289 i::FLAG_weak_embedded_objects_in_optimized_code = true;
4292 i::FLAG_allow_natives_syntax = true; 4290 i::FLAG_allow_natives_syntax = true;
(...skipping 20 matching lines...) Expand all
4313 4311
4314 Handle<JSFunction> bar = 4312 Handle<JSFunction> bar =
4315 v8::Utils::OpenHandle( 4313 v8::Utils::OpenHandle(
4316 *v8::Handle<v8::Function>::Cast( 4314 *v8::Handle<v8::Function>::Cast(
4317 CcTest::global()->Get(v8_str("bar")))); 4315 CcTest::global()->Get(v8_str("bar"))));
4318 code = scope.CloseAndEscape(Handle<Code>(bar->code())); 4316 code = scope.CloseAndEscape(Handle<Code>(bar->code()));
4319 } 4317 }
4320 4318
4321 // Now make sure that a gc should get rid of the function 4319 // Now make sure that a gc should get rid of the function
4322 for (int i = 0; i < 4; i++) { 4320 for (int i = 0; i < 4; i++) {
4323 heap->CollectAllGarbage(); 4321 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
4324 } 4322 }
4325 4323
4326 DCHECK(code->marked_for_deoptimization()); 4324 DCHECK(code->marked_for_deoptimization());
4327 } 4325 }
4328 4326
4329 4327
4330 TEST(NoWeakHashTableLeakWithIncrementalMarking) { 4328 TEST(NoWeakHashTableLeakWithIncrementalMarking) {
4331 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; 4329 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
4332 if (!i::FLAG_incremental_marking) return; 4330 if (!i::FLAG_incremental_marking) return;
4333 i::FLAG_weak_embedded_objects_in_optimized_code = true; 4331 i::FLAG_weak_embedded_objects_in_optimized_code = true;
(...skipping 18 matching lines...) Expand all
4352 "};" 4350 "};"
4353 "function foo%d(x) { with (x) { return 1 + x; } };" 4351 "function foo%d(x) { with (x) { return 1 + x; } };"
4354 "bar%d();" 4352 "bar%d();"
4355 "bar%d();" 4353 "bar%d();"
4356 "bar%d();" 4354 "bar%d();"
4357 "%%OptimizeFwunctionOnNextCall(bar%d);" 4355 "%%OptimizeFwunctionOnNextCall(bar%d);"
4358 "bar%d();", 4356 "bar%d();",
4359 i, i, i, i, i, i, i, i); 4357 i, i, i, i, i, i, i, i);
4360 CompileRun(source.start()); 4358 CompileRun(source.start());
4361 } 4359 }
4362 heap->CollectAllGarbage(); 4360 heap->CollectAllGarbage(i::Heap::kNoGCFlags);
4363 } 4361 }
4364 int elements = 0; 4362 int elements = 0;
4365 if (heap->weak_object_to_code_table()->IsHashTable()) { 4363 if (heap->weak_object_to_code_table()->IsHashTable()) {
4366 WeakHashTable* t = WeakHashTable::cast(heap->weak_object_to_code_table()); 4364 WeakHashTable* t = WeakHashTable::cast(heap->weak_object_to_code_table());
4367 elements = t->NumberOfElements(); 4365 elements = t->NumberOfElements();
4368 } 4366 }
4369 CHECK_EQ(0, elements); 4367 CHECK_EQ(0, elements);
4370 } 4368 }
4371 4369
4372 4370
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4502 " function hat() { this.x = 5; }" 4500 " function hat() { this.x = 5; }"
4503 " createObj(hat);" 4501 " createObj(hat);"
4504 " createObj(hat);" 4502 " createObj(hat);"
4505 " return hat;" 4503 " return hat;"
4506 " })();"; 4504 " })();";
4507 garbage.Reset(isolate, CompileRun(source)->ToObject(isolate)); 4505 garbage.Reset(isolate, CompileRun(source)->ToObject(isolate));
4508 } 4506 }
4509 weak_ic_cleared = false; 4507 weak_ic_cleared = false;
4510 garbage.SetWeak(static_cast<void*>(&garbage), &ClearWeakIC); 4508 garbage.SetWeak(static_cast<void*>(&garbage), &ClearWeakIC);
4511 Heap* heap = CcTest::i_isolate()->heap(); 4509 Heap* heap = CcTest::i_isolate()->heap();
4512 heap->CollectAllGarbage(); 4510 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
4513 CHECK(weak_ic_cleared); 4511 CHECK(weak_ic_cleared);
4514 4512
4515 // We've determined the constructor in createObj has had it's weak cell 4513 // We've determined the constructor in createObj has had it's weak cell
4516 // cleared. Now, verify that one additional call with a new function 4514 // cleared. Now, verify that one additional call with a new function
4517 // allows monomorphicity. 4515 // allows monomorphicity.
4518 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>( 4516 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>(
4519 createObj->shared()->feedback_vector(), CcTest::i_isolate()); 4517 createObj->shared()->feedback_vector(), CcTest::i_isolate());
4520 for (int i = 0; i < 20; i++) { 4518 for (int i = 0; i < 20; i++) {
4521 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); 4519 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0));
4522 CHECK(slot_value->IsWeakCell()); 4520 CHECK(slot_value->IsWeakCell());
4523 if (WeakCell::cast(slot_value)->cleared()) break; 4521 if (WeakCell::cast(slot_value)->cleared()) break;
4524 heap->CollectAllGarbage(); 4522 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
4525 } 4523 }
4526 4524
4527 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); 4525 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0));
4528 CHECK(slot_value->IsWeakCell() && WeakCell::cast(slot_value)->cleared()); 4526 CHECK(slot_value->IsWeakCell() && WeakCell::cast(slot_value)->cleared());
4529 CompileRun( 4527 CompileRun(
4530 "function coat() { this.x = 6; }" 4528 "function coat() { this.x = 6; }"
4531 "createObj(coat);"); 4529 "createObj(coat);");
4532 slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); 4530 slot_value = feedback_vector->Get(FeedbackVectorSlot(0));
4533 CHECK(slot_value->IsWeakCell() && !WeakCell::cast(slot_value)->cleared()); 4531 CHECK(slot_value->IsWeakCell() && !WeakCell::cast(slot_value)->cleared());
4534 } 4532 }
4535 4533
4536 4534
4537 // Checks that the value returned by execution of the source is weak. 4535 // Checks that the value returned by execution of the source is weak.
4538 void CheckWeakness(const char* source) { 4536 void CheckWeakness(const char* source) {
4539 i::FLAG_stress_compaction = false; 4537 i::FLAG_stress_compaction = false;
4540 CcTest::InitializeVM(); 4538 CcTest::InitializeVM();
4541 v8::Isolate* isolate = CcTest::isolate(); 4539 v8::Isolate* isolate = CcTest::isolate();
4542 v8::HandleScope scope(isolate); 4540 v8::HandleScope scope(isolate);
4543 v8::Persistent<v8::Object> garbage; 4541 v8::Persistent<v8::Object> garbage;
4544 { 4542 {
4545 v8::HandleScope scope(isolate); 4543 v8::HandleScope scope(isolate);
4546 garbage.Reset(isolate, CompileRun(source)->ToObject(isolate)); 4544 garbage.Reset(isolate, CompileRun(source)->ToObject(isolate));
4547 } 4545 }
4548 weak_ic_cleared = false; 4546 weak_ic_cleared = false;
4549 garbage.SetWeak(static_cast<void*>(&garbage), &ClearWeakIC); 4547 garbage.SetWeak(static_cast<void*>(&garbage), &ClearWeakIC);
4550 Heap* heap = CcTest::i_isolate()->heap(); 4548 Heap* heap = CcTest::i_isolate()->heap();
4551 heap->CollectAllGarbage(); 4549 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
4552 CHECK(weak_ic_cleared); 4550 CHECK(weak_ic_cleared);
4553 } 4551 }
4554 4552
4555 4553
4556 // Each of the following "weak IC" tests creates an IC that embeds a map with 4554 // Each of the following "weak IC" tests creates an IC that embeds a map with
4557 // the prototype pointing to _proto_ and checks that the _proto_ dies on GC. 4555 // the prototype pointing to _proto_ and checks that the _proto_ dies on GC.
4558 TEST(WeakMapInMonomorphicLoadIC) { 4556 TEST(WeakMapInMonomorphicLoadIC) {
4559 CheckWeakness("function loadIC(obj) {" 4557 CheckWeakness("function loadIC(obj) {"
4560 " return obj.name;" 4558 " return obj.name;"
4561 "}" 4559 "}"
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
4755 " loadIC(obj);" 4753 " loadIC(obj);"
4756 " loadIC(obj);" 4754 " loadIC(obj);"
4757 " loadIC(obj);" 4755 " loadIC(obj);"
4758 " return proto;" 4756 " return proto;"
4759 "};"); 4757 "};");
4760 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC"); 4758 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC");
4761 { 4759 {
4762 v8::HandleScope scope(CcTest::isolate()); 4760 v8::HandleScope scope(CcTest::isolate());
4763 CompileRun("(testIC())"); 4761 CompileRun("(testIC())");
4764 } 4762 }
4765 heap->CollectAllGarbage(); 4763 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
4766 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC); 4764 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC);
4767 { 4765 {
4768 v8::HandleScope scope(CcTest::isolate()); 4766 v8::HandleScope scope(CcTest::isolate());
4769 CompileRun("(testIC())"); 4767 CompileRun("(testIC())");
4770 } 4768 }
4771 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC); 4769 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC);
4772 } 4770 }
4773 4771
4774 4772
4775 TEST(PolymorphicStaysPolymorphicAfterGC) { 4773 TEST(PolymorphicStaysPolymorphicAfterGC) {
(...skipping 15 matching lines...) Expand all
4791 " var poly = Object.create(proto);" 4789 " var poly = Object.create(proto);"
4792 " poly.x = true;" 4790 " poly.x = true;"
4793 " loadIC(poly);" 4791 " loadIC(poly);"
4794 " return proto;" 4792 " return proto;"
4795 "};"); 4793 "};");
4796 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC"); 4794 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC");
4797 { 4795 {
4798 v8::HandleScope scope(CcTest::isolate()); 4796 v8::HandleScope scope(CcTest::isolate());
4799 CompileRun("(testIC())"); 4797 CompileRun("(testIC())");
4800 } 4798 }
4801 heap->CollectAllGarbage(); 4799 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
4802 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC); 4800 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC);
4803 { 4801 {
4804 v8::HandleScope scope(CcTest::isolate()); 4802 v8::HandleScope scope(CcTest::isolate());
4805 CompileRun("(testIC())"); 4803 CompileRun("(testIC())");
4806 } 4804 }
4807 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC); 4805 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC);
4808 } 4806 }
4809 4807
4810 4808
4811 TEST(WeakCell) { 4809 TEST(WeakCell) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4859 i == 0 ? survivor : factory->NewFixedArray(1, NOT_TENURED); 4857 i == 0 ? survivor : factory->NewFixedArray(1, NOT_TENURED);
4860 Handle<WeakCell> weak_cell = factory->NewWeakCell(value); 4858 Handle<WeakCell> weak_cell = factory->NewWeakCell(value);
4861 CHECK(weak_cell->value()->IsFixedArray()); 4859 CHECK(weak_cell->value()->IsFixedArray());
4862 IncrementalMarking* marking = heap->incremental_marking(); 4860 IncrementalMarking* marking = heap->incremental_marking();
4863 if (marking->IsStopped()) marking->Start(); 4861 if (marking->IsStopped()) marking->Start();
4864 marking->Step(128, IncrementalMarking::NO_GC_VIA_STACK_GUARD); 4862 marking->Step(128, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
4865 heap->CollectGarbage(NEW_SPACE); 4863 heap->CollectGarbage(NEW_SPACE);
4866 CHECK(weak_cell->value()->IsFixedArray()); 4864 CHECK(weak_cell->value()->IsFixedArray());
4867 weak_cells[i] = inner_scope.CloseAndEscape(weak_cell); 4865 weak_cells[i] = inner_scope.CloseAndEscape(weak_cell);
4868 } 4866 }
4869 heap->CollectAllGarbage(); 4867 heap->CollectAllGarbage(Heap::kNoGCFlags);
4870 CHECK_EQ(*survivor, weak_cells[0]->value()); 4868 CHECK_EQ(*survivor, weak_cells[0]->value());
4871 for (int i = 1; i < N; i++) { 4869 for (int i = 1; i < N; i++) {
4872 CHECK(weak_cells[i]->cleared()); 4870 CHECK(weak_cells[i]->cleared());
4873 } 4871 }
4874 } 4872 }
4875 4873
4876 4874
4877 #ifdef DEBUG 4875 #ifdef DEBUG
4878 TEST(AddInstructionChangesNewSpacePromotion) { 4876 TEST(AddInstructionChangesNewSpacePromotion) {
4879 i::FLAG_allow_natives_syntax = true; 4877 i::FLAG_allow_natives_syntax = true;
(...skipping 26 matching lines...) Expand all
4906 "%OptimizeFunctionOnNextCall(crash);" 4904 "%OptimizeFunctionOnNextCall(crash);"
4907 "crash(1);"); 4905 "crash(1);");
4908 4906
4909 v8::Handle<v8::Object> global = CcTest::global(); 4907 v8::Handle<v8::Object> global = CcTest::global();
4910 v8::Handle<v8::Function> g = 4908 v8::Handle<v8::Function> g =
4911 v8::Handle<v8::Function>::Cast(global->Get(v8_str("crash"))); 4909 v8::Handle<v8::Function>::Cast(global->Get(v8_str("crash")));
4912 v8::Handle<v8::Value> args1[] = { v8_num(1) }; 4910 v8::Handle<v8::Value> args1[] = { v8_num(1) };
4913 heap->DisableInlineAllocation(); 4911 heap->DisableInlineAllocation();
4914 heap->set_allocation_timeout(1); 4912 heap->set_allocation_timeout(1);
4915 g->Call(global, 1, args1); 4913 g->Call(global, 1, args1);
4916 heap->CollectAllGarbage(); 4914 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
4917 } 4915 }
4918 4916
4919 4917
4920 void OnFatalErrorExpectOOM(const char* location, const char* message) { 4918 void OnFatalErrorExpectOOM(const char* location, const char* message) {
4921 // Exit with 0 if the location matches our expectation. 4919 // Exit with 0 if the location matches our expectation.
4922 exit(strcmp(location, "CALL_AND_RETRY_LAST")); 4920 exit(strcmp(location, "CALL_AND_RETRY_LAST"));
4923 } 4921 }
4924 4922
4925 4923
4926 TEST(CEntryStubOOM) { 4924 TEST(CEntryStubOOM) {
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
5217 Handle<JSObject> proto = 5215 Handle<JSObject> proto =
5218 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result)); 5216 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result));
5219 weak_prototype = inner_scope.CloseAndEscape(factory->NewWeakCell(proto)); 5217 weak_prototype = inner_scope.CloseAndEscape(factory->NewWeakCell(proto));
5220 } 5218 }
5221 CHECK(!weak_prototype->cleared()); 5219 CHECK(!weak_prototype->cleared());
5222 CompileRun( 5220 CompileRun(
5223 "var a = { };" 5221 "var a = { };"
5224 "a.x = new cls();" 5222 "a.x = new cls();"
5225 "cls.prototype = null;"); 5223 "cls.prototype = null;");
5226 for (int i = 0; i < 4; i++) { 5224 for (int i = 0; i < 4; i++) {
5227 heap->CollectAllGarbage(); 5225 heap->CollectAllGarbage(Heap::kNoGCFlags);
5228 } 5226 }
5229 // The map of a.x keeps prototype alive 5227 // The map of a.x keeps prototype alive
5230 CHECK(!weak_prototype->cleared()); 5228 CHECK(!weak_prototype->cleared());
5231 // Change the map of a.x and make the previous map garbage collectable. 5229 // Change the map of a.x and make the previous map garbage collectable.
5232 CompileRun("a.x.__proto__ = {};"); 5230 CompileRun("a.x.__proto__ = {};");
5233 for (int i = 0; i < 4; i++) { 5231 for (int i = 0; i < 4; i++) {
5234 heap->CollectAllGarbage(); 5232 heap->CollectAllGarbage(Heap::kNoGCFlags);
5235 } 5233 }
5236 CHECK(weak_prototype->cleared()); 5234 CHECK(weak_prototype->cleared());
5237 } 5235 }
5238 5236
5239 5237
5240 Handle<WeakCell> AddRetainedMap(Isolate* isolate, Heap* heap) { 5238 Handle<WeakCell> AddRetainedMap(Isolate* isolate, Heap* heap) {
5241 HandleScope inner_scope(isolate); 5239 HandleScope inner_scope(isolate);
5242 Handle<Map> map = Map::Create(isolate, 1); 5240 Handle<Map> map = Map::Create(isolate, 1);
5243 v8::Local<v8::Value> result = 5241 v8::Local<v8::Value> result =
5244 CompileRun("(function () { return {x : 10}; })();"); 5242 CompileRun("(function () { return {x : 10}; })();");
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
5361 TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 8, 6); 5359 TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 8, 6);
5362 TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 8 - 1, 6); 5360 TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 8 - 1, 6);
5363 5361
5364 // 32-bit cases. 5362 // 32-bit cases.
5365 TestRightTrimFixedTypedArray(v8::kExternalUint8Array, 16, 3); 5363 TestRightTrimFixedTypedArray(v8::kExternalUint8Array, 16, 3);
5366 TestRightTrimFixedTypedArray(v8::kExternalUint8Array, 16 - 3, 3); 5364 TestRightTrimFixedTypedArray(v8::kExternalUint8Array, 16 - 3, 3);
5367 TestRightTrimFixedTypedArray(v8::kExternalUint16Array, 8, 3); 5365 TestRightTrimFixedTypedArray(v8::kExternalUint16Array, 8, 3);
5368 TestRightTrimFixedTypedArray(v8::kExternalUint16Array, 8 - 1, 3); 5366 TestRightTrimFixedTypedArray(v8::kExternalUint16Array, 8 - 1, 3);
5369 TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 4, 3); 5367 TestRightTrimFixedTypedArray(v8::kExternalUint32Array, 4, 3);
5370 } 5368 }
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