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 "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 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 869 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
870 | 870 |
871 v8::HandleScope scope; | 871 v8::HandleScope scope; |
872 | 872 |
873 // The plan: create JSObject which references objects in new space. | 873 // The plan: create JSObject which references objects in new space. |
874 // Then clone this object (forcing it to go into old space) and check | 874 // Then clone this object (forcing it to go into old space) and check |
875 // that region dirty marks are updated correctly. | 875 // that region dirty marks are updated correctly. |
876 | 876 |
877 // Step 1: prepare a map for the object. We add 1 inobject property to it. | 877 // Step 1: prepare a map for the object. We add 1 inobject property to it. |
878 Handle<JSFunction> object_ctor( | 878 Handle<JSFunction> object_ctor( |
879 Isolate::Current()->global_context()->object_function()); | 879 Isolate::Current()->native_context()->object_function()); |
880 CHECK(object_ctor->has_initial_map()); | 880 CHECK(object_ctor->has_initial_map()); |
881 Handle<Map> object_map(object_ctor->initial_map()); | 881 Handle<Map> object_map(object_ctor->initial_map()); |
882 // Create a map with single inobject property. | 882 // Create a map with single inobject property. |
883 Handle<Map> my_map = FACTORY->CopyMap(object_map, 1); | 883 Handle<Map> my_map = FACTORY->CopyMap(object_map, 1); |
884 int n_properties = my_map->inobject_properties(); | 884 int n_properties = my_map->inobject_properties(); |
885 CHECK_GT(n_properties, 0); | 885 CHECK_GT(n_properties, 0); |
886 | 886 |
887 int object_size = my_map->instance_size(); | 887 int object_size = my_map->instance_size(); |
888 | 888 |
889 // Step 2: allocate a lot of objects so to almost fill new space: we need | 889 // Step 2: allocate a lot of objects so to almost fill new space: we need |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 // foo should no longer be in the compilation cache | 978 // foo should no longer be in the compilation cache |
979 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 979 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); |
980 CHECK(!function->is_compiled() || function->IsOptimized()); | 980 CHECK(!function->is_compiled() || function->IsOptimized()); |
981 // Call foo to get it recompiled. | 981 // Call foo to get it recompiled. |
982 CompileRun("foo()"); | 982 CompileRun("foo()"); |
983 CHECK(function->shared()->is_compiled()); | 983 CHECK(function->shared()->is_compiled()); |
984 CHECK(function->is_compiled()); | 984 CHECK(function->is_compiled()); |
985 } | 985 } |
986 | 986 |
987 | 987 |
988 // Count the number of global contexts in the weak list of global contexts. | 988 // Count the number of native contexts in the weak list of native contexts. |
989 int CountGlobalContexts() { | 989 int CountNativeContexts() { |
990 int count = 0; | 990 int count = 0; |
991 Object* object = HEAP->global_contexts_list(); | 991 Object* object = HEAP->native_contexts_list(); |
992 while (!object->IsUndefined()) { | 992 while (!object->IsUndefined()) { |
993 count++; | 993 count++; |
994 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); | 994 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); |
995 } | 995 } |
996 return count; | 996 return count; |
997 } | 997 } |
998 | 998 |
999 | 999 |
1000 // Count the number of user functions in the weak list of optimized | 1000 // Count the number of user functions in the weak list of optimized |
1001 // functions attached to a global context. | 1001 // functions attached to a native context. |
1002 static int CountOptimizedUserFunctions(v8::Handle<v8::Context> context) { | 1002 static int CountOptimizedUserFunctions(v8::Handle<v8::Context> context) { |
1003 int count = 0; | 1003 int count = 0; |
1004 Handle<Context> icontext = v8::Utils::OpenHandle(*context); | 1004 Handle<Context> icontext = v8::Utils::OpenHandle(*context); |
1005 Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST); | 1005 Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST); |
1006 while (object->IsJSFunction() && !JSFunction::cast(object)->IsBuiltin()) { | 1006 while (object->IsJSFunction() && !JSFunction::cast(object)->IsBuiltin()) { |
1007 count++; | 1007 count++; |
1008 object = JSFunction::cast(object)->next_function_link(); | 1008 object = JSFunction::cast(object)->next_function_link(); |
1009 } | 1009 } |
1010 return count; | 1010 return count; |
1011 } | 1011 } |
1012 | 1012 |
1013 | 1013 |
1014 TEST(TestInternalWeakLists) { | 1014 TEST(TestInternalWeakLists) { |
1015 v8::V8::Initialize(); | 1015 v8::V8::Initialize(); |
1016 | 1016 |
1017 static const int kNumTestContexts = 10; | 1017 static const int kNumTestContexts = 10; |
1018 | 1018 |
1019 v8::HandleScope scope; | 1019 v8::HandleScope scope; |
1020 v8::Persistent<v8::Context> ctx[kNumTestContexts]; | 1020 v8::Persistent<v8::Context> ctx[kNumTestContexts]; |
1021 | 1021 |
1022 CHECK_EQ(0, CountGlobalContexts()); | 1022 CHECK_EQ(0, CountNativeContexts()); |
1023 | 1023 |
1024 // Create a number of global contests which gets linked together. | 1024 // Create a number of global contests which gets linked together. |
1025 for (int i = 0; i < kNumTestContexts; i++) { | 1025 for (int i = 0; i < kNumTestContexts; i++) { |
1026 ctx[i] = v8::Context::New(); | 1026 ctx[i] = v8::Context::New(); |
1027 | 1027 |
1028 bool opt = (FLAG_always_opt && i::V8::UseCrankshaft()); | 1028 bool opt = (FLAG_always_opt && i::V8::UseCrankshaft()); |
1029 | 1029 |
1030 CHECK_EQ(i + 1, CountGlobalContexts()); | 1030 CHECK_EQ(i + 1, CountNativeContexts()); |
1031 | 1031 |
1032 ctx[i]->Enter(); | 1032 ctx[i]->Enter(); |
1033 | 1033 |
1034 // Create a handle scope so no function objects get stuch in the outer | 1034 // Create a handle scope so no function objects get stuch in the outer |
1035 // handle scope | 1035 // handle scope |
1036 v8::HandleScope scope; | 1036 v8::HandleScope scope; |
1037 const char* source = "function f1() { };" | 1037 const char* source = "function f1() { };" |
1038 "function f2() { };" | 1038 "function f2() { };" |
1039 "function f3() { };" | 1039 "function f3() { };" |
1040 "function f4() { };" | 1040 "function f4() { };" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1080 } | 1080 } |
1081 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1081 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
1082 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); | 1082 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); |
1083 | 1083 |
1084 ctx[i]->Exit(); | 1084 ctx[i]->Exit(); |
1085 } | 1085 } |
1086 | 1086 |
1087 // Force compilation cache cleanup. | 1087 // Force compilation cache cleanup. |
1088 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1088 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
1089 | 1089 |
1090 // Dispose the global contexts one by one. | 1090 // Dispose the native contexts one by one. |
1091 for (int i = 0; i < kNumTestContexts; i++) { | 1091 for (int i = 0; i < kNumTestContexts; i++) { |
1092 ctx[i].Dispose(); | 1092 ctx[i].Dispose(); |
1093 ctx[i].Clear(); | 1093 ctx[i].Clear(); |
1094 | 1094 |
1095 // Scavenge treats these references as strong. | 1095 // Scavenge treats these references as strong. |
1096 for (int j = 0; j < 10; j++) { | 1096 for (int j = 0; j < 10; j++) { |
1097 HEAP->PerformScavenge(); | 1097 HEAP->PerformScavenge(); |
1098 CHECK_EQ(kNumTestContexts - i, CountGlobalContexts()); | 1098 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); |
1099 } | 1099 } |
1100 | 1100 |
1101 // Mark compact handles the weak references. | 1101 // Mark compact handles the weak references. |
1102 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1102 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
1103 CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts()); | 1103 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); |
1104 } | 1104 } |
1105 | 1105 |
1106 CHECK_EQ(0, CountGlobalContexts()); | 1106 CHECK_EQ(0, CountNativeContexts()); |
1107 } | 1107 } |
1108 | 1108 |
1109 | 1109 |
1110 // Count the number of global contexts in the weak list of global contexts | 1110 // Count the number of native contexts in the weak list of native contexts |
1111 // causing a GC after the specified number of elements. | 1111 // causing a GC after the specified number of elements. |
1112 static int CountGlobalContextsWithGC(int n) { | 1112 static int CountNativeContextsWithGC(int n) { |
1113 int count = 0; | 1113 int count = 0; |
1114 Handle<Object> object(HEAP->global_contexts_list()); | 1114 Handle<Object> object(HEAP->native_contexts_list()); |
1115 while (!object->IsUndefined()) { | 1115 while (!object->IsUndefined()) { |
1116 count++; | 1116 count++; |
1117 if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1117 if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
1118 object = | 1118 object = |
1119 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK)); | 1119 Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK)); |
1120 } | 1120 } |
1121 return count; | 1121 return count; |
1122 } | 1122 } |
1123 | 1123 |
1124 | 1124 |
1125 // Count the number of user functions in the weak list of optimized | 1125 // Count the number of user functions in the weak list of optimized |
1126 // functions attached to a global context causing a GC after the | 1126 // functions attached to a native context causing a GC after the |
1127 // specified number of elements. | 1127 // specified number of elements. |
1128 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, | 1128 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, |
1129 int n) { | 1129 int n) { |
1130 int count = 0; | 1130 int count = 0; |
1131 Handle<Context> icontext = v8::Utils::OpenHandle(*context); | 1131 Handle<Context> icontext = v8::Utils::OpenHandle(*context); |
1132 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST)); | 1132 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST)); |
1133 while (object->IsJSFunction() && | 1133 while (object->IsJSFunction() && |
1134 !Handle<JSFunction>::cast(object)->IsBuiltin()) { | 1134 !Handle<JSFunction>::cast(object)->IsBuiltin()) { |
1135 count++; | 1135 count++; |
1136 if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1136 if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
1137 object = Handle<Object>( | 1137 object = Handle<Object>( |
1138 Object::cast(JSFunction::cast(*object)->next_function_link())); | 1138 Object::cast(JSFunction::cast(*object)->next_function_link())); |
1139 } | 1139 } |
1140 return count; | 1140 return count; |
1141 } | 1141 } |
1142 | 1142 |
1143 | 1143 |
1144 TEST(TestInternalWeakListsTraverseWithGC) { | 1144 TEST(TestInternalWeakListsTraverseWithGC) { |
1145 v8::V8::Initialize(); | 1145 v8::V8::Initialize(); |
1146 | 1146 |
1147 static const int kNumTestContexts = 10; | 1147 static const int kNumTestContexts = 10; |
1148 | 1148 |
1149 v8::HandleScope scope; | 1149 v8::HandleScope scope; |
1150 v8::Persistent<v8::Context> ctx[kNumTestContexts]; | 1150 v8::Persistent<v8::Context> ctx[kNumTestContexts]; |
1151 | 1151 |
1152 CHECK_EQ(0, CountGlobalContexts()); | 1152 CHECK_EQ(0, CountNativeContexts()); |
1153 | 1153 |
1154 // Create an number of contexts and check the length of the weak list both | 1154 // Create an number of contexts and check the length of the weak list both |
1155 // with and without GCs while iterating the list. | 1155 // with and without GCs while iterating the list. |
1156 for (int i = 0; i < kNumTestContexts; i++) { | 1156 for (int i = 0; i < kNumTestContexts; i++) { |
1157 ctx[i] = v8::Context::New(); | 1157 ctx[i] = v8::Context::New(); |
1158 CHECK_EQ(i + 1, CountGlobalContexts()); | 1158 CHECK_EQ(i + 1, CountNativeContexts()); |
1159 CHECK_EQ(i + 1, CountGlobalContextsWithGC(i / 2 + 1)); | 1159 CHECK_EQ(i + 1, CountNativeContextsWithGC(i / 2 + 1)); |
1160 } | 1160 } |
1161 | 1161 |
1162 bool opt = (FLAG_always_opt && i::V8::UseCrankshaft()); | 1162 bool opt = (FLAG_always_opt && i::V8::UseCrankshaft()); |
1163 | 1163 |
1164 // Compile a number of functions the length of the weak list of optimized | 1164 // Compile a number of functions the length of the weak list of optimized |
1165 // functions both with and without GCs while iterating the list. | 1165 // functions both with and without GCs while iterating the list. |
1166 ctx[0]->Enter(); | 1166 ctx[0]->Enter(); |
1167 const char* source = "function f1() { };" | 1167 const char* source = "function f1() { };" |
1168 "function f2() { };" | 1168 "function f2() { };" |
1169 "function f3() { };" | 1169 "function f3() { };" |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1359 HeapIterator iterator; | 1359 HeapIterator iterator; |
1360 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1360 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
1361 if (obj->IsGlobalObject()) count++; | 1361 if (obj->IsGlobalObject()) count++; |
1362 } | 1362 } |
1363 return count; | 1363 return count; |
1364 } | 1364 } |
1365 | 1365 |
1366 | 1366 |
1367 // Test that we don't embed maps from foreign contexts into | 1367 // Test that we don't embed maps from foreign contexts into |
1368 // optimized code. | 1368 // optimized code. |
1369 TEST(LeakGlobalContextViaMap) { | 1369 TEST(LeakNativeContextViaMap) { |
1370 i::FLAG_allow_natives_syntax = true; | 1370 i::FLAG_allow_natives_syntax = true; |
1371 v8::HandleScope outer_scope; | 1371 v8::HandleScope outer_scope; |
1372 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); | 1372 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
1373 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); | 1373 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
1374 ctx1->Enter(); | 1374 ctx1->Enter(); |
1375 | 1375 |
1376 HEAP->CollectAllAvailableGarbage(); | 1376 HEAP->CollectAllAvailableGarbage(); |
1377 CHECK_EQ(4, NumberOfGlobalObjects()); | 1377 CHECK_EQ(4, NumberOfGlobalObjects()); |
1378 | 1378 |
1379 { | 1379 { |
(...skipping 16 matching lines...) Expand all Loading... |
1396 HEAP->CollectAllAvailableGarbage(); | 1396 HEAP->CollectAllAvailableGarbage(); |
1397 CHECK_EQ(2, NumberOfGlobalObjects()); | 1397 CHECK_EQ(2, NumberOfGlobalObjects()); |
1398 ctx2.Dispose(); | 1398 ctx2.Dispose(); |
1399 HEAP->CollectAllAvailableGarbage(); | 1399 HEAP->CollectAllAvailableGarbage(); |
1400 CHECK_EQ(0, NumberOfGlobalObjects()); | 1400 CHECK_EQ(0, NumberOfGlobalObjects()); |
1401 } | 1401 } |
1402 | 1402 |
1403 | 1403 |
1404 // Test that we don't embed functions from foreign contexts into | 1404 // Test that we don't embed functions from foreign contexts into |
1405 // optimized code. | 1405 // optimized code. |
1406 TEST(LeakGlobalContextViaFunction) { | 1406 TEST(LeakNativeContextViaFunction) { |
1407 i::FLAG_allow_natives_syntax = true; | 1407 i::FLAG_allow_natives_syntax = true; |
1408 v8::HandleScope outer_scope; | 1408 v8::HandleScope outer_scope; |
1409 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); | 1409 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
1410 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); | 1410 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
1411 ctx1->Enter(); | 1411 ctx1->Enter(); |
1412 | 1412 |
1413 HEAP->CollectAllAvailableGarbage(); | 1413 HEAP->CollectAllAvailableGarbage(); |
1414 CHECK_EQ(4, NumberOfGlobalObjects()); | 1414 CHECK_EQ(4, NumberOfGlobalObjects()); |
1415 | 1415 |
1416 { | 1416 { |
(...skipping 14 matching lines...) Expand all Loading... |
1431 ctx1.Dispose(); | 1431 ctx1.Dispose(); |
1432 } | 1432 } |
1433 HEAP->CollectAllAvailableGarbage(); | 1433 HEAP->CollectAllAvailableGarbage(); |
1434 CHECK_EQ(2, NumberOfGlobalObjects()); | 1434 CHECK_EQ(2, NumberOfGlobalObjects()); |
1435 ctx2.Dispose(); | 1435 ctx2.Dispose(); |
1436 HEAP->CollectAllAvailableGarbage(); | 1436 HEAP->CollectAllAvailableGarbage(); |
1437 CHECK_EQ(0, NumberOfGlobalObjects()); | 1437 CHECK_EQ(0, NumberOfGlobalObjects()); |
1438 } | 1438 } |
1439 | 1439 |
1440 | 1440 |
1441 TEST(LeakGlobalContextViaMapKeyed) { | 1441 TEST(LeakNativeContextViaMapKeyed) { |
1442 i::FLAG_allow_natives_syntax = true; | 1442 i::FLAG_allow_natives_syntax = true; |
1443 v8::HandleScope outer_scope; | 1443 v8::HandleScope outer_scope; |
1444 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); | 1444 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
1445 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); | 1445 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
1446 ctx1->Enter(); | 1446 ctx1->Enter(); |
1447 | 1447 |
1448 HEAP->CollectAllAvailableGarbage(); | 1448 HEAP->CollectAllAvailableGarbage(); |
1449 CHECK_EQ(4, NumberOfGlobalObjects()); | 1449 CHECK_EQ(4, NumberOfGlobalObjects()); |
1450 | 1450 |
1451 { | 1451 { |
(...skipping 14 matching lines...) Expand all Loading... |
1466 ctx1.Dispose(); | 1466 ctx1.Dispose(); |
1467 } | 1467 } |
1468 HEAP->CollectAllAvailableGarbage(); | 1468 HEAP->CollectAllAvailableGarbage(); |
1469 CHECK_EQ(2, NumberOfGlobalObjects()); | 1469 CHECK_EQ(2, NumberOfGlobalObjects()); |
1470 ctx2.Dispose(); | 1470 ctx2.Dispose(); |
1471 HEAP->CollectAllAvailableGarbage(); | 1471 HEAP->CollectAllAvailableGarbage(); |
1472 CHECK_EQ(0, NumberOfGlobalObjects()); | 1472 CHECK_EQ(0, NumberOfGlobalObjects()); |
1473 } | 1473 } |
1474 | 1474 |
1475 | 1475 |
1476 TEST(LeakGlobalContextViaMapProto) { | 1476 TEST(LeakNativeContextViaMapProto) { |
1477 i::FLAG_allow_natives_syntax = true; | 1477 i::FLAG_allow_natives_syntax = true; |
1478 v8::HandleScope outer_scope; | 1478 v8::HandleScope outer_scope; |
1479 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); | 1479 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
1480 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); | 1480 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
1481 ctx1->Enter(); | 1481 ctx1->Enter(); |
1482 | 1482 |
1483 HEAP->CollectAllAvailableGarbage(); | 1483 HEAP->CollectAllAvailableGarbage(); |
1484 CHECK_EQ(4, NumberOfGlobalObjects()); | 1484 CHECK_EQ(4, NumberOfGlobalObjects()); |
1485 | 1485 |
1486 { | 1486 { |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2033 fun1 = env->Global()->Get(v8_str("fun")); | 2033 fun1 = env->Global()->Get(v8_str("fun")); |
2034 } | 2034 } |
2035 | 2035 |
2036 { | 2036 { |
2037 LocalContext env; | 2037 LocalContext env; |
2038 CompileRun("function fun() {};"); | 2038 CompileRun("function fun() {};"); |
2039 fun2 = env->Global()->Get(v8_str("fun")); | 2039 fun2 = env->Global()->Get(v8_str("fun")); |
2040 } | 2040 } |
2041 | 2041 |
2042 // Prepare function f that contains type feedback for closures | 2042 // Prepare function f that contains type feedback for closures |
2043 // originating from two different global contexts. | 2043 // originating from two different native contexts. |
2044 v8::Context::GetCurrent()->Global()->Set(v8_str("fun1"), fun1); | 2044 v8::Context::GetCurrent()->Global()->Set(v8_str("fun1"), fun1); |
2045 v8::Context::GetCurrent()->Global()->Set(v8_str("fun2"), fun2); | 2045 v8::Context::GetCurrent()->Global()->Set(v8_str("fun2"), fun2); |
2046 CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);"); | 2046 CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);"); |
2047 Handle<JSFunction> f = | 2047 Handle<JSFunction> f = |
2048 v8::Utils::OpenHandle( | 2048 v8::Utils::OpenHandle( |
2049 *v8::Handle<v8::Function>::Cast( | 2049 *v8::Handle<v8::Function>::Cast( |
2050 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2050 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
2051 Handle<TypeFeedbackCells> cells(TypeFeedbackInfo::cast( | 2051 Handle<TypeFeedbackCells> cells(TypeFeedbackInfo::cast( |
2052 f->shared()->code()->type_feedback_info())->type_feedback_cells()); | 2052 f->shared()->code()->type_feedback_info())->type_feedback_cells()); |
2053 | 2053 |
(...skipping 25 matching lines...) Expand all Loading... |
2079 return NULL; | 2079 return NULL; |
2080 } | 2080 } |
2081 | 2081 |
2082 | 2082 |
2083 TEST(IncrementalMarkingPreservesMonomorhpicIC) { | 2083 TEST(IncrementalMarkingPreservesMonomorhpicIC) { |
2084 if (i::FLAG_always_opt) return; | 2084 if (i::FLAG_always_opt) return; |
2085 InitializeVM(); | 2085 InitializeVM(); |
2086 v8::HandleScope scope; | 2086 v8::HandleScope scope; |
2087 | 2087 |
2088 // Prepare function f that contains a monomorphic IC for object | 2088 // Prepare function f that contains a monomorphic IC for object |
2089 // originating from the same global context. | 2089 // originating from the same native context. |
2090 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" | 2090 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" |
2091 "function f(o) { return o.x; } f(obj); f(obj);"); | 2091 "function f(o) { return o.x; } f(obj); f(obj);"); |
2092 Handle<JSFunction> f = | 2092 Handle<JSFunction> f = |
2093 v8::Utils::OpenHandle( | 2093 v8::Utils::OpenHandle( |
2094 *v8::Handle<v8::Function>::Cast( | 2094 *v8::Handle<v8::Function>::Cast( |
2095 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2095 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
2096 | 2096 |
2097 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2097 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
2098 CHECK(ic_before->ic_state() == MONOMORPHIC); | 2098 CHECK(ic_before->ic_state() == MONOMORPHIC); |
2099 | 2099 |
(...skipping 13 matching lines...) Expand all Loading... |
2113 v8::HandleScope scope; | 2113 v8::HandleScope scope; |
2114 v8::Local<v8::Value> obj1; | 2114 v8::Local<v8::Value> obj1; |
2115 | 2115 |
2116 { | 2116 { |
2117 LocalContext env; | 2117 LocalContext env; |
2118 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); | 2118 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); |
2119 obj1 = env->Global()->Get(v8_str("obj")); | 2119 obj1 = env->Global()->Get(v8_str("obj")); |
2120 } | 2120 } |
2121 | 2121 |
2122 // Prepare function f that contains a monomorphic IC for object | 2122 // Prepare function f that contains a monomorphic IC for object |
2123 // originating from a different global context. | 2123 // originating from a different native context. |
2124 v8::Context::GetCurrent()->Global()->Set(v8_str("obj1"), obj1); | 2124 v8::Context::GetCurrent()->Global()->Set(v8_str("obj1"), obj1); |
2125 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1);"); | 2125 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1);"); |
2126 Handle<JSFunction> f = | 2126 Handle<JSFunction> f = |
2127 v8::Utils::OpenHandle( | 2127 v8::Utils::OpenHandle( |
2128 *v8::Handle<v8::Function>::Cast( | 2128 *v8::Handle<v8::Function>::Cast( |
2129 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2129 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
2130 | 2130 |
2131 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2131 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
2132 CHECK(ic_before->ic_state() == MONOMORPHIC); | 2132 CHECK(ic_before->ic_state() == MONOMORPHIC); |
2133 | 2133 |
(...skipping 19 matching lines...) Expand all Loading... |
2153 obj1 = env->Global()->Get(v8_str("obj")); | 2153 obj1 = env->Global()->Get(v8_str("obj")); |
2154 } | 2154 } |
2155 | 2155 |
2156 { | 2156 { |
2157 LocalContext env; | 2157 LocalContext env; |
2158 CompileRun("function fun() { this.x = 2; }; var obj = new fun();"); | 2158 CompileRun("function fun() { this.x = 2; }; var obj = new fun();"); |
2159 obj2 = env->Global()->Get(v8_str("obj")); | 2159 obj2 = env->Global()->Get(v8_str("obj")); |
2160 } | 2160 } |
2161 | 2161 |
2162 // Prepare function f that contains a polymorphic IC for objects | 2162 // Prepare function f that contains a polymorphic IC for objects |
2163 // originating from two different global contexts. | 2163 // originating from two different native contexts. |
2164 v8::Context::GetCurrent()->Global()->Set(v8_str("obj1"), obj1); | 2164 v8::Context::GetCurrent()->Global()->Set(v8_str("obj1"), obj1); |
2165 v8::Context::GetCurrent()->Global()->Set(v8_str("obj2"), obj2); | 2165 v8::Context::GetCurrent()->Global()->Set(v8_str("obj2"), obj2); |
2166 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);"); | 2166 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);"); |
2167 Handle<JSFunction> f = | 2167 Handle<JSFunction> f = |
2168 v8::Utils::OpenHandle( | 2168 v8::Utils::OpenHandle( |
2169 *v8::Handle<v8::Function>::Cast( | 2169 *v8::Handle<v8::Function>::Cast( |
2170 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); | 2170 v8::Context::GetCurrent()->Global()->Get(v8_str("f")))); |
2171 | 2171 |
2172 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2172 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
2173 CHECK(ic_before->ic_state() == MEGAMORPHIC); | 2173 CHECK(ic_before->ic_state() == MEGAMORPHIC); |
2174 | 2174 |
2175 // Fire context dispose notification. | 2175 // Fire context dispose notification. |
2176 v8::V8::ContextDisposedNotification(); | 2176 v8::V8::ContextDisposedNotification(); |
2177 SimulateIncrementalMarking(); | 2177 SimulateIncrementalMarking(); |
2178 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2178 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
2179 | 2179 |
2180 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 2180 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
2181 CHECK(ic_after->ic_state() == UNINITIALIZED); | 2181 CHECK(ic_after->ic_state() == UNINITIALIZED); |
2182 } | 2182 } |
OLD | NEW |