OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 | 2 |
3 #include <stdlib.h> | 3 #include <stdlib.h> |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "compilation-cache.h" | 7 #include "compilation-cache.h" |
8 #include "execution.h" | 8 #include "execution.h" |
9 #include "factory.h" | 9 #include "factory.h" |
10 #include "macro-assembler.h" | 10 #include "macro-assembler.h" |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();"); | 1062 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();"); |
1063 } | 1063 } |
1064 | 1064 |
1065 // Simulate one final GC to make sure the candidate queue is sane. | 1065 // Simulate one final GC to make sure the candidate queue is sane. |
1066 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1066 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
1067 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); | 1067 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); |
1068 CHECK(function->is_compiled() || !function->IsOptimized()); | 1068 CHECK(function->is_compiled() || !function->IsOptimized()); |
1069 } | 1069 } |
1070 | 1070 |
1071 | 1071 |
| 1072 TEST(TestCodeFlushingIncrementalScavenge) { |
| 1073 // If we do not flush code this test is invalid. |
| 1074 if (!FLAG_flush_code) return; |
| 1075 i::FLAG_allow_natives_syntax = true; |
| 1076 InitializeVM(); |
| 1077 v8::HandleScope scope; |
| 1078 const char* source = "var foo = function() {" |
| 1079 " var x = 42;" |
| 1080 " var y = 42;" |
| 1081 " var z = x + y;" |
| 1082 "};" |
| 1083 "foo();" |
| 1084 "var bar = function() {" |
| 1085 " var x = 23;" |
| 1086 "};" |
| 1087 "bar();"; |
| 1088 Handle<String> foo_name = FACTORY->LookupAsciiSymbol("foo"); |
| 1089 Handle<String> bar_name = FACTORY->LookupAsciiSymbol("bar"); |
| 1090 |
| 1091 // Perfrom one initial GC to enable code flushing. |
| 1092 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 1093 |
| 1094 // This compile will add the code to the compilation cache. |
| 1095 { v8::HandleScope scope; |
| 1096 CompileRun(source); |
| 1097 } |
| 1098 |
| 1099 // Check functions are compiled. |
| 1100 Object* func_value = Isolate::Current()->context()->global_object()-> |
| 1101 GetProperty(*foo_name)->ToObjectChecked(); |
| 1102 CHECK(func_value->IsJSFunction()); |
| 1103 Handle<JSFunction> function(JSFunction::cast(func_value)); |
| 1104 CHECK(function->shared()->is_compiled()); |
| 1105 Object* func_value2 = Isolate::Current()->context()->global_object()-> |
| 1106 GetProperty(*bar_name)->ToObjectChecked(); |
| 1107 CHECK(func_value2->IsJSFunction()); |
| 1108 Handle<JSFunction> function2(JSFunction::cast(func_value2)); |
| 1109 CHECK(function2->shared()->is_compiled()); |
| 1110 |
| 1111 // Clear references to functions so that one of them can die. |
| 1112 { v8::HandleScope scope; |
| 1113 CompileRun("foo = 0; bar = 0;"); |
| 1114 } |
| 1115 |
| 1116 // Bump the code age so that flushing is triggered while the function |
| 1117 // object is still located in new-space. |
| 1118 const int kAgingThreshold = 6; |
| 1119 function->shared()->set_code_age(kAgingThreshold); |
| 1120 function2->shared()->set_code_age(kAgingThreshold); |
| 1121 |
| 1122 // Simulate incremental marking so that the functions are enqueued as |
| 1123 // code flushing candidates. Then kill one of the functions. Finally |
| 1124 // perform a scavenge while incremental marking is still running. |
| 1125 SimulateIncrementalMarking(); |
| 1126 *function2.location() = NULL; |
| 1127 HEAP->CollectGarbage(NEW_SPACE, "test scavenge while marking"); |
| 1128 |
| 1129 // Simulate one final GC to make sure the candidate queue is sane. |
| 1130 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 1131 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); |
| 1132 CHECK(!function->is_compiled() || function->IsOptimized()); |
| 1133 } |
| 1134 |
| 1135 |
1072 // Count the number of native contexts in the weak list of native contexts. | 1136 // Count the number of native contexts in the weak list of native contexts. |
1073 int CountNativeContexts() { | 1137 int CountNativeContexts() { |
1074 int count = 0; | 1138 int count = 0; |
1075 Object* object = HEAP->native_contexts_list(); | 1139 Object* object = HEAP->native_contexts_list(); |
1076 while (!object->IsUndefined()) { | 1140 while (!object->IsUndefined()) { |
1077 count++; | 1141 count++; |
1078 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); | 1142 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); |
1079 } | 1143 } |
1080 return count; | 1144 return count; |
1081 } | 1145 } |
(...skipping 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2370 Handle<Object> call_function(call); | 2434 Handle<Object> call_function(call); |
2371 | 2435 |
2372 // Now we are ready to mess up the heap. | 2436 // Now we are ready to mess up the heap. |
2373 HEAP->CollectAllGarbage(Heap::kReduceMemoryFootprintMask); | 2437 HEAP->CollectAllGarbage(Heap::kReduceMemoryFootprintMask); |
2374 | 2438 |
2375 // Either heap verification caught the problem already or we go kaboom once | 2439 // Either heap verification caught the problem already or we go kaboom once |
2376 // the CallIC is executed the next time. | 2440 // the CallIC is executed the next time. |
2377 USE(global->SetProperty(*name, *call_function, NONE, kNonStrictMode)); | 2441 USE(global->SetProperty(*name, *call_function, NONE, kNonStrictMode)); |
2378 CompileRun("call();"); | 2442 CompileRun("call();"); |
2379 } | 2443 } |
OLD | NEW |