| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 | 2 |
| 3 #include <stdlib.h> | 3 #include <stdlib.h> |
| 4 | 4 |
| 5 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "execution.h" | 7 #include "execution.h" |
| 8 #include "factory.h" | 8 #include "factory.h" |
| 9 #include "macro-assembler.h" | 9 #include "macro-assembler.h" |
| 10 #include "global-handles.h" | 10 #include "global-handles.h" |
| (...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 v8::HandleScope scope; | 975 v8::HandleScope scope; |
| 976 const char* source = "function foo() {" | 976 const char* source = "function foo() {" |
| 977 " var x = 42;" | 977 " var x = 42;" |
| 978 " var y = 42;" | 978 " var y = 42;" |
| 979 " var z = x + y;" | 979 " var z = x + y;" |
| 980 "};" | 980 "};" |
| 981 "foo()"; | 981 "foo()"; |
| 982 Handle<String> foo_name = FACTORY->LookupAsciiSymbol("foo"); | 982 Handle<String> foo_name = FACTORY->LookupAsciiSymbol("foo"); |
| 983 | 983 |
| 984 // This compile will add the code to the compilation cache. | 984 // This compile will add the code to the compilation cache. |
| 985 CompileRun(source); | 985 { v8::HandleScope scope; |
| 986 CompileRun(source); |
| 987 } |
| 986 | 988 |
| 987 // Check function is compiled. | 989 // Check function is compiled. |
| 988 Object* func_value = Isolate::Current()->context()->global()-> | 990 Object* func_value = Isolate::Current()->context()->global()-> |
| 989 GetProperty(*foo_name)->ToObjectChecked(); | 991 GetProperty(*foo_name)->ToObjectChecked(); |
| 990 CHECK(func_value->IsJSFunction()); | 992 CHECK(func_value->IsJSFunction()); |
| 991 Handle<JSFunction> function(JSFunction::cast(func_value)); | 993 Handle<JSFunction> function(JSFunction::cast(func_value)); |
| 992 CHECK(function->shared()->is_compiled()); | 994 CHECK(function->shared()->is_compiled()); |
| 993 | 995 |
| 994 HEAP->CollectAllGarbage(true); | 996 HEAP->CollectAllGarbage(true); |
| 995 HEAP->CollectAllGarbage(true); | 997 HEAP->CollectAllGarbage(true); |
| 996 | 998 |
| 997 CHECK(function->shared()->is_compiled()); | 999 CHECK(function->shared()->is_compiled()); |
| 998 | 1000 |
| 999 HEAP->CollectAllGarbage(true); | 1001 HEAP->CollectAllGarbage(true); |
| 1000 HEAP->CollectAllGarbage(true); | 1002 HEAP->CollectAllGarbage(true); |
| 1001 HEAP->CollectAllGarbage(true); | 1003 HEAP->CollectAllGarbage(true); |
| 1002 HEAP->CollectAllGarbage(true); | 1004 HEAP->CollectAllGarbage(true); |
| 1003 HEAP->CollectAllGarbage(true); | 1005 HEAP->CollectAllGarbage(true); |
| 1004 HEAP->CollectAllGarbage(true); | 1006 HEAP->CollectAllGarbage(true); |
| 1005 | 1007 |
| 1006 // foo should no longer be in the compilation cache | 1008 // foo should no longer be in the compilation cache |
| 1007 CHECK(!function->shared()->is_compiled()); | 1009 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); |
| 1008 CHECK(!function->is_compiled()); | 1010 CHECK(!function->is_compiled() || function->IsOptimized()); |
| 1009 // Call foo to get it recompiled. | 1011 // Call foo to get it recompiled. |
| 1010 CompileRun("foo()"); | 1012 CompileRun("foo()"); |
| 1011 CHECK(function->shared()->is_compiled()); | 1013 CHECK(function->shared()->is_compiled()); |
| 1012 CHECK(function->is_compiled()); | 1014 CHECK(function->is_compiled()); |
| 1013 } | 1015 } |
| 1014 | 1016 |
| 1015 | 1017 |
| 1016 // Count the number of global contexts in the weak list of global contexts. | 1018 // Count the number of global contexts in the weak list of global contexts. |
| 1017 static int CountGlobalContexts() { | 1019 static int CountGlobalContexts() { |
| 1018 int count = 0; | 1020 int count = 0; |
| 1019 Object* object = HEAP->global_contexts_list(); | 1021 Object* object = HEAP->global_contexts_list(); |
| 1020 while (!object->IsUndefined()) { | 1022 while (!object->IsUndefined()) { |
| 1021 count++; | 1023 count++; |
| 1022 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); | 1024 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); |
| 1023 } | 1025 } |
| 1024 return count; | 1026 return count; |
| 1025 } | 1027 } |
| 1026 | 1028 |
| 1027 | 1029 |
| 1030 // Count the number of user functions in the weak list of optimized |
| 1031 // functions attached to a global context. |
| 1032 static int CountOptimizedUserFunctions(v8::Handle<v8::Context> context) { |
| 1033 int count = 0; |
| 1034 Handle<Context> icontext = v8::Utils::OpenHandle(*context); |
| 1035 Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST); |
| 1036 while (object->IsJSFunction() && !JSFunction::cast(object)->IsBuiltin()) { |
| 1037 count++; |
| 1038 object = JSFunction::cast(object)->next_function_link(); |
| 1039 } |
| 1040 return count; |
| 1041 } |
| 1042 |
| 1043 |
| 1028 TEST(TestInternalWeakLists) { | 1044 TEST(TestInternalWeakLists) { |
| 1029 v8::V8::Initialize(); | 1045 v8::V8::Initialize(); |
| 1030 | 1046 |
| 1031 static const int kNumTestContexts = 10; | 1047 static const int kNumTestContexts = 10; |
| 1032 | 1048 |
| 1033 v8::HandleScope scope; | 1049 v8::HandleScope scope; |
| 1034 v8::Persistent<v8::Context> ctx[kNumTestContexts]; | 1050 v8::Persistent<v8::Context> ctx[kNumTestContexts]; |
| 1035 | 1051 |
| 1036 CHECK_EQ(0, CountGlobalContexts()); | 1052 CHECK_EQ(0, CountGlobalContexts()); |
| 1037 | 1053 |
| 1038 // Create a number of global contests which gets linked together. | 1054 // Create a number of global contests which gets linked together. |
| 1039 for (int i = 0; i < kNumTestContexts; i++) { | 1055 for (int i = 0; i < kNumTestContexts; i++) { |
| 1040 ctx[i] = v8::Context::New(); | 1056 ctx[i] = v8::Context::New(); |
| 1057 |
| 1058 bool opt = (FLAG_always_opt && i::V8::UseCrankshaft()); |
| 1059 |
| 1041 CHECK_EQ(i + 1, CountGlobalContexts()); | 1060 CHECK_EQ(i + 1, CountGlobalContexts()); |
| 1042 | 1061 |
| 1043 ctx[i]->Enter(); | 1062 ctx[i]->Enter(); |
| 1063 |
| 1064 // Create a handle scope so no function objects get stuch in the outer |
| 1065 // handle scope |
| 1066 v8::HandleScope scope; |
| 1067 const char* source = "function f1() { };" |
| 1068 "function f2() { };" |
| 1069 "function f3() { };" |
| 1070 "function f4() { };" |
| 1071 "function f5() { };"; |
| 1072 CompileRun(source); |
| 1073 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i])); |
| 1074 CompileRun("f1()"); |
| 1075 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1076 CompileRun("f2()"); |
| 1077 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1078 CompileRun("f3()"); |
| 1079 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1080 CompileRun("f4()"); |
| 1081 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1082 CompileRun("f5()"); |
| 1083 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1084 |
| 1085 // Remove function f1, and |
| 1086 CompileRun("f1=null"); |
| 1087 |
| 1088 // Scavenge treats these references as strong. |
| 1089 for (int j = 0; j < 10; j++) { |
| 1090 HEAP->PerformScavenge(); |
| 1091 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1092 } |
| 1093 |
| 1094 // Mark compact handles the weak references. |
| 1095 HEAP->CollectAllGarbage(true); |
| 1096 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1097 |
| 1098 // Get rid of f3 and f5 in the same way. |
| 1099 CompileRun("f3=null"); |
| 1100 for (int j = 0; j < 10; j++) { |
| 1101 HEAP->PerformScavenge(); |
| 1102 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1103 } |
| 1104 HEAP->CollectAllGarbage(true); |
| 1105 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1106 CompileRun("f5=null"); |
| 1107 for (int j = 0; j < 10; j++) { |
| 1108 HEAP->PerformScavenge(); |
| 1109 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1110 } |
| 1111 HEAP->CollectAllGarbage(true); |
| 1112 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1113 |
| 1044 ctx[i]->Exit(); | 1114 ctx[i]->Exit(); |
| 1045 } | 1115 } |
| 1046 | 1116 |
| 1047 // Force compilation cache cleanup. | 1117 // Force compilation cache cleanup. |
| 1048 HEAP->CollectAllGarbage(true); | 1118 HEAP->CollectAllGarbage(true); |
| 1049 | 1119 |
| 1050 // Dispose the global contexts one by one. | 1120 // Dispose the global contexts one by one. |
| 1051 for (int i = 0; i < kNumTestContexts; i++) { | 1121 for (int i = 0; i < kNumTestContexts; i++) { |
| 1052 ctx[i].Dispose(); | 1122 ctx[i].Dispose(); |
| 1053 ctx[i].Clear(); | 1123 ctx[i].Clear(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1075 while (!object->IsUndefined()) { | 1145 while (!object->IsUndefined()) { |
| 1076 count++; | 1146 count++; |
| 1077 if (count == n) HEAP->CollectAllGarbage(true); | 1147 if (count == n) HEAP->CollectAllGarbage(true); |
| 1078 object = | 1148 object = |
| 1079 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK)); | 1149 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK)); |
| 1080 } | 1150 } |
| 1081 return count; | 1151 return count; |
| 1082 } | 1152 } |
| 1083 | 1153 |
| 1084 | 1154 |
| 1155 // Count the number of user functions in the weak list of optimized |
| 1156 // functions attached to a global context causing a GC after the |
| 1157 // specified number of elements. |
| 1158 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, |
| 1159 int n) { |
| 1160 int count = 0; |
| 1161 Handle<Context> icontext = v8::Utils::OpenHandle(*context); |
| 1162 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST)); |
| 1163 while (object->IsJSFunction() && |
| 1164 !Handle<JSFunction>::cast(object)->IsBuiltin()) { |
| 1165 count++; |
| 1166 if (count == n) HEAP->CollectAllGarbage(true); |
| 1167 object = Handle<Object>( |
| 1168 Object::cast(JSFunction::cast(*object)->next_function_link())); |
| 1169 } |
| 1170 return count; |
| 1171 } |
| 1172 |
| 1173 |
| 1085 TEST(TestInternalWeakListsTraverseWithGC) { | 1174 TEST(TestInternalWeakListsTraverseWithGC) { |
| 1086 v8::V8::Initialize(); | 1175 v8::V8::Initialize(); |
| 1087 | 1176 |
| 1088 static const int kNumTestContexts = 10; | 1177 static const int kNumTestContexts = 10; |
| 1089 | 1178 |
| 1090 v8::HandleScope scope; | 1179 v8::HandleScope scope; |
| 1091 v8::Persistent<v8::Context> ctx[kNumTestContexts]; | 1180 v8::Persistent<v8::Context> ctx[kNumTestContexts]; |
| 1092 | 1181 |
| 1093 CHECK_EQ(0, CountGlobalContexts()); | 1182 CHECK_EQ(0, CountGlobalContexts()); |
| 1094 | 1183 |
| 1095 // Create an number of contexts and check the length of the weak list both | 1184 // Create an number of contexts and check the length of the weak list both |
| 1096 // with and without GCs while iterating the list. | 1185 // with and without GCs while iterating the list. |
| 1097 for (int i = 0; i < kNumTestContexts; i++) { | 1186 for (int i = 0; i < kNumTestContexts; i++) { |
| 1098 ctx[i] = v8::Context::New(); | 1187 ctx[i] = v8::Context::New(); |
| 1099 CHECK_EQ(i + 1, CountGlobalContexts()); | 1188 CHECK_EQ(i + 1, CountGlobalContexts()); |
| 1100 CHECK_EQ(i + 1, CountGlobalContextsWithGC(i / 2 + 1)); | 1189 CHECK_EQ(i + 1, CountGlobalContextsWithGC(i / 2 + 1)); |
| 1190 } |
| 1101 | 1191 |
| 1102 ctx[i]->Enter(); | 1192 bool opt = (FLAG_always_opt && i::V8::UseCrankshaft()); |
| 1103 ctx[i]->Exit(); | 1193 |
| 1104 } | 1194 // Compile a number of functions the length of the weak list of optimized |
| 1195 // functions both with and without GCs while iterating the list. |
| 1196 ctx[0]->Enter(); |
| 1197 const char* source = "function f1() { };" |
| 1198 "function f2() { };" |
| 1199 "function f3() { };" |
| 1200 "function f4() { };" |
| 1201 "function f5() { };"; |
| 1202 CompileRun(source); |
| 1203 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[0])); |
| 1204 CompileRun("f1()"); |
| 1205 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctions(ctx[0])); |
| 1206 CHECK_EQ(opt ? 1 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
| 1207 CompileRun("f2()"); |
| 1208 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[0])); |
| 1209 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
| 1210 CompileRun("f3()"); |
| 1211 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[0])); |
| 1212 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
| 1213 CompileRun("f4()"); |
| 1214 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[0])); |
| 1215 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 2)); |
| 1216 CompileRun("f5()"); |
| 1217 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[0])); |
| 1218 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctionsWithGC(ctx[0], 4)); |
| 1219 |
| 1220 ctx[0]->Exit(); |
| 1105 } | 1221 } |
| 1106 | 1222 |
| 1107 | 1223 |
| 1108 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) { | 1224 TEST(TestSizeOfObjectsVsHeapIteratorPrecision) { |
| 1109 InitializeVM(); | 1225 InitializeVM(); |
| 1110 intptr_t size_of_objects_1 = HEAP->SizeOfObjects(); | 1226 intptr_t size_of_objects_1 = HEAP->SizeOfObjects(); |
| 1111 HeapIterator iterator(HeapIterator::kPreciseFiltering); | 1227 HeapIterator iterator(HeapIterator::kPreciseFiltering); |
| 1112 intptr_t size_of_objects_2 = 0; | 1228 intptr_t size_of_objects_2 = 0; |
| 1113 for (HeapObject* obj = iterator.next(); | 1229 for (HeapObject* obj = iterator.next(); |
| 1114 obj != NULL; | 1230 obj != NULL; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1125 CHECK_GT(size_of_objects_1 / 100, delta); | 1241 CHECK_GT(size_of_objects_1 / 100, delta); |
| 1126 } else { | 1242 } else { |
| 1127 intptr_t delta = size_of_objects_2 - size_of_objects_1; | 1243 intptr_t delta = size_of_objects_2 - size_of_objects_1; |
| 1128 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, " | 1244 PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, " |
| 1129 "Iterator: %" V8_PTR_PREFIX "d, " | 1245 "Iterator: %" V8_PTR_PREFIX "d, " |
| 1130 "delta: %" V8_PTR_PREFIX "d\n", | 1246 "delta: %" V8_PTR_PREFIX "d\n", |
| 1131 size_of_objects_1, size_of_objects_2, delta); | 1247 size_of_objects_1, size_of_objects_2, delta); |
| 1132 CHECK_GT(size_of_objects_2 / 100, delta); | 1248 CHECK_GT(size_of_objects_2 / 100, delta); |
| 1133 } | 1249 } |
| 1134 } | 1250 } |
| OLD | NEW |