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 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1326 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1326 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
1327 if (obj->IsGlobalObject()) count++; | 1327 if (obj->IsGlobalObject()) count++; |
1328 } | 1328 } |
1329 return count; | 1329 return count; |
1330 } | 1330 } |
1331 | 1331 |
1332 | 1332 |
1333 // Test that we don't embed maps from foreign contexts into | 1333 // Test that we don't embed maps from foreign contexts into |
1334 // optimized code. | 1334 // optimized code. |
1335 TEST(LeakGlobalContextViaMap) { | 1335 TEST(LeakGlobalContextViaMap) { |
| 1336 i::FLAG_allow_natives_syntax = true; |
1336 v8::HandleScope outer_scope; | 1337 v8::HandleScope outer_scope; |
1337 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); | 1338 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
1338 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); | 1339 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
1339 ctx1->Enter(); | 1340 ctx1->Enter(); |
1340 | 1341 |
1341 HEAP->CollectAllAvailableGarbage(); | 1342 HEAP->CollectAllAvailableGarbage(); |
1342 CHECK_EQ(4, NumberOfGlobalObjects()); | 1343 CHECK_EQ(4, NumberOfGlobalObjects()); |
1343 | 1344 |
1344 { | 1345 { |
1345 v8::HandleScope inner_scope; | 1346 v8::HandleScope inner_scope; |
1346 CompileRun("var v = {x: 42}"); | 1347 CompileRun("var v = {x: 42}"); |
1347 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 1348 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
1348 ctx2->Enter(); | 1349 ctx2->Enter(); |
1349 ctx2->Global()->Set(v8_str("o"), v); | 1350 ctx2->Global()->Set(v8_str("o"), v); |
1350 v8::Local<v8::Value> res = CompileRun( | 1351 v8::Local<v8::Value> res = CompileRun( |
1351 "function f() { return o.x; }" | 1352 "function f() { return o.x; }" |
1352 "for (var i = 0; i < 1000000; ++i) f();" | 1353 "for (var i = 0; i < 10; ++i) f();" |
| 1354 "%OptimizeFunctionOnNextCall(f);" |
1353 "f();"); | 1355 "f();"); |
1354 CHECK_EQ(42, res->Int32Value()); | 1356 CHECK_EQ(42, res->Int32Value()); |
1355 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1357 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
1356 ctx2->Exit(); | 1358 ctx2->Exit(); |
1357 ctx1->Exit(); | 1359 ctx1->Exit(); |
1358 ctx1.Dispose(); | 1360 ctx1.Dispose(); |
1359 } | 1361 } |
1360 HEAP->CollectAllAvailableGarbage(); | 1362 HEAP->CollectAllAvailableGarbage(); |
1361 CHECK_EQ(2, NumberOfGlobalObjects()); | 1363 CHECK_EQ(2, NumberOfGlobalObjects()); |
1362 ctx2.Dispose(); | 1364 ctx2.Dispose(); |
1363 HEAP->CollectAllAvailableGarbage(); | 1365 HEAP->CollectAllAvailableGarbage(); |
1364 CHECK_EQ(0, NumberOfGlobalObjects()); | 1366 CHECK_EQ(0, NumberOfGlobalObjects()); |
1365 } | 1367 } |
1366 | 1368 |
1367 | 1369 |
1368 // Test that we don't embed functions from foreign contexts into | 1370 // Test that we don't embed functions from foreign contexts into |
1369 // optimized code. | 1371 // optimized code. |
1370 TEST(LeakGlobalContextViaFunction) { | 1372 TEST(LeakGlobalContextViaFunction) { |
| 1373 i::FLAG_allow_natives_syntax = true; |
1371 v8::HandleScope outer_scope; | 1374 v8::HandleScope outer_scope; |
1372 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); | 1375 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
1373 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); | 1376 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
1374 ctx1->Enter(); | 1377 ctx1->Enter(); |
1375 | 1378 |
1376 HEAP->CollectAllAvailableGarbage(); | 1379 HEAP->CollectAllAvailableGarbage(); |
1377 CHECK_EQ(4, NumberOfGlobalObjects()); | 1380 CHECK_EQ(4, NumberOfGlobalObjects()); |
1378 | 1381 |
1379 { | 1382 { |
1380 v8::HandleScope inner_scope; | 1383 v8::HandleScope inner_scope; |
1381 CompileRun("var v = function() { return 42; }"); | 1384 CompileRun("var v = function() { return 42; }"); |
1382 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 1385 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
1383 ctx2->Enter(); | 1386 ctx2->Enter(); |
1384 ctx2->Global()->Set(v8_str("o"), v); | 1387 ctx2->Global()->Set(v8_str("o"), v); |
1385 v8::Local<v8::Value> res = CompileRun( | 1388 v8::Local<v8::Value> res = CompileRun( |
1386 "function f(x) { return x(); }" | 1389 "function f(x) { return x(); }" |
1387 "for (var i = 0; i < 1000000; ++i) f(o);" | 1390 "for (var i = 0; i < 10; ++i) f(o);" |
| 1391 "%OptimizeFunctionOnNextCall(f);" |
1388 "f(o);"); | 1392 "f(o);"); |
1389 CHECK_EQ(42, res->Int32Value()); | 1393 CHECK_EQ(42, res->Int32Value()); |
1390 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1394 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
1391 ctx2->Exit(); | 1395 ctx2->Exit(); |
1392 ctx1->Exit(); | 1396 ctx1->Exit(); |
1393 ctx1.Dispose(); | 1397 ctx1.Dispose(); |
1394 } | 1398 } |
1395 HEAP->CollectAllAvailableGarbage(); | 1399 HEAP->CollectAllAvailableGarbage(); |
1396 CHECK_EQ(2, NumberOfGlobalObjects()); | 1400 CHECK_EQ(2, NumberOfGlobalObjects()); |
1397 ctx2.Dispose(); | 1401 ctx2.Dispose(); |
1398 HEAP->CollectAllAvailableGarbage(); | 1402 HEAP->CollectAllAvailableGarbage(); |
1399 CHECK_EQ(0, NumberOfGlobalObjects()); | 1403 CHECK_EQ(0, NumberOfGlobalObjects()); |
1400 } | 1404 } |
| 1405 |
| 1406 |
| 1407 TEST(LeakGlobalContextViaMapKeyed) { |
| 1408 i::FLAG_allow_natives_syntax = true; |
| 1409 v8::HandleScope outer_scope; |
| 1410 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
| 1411 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
| 1412 ctx1->Enter(); |
| 1413 |
| 1414 HEAP->CollectAllAvailableGarbage(); |
| 1415 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1416 |
| 1417 { |
| 1418 v8::HandleScope inner_scope; |
| 1419 CompileRun("var v = [42, 43]"); |
| 1420 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1421 ctx2->Enter(); |
| 1422 ctx2->Global()->Set(v8_str("o"), v); |
| 1423 v8::Local<v8::Value> res = CompileRun( |
| 1424 "function f() { return o[0]; }" |
| 1425 "for (var i = 0; i < 10; ++i) f();" |
| 1426 "%OptimizeFunctionOnNextCall(f);" |
| 1427 "f();"); |
| 1428 CHECK_EQ(42, res->Int32Value()); |
| 1429 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1430 ctx2->Exit(); |
| 1431 ctx1->Exit(); |
| 1432 ctx1.Dispose(); |
| 1433 } |
| 1434 HEAP->CollectAllAvailableGarbage(); |
| 1435 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1436 ctx2.Dispose(); |
| 1437 HEAP->CollectAllAvailableGarbage(); |
| 1438 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1439 } |
| 1440 |
| 1441 |
| 1442 TEST(LeakGlobalContextViaMapProto) { |
| 1443 i::FLAG_allow_natives_syntax = true; |
| 1444 v8::HandleScope outer_scope; |
| 1445 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
| 1446 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
| 1447 ctx1->Enter(); |
| 1448 |
| 1449 HEAP->CollectAllAvailableGarbage(); |
| 1450 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1451 |
| 1452 { |
| 1453 v8::HandleScope inner_scope; |
| 1454 CompileRun("var v = { y: 42}"); |
| 1455 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1456 ctx2->Enter(); |
| 1457 ctx2->Global()->Set(v8_str("o"), v); |
| 1458 v8::Local<v8::Value> res = CompileRun( |
| 1459 "function f() {" |
| 1460 " var p = {x: 42};" |
| 1461 " p.__proto__ = o;" |
| 1462 " return p.x;" |
| 1463 "}" |
| 1464 "for (var i = 0; i < 10; ++i) f();" |
| 1465 "%OptimizeFunctionOnNextCall(f);" |
| 1466 "f();"); |
| 1467 CHECK_EQ(42, res->Int32Value()); |
| 1468 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1469 ctx2->Exit(); |
| 1470 ctx1->Exit(); |
| 1471 ctx1.Dispose(); |
| 1472 } |
| 1473 HEAP->CollectAllAvailableGarbage(); |
| 1474 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1475 ctx2.Dispose(); |
| 1476 HEAP->CollectAllAvailableGarbage(); |
| 1477 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1478 } |
OLD | NEW |