| 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 |