| 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 1271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 intptr_t old_capacity, new_capacity; | 1282 intptr_t old_capacity, new_capacity; |
| 1283 old_capacity = new_space->Capacity(); | 1283 old_capacity = new_space->Capacity(); |
| 1284 new_space->Grow(); | 1284 new_space->Grow(); |
| 1285 new_capacity = new_space->Capacity(); | 1285 new_capacity = new_space->Capacity(); |
| 1286 CHECK(2 * old_capacity == new_capacity); | 1286 CHECK(2 * old_capacity == new_capacity); |
| 1287 FillUpNewSpace(new_space); | 1287 FillUpNewSpace(new_space); |
| 1288 HEAP->CollectAllAvailableGarbage(); | 1288 HEAP->CollectAllAvailableGarbage(); |
| 1289 new_capacity = new_space->Capacity(); | 1289 new_capacity = new_space->Capacity(); |
| 1290 CHECK(old_capacity == new_capacity); | 1290 CHECK(old_capacity == new_capacity); |
| 1291 } | 1291 } |
| 1292 |
| 1293 |
| 1294 static int NumberOfGlobalObjects() { |
| 1295 int count = 0; |
| 1296 HeapIterator iterator; |
| 1297 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 1298 if (obj->IsGlobalObject()) count++; |
| 1299 } |
| 1300 return count; |
| 1301 } |
| 1302 |
| 1303 |
| 1304 // Test that we don't embed maps from foreign contexts into |
| 1305 // optimized code. |
| 1306 TEST(LeakGlobalContextViaMap) { |
| 1307 i::FLAG_allow_natives_syntax = true; |
| 1308 v8::HandleScope outer_scope; |
| 1309 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
| 1310 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
| 1311 ctx1->Enter(); |
| 1312 |
| 1313 HEAP->CollectAllAvailableGarbage(); |
| 1314 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1315 |
| 1316 { |
| 1317 v8::HandleScope inner_scope; |
| 1318 CompileRun("var v = {x: 42}"); |
| 1319 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1320 ctx2->Enter(); |
| 1321 ctx2->Global()->Set(v8_str("o"), v); |
| 1322 v8::Local<v8::Value> res = CompileRun( |
| 1323 "function f() { return o.x; }" |
| 1324 "for (var i = 0; i < 10; ++i) f();" |
| 1325 "%OptimizeFunctionOnNextCall(f);" |
| 1326 "f();"); |
| 1327 CHECK_EQ(42, res->Int32Value()); |
| 1328 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1329 ctx2->Exit(); |
| 1330 ctx1->Exit(); |
| 1331 ctx1.Dispose(); |
| 1332 } |
| 1333 HEAP->CollectAllAvailableGarbage(); |
| 1334 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1335 ctx2.Dispose(); |
| 1336 HEAP->CollectAllAvailableGarbage(); |
| 1337 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1338 } |
| 1339 |
| 1340 |
| 1341 // Test that we don't embed functions from foreign contexts into |
| 1342 // optimized code. |
| 1343 TEST(LeakGlobalContextViaFunction) { |
| 1344 i::FLAG_allow_natives_syntax = true; |
| 1345 v8::HandleScope outer_scope; |
| 1346 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
| 1347 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
| 1348 ctx1->Enter(); |
| 1349 |
| 1350 HEAP->CollectAllAvailableGarbage(); |
| 1351 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1352 |
| 1353 { |
| 1354 v8::HandleScope inner_scope; |
| 1355 CompileRun("var v = function() { return 42; }"); |
| 1356 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1357 ctx2->Enter(); |
| 1358 ctx2->Global()->Set(v8_str("o"), v); |
| 1359 v8::Local<v8::Value> res = CompileRun( |
| 1360 "function f(x) { return x(); }" |
| 1361 "for (var i = 0; i < 10; ++i) f(o);" |
| 1362 "%OptimizeFunctionOnNextCall(f);" |
| 1363 "f(o);"); |
| 1364 CHECK_EQ(42, res->Int32Value()); |
| 1365 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1366 ctx2->Exit(); |
| 1367 ctx1->Exit(); |
| 1368 ctx1.Dispose(); |
| 1369 } |
| 1370 HEAP->CollectAllAvailableGarbage(); |
| 1371 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1372 ctx2.Dispose(); |
| 1373 HEAP->CollectAllAvailableGarbage(); |
| 1374 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1375 } |
| 1376 |
| 1377 |
| 1378 TEST(LeakGlobalContextViaMapKeyed) { |
| 1379 i::FLAG_allow_natives_syntax = true; |
| 1380 v8::HandleScope outer_scope; |
| 1381 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
| 1382 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
| 1383 ctx1->Enter(); |
| 1384 |
| 1385 HEAP->CollectAllAvailableGarbage(); |
| 1386 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1387 |
| 1388 { |
| 1389 v8::HandleScope inner_scope; |
| 1390 CompileRun("var v = [42, 43]"); |
| 1391 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1392 ctx2->Enter(); |
| 1393 ctx2->Global()->Set(v8_str("o"), v); |
| 1394 v8::Local<v8::Value> res = CompileRun( |
| 1395 "function f() { return o[0]; }" |
| 1396 "for (var i = 0; i < 10; ++i) f();" |
| 1397 "%OptimizeFunctionOnNextCall(f);" |
| 1398 "f();"); |
| 1399 CHECK_EQ(42, res->Int32Value()); |
| 1400 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1401 ctx2->Exit(); |
| 1402 ctx1->Exit(); |
| 1403 ctx1.Dispose(); |
| 1404 } |
| 1405 HEAP->CollectAllAvailableGarbage(); |
| 1406 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1407 ctx2.Dispose(); |
| 1408 HEAP->CollectAllAvailableGarbage(); |
| 1409 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1410 } |
| 1411 |
| 1412 |
| 1413 TEST(LeakGlobalContextViaMapProto) { |
| 1414 i::FLAG_allow_natives_syntax = true; |
| 1415 v8::HandleScope outer_scope; |
| 1416 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
| 1417 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
| 1418 ctx1->Enter(); |
| 1419 |
| 1420 HEAP->CollectAllAvailableGarbage(); |
| 1421 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 1422 |
| 1423 { |
| 1424 v8::HandleScope inner_scope; |
| 1425 CompileRun("var v = { y: 42}"); |
| 1426 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 1427 ctx2->Enter(); |
| 1428 ctx2->Global()->Set(v8_str("o"), v); |
| 1429 v8::Local<v8::Value> res = CompileRun( |
| 1430 "function f() {" |
| 1431 " var p = {x: 42};" |
| 1432 " p.__proto__ = o;" |
| 1433 " return p.x;" |
| 1434 "}" |
| 1435 "for (var i = 0; i < 10; ++i) f();" |
| 1436 "%OptimizeFunctionOnNextCall(f);" |
| 1437 "f();"); |
| 1438 CHECK_EQ(42, res->Int32Value()); |
| 1439 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
| 1440 ctx2->Exit(); |
| 1441 ctx1->Exit(); |
| 1442 ctx1.Dispose(); |
| 1443 } |
| 1444 HEAP->CollectAllAvailableGarbage(); |
| 1445 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 1446 ctx2.Dispose(); |
| 1447 HEAP->CollectAllAvailableGarbage(); |
| 1448 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 1449 } |
| OLD | NEW |