| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 static int LenFromSize(int size) { | 857 static int LenFromSize(int size) { |
| 858 return (size - FixedArray::kHeaderSize) / kPointerSize; | 858 return (size - FixedArray::kHeaderSize) / kPointerSize; |
| 859 } | 859 } |
| 860 | 860 |
| 861 | 861 |
| 862 TEST(Regression39128) { | 862 TEST(Regression39128) { |
| 863 // Test case for crbug.com/39128. | 863 // Test case for crbug.com/39128. |
| 864 InitializeVM(); | 864 InitializeVM(); |
| 865 | 865 |
| 866 // Increase the chance of 'bump-the-pointer' allocation in old space. | 866 // Increase the chance of 'bump-the-pointer' allocation in old space. |
| 867 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 867 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 868 | 868 |
| 869 v8::HandleScope scope; | 869 v8::HandleScope scope; |
| 870 | 870 |
| 871 // The plan: create JSObject which references objects in new space. | 871 // The plan: create JSObject which references objects in new space. |
| 872 // Then clone this object (forcing it to go into old space) and check | 872 // Then clone this object (forcing it to go into old space) and check |
| 873 // that region dirty marks are updated correctly. | 873 // that region dirty marks are updated correctly. |
| 874 | 874 |
| 875 // Step 1: prepare a map for the object. We add 1 inobject property to it. | 875 // Step 1: prepare a map for the object. We add 1 inobject property to it. |
| 876 Handle<JSFunction> object_ctor( | 876 Handle<JSFunction> object_ctor( |
| 877 Isolate::Current()->global_context()->object_function()); | 877 Isolate::Current()->global_context()->object_function()); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 CompileRun(source); | 953 CompileRun(source); |
| 954 } | 954 } |
| 955 | 955 |
| 956 // Check function is compiled. | 956 // Check function is compiled. |
| 957 Object* func_value = Isolate::Current()->context()->global()-> | 957 Object* func_value = Isolate::Current()->context()->global()-> |
| 958 GetProperty(*foo_name)->ToObjectChecked(); | 958 GetProperty(*foo_name)->ToObjectChecked(); |
| 959 CHECK(func_value->IsJSFunction()); | 959 CHECK(func_value->IsJSFunction()); |
| 960 Handle<JSFunction> function(JSFunction::cast(func_value)); | 960 Handle<JSFunction> function(JSFunction::cast(func_value)); |
| 961 CHECK(function->shared()->is_compiled()); | 961 CHECK(function->shared()->is_compiled()); |
| 962 | 962 |
| 963 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 963 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 964 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 964 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 965 | 965 |
| 966 CHECK(function->shared()->is_compiled()); | 966 CHECK(function->shared()->is_compiled()); |
| 967 | 967 |
| 968 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 968 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 969 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 969 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 970 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 970 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 971 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 971 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 972 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 972 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 973 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 973 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 974 | 974 |
| 975 // foo should no longer be in the compilation cache | 975 // foo should no longer be in the compilation cache |
| 976 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 976 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); |
| 977 CHECK(!function->is_compiled() || function->IsOptimized()); | 977 CHECK(!function->is_compiled() || function->IsOptimized()); |
| 978 // Call foo to get it recompiled. | 978 // Call foo to get it recompiled. |
| 979 CompileRun("foo()"); | 979 CompileRun("foo()"); |
| 980 CHECK(function->shared()->is_compiled()); | 980 CHECK(function->shared()->is_compiled()); |
| 981 CHECK(function->is_compiled()); | 981 CHECK(function->is_compiled()); |
| 982 } | 982 } |
| 983 | 983 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1052 // Remove function f1, and | 1052 // Remove function f1, and |
| 1053 CompileRun("f1=null"); | 1053 CompileRun("f1=null"); |
| 1054 | 1054 |
| 1055 // Scavenge treats these references as strong. | 1055 // Scavenge treats these references as strong. |
| 1056 for (int j = 0; j < 10; j++) { | 1056 for (int j = 0; j < 10; j++) { |
| 1057 HEAP->PerformScavenge(); | 1057 HEAP->PerformScavenge(); |
| 1058 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); | 1058 CHECK_EQ(opt ? 5 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1059 } | 1059 } |
| 1060 | 1060 |
| 1061 // Mark compact handles the weak references. | 1061 // Mark compact handles the weak references. |
| 1062 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 1062 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 1063 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1063 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1064 | 1064 |
| 1065 // Get rid of f3 and f5 in the same way. | 1065 // Get rid of f3 and f5 in the same way. |
| 1066 CompileRun("f3=null"); | 1066 CompileRun("f3=null"); |
| 1067 for (int j = 0; j < 10; j++) { | 1067 for (int j = 0; j < 10; j++) { |
| 1068 HEAP->PerformScavenge(); | 1068 HEAP->PerformScavenge(); |
| 1069 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); | 1069 CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1070 } | 1070 } |
| 1071 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 1071 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 1072 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); | 1072 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1073 CompileRun("f5=null"); | 1073 CompileRun("f5=null"); |
| 1074 for (int j = 0; j < 10; j++) { | 1074 for (int j = 0; j < 10; j++) { |
| 1075 HEAP->PerformScavenge(); | 1075 HEAP->PerformScavenge(); |
| 1076 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); | 1076 CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1077 } | 1077 } |
| 1078 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 1078 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 1079 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); | 1079 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); |
| 1080 | 1080 |
| 1081 ctx[i]->Exit(); | 1081 ctx[i]->Exit(); |
| 1082 } | 1082 } |
| 1083 | 1083 |
| 1084 // Force compilation cache cleanup. | 1084 // Force compilation cache cleanup. |
| 1085 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 1085 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 1086 | 1086 |
| 1087 // Dispose the global contexts one by one. | 1087 // Dispose the global contexts one by one. |
| 1088 for (int i = 0; i < kNumTestContexts; i++) { | 1088 for (int i = 0; i < kNumTestContexts; i++) { |
| 1089 ctx[i].Dispose(); | 1089 ctx[i].Dispose(); |
| 1090 ctx[i].Clear(); | 1090 ctx[i].Clear(); |
| 1091 | 1091 |
| 1092 // Scavenge treats these references as strong. | 1092 // Scavenge treats these references as strong. |
| 1093 for (int j = 0; j < 10; j++) { | 1093 for (int j = 0; j < 10; j++) { |
| 1094 HEAP->PerformScavenge(); | 1094 HEAP->PerformScavenge(); |
| 1095 CHECK_EQ(kNumTestContexts - i, CountGlobalContexts()); | 1095 CHECK_EQ(kNumTestContexts - i, CountGlobalContexts()); |
| 1096 } | 1096 } |
| 1097 | 1097 |
| 1098 // Mark compact handles the weak references. | 1098 // Mark compact handles the weak references. |
| 1099 HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 1099 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 1100 CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts()); | 1100 CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts()); |
| 1101 } | 1101 } |
| 1102 | 1102 |
| 1103 CHECK_EQ(0, CountGlobalContexts()); | 1103 CHECK_EQ(0, CountGlobalContexts()); |
| 1104 } | 1104 } |
| 1105 | 1105 |
| 1106 | 1106 |
| 1107 // Count the number of global contexts in the weak list of global contexts | 1107 // Count the number of global contexts in the weak list of global contexts |
| 1108 // causing a GC after the specified number of elements. | 1108 // causing a GC after the specified number of elements. |
| 1109 static int CountGlobalContextsWithGC(int n) { | 1109 static int CountGlobalContextsWithGC(int n) { |
| 1110 int count = 0; | 1110 int count = 0; |
| 1111 Handle<Object> object(HEAP->global_contexts_list()); | 1111 Handle<Object> object(HEAP->global_contexts_list()); |
| 1112 while (!object->IsUndefined()) { | 1112 while (!object->IsUndefined()) { |
| 1113 count++; | 1113 count++; |
| 1114 if (count == n) HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 1114 if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 1115 object = | 1115 object = |
| 1116 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK)); | 1116 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK)); |
| 1117 } | 1117 } |
| 1118 return count; | 1118 return count; |
| 1119 } | 1119 } |
| 1120 | 1120 |
| 1121 | 1121 |
| 1122 // Count the number of user functions in the weak list of optimized | 1122 // Count the number of user functions in the weak list of optimized |
| 1123 // functions attached to a global context causing a GC after the | 1123 // functions attached to a global context causing a GC after the |
| 1124 // specified number of elements. | 1124 // specified number of elements. |
| 1125 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, | 1125 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, |
| 1126 int n) { | 1126 int n) { |
| 1127 int count = 0; | 1127 int count = 0; |
| 1128 Handle<Context> icontext = v8::Utils::OpenHandle(*context); | 1128 Handle<Context> icontext = v8::Utils::OpenHandle(*context); |
| 1129 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST)); | 1129 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST)); |
| 1130 while (object->IsJSFunction() && | 1130 while (object->IsJSFunction() && |
| 1131 !Handle<JSFunction>::cast(object)->IsBuiltin()) { | 1131 !Handle<JSFunction>::cast(object)->IsBuiltin()) { |
| 1132 count++; | 1132 count++; |
| 1133 if (count == n) HEAP->CollectAllGarbage(Heap::kForceCompactionMask); | 1133 if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
| 1134 object = Handle<Object>( | 1134 object = Handle<Object>( |
| 1135 Object::cast(JSFunction::cast(*object)->next_function_link())); | 1135 Object::cast(JSFunction::cast(*object)->next_function_link())); |
| 1136 } | 1136 } |
| 1137 return count; | 1137 return count; |
| 1138 } | 1138 } |
| 1139 | 1139 |
| 1140 | 1140 |
| 1141 TEST(TestInternalWeakListsTraverseWithGC) { | 1141 TEST(TestInternalWeakListsTraverseWithGC) { |
| 1142 v8::V8::Initialize(); | 1142 v8::V8::Initialize(); |
| 1143 | 1143 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1237 else if (obj == b_) | 1237 else if (obj == b_) |
| 1238 b_found_ = true; | 1238 b_found_ = true; |
| 1239 } | 1239 } |
| 1240 } | 1240 } |
| 1241 private: | 1241 private: |
| 1242 Object* a_; | 1242 Object* a_; |
| 1243 Object* b_; | 1243 Object* b_; |
| 1244 bool a_found_; | 1244 bool a_found_; |
| 1245 bool b_found_; | 1245 bool b_found_; |
| 1246 }; | 1246 }; |
| OLD | NEW |