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 "compilation-cache.h" | 7 #include "compilation-cache.h" |
8 #include "execution.h" | 8 #include "execution.h" |
9 #include "factory.h" | 9 #include "factory.h" |
10 #include "macro-assembler.h" | 10 #include "macro-assembler.h" |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 global_handles->Destroy(h3.location()); | 351 global_handles->Destroy(h3.location()); |
352 | 352 |
353 CHECK_EQ(*h4, *h2); | 353 CHECK_EQ(*h4, *h2); |
354 global_handles->Destroy(h2.location()); | 354 global_handles->Destroy(h2.location()); |
355 global_handles->Destroy(h4.location()); | 355 global_handles->Destroy(h4.location()); |
356 } | 356 } |
357 | 357 |
358 | 358 |
359 static bool WeakPointerCleared = false; | 359 static bool WeakPointerCleared = false; |
360 | 360 |
361 static void TestWeakGlobalHandleCallback(v8::Persistent<v8::Value> handle, | 361 static void TestWeakGlobalHandleCallback(v8::Isolate* isolate, |
| 362 v8::Persistent<v8::Value> handle, |
362 void* id) { | 363 void* id) { |
363 if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true; | 364 if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true; |
364 handle.Dispose(); | 365 handle.Dispose(isolate); |
365 } | 366 } |
366 | 367 |
367 | 368 |
368 TEST(WeakGlobalHandlesScavenge) { | 369 TEST(WeakGlobalHandlesScavenge) { |
369 InitializeVM(); | 370 InitializeVM(); |
370 GlobalHandles* global_handles = Isolate::Current()->global_handles(); | 371 GlobalHandles* global_handles = Isolate::Current()->global_handles(); |
371 | 372 |
372 WeakPointerCleared = false; | 373 WeakPointerCleared = false; |
373 | 374 |
374 Handle<Object> h1; | 375 Handle<Object> h1; |
375 Handle<Object> h2; | 376 Handle<Object> h2; |
376 | 377 |
377 { | 378 { |
378 HandleScope scope; | 379 HandleScope scope; |
379 | 380 |
380 Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk")); | 381 Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk")); |
381 Handle<Object> u = FACTORY->NewNumber(1.12344); | 382 Handle<Object> u = FACTORY->NewNumber(1.12344); |
382 | 383 |
383 h1 = global_handles->Create(*i); | 384 h1 = global_handles->Create(*i); |
384 h2 = global_handles->Create(*u); | 385 h2 = global_handles->Create(*u); |
385 } | 386 } |
386 | 387 |
387 global_handles->MakeWeak(h2.location(), | 388 global_handles->MakeWeak(h2.location(), |
388 reinterpret_cast<void*>(1234), | 389 reinterpret_cast<void*>(1234), |
| 390 NULL, |
389 &TestWeakGlobalHandleCallback); | 391 &TestWeakGlobalHandleCallback); |
390 | 392 |
391 // Scavenge treats weak pointers as normal roots. | 393 // Scavenge treats weak pointers as normal roots. |
392 HEAP->PerformScavenge(); | 394 HEAP->PerformScavenge(); |
393 | 395 |
394 CHECK((*h1)->IsString()); | 396 CHECK((*h1)->IsString()); |
395 CHECK((*h2)->IsHeapNumber()); | 397 CHECK((*h2)->IsHeapNumber()); |
396 | 398 |
397 CHECK(!WeakPointerCleared); | 399 CHECK(!WeakPointerCleared); |
398 CHECK(!global_handles->IsNearDeath(h2.location())); | 400 CHECK(!global_handles->IsNearDeath(h2.location())); |
(...skipping 23 matching lines...) Expand all Loading... |
422 h2 = global_handles->Create(*u); | 424 h2 = global_handles->Create(*u); |
423 } | 425 } |
424 | 426 |
425 // Make sure the objects are promoted. | 427 // Make sure the objects are promoted. |
426 HEAP->CollectGarbage(OLD_POINTER_SPACE); | 428 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
427 HEAP->CollectGarbage(NEW_SPACE); | 429 HEAP->CollectGarbage(NEW_SPACE); |
428 CHECK(!HEAP->InNewSpace(*h1) && !HEAP->InNewSpace(*h2)); | 430 CHECK(!HEAP->InNewSpace(*h1) && !HEAP->InNewSpace(*h2)); |
429 | 431 |
430 global_handles->MakeWeak(h2.location(), | 432 global_handles->MakeWeak(h2.location(), |
431 reinterpret_cast<void*>(1234), | 433 reinterpret_cast<void*>(1234), |
| 434 NULL, |
432 &TestWeakGlobalHandleCallback); | 435 &TestWeakGlobalHandleCallback); |
433 CHECK(!GlobalHandles::IsNearDeath(h1.location())); | 436 CHECK(!GlobalHandles::IsNearDeath(h1.location())); |
434 CHECK(!GlobalHandles::IsNearDeath(h2.location())); | 437 CHECK(!GlobalHandles::IsNearDeath(h2.location())); |
435 | 438 |
436 // Incremental marking potentially marked handles before they turned weak. | 439 // Incremental marking potentially marked handles before they turned weak. |
437 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 440 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
438 | 441 |
439 CHECK((*h1)->IsString()); | 442 CHECK((*h1)->IsString()); |
440 | 443 |
441 CHECK(WeakPointerCleared); | 444 CHECK(WeakPointerCleared); |
(...skipping 13 matching lines...) Expand all Loading... |
455 | 458 |
456 { | 459 { |
457 HandleScope scope; | 460 HandleScope scope; |
458 | 461 |
459 Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk")); | 462 Handle<Object> i = FACTORY->NewStringFromAscii(CStrVector("fisk")); |
460 h = global_handles->Create(*i); | 463 h = global_handles->Create(*i); |
461 } | 464 } |
462 | 465 |
463 global_handles->MakeWeak(h.location(), | 466 global_handles->MakeWeak(h.location(), |
464 reinterpret_cast<void*>(1234), | 467 reinterpret_cast<void*>(1234), |
| 468 NULL, |
465 &TestWeakGlobalHandleCallback); | 469 &TestWeakGlobalHandleCallback); |
466 | 470 |
467 // Scanvenge does not recognize weak reference. | 471 // Scanvenge does not recognize weak reference. |
468 HEAP->PerformScavenge(); | 472 HEAP->PerformScavenge(); |
469 | 473 |
470 CHECK(!WeakPointerCleared); | 474 CHECK(!WeakPointerCleared); |
471 | 475 |
472 // Mark-compact treats weak reference properly. | 476 // Mark-compact treats weak reference properly. |
473 HEAP->CollectGarbage(OLD_POINTER_SPACE); | 477 HEAP->CollectGarbage(OLD_POINTER_SPACE); |
474 | 478 |
(...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); | 1311 CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i])); |
1308 | 1312 |
1309 ctx[i]->Exit(); | 1313 ctx[i]->Exit(); |
1310 } | 1314 } |
1311 | 1315 |
1312 // Force compilation cache cleanup. | 1316 // Force compilation cache cleanup. |
1313 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1317 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
1314 | 1318 |
1315 // Dispose the native contexts one by one. | 1319 // Dispose the native contexts one by one. |
1316 for (int i = 0; i < kNumTestContexts; i++) { | 1320 for (int i = 0; i < kNumTestContexts; i++) { |
1317 ctx[i].Dispose(); | 1321 ctx[i].Dispose(ctx[i]->GetIsolate()); |
1318 ctx[i].Clear(); | 1322 ctx[i].Clear(); |
1319 | 1323 |
1320 // Scavenge treats these references as strong. | 1324 // Scavenge treats these references as strong. |
1321 for (int j = 0; j < 10; j++) { | 1325 for (int j = 0; j < 10; j++) { |
1322 HEAP->PerformScavenge(); | 1326 HEAP->PerformScavenge(); |
1323 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); | 1327 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); |
1324 } | 1328 } |
1325 | 1329 |
1326 // Mark compact handles the weak references. | 1330 // Mark compact handles the weak references. |
1327 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 1331 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1610 ctx2->Global()->Set(v8_str("o"), v); | 1614 ctx2->Global()->Set(v8_str("o"), v); |
1611 v8::Local<v8::Value> res = CompileRun( | 1615 v8::Local<v8::Value> res = CompileRun( |
1612 "function f() { return o.x; }" | 1616 "function f() { return o.x; }" |
1613 "for (var i = 0; i < 10; ++i) f();" | 1617 "for (var i = 0; i < 10; ++i) f();" |
1614 "%OptimizeFunctionOnNextCall(f);" | 1618 "%OptimizeFunctionOnNextCall(f);" |
1615 "f();"); | 1619 "f();"); |
1616 CHECK_EQ(42, res->Int32Value()); | 1620 CHECK_EQ(42, res->Int32Value()); |
1617 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1621 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
1618 ctx2->Exit(); | 1622 ctx2->Exit(); |
1619 ctx1->Exit(); | 1623 ctx1->Exit(); |
1620 ctx1.Dispose(); | 1624 ctx1.Dispose(ctx1->GetIsolate()); |
1621 v8::V8::ContextDisposedNotification(); | 1625 v8::V8::ContextDisposedNotification(); |
1622 } | 1626 } |
1623 HEAP->CollectAllAvailableGarbage(); | 1627 HEAP->CollectAllAvailableGarbage(); |
1624 CHECK_EQ(2, NumberOfGlobalObjects()); | 1628 CHECK_EQ(2, NumberOfGlobalObjects()); |
1625 ctx2.Dispose(); | 1629 ctx2.Dispose(ctx2->GetIsolate()); |
1626 HEAP->CollectAllAvailableGarbage(); | 1630 HEAP->CollectAllAvailableGarbage(); |
1627 CHECK_EQ(0, NumberOfGlobalObjects()); | 1631 CHECK_EQ(0, NumberOfGlobalObjects()); |
1628 } | 1632 } |
1629 | 1633 |
1630 | 1634 |
1631 // Test that we don't embed functions from foreign contexts into | 1635 // Test that we don't embed functions from foreign contexts into |
1632 // optimized code. | 1636 // optimized code. |
1633 TEST(LeakNativeContextViaFunction) { | 1637 TEST(LeakNativeContextViaFunction) { |
1634 i::FLAG_allow_natives_syntax = true; | 1638 i::FLAG_allow_natives_syntax = true; |
1635 v8::HandleScope outer_scope; | 1639 v8::HandleScope outer_scope; |
(...skipping 12 matching lines...) Expand all Loading... |
1648 ctx2->Global()->Set(v8_str("o"), v); | 1652 ctx2->Global()->Set(v8_str("o"), v); |
1649 v8::Local<v8::Value> res = CompileRun( | 1653 v8::Local<v8::Value> res = CompileRun( |
1650 "function f(x) { return x(); }" | 1654 "function f(x) { return x(); }" |
1651 "for (var i = 0; i < 10; ++i) f(o);" | 1655 "for (var i = 0; i < 10; ++i) f(o);" |
1652 "%OptimizeFunctionOnNextCall(f);" | 1656 "%OptimizeFunctionOnNextCall(f);" |
1653 "f(o);"); | 1657 "f(o);"); |
1654 CHECK_EQ(42, res->Int32Value()); | 1658 CHECK_EQ(42, res->Int32Value()); |
1655 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1659 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
1656 ctx2->Exit(); | 1660 ctx2->Exit(); |
1657 ctx1->Exit(); | 1661 ctx1->Exit(); |
1658 ctx1.Dispose(); | 1662 ctx1.Dispose(ctx1->GetIsolate()); |
1659 v8::V8::ContextDisposedNotification(); | 1663 v8::V8::ContextDisposedNotification(); |
1660 } | 1664 } |
1661 HEAP->CollectAllAvailableGarbage(); | 1665 HEAP->CollectAllAvailableGarbage(); |
1662 CHECK_EQ(2, NumberOfGlobalObjects()); | 1666 CHECK_EQ(2, NumberOfGlobalObjects()); |
1663 ctx2.Dispose(); | 1667 ctx2.Dispose(ctx2->GetIsolate()); |
1664 HEAP->CollectAllAvailableGarbage(); | 1668 HEAP->CollectAllAvailableGarbage(); |
1665 CHECK_EQ(0, NumberOfGlobalObjects()); | 1669 CHECK_EQ(0, NumberOfGlobalObjects()); |
1666 } | 1670 } |
1667 | 1671 |
1668 | 1672 |
1669 TEST(LeakNativeContextViaMapKeyed) { | 1673 TEST(LeakNativeContextViaMapKeyed) { |
1670 i::FLAG_allow_natives_syntax = true; | 1674 i::FLAG_allow_natives_syntax = true; |
1671 v8::HandleScope outer_scope; | 1675 v8::HandleScope outer_scope; |
1672 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); | 1676 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
1673 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); | 1677 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
(...skipping 10 matching lines...) Expand all Loading... |
1684 ctx2->Global()->Set(v8_str("o"), v); | 1688 ctx2->Global()->Set(v8_str("o"), v); |
1685 v8::Local<v8::Value> res = CompileRun( | 1689 v8::Local<v8::Value> res = CompileRun( |
1686 "function f() { return o[0]; }" | 1690 "function f() { return o[0]; }" |
1687 "for (var i = 0; i < 10; ++i) f();" | 1691 "for (var i = 0; i < 10; ++i) f();" |
1688 "%OptimizeFunctionOnNextCall(f);" | 1692 "%OptimizeFunctionOnNextCall(f);" |
1689 "f();"); | 1693 "f();"); |
1690 CHECK_EQ(42, res->Int32Value()); | 1694 CHECK_EQ(42, res->Int32Value()); |
1691 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1695 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
1692 ctx2->Exit(); | 1696 ctx2->Exit(); |
1693 ctx1->Exit(); | 1697 ctx1->Exit(); |
1694 ctx1.Dispose(); | 1698 ctx1.Dispose(ctx1->GetIsolate()); |
1695 v8::V8::ContextDisposedNotification(); | 1699 v8::V8::ContextDisposedNotification(); |
1696 } | 1700 } |
1697 HEAP->CollectAllAvailableGarbage(); | 1701 HEAP->CollectAllAvailableGarbage(); |
1698 CHECK_EQ(2, NumberOfGlobalObjects()); | 1702 CHECK_EQ(2, NumberOfGlobalObjects()); |
1699 ctx2.Dispose(); | 1703 ctx2.Dispose(ctx2->GetIsolate()); |
1700 HEAP->CollectAllAvailableGarbage(); | 1704 HEAP->CollectAllAvailableGarbage(); |
1701 CHECK_EQ(0, NumberOfGlobalObjects()); | 1705 CHECK_EQ(0, NumberOfGlobalObjects()); |
1702 } | 1706 } |
1703 | 1707 |
1704 | 1708 |
1705 TEST(LeakNativeContextViaMapProto) { | 1709 TEST(LeakNativeContextViaMapProto) { |
1706 i::FLAG_allow_natives_syntax = true; | 1710 i::FLAG_allow_natives_syntax = true; |
1707 v8::HandleScope outer_scope; | 1711 v8::HandleScope outer_scope; |
1708 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); | 1712 v8::Persistent<v8::Context> ctx1 = v8::Context::New(); |
1709 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); | 1713 v8::Persistent<v8::Context> ctx2 = v8::Context::New(); |
(...skipping 14 matching lines...) Expand all Loading... |
1724 " p.__proto__ = o;" | 1728 " p.__proto__ = o;" |
1725 " return p.x;" | 1729 " return p.x;" |
1726 "}" | 1730 "}" |
1727 "for (var i = 0; i < 10; ++i) f();" | 1731 "for (var i = 0; i < 10; ++i) f();" |
1728 "%OptimizeFunctionOnNextCall(f);" | 1732 "%OptimizeFunctionOnNextCall(f);" |
1729 "f();"); | 1733 "f();"); |
1730 CHECK_EQ(42, res->Int32Value()); | 1734 CHECK_EQ(42, res->Int32Value()); |
1731 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); | 1735 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0)); |
1732 ctx2->Exit(); | 1736 ctx2->Exit(); |
1733 ctx1->Exit(); | 1737 ctx1->Exit(); |
1734 ctx1.Dispose(); | 1738 ctx1.Dispose(ctx1->GetIsolate()); |
1735 v8::V8::ContextDisposedNotification(); | 1739 v8::V8::ContextDisposedNotification(); |
1736 } | 1740 } |
1737 HEAP->CollectAllAvailableGarbage(); | 1741 HEAP->CollectAllAvailableGarbage(); |
1738 CHECK_EQ(2, NumberOfGlobalObjects()); | 1742 CHECK_EQ(2, NumberOfGlobalObjects()); |
1739 ctx2.Dispose(); | 1743 ctx2.Dispose(ctx2->GetIsolate()); |
1740 HEAP->CollectAllAvailableGarbage(); | 1744 HEAP->CollectAllAvailableGarbage(); |
1741 CHECK_EQ(0, NumberOfGlobalObjects()); | 1745 CHECK_EQ(0, NumberOfGlobalObjects()); |
1742 } | 1746 } |
1743 | 1747 |
1744 | 1748 |
1745 TEST(InstanceOfStubWriteBarrier) { | 1749 TEST(InstanceOfStubWriteBarrier) { |
1746 i::FLAG_allow_natives_syntax = true; | 1750 i::FLAG_allow_natives_syntax = true; |
1747 #ifdef VERIFY_HEAP | 1751 #ifdef VERIFY_HEAP |
1748 i::FLAG_verify_heap = true; | 1752 i::FLAG_verify_heap = true; |
1749 #endif | 1753 #endif |
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2825 // Now optimize the function so that it is taken off the candidate list. | 2829 // Now optimize the function so that it is taken off the candidate list. |
2826 { | 2830 { |
2827 HandleScope inner_scope; | 2831 HandleScope inner_scope; |
2828 CompileRun("%OptimizeFunctionOnNextCall(f); f(3);"); | 2832 CompileRun("%OptimizeFunctionOnNextCall(f); f(3);"); |
2829 } | 2833 } |
2830 | 2834 |
2831 // This cycle will bust the heap and subsequent cycles will go ballistic. | 2835 // This cycle will bust the heap and subsequent cycles will go ballistic. |
2832 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2836 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
2833 HEAP->CollectAllGarbage(Heap::kNoGCFlags); | 2837 HEAP->CollectAllGarbage(Heap::kNoGCFlags); |
2834 } | 2838 } |
OLD | NEW |