| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| 11 // with the distribution. | 11 // with the distribution. |
| 12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
| 13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
| 14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
| 15 // | 15 // |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 // TODO(jochen): Remove this after the setting is turned on globally. |
| 29 #define V8_IMMINENT_DEPRECATION_WARNINGS |
| 30 |
| 28 #include <stdlib.h> | 31 #include <stdlib.h> |
| 29 #include <utility> | 32 #include <utility> |
| 30 | 33 |
| 31 #include "src/compilation-cache.h" | 34 #include "src/compilation-cache.h" |
| 32 #include "src/context-measure.h" | 35 #include "src/context-measure.h" |
| 33 #include "src/deoptimizer.h" | 36 #include "src/deoptimizer.h" |
| 34 #include "src/execution.h" | 37 #include "src/execution.h" |
| 35 #include "src/factory.h" | 38 #include "src/factory.h" |
| 36 #include "src/global-handles.h" | 39 #include "src/global-handles.h" |
| 37 #include "src/heap/gc-tracer.h" | 40 #include "src/heap/gc-tracer.h" |
| 38 #include "src/heap/memory-reducer.h" | 41 #include "src/heap/memory-reducer.h" |
| 39 #include "src/ic/ic.h" | 42 #include "src/ic/ic.h" |
| 40 #include "src/macro-assembler.h" | 43 #include "src/macro-assembler.h" |
| 41 #include "src/snapshot/snapshot.h" | 44 #include "src/snapshot/snapshot.h" |
| 42 #include "test/cctest/cctest.h" | 45 #include "test/cctest/cctest.h" |
| 43 #include "test/cctest/heap-tester.h" | 46 #include "test/cctest/heap-tester.h" |
| 44 #include "test/cctest/test-feedback-vector.h" | 47 #include "test/cctest/test-feedback-vector.h" |
| 45 | 48 |
| 46 using v8::Just; | |
| 47 | 49 |
| 48 namespace v8 { | 50 namespace v8 { |
| 49 namespace internal { | 51 namespace internal { |
| 50 | 52 |
| 51 static void CheckMap(Map* map, int type, int instance_size) { | 53 static void CheckMap(Map* map, int type, int instance_size) { |
| 52 CHECK(map->IsHeapObject()); | 54 CHECK(map->IsHeapObject()); |
| 53 #ifdef DEBUG | 55 #ifdef DEBUG |
| 54 CHECK(CcTest::heap()->Contains(map)); | 56 CHECK(CcTest::heap()->Contains(map)); |
| 55 #endif | 57 #endif |
| 56 CHECK_EQ(CcTest::heap()->meta_map(), map->map()); | 58 CHECK_EQ(CcTest::heap()->meta_map(), map->map()); |
| (...skipping 1584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1641 count++; | 1643 count++; |
| 1642 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); | 1644 object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); |
| 1643 } | 1645 } |
| 1644 // Subtract one to compensate for the code stub context that is always present | 1646 // Subtract one to compensate for the code stub context that is always present |
| 1645 return count - 1; | 1647 return count - 1; |
| 1646 } | 1648 } |
| 1647 | 1649 |
| 1648 | 1650 |
| 1649 // Count the number of user functions in the weak list of optimized | 1651 // Count the number of user functions in the weak list of optimized |
| 1650 // functions attached to a native context. | 1652 // functions attached to a native context. |
| 1651 static int CountOptimizedUserFunctions(v8::Handle<v8::Context> context) { | 1653 static int CountOptimizedUserFunctions(v8::Local<v8::Context> context) { |
| 1652 int count = 0; | 1654 int count = 0; |
| 1653 Handle<Context> icontext = v8::Utils::OpenHandle(*context); | 1655 Handle<Context> icontext = v8::Utils::OpenHandle(*context); |
| 1654 Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST); | 1656 Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST); |
| 1655 while (object->IsJSFunction() && | 1657 while (object->IsJSFunction() && |
| 1656 !JSFunction::cast(object)->shared()->IsBuiltin()) { | 1658 !JSFunction::cast(object)->shared()->IsBuiltin()) { |
| 1657 count++; | 1659 count++; |
| 1658 object = JSFunction::cast(object)->next_function_link(); | 1660 object = JSFunction::cast(object)->next_function_link(); |
| 1659 } | 1661 } |
| 1660 return count; | 1662 return count; |
| 1661 } | 1663 } |
| 1662 | 1664 |
| 1663 | 1665 |
| 1664 TEST(TestInternalWeakLists) { | 1666 TEST(TestInternalWeakLists) { |
| 1665 FLAG_always_opt = false; | 1667 FLAG_always_opt = false; |
| 1666 FLAG_allow_natives_syntax = true; | 1668 FLAG_allow_natives_syntax = true; |
| 1667 v8::V8::Initialize(); | 1669 v8::V8::Initialize(); |
| 1668 | 1670 |
| 1669 // Some flags turn Scavenge collections into Mark-sweep collections | 1671 // Some flags turn Scavenge collections into Mark-sweep collections |
| 1670 // and hence are incompatible with this test case. | 1672 // and hence are incompatible with this test case. |
| 1671 if (FLAG_gc_global || FLAG_stress_compaction) return; | 1673 if (FLAG_gc_global || FLAG_stress_compaction) return; |
| 1672 FLAG_retain_maps_for_n_gc = 0; | 1674 FLAG_retain_maps_for_n_gc = 0; |
| 1673 | 1675 |
| 1674 static const int kNumTestContexts = 10; | 1676 static const int kNumTestContexts = 10; |
| 1675 | 1677 |
| 1676 Isolate* isolate = CcTest::i_isolate(); | 1678 Isolate* isolate = CcTest::i_isolate(); |
| 1677 Heap* heap = isolate->heap(); | 1679 Heap* heap = isolate->heap(); |
| 1678 HandleScope scope(isolate); | 1680 HandleScope scope(isolate); |
| 1679 v8::Handle<v8::Context> ctx[kNumTestContexts]; | 1681 v8::Local<v8::Context> ctx[kNumTestContexts]; |
| 1680 if (!isolate->use_crankshaft()) return; | 1682 if (!isolate->use_crankshaft()) return; |
| 1681 | 1683 |
| 1682 CHECK_EQ(0, CountNativeContexts()); | 1684 CHECK_EQ(0, CountNativeContexts()); |
| 1683 | 1685 |
| 1684 // Create a number of global contests which gets linked together. | 1686 // Create a number of global contests which gets linked together. |
| 1685 for (int i = 0; i < kNumTestContexts; i++) { | 1687 for (int i = 0; i < kNumTestContexts; i++) { |
| 1686 ctx[i] = v8::Context::New(CcTest::isolate()); | 1688 ctx[i] = v8::Context::New(CcTest::isolate()); |
| 1687 | 1689 |
| 1688 // Collect garbage that might have been created by one of the | 1690 // Collect garbage that might have been created by one of the |
| 1689 // installed extensions. | 1691 // installed extensions. |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1782 isolate); | 1784 isolate); |
| 1783 } | 1785 } |
| 1784 // Subtract one to compensate for the code stub context that is always present | 1786 // Subtract one to compensate for the code stub context that is always present |
| 1785 return count - 1; | 1787 return count - 1; |
| 1786 } | 1788 } |
| 1787 | 1789 |
| 1788 | 1790 |
| 1789 // Count the number of user functions in the weak list of optimized | 1791 // Count the number of user functions in the weak list of optimized |
| 1790 // functions attached to a native context causing a GC after the | 1792 // functions attached to a native context causing a GC after the |
| 1791 // specified number of elements. | 1793 // specified number of elements. |
| 1792 static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context, | 1794 static int CountOptimizedUserFunctionsWithGC(v8::Local<v8::Context> context, |
| 1793 int n) { | 1795 int n) { |
| 1794 int count = 0; | 1796 int count = 0; |
| 1795 Handle<Context> icontext = v8::Utils::OpenHandle(*context); | 1797 Handle<Context> icontext = v8::Utils::OpenHandle(*context); |
| 1796 Isolate* isolate = icontext->GetIsolate(); | 1798 Isolate* isolate = icontext->GetIsolate(); |
| 1797 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST), | 1799 Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST), |
| 1798 isolate); | 1800 isolate); |
| 1799 while (object->IsJSFunction() && | 1801 while (object->IsJSFunction() && |
| 1800 !Handle<JSFunction>::cast(object)->shared()->IsBuiltin()) { | 1802 !Handle<JSFunction>::cast(object)->shared()->IsBuiltin()) { |
| 1801 count++; | 1803 count++; |
| 1802 if (count == n) isolate->heap()->CollectAllGarbage(); | 1804 if (count == n) isolate->heap()->CollectAllGarbage(); |
| 1803 object = Handle<Object>( | 1805 object = Handle<Object>( |
| 1804 Object::cast(JSFunction::cast(*object)->next_function_link()), | 1806 Object::cast(JSFunction::cast(*object)->next_function_link()), |
| 1805 isolate); | 1807 isolate); |
| 1806 } | 1808 } |
| 1807 return count; | 1809 return count; |
| 1808 } | 1810 } |
| 1809 | 1811 |
| 1810 | 1812 |
| 1811 TEST(TestInternalWeakListsTraverseWithGC) { | 1813 TEST(TestInternalWeakListsTraverseWithGC) { |
| 1812 FLAG_always_opt = false; | 1814 FLAG_always_opt = false; |
| 1813 FLAG_allow_natives_syntax = true; | 1815 FLAG_allow_natives_syntax = true; |
| 1814 v8::V8::Initialize(); | 1816 v8::V8::Initialize(); |
| 1815 | 1817 |
| 1816 static const int kNumTestContexts = 10; | 1818 static const int kNumTestContexts = 10; |
| 1817 | 1819 |
| 1818 Isolate* isolate = CcTest::i_isolate(); | 1820 Isolate* isolate = CcTest::i_isolate(); |
| 1819 HandleScope scope(isolate); | 1821 HandleScope scope(isolate); |
| 1820 v8::Handle<v8::Context> ctx[kNumTestContexts]; | 1822 v8::Local<v8::Context> ctx[kNumTestContexts]; |
| 1821 if (!isolate->use_crankshaft()) return; | 1823 if (!isolate->use_crankshaft()) return; |
| 1822 | 1824 |
| 1823 CHECK_EQ(0, CountNativeContexts()); | 1825 CHECK_EQ(0, CountNativeContexts()); |
| 1824 | 1826 |
| 1825 // Create an number of contexts and check the length of the weak list both | 1827 // Create an number of contexts and check the length of the weak list both |
| 1826 // with and without GCs while iterating the list. | 1828 // with and without GCs while iterating the list. |
| 1827 for (int i = 0; i < kNumTestContexts; i++) { | 1829 for (int i = 0; i < kNumTestContexts; i++) { |
| 1828 ctx[i] = v8::Context::New(CcTest::isolate()); | 1830 ctx[i] = v8::Context::New(CcTest::isolate()); |
| 1829 CHECK_EQ(i + 1, CountNativeContexts()); | 1831 CHECK_EQ(i + 1, CountNativeContexts()); |
| 1830 CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); | 1832 CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2382 } | 2384 } |
| 2383 | 2385 |
| 2384 CcTest::heap()->CollectAllAvailableGarbage(); | 2386 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2385 CHECK_EQ(4, NumberOfGlobalObjects()); | 2387 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 2386 | 2388 |
| 2387 { | 2389 { |
| 2388 v8::HandleScope inner_scope(isolate); | 2390 v8::HandleScope inner_scope(isolate); |
| 2389 CompileRun("var v = {x: 42}"); | 2391 CompileRun("var v = {x: 42}"); |
| 2390 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); | 2392 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); |
| 2391 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); | 2393 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); |
| 2392 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 2394 v8::Local<v8::Value> v = |
| 2395 ctx1->Global()->Get(ctx1, v8_str("v")).ToLocalChecked(); |
| 2393 ctx2->Enter(); | 2396 ctx2->Enter(); |
| 2394 ctx2->Global()->Set(v8_str("o"), v); | 2397 CHECK(ctx2->Global()->Set(ctx2, v8_str("o"), v).FromJust()); |
| 2395 v8::Local<v8::Value> res = CompileRun( | 2398 v8::Local<v8::Value> res = CompileRun( |
| 2396 "function f() { return o.x; }" | 2399 "function f() { return o.x; }" |
| 2397 "for (var i = 0; i < 10; ++i) f();" | 2400 "for (var i = 0; i < 10; ++i) f();" |
| 2398 "%OptimizeFunctionOnNextCall(f);" | 2401 "%OptimizeFunctionOnNextCall(f);" |
| 2399 "f();"); | 2402 "f();"); |
| 2400 CHECK_EQ(42, res->Int32Value()); | 2403 CHECK_EQ(42, res->Int32Value(ctx2).FromJust()); |
| 2401 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); | 2404 CHECK(ctx2->Global() |
| 2405 ->Set(ctx2, v8_str("o"), v8::Int32::New(isolate, 0)) |
| 2406 .FromJust()); |
| 2402 ctx2->Exit(); | 2407 ctx2->Exit(); |
| 2403 v8::Local<v8::Context>::New(isolate, ctx1)->Exit(); | 2408 v8::Local<v8::Context>::New(isolate, ctx1)->Exit(); |
| 2404 ctx1p.Reset(); | 2409 ctx1p.Reset(); |
| 2405 isolate->ContextDisposedNotification(); | 2410 isolate->ContextDisposedNotification(); |
| 2406 } | 2411 } |
| 2407 CcTest::heap()->CollectAllAvailableGarbage(); | 2412 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2408 CHECK_EQ(2, NumberOfGlobalObjects()); | 2413 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 2409 ctx2p.Reset(); | 2414 ctx2p.Reset(); |
| 2410 CcTest::heap()->CollectAllAvailableGarbage(); | 2415 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2411 CHECK_EQ(0, NumberOfGlobalObjects()); | 2416 CHECK_EQ(0, NumberOfGlobalObjects()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2428 } | 2433 } |
| 2429 | 2434 |
| 2430 CcTest::heap()->CollectAllAvailableGarbage(); | 2435 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2431 CHECK_EQ(4, NumberOfGlobalObjects()); | 2436 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 2432 | 2437 |
| 2433 { | 2438 { |
| 2434 v8::HandleScope inner_scope(isolate); | 2439 v8::HandleScope inner_scope(isolate); |
| 2435 CompileRun("var v = function() { return 42; }"); | 2440 CompileRun("var v = function() { return 42; }"); |
| 2436 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); | 2441 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); |
| 2437 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); | 2442 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); |
| 2438 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 2443 v8::Local<v8::Value> v = |
| 2444 ctx1->Global()->Get(ctx1, v8_str("v")).ToLocalChecked(); |
| 2439 ctx2->Enter(); | 2445 ctx2->Enter(); |
| 2440 ctx2->Global()->Set(v8_str("o"), v); | 2446 CHECK(ctx2->Global()->Set(ctx2, v8_str("o"), v).FromJust()); |
| 2441 v8::Local<v8::Value> res = CompileRun( | 2447 v8::Local<v8::Value> res = CompileRun( |
| 2442 "function f(x) { return x(); }" | 2448 "function f(x) { return x(); }" |
| 2443 "for (var i = 0; i < 10; ++i) f(o);" | 2449 "for (var i = 0; i < 10; ++i) f(o);" |
| 2444 "%OptimizeFunctionOnNextCall(f);" | 2450 "%OptimizeFunctionOnNextCall(f);" |
| 2445 "f(o);"); | 2451 "f(o);"); |
| 2446 CHECK_EQ(42, res->Int32Value()); | 2452 CHECK_EQ(42, res->Int32Value(ctx2).FromJust()); |
| 2447 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); | 2453 CHECK(ctx2->Global() |
| 2454 ->Set(ctx2, v8_str("o"), v8::Int32::New(isolate, 0)) |
| 2455 .FromJust()); |
| 2448 ctx2->Exit(); | 2456 ctx2->Exit(); |
| 2449 ctx1->Exit(); | 2457 ctx1->Exit(); |
| 2450 ctx1p.Reset(); | 2458 ctx1p.Reset(); |
| 2451 isolate->ContextDisposedNotification(); | 2459 isolate->ContextDisposedNotification(); |
| 2452 } | 2460 } |
| 2453 CcTest::heap()->CollectAllAvailableGarbage(); | 2461 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2454 CHECK_EQ(2, NumberOfGlobalObjects()); | 2462 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 2455 ctx2p.Reset(); | 2463 ctx2p.Reset(); |
| 2456 CcTest::heap()->CollectAllAvailableGarbage(); | 2464 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2457 CHECK_EQ(0, NumberOfGlobalObjects()); | 2465 CHECK_EQ(0, NumberOfGlobalObjects()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2472 } | 2480 } |
| 2473 | 2481 |
| 2474 CcTest::heap()->CollectAllAvailableGarbage(); | 2482 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2475 CHECK_EQ(4, NumberOfGlobalObjects()); | 2483 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 2476 | 2484 |
| 2477 { | 2485 { |
| 2478 v8::HandleScope inner_scope(isolate); | 2486 v8::HandleScope inner_scope(isolate); |
| 2479 CompileRun("var v = [42, 43]"); | 2487 CompileRun("var v = [42, 43]"); |
| 2480 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); | 2488 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); |
| 2481 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); | 2489 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); |
| 2482 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 2490 v8::Local<v8::Value> v = |
| 2491 ctx1->Global()->Get(ctx1, v8_str("v")).ToLocalChecked(); |
| 2483 ctx2->Enter(); | 2492 ctx2->Enter(); |
| 2484 ctx2->Global()->Set(v8_str("o"), v); | 2493 CHECK(ctx2->Global()->Set(ctx2, v8_str("o"), v).FromJust()); |
| 2485 v8::Local<v8::Value> res = CompileRun( | 2494 v8::Local<v8::Value> res = CompileRun( |
| 2486 "function f() { return o[0]; }" | 2495 "function f() { return o[0]; }" |
| 2487 "for (var i = 0; i < 10; ++i) f();" | 2496 "for (var i = 0; i < 10; ++i) f();" |
| 2488 "%OptimizeFunctionOnNextCall(f);" | 2497 "%OptimizeFunctionOnNextCall(f);" |
| 2489 "f();"); | 2498 "f();"); |
| 2490 CHECK_EQ(42, res->Int32Value()); | 2499 CHECK_EQ(42, res->Int32Value(ctx2).FromJust()); |
| 2491 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); | 2500 CHECK(ctx2->Global() |
| 2501 ->Set(ctx2, v8_str("o"), v8::Int32::New(isolate, 0)) |
| 2502 .FromJust()); |
| 2492 ctx2->Exit(); | 2503 ctx2->Exit(); |
| 2493 ctx1->Exit(); | 2504 ctx1->Exit(); |
| 2494 ctx1p.Reset(); | 2505 ctx1p.Reset(); |
| 2495 isolate->ContextDisposedNotification(); | 2506 isolate->ContextDisposedNotification(); |
| 2496 } | 2507 } |
| 2497 CcTest::heap()->CollectAllAvailableGarbage(); | 2508 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2498 CHECK_EQ(2, NumberOfGlobalObjects()); | 2509 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 2499 ctx2p.Reset(); | 2510 ctx2p.Reset(); |
| 2500 CcTest::heap()->CollectAllAvailableGarbage(); | 2511 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2501 CHECK_EQ(0, NumberOfGlobalObjects()); | 2512 CHECK_EQ(0, NumberOfGlobalObjects()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2516 } | 2527 } |
| 2517 | 2528 |
| 2518 CcTest::heap()->CollectAllAvailableGarbage(); | 2529 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2519 CHECK_EQ(4, NumberOfGlobalObjects()); | 2530 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 2520 | 2531 |
| 2521 { | 2532 { |
| 2522 v8::HandleScope inner_scope(isolate); | 2533 v8::HandleScope inner_scope(isolate); |
| 2523 CompileRun("var v = { y: 42}"); | 2534 CompileRun("var v = { y: 42}"); |
| 2524 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); | 2535 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); |
| 2525 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); | 2536 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); |
| 2526 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 2537 v8::Local<v8::Value> v = |
| 2538 ctx1->Global()->Get(ctx1, v8_str("v")).ToLocalChecked(); |
| 2527 ctx2->Enter(); | 2539 ctx2->Enter(); |
| 2528 ctx2->Global()->Set(v8_str("o"), v); | 2540 CHECK(ctx2->Global()->Set(ctx2, v8_str("o"), v).FromJust()); |
| 2529 v8::Local<v8::Value> res = CompileRun( | 2541 v8::Local<v8::Value> res = CompileRun( |
| 2530 "function f() {" | 2542 "function f() {" |
| 2531 " var p = {x: 42};" | 2543 " var p = {x: 42};" |
| 2532 " p.__proto__ = o;" | 2544 " p.__proto__ = o;" |
| 2533 " return p.x;" | 2545 " return p.x;" |
| 2534 "}" | 2546 "}" |
| 2535 "for (var i = 0; i < 10; ++i) f();" | 2547 "for (var i = 0; i < 10; ++i) f();" |
| 2536 "%OptimizeFunctionOnNextCall(f);" | 2548 "%OptimizeFunctionOnNextCall(f);" |
| 2537 "f();"); | 2549 "f();"); |
| 2538 CHECK_EQ(42, res->Int32Value()); | 2550 CHECK_EQ(42, res->Int32Value(ctx2).FromJust()); |
| 2539 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); | 2551 CHECK(ctx2->Global() |
| 2552 ->Set(ctx2, v8_str("o"), v8::Int32::New(isolate, 0)) |
| 2553 .FromJust()); |
| 2540 ctx2->Exit(); | 2554 ctx2->Exit(); |
| 2541 ctx1->Exit(); | 2555 ctx1->Exit(); |
| 2542 ctx1p.Reset(); | 2556 ctx1p.Reset(); |
| 2543 isolate->ContextDisposedNotification(); | 2557 isolate->ContextDisposedNotification(); |
| 2544 } | 2558 } |
| 2545 CcTest::heap()->CollectAllAvailableGarbage(); | 2559 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2546 CHECK_EQ(2, NumberOfGlobalObjects()); | 2560 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 2547 ctx2p.Reset(); | 2561 ctx2p.Reset(); |
| 2548 CcTest::heap()->CollectAllAvailableGarbage(); | 2562 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2549 CHECK_EQ(0, NumberOfGlobalObjects()); | 2563 CHECK_EQ(0, NumberOfGlobalObjects()); |
| 2550 } | 2564 } |
| 2551 | 2565 |
| 2552 | 2566 |
| 2553 TEST(InstanceOfStubWriteBarrier) { | 2567 TEST(InstanceOfStubWriteBarrier) { |
| 2554 i::FLAG_allow_natives_syntax = true; | 2568 i::FLAG_allow_natives_syntax = true; |
| 2555 #ifdef VERIFY_HEAP | 2569 #ifdef VERIFY_HEAP |
| 2556 i::FLAG_verify_heap = true; | 2570 i::FLAG_verify_heap = true; |
| 2557 #endif | 2571 #endif |
| 2558 | 2572 |
| 2559 CcTest::InitializeVM(); | 2573 CcTest::InitializeVM(); |
| 2560 if (!CcTest::i_isolate()->use_crankshaft()) return; | 2574 if (!CcTest::i_isolate()->use_crankshaft()) return; |
| 2561 if (i::FLAG_force_marking_deque_overflows) return; | 2575 if (i::FLAG_force_marking_deque_overflows) return; |
| 2562 v8::HandleScope outer_scope(CcTest::isolate()); | 2576 v8::HandleScope outer_scope(CcTest::isolate()); |
| 2577 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 2563 | 2578 |
| 2564 { | 2579 { |
| 2565 v8::HandleScope scope(CcTest::isolate()); | 2580 v8::HandleScope scope(CcTest::isolate()); |
| 2566 CompileRun( | 2581 CompileRun( |
| 2567 "function foo () { }" | 2582 "function foo () { }" |
| 2568 "function mkbar () { return new (new Function(\"\")) (); }" | 2583 "function mkbar () { return new (new Function(\"\")) (); }" |
| 2569 "function f (x) { return (x instanceof foo); }" | 2584 "function f (x) { return (x instanceof foo); }" |
| 2570 "function g () { f(mkbar()); }" | 2585 "function g () { f(mkbar()); }" |
| 2571 "f(new foo()); f(new foo());" | 2586 "f(new foo()); f(new foo());" |
| 2572 "%OptimizeFunctionOnNextCall(f);" | 2587 "%OptimizeFunctionOnNextCall(f);" |
| 2573 "f(new foo()); g();"); | 2588 "f(new foo()); g();"); |
| 2574 } | 2589 } |
| 2575 | 2590 |
| 2576 IncrementalMarking* marking = CcTest::heap()->incremental_marking(); | 2591 IncrementalMarking* marking = CcTest::heap()->incremental_marking(); |
| 2577 marking->Stop(); | 2592 marking->Stop(); |
| 2578 CcTest::heap()->StartIncrementalMarking(); | 2593 CcTest::heap()->StartIncrementalMarking(); |
| 2579 | 2594 |
| 2580 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 2595 i::Handle<JSFunction> f = i::Handle<JSFunction>::cast( |
| 2581 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 2596 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 2597 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
| 2582 | 2598 |
| 2583 CHECK(f->IsOptimized()); | 2599 CHECK(f->IsOptimized()); |
| 2584 | 2600 |
| 2585 while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) && | 2601 while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) && |
| 2586 !marking->IsStopped()) { | 2602 !marking->IsStopped()) { |
| 2587 // Discard any pending GC requests otherwise we will get GC when we enter | 2603 // Discard any pending GC requests otherwise we will get GC when we enter |
| 2588 // code below. | 2604 // code below. |
| 2589 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | 2605 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 2590 } | 2606 } |
| 2591 | 2607 |
| 2592 CHECK(marking->IsMarking()); | 2608 CHECK(marking->IsMarking()); |
| 2593 | 2609 |
| 2594 { | 2610 { |
| 2595 v8::HandleScope scope(CcTest::isolate()); | 2611 v8::HandleScope scope(CcTest::isolate()); |
| 2596 v8::Handle<v8::Object> global = CcTest::global(); | 2612 v8::Local<v8::Object> global = CcTest::global(); |
| 2597 v8::Handle<v8::Function> g = | 2613 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( |
| 2598 v8::Handle<v8::Function>::Cast(global->Get(v8_str("g"))); | 2614 global->Get(ctx, v8_str("g")).ToLocalChecked()); |
| 2599 g->Call(global, 0, NULL); | 2615 g->Call(ctx, global, 0, nullptr).ToLocalChecked(); |
| 2600 } | 2616 } |
| 2601 | 2617 |
| 2602 CcTest::heap()->incremental_marking()->set_should_hurry(true); | 2618 CcTest::heap()->incremental_marking()->set_should_hurry(true); |
| 2603 CcTest::heap()->CollectGarbage(OLD_SPACE); | 2619 CcTest::heap()->CollectGarbage(OLD_SPACE); |
| 2604 } | 2620 } |
| 2605 | 2621 |
| 2606 | 2622 |
| 2607 static int NumberOfProtoTransitions(Map* map) { | 2623 static int NumberOfProtoTransitions(Map* map) { |
| 2608 return TransitionArray::NumberOfPrototypeTransitions( | 2624 return TransitionArray::NumberOfPrototypeTransitions( |
| 2609 TransitionArray::GetPrototypeTransitions(map)); | 2625 TransitionArray::GetPrototypeTransitions(map)); |
| 2610 } | 2626 } |
| 2611 | 2627 |
| 2612 | 2628 |
| 2613 TEST(PrototypeTransitionClearing) { | 2629 TEST(PrototypeTransitionClearing) { |
| 2614 if (FLAG_never_compact) return; | 2630 if (FLAG_never_compact) return; |
| 2615 CcTest::InitializeVM(); | 2631 CcTest::InitializeVM(); |
| 2616 Isolate* isolate = CcTest::i_isolate(); | 2632 Isolate* isolate = CcTest::i_isolate(); |
| 2617 Factory* factory = isolate->factory(); | 2633 Factory* factory = isolate->factory(); |
| 2618 v8::HandleScope scope(CcTest::isolate()); | 2634 v8::HandleScope scope(CcTest::isolate()); |
| 2635 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 2619 | 2636 |
| 2620 CompileRun("var base = {};"); | 2637 CompileRun("var base = {};"); |
| 2621 Handle<JSObject> baseObject = | 2638 i::Handle<JSObject> baseObject = |
| 2622 v8::Utils::OpenHandle( | 2639 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( |
| 2623 *v8::Handle<v8::Object>::Cast( | 2640 CcTest::global()->Get(ctx, v8_str("base")).ToLocalChecked())); |
| 2624 CcTest::global()->Get(v8_str("base")))); | 2641 |
| 2625 int initialTransitions = NumberOfProtoTransitions(baseObject->map()); | 2642 int initialTransitions = NumberOfProtoTransitions(baseObject->map()); |
| 2626 | 2643 |
| 2627 CompileRun( | 2644 CompileRun( |
| 2628 "var live = [];" | 2645 "var live = [];" |
| 2629 "for (var i = 0; i < 10; i++) {" | 2646 "for (var i = 0; i < 10; i++) {" |
| 2630 " var object = {};" | 2647 " var object = {};" |
| 2631 " var prototype = {};" | 2648 " var prototype = {};" |
| 2632 " object.__proto__ = prototype;" | 2649 " object.__proto__ = prototype;" |
| 2633 " if (i >= 3) live.push(object, prototype);" | 2650 " if (i >= 3) live.push(object, prototype);" |
| 2634 "}"); | 2651 "}"); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2673 TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { | 2690 TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { |
| 2674 i::FLAG_stress_compaction = false; | 2691 i::FLAG_stress_compaction = false; |
| 2675 i::FLAG_allow_natives_syntax = true; | 2692 i::FLAG_allow_natives_syntax = true; |
| 2676 #ifdef VERIFY_HEAP | 2693 #ifdef VERIFY_HEAP |
| 2677 i::FLAG_verify_heap = true; | 2694 i::FLAG_verify_heap = true; |
| 2678 #endif | 2695 #endif |
| 2679 | 2696 |
| 2680 CcTest::InitializeVM(); | 2697 CcTest::InitializeVM(); |
| 2681 if (!CcTest::i_isolate()->use_crankshaft()) return; | 2698 if (!CcTest::i_isolate()->use_crankshaft()) return; |
| 2682 v8::HandleScope outer_scope(CcTest::isolate()); | 2699 v8::HandleScope outer_scope(CcTest::isolate()); |
| 2700 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 2683 | 2701 |
| 2684 { | 2702 { |
| 2685 v8::HandleScope scope(CcTest::isolate()); | 2703 v8::HandleScope scope(CcTest::isolate()); |
| 2686 CompileRun( | 2704 CompileRun( |
| 2687 "function f () {" | 2705 "function f () {" |
| 2688 " var s = 0;" | 2706 " var s = 0;" |
| 2689 " for (var i = 0; i < 100; i++) s += i;" | 2707 " for (var i = 0; i < 100; i++) s += i;" |
| 2690 " return s;" | 2708 " return s;" |
| 2691 "}" | 2709 "}" |
| 2692 "f(); f();" | 2710 "f(); f();" |
| 2693 "%OptimizeFunctionOnNextCall(f);" | 2711 "%OptimizeFunctionOnNextCall(f);" |
| 2694 "f();"); | 2712 "f();"); |
| 2695 } | 2713 } |
| 2696 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 2714 i::Handle<JSFunction> f = i::Handle<JSFunction>::cast( |
| 2697 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 2715 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 2716 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
| 2698 CHECK(f->IsOptimized()); | 2717 CHECK(f->IsOptimized()); |
| 2699 | 2718 |
| 2700 IncrementalMarking* marking = CcTest::heap()->incremental_marking(); | 2719 IncrementalMarking* marking = CcTest::heap()->incremental_marking(); |
| 2701 marking->Stop(); | 2720 marking->Stop(); |
| 2702 CcTest::heap()->StartIncrementalMarking(); | 2721 CcTest::heap()->StartIncrementalMarking(); |
| 2703 // The following calls will increment CcTest::heap()->global_ic_age(). | 2722 // The following calls will increment CcTest::heap()->global_ic_age(). |
| 2704 CcTest::isolate()->ContextDisposedNotification(); | 2723 CcTest::isolate()->ContextDisposedNotification(); |
| 2705 SimulateIncrementalMarking(CcTest::heap()); | 2724 SimulateIncrementalMarking(CcTest::heap()); |
| 2706 CcTest::heap()->CollectAllGarbage(); | 2725 CcTest::heap()->CollectAllGarbage(); |
| 2707 CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age()); | 2726 CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age()); |
| 2708 CHECK_EQ(0, f->shared()->opt_count()); | 2727 CHECK_EQ(0, f->shared()->opt_count()); |
| 2709 CHECK_EQ(0, f->shared()->code()->profiler_ticks()); | 2728 CHECK_EQ(0, f->shared()->code()->profiler_ticks()); |
| 2710 } | 2729 } |
| 2711 | 2730 |
| 2712 | 2731 |
| 2713 TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { | 2732 TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { |
| 2714 i::FLAG_stress_compaction = false; | 2733 i::FLAG_stress_compaction = false; |
| 2715 i::FLAG_allow_natives_syntax = true; | 2734 i::FLAG_allow_natives_syntax = true; |
| 2716 #ifdef VERIFY_HEAP | 2735 #ifdef VERIFY_HEAP |
| 2717 i::FLAG_verify_heap = true; | 2736 i::FLAG_verify_heap = true; |
| 2718 #endif | 2737 #endif |
| 2719 | 2738 |
| 2720 CcTest::InitializeVM(); | 2739 CcTest::InitializeVM(); |
| 2721 if (!CcTest::i_isolate()->use_crankshaft()) return; | 2740 if (!CcTest::i_isolate()->use_crankshaft()) return; |
| 2722 v8::HandleScope outer_scope(CcTest::isolate()); | 2741 v8::HandleScope outer_scope(CcTest::isolate()); |
| 2742 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 2723 | 2743 |
| 2724 { | 2744 { |
| 2725 v8::HandleScope scope(CcTest::isolate()); | 2745 v8::HandleScope scope(CcTest::isolate()); |
| 2726 CompileRun( | 2746 CompileRun( |
| 2727 "function f () {" | 2747 "function f () {" |
| 2728 " var s = 0;" | 2748 " var s = 0;" |
| 2729 " for (var i = 0; i < 100; i++) s += i;" | 2749 " for (var i = 0; i < 100; i++) s += i;" |
| 2730 " return s;" | 2750 " return s;" |
| 2731 "}" | 2751 "}" |
| 2732 "f(); f();" | 2752 "f(); f();" |
| 2733 "%OptimizeFunctionOnNextCall(f);" | 2753 "%OptimizeFunctionOnNextCall(f);" |
| 2734 "f();"); | 2754 "f();"); |
| 2735 } | 2755 } |
| 2736 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 2756 i::Handle<JSFunction> f = i::Handle<JSFunction>::cast( |
| 2737 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 2757 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 2758 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
| 2759 |
| 2738 CHECK(f->IsOptimized()); | 2760 CHECK(f->IsOptimized()); |
| 2739 | 2761 |
| 2740 CcTest::heap()->incremental_marking()->Stop(); | 2762 CcTest::heap()->incremental_marking()->Stop(); |
| 2741 | 2763 |
| 2742 // The following two calls will increment CcTest::heap()->global_ic_age(). | 2764 // The following two calls will increment CcTest::heap()->global_ic_age(). |
| 2743 CcTest::isolate()->ContextDisposedNotification(); | 2765 CcTest::isolate()->ContextDisposedNotification(); |
| 2744 CcTest::heap()->CollectAllGarbage(); | 2766 CcTest::heap()->CollectAllGarbage(); |
| 2745 | 2767 |
| 2746 CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age()); | 2768 CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age()); |
| 2747 CHECK_EQ(0, f->shared()->opt_count()); | 2769 CHECK_EQ(0, f->shared()->opt_count()); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2827 } | 2849 } |
| 2828 | 2850 |
| 2829 | 2851 |
| 2830 // Test that HAllocateObject will always return an object in new-space. | 2852 // Test that HAllocateObject will always return an object in new-space. |
| 2831 TEST(OptimizedAllocationAlwaysInNewSpace) { | 2853 TEST(OptimizedAllocationAlwaysInNewSpace) { |
| 2832 i::FLAG_allow_natives_syntax = true; | 2854 i::FLAG_allow_natives_syntax = true; |
| 2833 CcTest::InitializeVM(); | 2855 CcTest::InitializeVM(); |
| 2834 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2856 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2835 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2857 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2836 v8::HandleScope scope(CcTest::isolate()); | 2858 v8::HandleScope scope(CcTest::isolate()); |
| 2837 | 2859 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 2838 SimulateFullSpace(CcTest::heap()->new_space()); | 2860 SimulateFullSpace(CcTest::heap()->new_space()); |
| 2839 AlwaysAllocateScope always_allocate(CcTest::i_isolate()); | 2861 AlwaysAllocateScope always_allocate(CcTest::i_isolate()); |
| 2840 v8::Local<v8::Value> res = CompileRun( | 2862 v8::Local<v8::Value> res = CompileRun( |
| 2841 "function c(x) {" | 2863 "function c(x) {" |
| 2842 " this.x = x;" | 2864 " this.x = x;" |
| 2843 " for (var i = 0; i < 32; i++) {" | 2865 " for (var i = 0; i < 32; i++) {" |
| 2844 " this['x' + i] = x;" | 2866 " this['x' + i] = x;" |
| 2845 " }" | 2867 " }" |
| 2846 "}" | 2868 "}" |
| 2847 "function f(x) { return new c(x); };" | 2869 "function f(x) { return new c(x); };" |
| 2848 "f(1); f(2); f(3);" | 2870 "f(1); f(2); f(3);" |
| 2849 "%OptimizeFunctionOnNextCall(f);" | 2871 "%OptimizeFunctionOnNextCall(f);" |
| 2850 "f(4);"); | 2872 "f(4);"); |
| 2851 CHECK_EQ( | |
| 2852 4, res.As<v8::Object>()->GetRealNamedProperty(v8_str("x"))->Int32Value()); | |
| 2853 | 2873 |
| 2854 Handle<JSObject> o = | 2874 CHECK_EQ(4, res.As<v8::Object>() |
| 2855 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2875 ->GetRealNamedProperty(ctx, v8_str("x")) |
| 2876 .ToLocalChecked() |
| 2877 ->Int32Value(ctx) |
| 2878 .FromJust()); |
| 2879 |
| 2880 i::Handle<JSObject> o = |
| 2881 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); |
| 2856 | 2882 |
| 2857 CHECK(CcTest::heap()->InNewSpace(*o)); | 2883 CHECK(CcTest::heap()->InNewSpace(*o)); |
| 2858 } | 2884 } |
| 2859 | 2885 |
| 2860 | 2886 |
| 2861 TEST(OptimizedPretenuringAllocationFolding) { | 2887 TEST(OptimizedPretenuringAllocationFolding) { |
| 2862 i::FLAG_allow_natives_syntax = true; | 2888 i::FLAG_allow_natives_syntax = true; |
| 2863 i::FLAG_expose_gc = true; | 2889 i::FLAG_expose_gc = true; |
| 2864 CcTest::InitializeVM(); | 2890 CcTest::InitializeVM(); |
| 2865 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 2891 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 2866 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 2892 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 2867 v8::HandleScope scope(CcTest::isolate()); | 2893 v8::HandleScope scope(CcTest::isolate()); |
| 2868 | 2894 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 2869 // Grow new space unitl maximum capacity reached. | 2895 // Grow new space unitl maximum capacity reached. |
| 2870 while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) { | 2896 while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) { |
| 2871 CcTest::heap()->new_space()->Grow(); | 2897 CcTest::heap()->new_space()->Grow(); |
| 2872 } | 2898 } |
| 2873 | 2899 |
| 2874 i::ScopedVector<char> source(1024); | 2900 i::ScopedVector<char> source(1024); |
| 2875 i::SNPrintF( | 2901 i::SNPrintF( |
| 2876 source, | 2902 source, |
| 2877 "var number_elements = %d;" | 2903 "var number_elements = %d;" |
| 2878 "var elements = new Array();" | 2904 "var elements = new Array();" |
| 2879 "function f() {" | 2905 "function f() {" |
| 2880 " for (var i = 0; i < number_elements; i++) {" | 2906 " for (var i = 0; i < number_elements; i++) {" |
| 2881 " elements[i] = [[{}], [1.1]];" | 2907 " elements[i] = [[{}], [1.1]];" |
| 2882 " }" | 2908 " }" |
| 2883 " return elements[number_elements-1]" | 2909 " return elements[number_elements-1]" |
| 2884 "};" | 2910 "};" |
| 2885 "f(); gc();" | 2911 "f(); gc();" |
| 2886 "f(); f();" | 2912 "f(); f();" |
| 2887 "%%OptimizeFunctionOnNextCall(f);" | 2913 "%%OptimizeFunctionOnNextCall(f);" |
| 2888 "f();", | 2914 "f();", |
| 2889 AllocationSite::kPretenureMinimumCreated); | 2915 AllocationSite::kPretenureMinimumCreated); |
| 2890 | 2916 |
| 2891 v8::Local<v8::Value> res = CompileRun(source.start()); | 2917 v8::Local<v8::Value> res = CompileRun(source.start()); |
| 2892 | 2918 |
| 2893 v8::Local<v8::Value> int_array = v8::Object::Cast(*res)->Get(v8_str("0")); | 2919 v8::Local<v8::Value> int_array = |
| 2894 Handle<JSObject> int_array_handle = | 2920 v8::Object::Cast(*res)->Get(ctx, v8_str("0")).ToLocalChecked(); |
| 2895 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array)); | 2921 i::Handle<JSObject> int_array_handle = |
| 2896 v8::Local<v8::Value> double_array = v8::Object::Cast(*res)->Get(v8_str("1")); | 2922 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(int_array)); |
| 2897 Handle<JSObject> double_array_handle = | 2923 v8::Local<v8::Value> double_array = |
| 2898 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array)); | 2924 v8::Object::Cast(*res)->Get(ctx, v8_str("1")).ToLocalChecked(); |
| 2925 i::Handle<JSObject> double_array_handle = |
| 2926 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(double_array)); |
| 2899 | 2927 |
| 2900 Handle<JSObject> o = | 2928 i::Handle<JSObject> o = |
| 2901 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2929 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); |
| 2902 CHECK(CcTest::heap()->InOldSpace(*o)); | 2930 CHECK(CcTest::heap()->InOldSpace(*o)); |
| 2903 CHECK(CcTest::heap()->InOldSpace(*int_array_handle)); | 2931 CHECK(CcTest::heap()->InOldSpace(*int_array_handle)); |
| 2904 CHECK(CcTest::heap()->InOldSpace(int_array_handle->elements())); | 2932 CHECK(CcTest::heap()->InOldSpace(int_array_handle->elements())); |
| 2905 CHECK(CcTest::heap()->InOldSpace(*double_array_handle)); | 2933 CHECK(CcTest::heap()->InOldSpace(*double_array_handle)); |
| 2906 CHECK(CcTest::heap()->InOldSpace(double_array_handle->elements())); | 2934 CHECK(CcTest::heap()->InOldSpace(double_array_handle->elements())); |
| 2907 } | 2935 } |
| 2908 | 2936 |
| 2909 | 2937 |
| 2910 TEST(OptimizedPretenuringObjectArrayLiterals) { | 2938 TEST(OptimizedPretenuringObjectArrayLiterals) { |
| 2911 i::FLAG_allow_natives_syntax = true; | 2939 i::FLAG_allow_natives_syntax = true; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2932 " return elements[number_elements - 1];" | 2960 " return elements[number_elements - 1];" |
| 2933 "};" | 2961 "};" |
| 2934 "f(); gc();" | 2962 "f(); gc();" |
| 2935 "f(); f();" | 2963 "f(); f();" |
| 2936 "%%OptimizeFunctionOnNextCall(f);" | 2964 "%%OptimizeFunctionOnNextCall(f);" |
| 2937 "f();", | 2965 "f();", |
| 2938 AllocationSite::kPretenureMinimumCreated); | 2966 AllocationSite::kPretenureMinimumCreated); |
| 2939 | 2967 |
| 2940 v8::Local<v8::Value> res = CompileRun(source.start()); | 2968 v8::Local<v8::Value> res = CompileRun(source.start()); |
| 2941 | 2969 |
| 2942 Handle<JSObject> o = | 2970 i::Handle<JSObject> o = |
| 2943 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2971 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); |
| 2944 | 2972 |
| 2945 CHECK(CcTest::heap()->InOldSpace(o->elements())); | 2973 CHECK(CcTest::heap()->InOldSpace(o->elements())); |
| 2946 CHECK(CcTest::heap()->InOldSpace(*o)); | 2974 CHECK(CcTest::heap()->InOldSpace(*o)); |
| 2947 } | 2975 } |
| 2948 | 2976 |
| 2949 | 2977 |
| 2950 TEST(OptimizedPretenuringMixedInObjectProperties) { | 2978 TEST(OptimizedPretenuringMixedInObjectProperties) { |
| 2951 i::FLAG_allow_natives_syntax = true; | 2979 i::FLAG_allow_natives_syntax = true; |
| 2952 i::FLAG_expose_gc = true; | 2980 i::FLAG_expose_gc = true; |
| 2953 CcTest::InitializeVM(); | 2981 CcTest::InitializeVM(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2973 " return elements[number_elements - 1];" | 3001 " return elements[number_elements - 1];" |
| 2974 "};" | 3002 "};" |
| 2975 "f(); gc();" | 3003 "f(); gc();" |
| 2976 "f(); f();" | 3004 "f(); f();" |
| 2977 "%%OptimizeFunctionOnNextCall(f);" | 3005 "%%OptimizeFunctionOnNextCall(f);" |
| 2978 "f();", | 3006 "f();", |
| 2979 AllocationSite::kPretenureMinimumCreated); | 3007 AllocationSite::kPretenureMinimumCreated); |
| 2980 | 3008 |
| 2981 v8::Local<v8::Value> res = CompileRun(source.start()); | 3009 v8::Local<v8::Value> res = CompileRun(source.start()); |
| 2982 | 3010 |
| 2983 Handle<JSObject> o = | 3011 i::Handle<JSObject> o = |
| 2984 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 3012 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); |
| 2985 | 3013 |
| 2986 CHECK(CcTest::heap()->InOldSpace(*o)); | 3014 CHECK(CcTest::heap()->InOldSpace(*o)); |
| 2987 FieldIndex idx1 = FieldIndex::ForPropertyIndex(o->map(), 0); | 3015 FieldIndex idx1 = FieldIndex::ForPropertyIndex(o->map(), 0); |
| 2988 FieldIndex idx2 = FieldIndex::ForPropertyIndex(o->map(), 1); | 3016 FieldIndex idx2 = FieldIndex::ForPropertyIndex(o->map(), 1); |
| 2989 CHECK(CcTest::heap()->InOldSpace(o->RawFastPropertyAt(idx1))); | 3017 CHECK(CcTest::heap()->InOldSpace(o->RawFastPropertyAt(idx1))); |
| 2990 if (!o->IsUnboxedDoubleField(idx2)) { | 3018 if (!o->IsUnboxedDoubleField(idx2)) { |
| 2991 CHECK(CcTest::heap()->InOldSpace(o->RawFastPropertyAt(idx2))); | 3019 CHECK(CcTest::heap()->InOldSpace(o->RawFastPropertyAt(idx2))); |
| 2992 } else { | 3020 } else { |
| 2993 CHECK_EQ(1.1, o->RawFastDoublePropertyAt(idx2)); | 3021 CHECK_EQ(1.1, o->RawFastDoublePropertyAt(idx2)); |
| 2994 } | 3022 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3030 " return elements[i - 1];" | 3058 " return elements[i - 1];" |
| 3031 "};" | 3059 "};" |
| 3032 "f(); gc();" | 3060 "f(); gc();" |
| 3033 "f(); f();" | 3061 "f(); f();" |
| 3034 "%%OptimizeFunctionOnNextCall(f);" | 3062 "%%OptimizeFunctionOnNextCall(f);" |
| 3035 "f();", | 3063 "f();", |
| 3036 AllocationSite::kPretenureMinimumCreated); | 3064 AllocationSite::kPretenureMinimumCreated); |
| 3037 | 3065 |
| 3038 v8::Local<v8::Value> res = CompileRun(source.start()); | 3066 v8::Local<v8::Value> res = CompileRun(source.start()); |
| 3039 | 3067 |
| 3040 Handle<JSObject> o = | 3068 i::Handle<JSObject> o = |
| 3041 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 3069 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); |
| 3042 | 3070 |
| 3043 CHECK(CcTest::heap()->InOldSpace(*o)); | 3071 CHECK(CcTest::heap()->InOldSpace(*o)); |
| 3044 CHECK(CcTest::heap()->InOldSpace(o->properties())); | 3072 CHECK(CcTest::heap()->InOldSpace(o->properties())); |
| 3045 } | 3073 } |
| 3046 | 3074 |
| 3047 | 3075 |
| 3048 TEST(OptimizedPretenuringdoubleArrayLiterals) { | 3076 TEST(OptimizedPretenuringdoubleArrayLiterals) { |
| 3049 i::FLAG_allow_natives_syntax = true; | 3077 i::FLAG_allow_natives_syntax = true; |
| 3050 i::FLAG_expose_gc = true; | 3078 i::FLAG_expose_gc = true; |
| 3051 CcTest::InitializeVM(); | 3079 CcTest::InitializeVM(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3070 " return elements[number_elements - 1];" | 3098 " return elements[number_elements - 1];" |
| 3071 "};" | 3099 "};" |
| 3072 "f(); gc();" | 3100 "f(); gc();" |
| 3073 "f(); f();" | 3101 "f(); f();" |
| 3074 "%%OptimizeFunctionOnNextCall(f);" | 3102 "%%OptimizeFunctionOnNextCall(f);" |
| 3075 "f();", | 3103 "f();", |
| 3076 AllocationSite::kPretenureMinimumCreated); | 3104 AllocationSite::kPretenureMinimumCreated); |
| 3077 | 3105 |
| 3078 v8::Local<v8::Value> res = CompileRun(source.start()); | 3106 v8::Local<v8::Value> res = CompileRun(source.start()); |
| 3079 | 3107 |
| 3080 Handle<JSObject> o = | 3108 i::Handle<JSObject> o = |
| 3081 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 3109 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); |
| 3082 | 3110 |
| 3083 CHECK(CcTest::heap()->InOldSpace(o->elements())); | 3111 CHECK(CcTest::heap()->InOldSpace(o->elements())); |
| 3084 CHECK(CcTest::heap()->InOldSpace(*o)); | 3112 CHECK(CcTest::heap()->InOldSpace(*o)); |
| 3085 } | 3113 } |
| 3086 | 3114 |
| 3087 | 3115 |
| 3088 TEST(OptimizedPretenuringNestedMixedArrayLiterals) { | 3116 TEST(OptimizedPretenuringNestedMixedArrayLiterals) { |
| 3089 i::FLAG_allow_natives_syntax = true; | 3117 i::FLAG_allow_natives_syntax = true; |
| 3090 i::FLAG_expose_gc = true; | 3118 i::FLAG_expose_gc = true; |
| 3091 CcTest::InitializeVM(); | 3119 CcTest::InitializeVM(); |
| 3092 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 3120 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 3093 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 3121 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 3094 v8::HandleScope scope(CcTest::isolate()); | 3122 v8::HandleScope scope(CcTest::isolate()); |
| 3095 | 3123 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3096 // Grow new space unitl maximum capacity reached. | 3124 // Grow new space unitl maximum capacity reached. |
| 3097 while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) { | 3125 while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) { |
| 3098 CcTest::heap()->new_space()->Grow(); | 3126 CcTest::heap()->new_space()->Grow(); |
| 3099 } | 3127 } |
| 3100 | 3128 |
| 3101 i::ScopedVector<char> source(1024); | 3129 i::ScopedVector<char> source(1024); |
| 3102 i::SNPrintF( | 3130 i::SNPrintF( |
| 3103 source, | 3131 source, |
| 3104 "var number_elements = 100;" | 3132 "var number_elements = 100;" |
| 3105 "var elements = new Array(number_elements);" | 3133 "var elements = new Array(number_elements);" |
| 3106 "function f() {" | 3134 "function f() {" |
| 3107 " for (var i = 0; i < number_elements; i++) {" | 3135 " for (var i = 0; i < number_elements; i++) {" |
| 3108 " elements[i] = [[{}, {}, {}], [1.1, 2.2, 3.3]];" | 3136 " elements[i] = [[{}, {}, {}], [1.1, 2.2, 3.3]];" |
| 3109 " }" | 3137 " }" |
| 3110 " return elements[number_elements - 1];" | 3138 " return elements[number_elements - 1];" |
| 3111 "};" | 3139 "};" |
| 3112 "f(); gc();" | 3140 "f(); gc();" |
| 3113 "f(); f();" | 3141 "f(); f();" |
| 3114 "%%OptimizeFunctionOnNextCall(f);" | 3142 "%%OptimizeFunctionOnNextCall(f);" |
| 3115 "f();"); | 3143 "f();"); |
| 3116 | 3144 |
| 3117 v8::Local<v8::Value> res = CompileRun(source.start()); | 3145 v8::Local<v8::Value> res = CompileRun(source.start()); |
| 3118 | 3146 |
| 3119 v8::Local<v8::Value> int_array = v8::Object::Cast(*res)->Get(v8_str("0")); | 3147 v8::Local<v8::Value> int_array = |
| 3120 Handle<JSObject> int_array_handle = | 3148 v8::Object::Cast(*res)->Get(ctx, v8_str("0")).ToLocalChecked(); |
| 3121 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array)); | 3149 i::Handle<JSObject> int_array_handle = |
| 3122 v8::Local<v8::Value> double_array = v8::Object::Cast(*res)->Get(v8_str("1")); | 3150 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(int_array)); |
| 3123 Handle<JSObject> double_array_handle = | 3151 v8::Local<v8::Value> double_array = |
| 3124 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array)); | 3152 v8::Object::Cast(*res)->Get(ctx, v8_str("1")).ToLocalChecked(); |
| 3153 i::Handle<JSObject> double_array_handle = |
| 3154 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(double_array)); |
| 3125 | 3155 |
| 3126 Handle<JSObject> o = | 3156 Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); |
| 3127 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | |
| 3128 CHECK(CcTest::heap()->InOldSpace(*o)); | 3157 CHECK(CcTest::heap()->InOldSpace(*o)); |
| 3129 CHECK(CcTest::heap()->InOldSpace(*int_array_handle)); | 3158 CHECK(CcTest::heap()->InOldSpace(*int_array_handle)); |
| 3130 CHECK(CcTest::heap()->InOldSpace(int_array_handle->elements())); | 3159 CHECK(CcTest::heap()->InOldSpace(int_array_handle->elements())); |
| 3131 CHECK(CcTest::heap()->InOldSpace(*double_array_handle)); | 3160 CHECK(CcTest::heap()->InOldSpace(*double_array_handle)); |
| 3132 CHECK(CcTest::heap()->InOldSpace(double_array_handle->elements())); | 3161 CHECK(CcTest::heap()->InOldSpace(double_array_handle->elements())); |
| 3133 } | 3162 } |
| 3134 | 3163 |
| 3135 | 3164 |
| 3136 TEST(OptimizedPretenuringNestedObjectLiterals) { | 3165 TEST(OptimizedPretenuringNestedObjectLiterals) { |
| 3137 i::FLAG_allow_natives_syntax = true; | 3166 i::FLAG_allow_natives_syntax = true; |
| 3138 i::FLAG_expose_gc = true; | 3167 i::FLAG_expose_gc = true; |
| 3139 CcTest::InitializeVM(); | 3168 CcTest::InitializeVM(); |
| 3140 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 3169 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 3141 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 3170 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 3142 v8::HandleScope scope(CcTest::isolate()); | 3171 v8::HandleScope scope(CcTest::isolate()); |
| 3143 | 3172 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3144 // Grow new space unitl maximum capacity reached. | 3173 // Grow new space unitl maximum capacity reached. |
| 3145 while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) { | 3174 while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) { |
| 3146 CcTest::heap()->new_space()->Grow(); | 3175 CcTest::heap()->new_space()->Grow(); |
| 3147 } | 3176 } |
| 3148 | 3177 |
| 3149 i::ScopedVector<char> source(1024); | 3178 i::ScopedVector<char> source(1024); |
| 3150 i::SNPrintF( | 3179 i::SNPrintF( |
| 3151 source, | 3180 source, |
| 3152 "var number_elements = %d;" | 3181 "var number_elements = %d;" |
| 3153 "var elements = new Array(number_elements);" | 3182 "var elements = new Array(number_elements);" |
| 3154 "function f() {" | 3183 "function f() {" |
| 3155 " for (var i = 0; i < number_elements; i++) {" | 3184 " for (var i = 0; i < number_elements; i++) {" |
| 3156 " elements[i] = [[{}, {}, {}],[{}, {}, {}]];" | 3185 " elements[i] = [[{}, {}, {}],[{}, {}, {}]];" |
| 3157 " }" | 3186 " }" |
| 3158 " return elements[number_elements - 1];" | 3187 " return elements[number_elements - 1];" |
| 3159 "};" | 3188 "};" |
| 3160 "f(); gc();" | 3189 "f(); gc();" |
| 3161 "f(); f();" | 3190 "f(); f();" |
| 3162 "%%OptimizeFunctionOnNextCall(f);" | 3191 "%%OptimizeFunctionOnNextCall(f);" |
| 3163 "f();", | 3192 "f();", |
| 3164 AllocationSite::kPretenureMinimumCreated); | 3193 AllocationSite::kPretenureMinimumCreated); |
| 3165 | 3194 |
| 3166 v8::Local<v8::Value> res = CompileRun(source.start()); | 3195 v8::Local<v8::Value> res = CompileRun(source.start()); |
| 3167 | 3196 |
| 3168 v8::Local<v8::Value> int_array_1 = v8::Object::Cast(*res)->Get(v8_str("0")); | 3197 v8::Local<v8::Value> int_array_1 = |
| 3198 v8::Object::Cast(*res)->Get(ctx, v8_str("0")).ToLocalChecked(); |
| 3169 Handle<JSObject> int_array_handle_1 = | 3199 Handle<JSObject> int_array_handle_1 = |
| 3170 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array_1)); | 3200 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(int_array_1)); |
| 3171 v8::Local<v8::Value> int_array_2 = v8::Object::Cast(*res)->Get(v8_str("1")); | 3201 v8::Local<v8::Value> int_array_2 = |
| 3202 v8::Object::Cast(*res)->Get(ctx, v8_str("1")).ToLocalChecked(); |
| 3172 Handle<JSObject> int_array_handle_2 = | 3203 Handle<JSObject> int_array_handle_2 = |
| 3173 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(int_array_2)); | 3204 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(int_array_2)); |
| 3174 | 3205 |
| 3175 Handle<JSObject> o = | 3206 Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); |
| 3176 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | |
| 3177 CHECK(CcTest::heap()->InOldSpace(*o)); | 3207 CHECK(CcTest::heap()->InOldSpace(*o)); |
| 3178 CHECK(CcTest::heap()->InOldSpace(*int_array_handle_1)); | 3208 CHECK(CcTest::heap()->InOldSpace(*int_array_handle_1)); |
| 3179 CHECK(CcTest::heap()->InOldSpace(int_array_handle_1->elements())); | 3209 CHECK(CcTest::heap()->InOldSpace(int_array_handle_1->elements())); |
| 3180 CHECK(CcTest::heap()->InOldSpace(*int_array_handle_2)); | 3210 CHECK(CcTest::heap()->InOldSpace(*int_array_handle_2)); |
| 3181 CHECK(CcTest::heap()->InOldSpace(int_array_handle_2->elements())); | 3211 CHECK(CcTest::heap()->InOldSpace(int_array_handle_2->elements())); |
| 3182 } | 3212 } |
| 3183 | 3213 |
| 3184 | 3214 |
| 3185 TEST(OptimizedPretenuringNestedDoubleLiterals) { | 3215 TEST(OptimizedPretenuringNestedDoubleLiterals) { |
| 3186 i::FLAG_allow_natives_syntax = true; | 3216 i::FLAG_allow_natives_syntax = true; |
| 3187 i::FLAG_expose_gc = true; | 3217 i::FLAG_expose_gc = true; |
| 3188 CcTest::InitializeVM(); | 3218 CcTest::InitializeVM(); |
| 3189 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 3219 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 3190 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 3220 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 3191 v8::HandleScope scope(CcTest::isolate()); | 3221 v8::HandleScope scope(CcTest::isolate()); |
| 3192 | 3222 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3193 // Grow new space unitl maximum capacity reached. | 3223 // Grow new space unitl maximum capacity reached. |
| 3194 while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) { | 3224 while (!CcTest::heap()->new_space()->IsAtMaximumCapacity()) { |
| 3195 CcTest::heap()->new_space()->Grow(); | 3225 CcTest::heap()->new_space()->Grow(); |
| 3196 } | 3226 } |
| 3197 | 3227 |
| 3198 i::ScopedVector<char> source(1024); | 3228 i::ScopedVector<char> source(1024); |
| 3199 i::SNPrintF( | 3229 i::SNPrintF( |
| 3200 source, | 3230 source, |
| 3201 "var number_elements = %d;" | 3231 "var number_elements = %d;" |
| 3202 "var elements = new Array(number_elements);" | 3232 "var elements = new Array(number_elements);" |
| 3203 "function f() {" | 3233 "function f() {" |
| 3204 " for (var i = 0; i < number_elements; i++) {" | 3234 " for (var i = 0; i < number_elements; i++) {" |
| 3205 " elements[i] = [[1.1, 1.2, 1.3],[2.1, 2.2, 2.3]];" | 3235 " elements[i] = [[1.1, 1.2, 1.3],[2.1, 2.2, 2.3]];" |
| 3206 " }" | 3236 " }" |
| 3207 " return elements[number_elements - 1];" | 3237 " return elements[number_elements - 1];" |
| 3208 "};" | 3238 "};" |
| 3209 "f(); gc();" | 3239 "f(); gc();" |
| 3210 "f(); f();" | 3240 "f(); f();" |
| 3211 "%%OptimizeFunctionOnNextCall(f);" | 3241 "%%OptimizeFunctionOnNextCall(f);" |
| 3212 "f();", | 3242 "f();", |
| 3213 AllocationSite::kPretenureMinimumCreated); | 3243 AllocationSite::kPretenureMinimumCreated); |
| 3214 | 3244 |
| 3215 v8::Local<v8::Value> res = CompileRun(source.start()); | 3245 v8::Local<v8::Value> res = CompileRun(source.start()); |
| 3216 | 3246 |
| 3217 v8::Local<v8::Value> double_array_1 = | 3247 v8::Local<v8::Value> double_array_1 = |
| 3218 v8::Object::Cast(*res)->Get(v8_str("0")); | 3248 v8::Object::Cast(*res)->Get(ctx, v8_str("0")).ToLocalChecked(); |
| 3219 Handle<JSObject> double_array_handle_1 = | 3249 i::Handle<JSObject> double_array_handle_1 = |
| 3220 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array_1)); | 3250 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(double_array_1)); |
| 3221 v8::Local<v8::Value> double_array_2 = | 3251 v8::Local<v8::Value> double_array_2 = |
| 3222 v8::Object::Cast(*res)->Get(v8_str("1")); | 3252 v8::Object::Cast(*res)->Get(ctx, v8_str("1")).ToLocalChecked(); |
| 3223 Handle<JSObject> double_array_handle_2 = | 3253 i::Handle<JSObject> double_array_handle_2 = |
| 3224 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(double_array_2)); | 3254 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(double_array_2)); |
| 3225 | 3255 |
| 3226 Handle<JSObject> o = | 3256 i::Handle<JSObject> o = |
| 3227 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 3257 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); |
| 3228 CHECK(CcTest::heap()->InOldSpace(*o)); | 3258 CHECK(CcTest::heap()->InOldSpace(*o)); |
| 3229 CHECK(CcTest::heap()->InOldSpace(*double_array_handle_1)); | 3259 CHECK(CcTest::heap()->InOldSpace(*double_array_handle_1)); |
| 3230 CHECK(CcTest::heap()->InOldSpace(double_array_handle_1->elements())); | 3260 CHECK(CcTest::heap()->InOldSpace(double_array_handle_1->elements())); |
| 3231 CHECK(CcTest::heap()->InOldSpace(*double_array_handle_2)); | 3261 CHECK(CcTest::heap()->InOldSpace(*double_array_handle_2)); |
| 3232 CHECK(CcTest::heap()->InOldSpace(double_array_handle_2->elements())); | 3262 CHECK(CcTest::heap()->InOldSpace(double_array_handle_2->elements())); |
| 3233 } | 3263 } |
| 3234 | 3264 |
| 3235 | 3265 |
| 3236 // Test regular array literals allocation. | 3266 // Test regular array literals allocation. |
| 3237 TEST(OptimizedAllocationArrayLiterals) { | 3267 TEST(OptimizedAllocationArrayLiterals) { |
| 3238 i::FLAG_allow_natives_syntax = true; | 3268 i::FLAG_allow_natives_syntax = true; |
| 3239 CcTest::InitializeVM(); | 3269 CcTest::InitializeVM(); |
| 3240 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; | 3270 if (!CcTest::i_isolate()->use_crankshaft() || i::FLAG_always_opt) return; |
| 3241 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; | 3271 if (i::FLAG_gc_global || i::FLAG_stress_compaction) return; |
| 3242 v8::HandleScope scope(CcTest::isolate()); | 3272 v8::HandleScope scope(CcTest::isolate()); |
| 3243 | 3273 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3244 v8::Local<v8::Value> res = CompileRun( | 3274 v8::Local<v8::Value> res = CompileRun( |
| 3245 "function f() {" | 3275 "function f() {" |
| 3246 " var numbers = new Array(1, 2, 3);" | 3276 " var numbers = new Array(1, 2, 3);" |
| 3247 " numbers[0] = 3.14;" | 3277 " numbers[0] = 3.14;" |
| 3248 " return numbers;" | 3278 " return numbers;" |
| 3249 "};" | 3279 "};" |
| 3250 "f(); f(); f();" | 3280 "f(); f(); f();" |
| 3251 "%OptimizeFunctionOnNextCall(f);" | 3281 "%OptimizeFunctionOnNextCall(f);" |
| 3252 "f();"); | 3282 "f();"); |
| 3253 CHECK_EQ(static_cast<int>(3.14), | 3283 CHECK_EQ(static_cast<int>(3.14), v8::Object::Cast(*res) |
| 3254 v8::Object::Cast(*res)->Get(v8_str("0"))->Int32Value()); | 3284 ->Get(ctx, v8_str("0")) |
| 3285 .ToLocalChecked() |
| 3286 ->Int32Value(ctx) |
| 3287 .FromJust()); |
| 3255 | 3288 |
| 3256 Handle<JSObject> o = | 3289 i::Handle<JSObject> o = |
| 3257 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 3290 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); |
| 3258 | 3291 |
| 3259 CHECK(CcTest::heap()->InNewSpace(o->elements())); | 3292 CHECK(CcTest::heap()->InNewSpace(o->elements())); |
| 3260 } | 3293 } |
| 3261 | 3294 |
| 3262 | 3295 |
| 3263 static int CountMapTransitions(Map* map) { | 3296 static int CountMapTransitions(Map* map) { |
| 3264 return TransitionArray::NumberOfTransitions(map->raw_transitions()); | 3297 return TransitionArray::NumberOfTransitions(map->raw_transitions()); |
| 3265 } | 3298 } |
| 3266 | 3299 |
| 3267 | 3300 |
| 3268 // Test that map transitions are cleared and maps are collected with | 3301 // Test that map transitions are cleared and maps are collected with |
| 3269 // incremental marking as well. | 3302 // incremental marking as well. |
| 3270 TEST(Regress1465) { | 3303 TEST(Regress1465) { |
| 3271 i::FLAG_stress_compaction = false; | 3304 i::FLAG_stress_compaction = false; |
| 3272 i::FLAG_allow_natives_syntax = true; | 3305 i::FLAG_allow_natives_syntax = true; |
| 3273 i::FLAG_trace_incremental_marking = true; | 3306 i::FLAG_trace_incremental_marking = true; |
| 3274 i::FLAG_retain_maps_for_n_gc = 0; | 3307 i::FLAG_retain_maps_for_n_gc = 0; |
| 3275 CcTest::InitializeVM(); | 3308 CcTest::InitializeVM(); |
| 3276 v8::HandleScope scope(CcTest::isolate()); | 3309 v8::HandleScope scope(CcTest::isolate()); |
| 3310 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3277 static const int transitions_count = 256; | 3311 static const int transitions_count = 256; |
| 3278 | 3312 |
| 3279 CompileRun("function F() {}"); | 3313 CompileRun("function F() {}"); |
| 3280 { | 3314 { |
| 3281 AlwaysAllocateScope always_allocate(CcTest::i_isolate()); | 3315 AlwaysAllocateScope always_allocate(CcTest::i_isolate()); |
| 3282 for (int i = 0; i < transitions_count; i++) { | 3316 for (int i = 0; i < transitions_count; i++) { |
| 3283 EmbeddedVector<char, 64> buffer; | 3317 EmbeddedVector<char, 64> buffer; |
| 3284 SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i); | 3318 SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i); |
| 3285 CompileRun(buffer.start()); | 3319 CompileRun(buffer.start()); |
| 3286 } | 3320 } |
| 3287 CompileRun("var root = new F;"); | 3321 CompileRun("var root = new F;"); |
| 3288 } | 3322 } |
| 3289 | 3323 |
| 3290 Handle<JSObject> root = | 3324 i::Handle<JSObject> root = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( |
| 3291 v8::Utils::OpenHandle( | 3325 CcTest::global()->Get(ctx, v8_str("root")).ToLocalChecked())); |
| 3292 *v8::Handle<v8::Object>::Cast( | |
| 3293 CcTest::global()->Get(v8_str("root")))); | |
| 3294 | 3326 |
| 3295 // Count number of live transitions before marking. | 3327 // Count number of live transitions before marking. |
| 3296 int transitions_before = CountMapTransitions(root->map()); | 3328 int transitions_before = CountMapTransitions(root->map()); |
| 3297 CompileRun("%DebugPrint(root);"); | 3329 CompileRun("%DebugPrint(root);"); |
| 3298 CHECK_EQ(transitions_count, transitions_before); | 3330 CHECK_EQ(transitions_count, transitions_before); |
| 3299 | 3331 |
| 3300 SimulateIncrementalMarking(CcTest::heap()); | 3332 SimulateIncrementalMarking(CcTest::heap()); |
| 3301 CcTest::heap()->CollectAllGarbage(); | 3333 CcTest::heap()->CollectAllGarbage(); |
| 3302 | 3334 |
| 3303 // Count number of live transitions after marking. Note that one transition | 3335 // Count number of live transitions after marking. Note that one transition |
| 3304 // is left, because 'o' still holds an instance of one transition target. | 3336 // is left, because 'o' still holds an instance of one transition target. |
| 3305 int transitions_after = CountMapTransitions(root->map()); | 3337 int transitions_after = CountMapTransitions(root->map()); |
| 3306 CompileRun("%DebugPrint(root);"); | 3338 CompileRun("%DebugPrint(root);"); |
| 3307 CHECK_EQ(1, transitions_after); | 3339 CHECK_EQ(1, transitions_after); |
| 3308 } | 3340 } |
| 3309 | 3341 |
| 3310 | 3342 |
| 3311 #ifdef DEBUG | 3343 #ifdef DEBUG |
| 3312 static void AddTransitions(int transitions_count) { | 3344 static void AddTransitions(int transitions_count) { |
| 3313 AlwaysAllocateScope always_allocate(CcTest::i_isolate()); | 3345 AlwaysAllocateScope always_allocate(CcTest::i_isolate()); |
| 3314 for (int i = 0; i < transitions_count; i++) { | 3346 for (int i = 0; i < transitions_count; i++) { |
| 3315 EmbeddedVector<char, 64> buffer; | 3347 EmbeddedVector<char, 64> buffer; |
| 3316 SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i); | 3348 SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i); |
| 3317 CompileRun(buffer.start()); | 3349 CompileRun(buffer.start()); |
| 3318 } | 3350 } |
| 3319 } | 3351 } |
| 3320 | 3352 |
| 3321 | 3353 |
| 3322 static Handle<JSObject> GetByName(const char* name) { | 3354 static i::Handle<JSObject> GetByName(const char* name) { |
| 3323 return v8::Utils::OpenHandle( | 3355 return v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( |
| 3324 *v8::Handle<v8::Object>::Cast( | 3356 CcTest::global() |
| 3325 CcTest::global()->Get(v8_str(name)))); | 3357 ->Get(CcTest::isolate()->GetCurrentContext(), v8_str(name)) |
| 3358 .ToLocalChecked())); |
| 3326 } | 3359 } |
| 3327 | 3360 |
| 3328 | 3361 |
| 3329 static void AddPropertyTo( | 3362 static void AddPropertyTo( |
| 3330 int gc_count, Handle<JSObject> object, const char* property_name) { | 3363 int gc_count, Handle<JSObject> object, const char* property_name) { |
| 3331 Isolate* isolate = CcTest::i_isolate(); | 3364 Isolate* isolate = CcTest::i_isolate(); |
| 3332 Factory* factory = isolate->factory(); | 3365 Factory* factory = isolate->factory(); |
| 3333 Handle<String> prop_name = factory->InternalizeUtf8String(property_name); | 3366 Handle<String> prop_name = factory->InternalizeUtf8String(property_name); |
| 3334 Handle<Smi> twenty_three(Smi::FromInt(23), isolate); | 3367 Handle<Smi> twenty_three(Smi::FromInt(23), isolate); |
| 3335 i::FLAG_gc_interval = gc_count; | 3368 i::FLAG_gc_interval = gc_count; |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3475 "}" | 3508 "}" |
| 3476 "f(new Object);" | 3509 "f(new Object);" |
| 3477 "f(root);"); | 3510 "f(root);"); |
| 3478 | 3511 |
| 3479 // This bug only triggers with aggressive IC clearing. | 3512 // This bug only triggers with aggressive IC clearing. |
| 3480 CcTest::heap()->AgeInlineCaches(); | 3513 CcTest::heap()->AgeInlineCaches(); |
| 3481 | 3514 |
| 3482 // Explicitly request GC to perform final marking step and sweeping. | 3515 // Explicitly request GC to perform final marking step and sweeping. |
| 3483 CcTest::heap()->CollectAllGarbage(); | 3516 CcTest::heap()->CollectAllGarbage(); |
| 3484 | 3517 |
| 3485 Handle<JSObject> root = | 3518 Handle<JSObject> root = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( |
| 3486 v8::Utils::OpenHandle( | 3519 CcTest::global() |
| 3487 *v8::Handle<v8::Object>::Cast( | 3520 ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("root")) |
| 3488 CcTest::global()->Get(v8_str("root")))); | 3521 .ToLocalChecked())); |
| 3489 | 3522 |
| 3490 // The root object should be in a sane state. | 3523 // The root object should be in a sane state. |
| 3491 CHECK(root->IsJSObject()); | 3524 CHECK(root->IsJSObject()); |
| 3492 CHECK(root->map()->IsMap()); | 3525 CHECK(root->map()->IsMap()); |
| 3493 } | 3526 } |
| 3494 | 3527 |
| 3495 | 3528 |
| 3496 TEST(Regress2143b) { | 3529 TEST(Regress2143b) { |
| 3497 i::FLAG_incremental_marking = true; | 3530 i::FLAG_incremental_marking = true; |
| 3498 i::FLAG_allow_natives_syntax = true; | 3531 i::FLAG_allow_natives_syntax = true; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3518 "%OptimizeFunctionOnNextCall(f);" | 3551 "%OptimizeFunctionOnNextCall(f);" |
| 3519 "f(root);" | 3552 "f(root);" |
| 3520 "%DeoptimizeFunction(f);"); | 3553 "%DeoptimizeFunction(f);"); |
| 3521 | 3554 |
| 3522 // This bug only triggers with aggressive IC clearing. | 3555 // This bug only triggers with aggressive IC clearing. |
| 3523 CcTest::heap()->AgeInlineCaches(); | 3556 CcTest::heap()->AgeInlineCaches(); |
| 3524 | 3557 |
| 3525 // Explicitly request GC to perform final marking step and sweeping. | 3558 // Explicitly request GC to perform final marking step and sweeping. |
| 3526 CcTest::heap()->CollectAllGarbage(); | 3559 CcTest::heap()->CollectAllGarbage(); |
| 3527 | 3560 |
| 3528 Handle<JSObject> root = | 3561 Handle<JSObject> root = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( |
| 3529 v8::Utils::OpenHandle( | 3562 CcTest::global() |
| 3530 *v8::Handle<v8::Object>::Cast( | 3563 ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("root")) |
| 3531 CcTest::global()->Get(v8_str("root")))); | 3564 .ToLocalChecked())); |
| 3532 | 3565 |
| 3533 // The root object should be in a sane state. | 3566 // The root object should be in a sane state. |
| 3534 CHECK(root->IsJSObject()); | 3567 CHECK(root->IsJSObject()); |
| 3535 CHECK(root->map()->IsMap()); | 3568 CHECK(root->map()->IsMap()); |
| 3536 } | 3569 } |
| 3537 | 3570 |
| 3538 | 3571 |
| 3539 TEST(ReleaseOverReservedPages) { | 3572 TEST(ReleaseOverReservedPages) { |
| 3540 if (FLAG_never_compact) return; | 3573 if (FLAG_never_compact) return; |
| 3541 i::FLAG_trace_gc = true; | 3574 i::FLAG_trace_gc = true; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3608 const char* source = "gc();"; | 3641 const char* source = "gc();"; |
| 3609 CompileRun(source); | 3642 CompileRun(source); |
| 3610 CHECK_GT(forced_gc_counter, 0); | 3643 CHECK_GT(forced_gc_counter, 0); |
| 3611 } | 3644 } |
| 3612 | 3645 |
| 3613 | 3646 |
| 3614 #ifdef OBJECT_PRINT | 3647 #ifdef OBJECT_PRINT |
| 3615 TEST(PrintSharedFunctionInfo) { | 3648 TEST(PrintSharedFunctionInfo) { |
| 3616 CcTest::InitializeVM(); | 3649 CcTest::InitializeVM(); |
| 3617 v8::HandleScope scope(CcTest::isolate()); | 3650 v8::HandleScope scope(CcTest::isolate()); |
| 3651 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3618 const char* source = "f = function() { return 987654321; }\n" | 3652 const char* source = "f = function() { return 987654321; }\n" |
| 3619 "g = function() { return 123456789; }\n"; | 3653 "g = function() { return 123456789; }\n"; |
| 3620 CompileRun(source); | 3654 CompileRun(source); |
| 3621 Handle<JSFunction> g = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 3655 i::Handle<JSFunction> g = i::Handle<JSFunction>::cast( |
| 3622 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("g"))))); | 3656 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 3657 CcTest::global()->Get(ctx, v8_str("g")).ToLocalChecked()))); |
| 3623 | 3658 |
| 3624 OFStream os(stdout); | 3659 OFStream os(stdout); |
| 3625 g->shared()->Print(os); | 3660 g->shared()->Print(os); |
| 3626 os << std::endl; | 3661 os << std::endl; |
| 3627 } | 3662 } |
| 3628 #endif // OBJECT_PRINT | 3663 #endif // OBJECT_PRINT |
| 3629 | 3664 |
| 3630 | 3665 |
| 3631 TEST(IncrementalMarkingPreservesMonomorphicCallIC) { | 3666 TEST(IncrementalMarkingPreservesMonomorphicCallIC) { |
| 3632 if (i::FLAG_always_opt) return; | 3667 if (i::FLAG_always_opt) return; |
| 3633 CcTest::InitializeVM(); | 3668 CcTest::InitializeVM(); |
| 3634 v8::HandleScope scope(CcTest::isolate()); | 3669 v8::HandleScope scope(CcTest::isolate()); |
| 3635 v8::Local<v8::Value> fun1, fun2; | 3670 v8::Local<v8::Value> fun1, fun2; |
| 3636 | 3671 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3637 { | 3672 { |
| 3638 LocalContext env; | 3673 LocalContext env; |
| 3639 CompileRun("function fun() {};"); | 3674 CompileRun("function fun() {};"); |
| 3640 fun1 = env->Global()->Get(v8_str("fun")); | 3675 fun1 = env->Global()->Get(env.local(), v8_str("fun")).ToLocalChecked(); |
| 3641 } | 3676 } |
| 3642 | 3677 |
| 3643 { | 3678 { |
| 3644 LocalContext env; | 3679 LocalContext env; |
| 3645 CompileRun("function fun() {};"); | 3680 CompileRun("function fun() {};"); |
| 3646 fun2 = env->Global()->Get(v8_str("fun")); | 3681 fun2 = env->Global()->Get(env.local(), v8_str("fun")).ToLocalChecked(); |
| 3647 } | 3682 } |
| 3648 | 3683 |
| 3649 // Prepare function f that contains type feedback for closures | 3684 // Prepare function f that contains type feedback for closures |
| 3650 // originating from two different native contexts. | 3685 // originating from two different native contexts. |
| 3651 CcTest::global()->Set(v8_str("fun1"), fun1); | 3686 CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust()); |
| 3652 CcTest::global()->Set(v8_str("fun2"), fun2); | 3687 CHECK(CcTest::global()->Set(ctx, v8_str("fun2"), fun2).FromJust()); |
| 3653 CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);"); | 3688 CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);"); |
| 3654 | 3689 |
| 3655 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 3690 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 3656 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 3691 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 3692 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
| 3657 | 3693 |
| 3658 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 3694 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); |
| 3659 FeedbackVectorHelper feedback_helper(feedback_vector); | 3695 FeedbackVectorHelper feedback_helper(feedback_vector); |
| 3660 | 3696 |
| 3661 int expected_slots = 2; | 3697 int expected_slots = 2; |
| 3662 CHECK_EQ(expected_slots, feedback_helper.slot_count()); | 3698 CHECK_EQ(expected_slots, feedback_helper.slot_count()); |
| 3663 int slot1 = 0; | 3699 int slot1 = 0; |
| 3664 int slot2 = 1; | 3700 int slot2 = 1; |
| 3665 CHECK(feedback_vector->Get(feedback_helper.slot(slot1))->IsWeakCell()); | 3701 CHECK(feedback_vector->Get(feedback_helper.slot(slot1))->IsWeakCell()); |
| 3666 CHECK(feedback_vector->Get(feedback_helper.slot(slot2))->IsWeakCell()); | 3702 CHECK(feedback_vector->Get(feedback_helper.slot(slot2))->IsWeakCell()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3718 | 3754 |
| 3719 TEST(ICInBuiltInIsClearedAppropriately) { | 3755 TEST(ICInBuiltInIsClearedAppropriately) { |
| 3720 if (i::FLAG_always_opt) return; | 3756 if (i::FLAG_always_opt) return; |
| 3721 CcTest::InitializeVM(); | 3757 CcTest::InitializeVM(); |
| 3722 v8::HandleScope scope(CcTest::isolate()); | 3758 v8::HandleScope scope(CcTest::isolate()); |
| 3723 | 3759 |
| 3724 Handle<JSFunction> apply; | 3760 Handle<JSFunction> apply; |
| 3725 { | 3761 { |
| 3726 LocalContext env; | 3762 LocalContext env; |
| 3727 v8::Local<v8::Value> res = CompileRun("Function.apply"); | 3763 v8::Local<v8::Value> res = CompileRun("Function.apply"); |
| 3728 Handle<JSObject> maybe_apply = | 3764 i::Handle<JSObject> maybe_apply = |
| 3729 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 3765 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); |
| 3730 apply = Handle<JSFunction>::cast(maybe_apply); | 3766 apply = i::Handle<JSFunction>::cast(maybe_apply); |
| 3731 Handle<TypeFeedbackVector> vector(apply->shared()->feedback_vector()); | 3767 i::Handle<TypeFeedbackVector> vector(apply->shared()->feedback_vector()); |
| 3732 FeedbackVectorHelper feedback_helper(vector); | 3768 FeedbackVectorHelper feedback_helper(vector); |
| 3733 CHECK_EQ(1, feedback_helper.slot_count()); | 3769 CHECK_EQ(1, feedback_helper.slot_count()); |
| 3734 CheckVectorIC(apply, 0, UNINITIALIZED); | 3770 CheckVectorIC(apply, 0, UNINITIALIZED); |
| 3735 CompileRun( | 3771 CompileRun( |
| 3736 "function b(a1, a2, a3) { return a1 + a2 + a3; }" | 3772 "function b(a1, a2, a3) { return a1 + a2 + a3; }" |
| 3737 "function fun(bar) { bar.apply({}, [1, 2, 3]); };" | 3773 "function fun(bar) { bar.apply({}, [1, 2, 3]); };" |
| 3738 "fun(b); fun(b)"); | 3774 "fun(b); fun(b)"); |
| 3739 CheckVectorIC(apply, 0, MONOMORPHIC); | 3775 CheckVectorIC(apply, 0, MONOMORPHIC); |
| 3740 } | 3776 } |
| 3741 | 3777 |
| 3742 // Fire context dispose notification. | 3778 // Fire context dispose notification. |
| 3743 CcTest::isolate()->ContextDisposedNotification(); | 3779 CcTest::isolate()->ContextDisposedNotification(); |
| 3744 SimulateIncrementalMarking(CcTest::heap()); | 3780 SimulateIncrementalMarking(CcTest::heap()); |
| 3745 CcTest::heap()->CollectAllGarbage(); | 3781 CcTest::heap()->CollectAllGarbage(); |
| 3746 | 3782 |
| 3747 // The IC in apply has been cleared, ready to learn again. | 3783 // The IC in apply has been cleared, ready to learn again. |
| 3748 CheckVectorIC(apply, 0, PREMONOMORPHIC); | 3784 CheckVectorIC(apply, 0, PREMONOMORPHIC); |
| 3749 } | 3785 } |
| 3750 | 3786 |
| 3751 | 3787 |
| 3752 TEST(IncrementalMarkingPreservesMonomorphicConstructor) { | 3788 TEST(IncrementalMarkingPreservesMonomorphicConstructor) { |
| 3753 if (i::FLAG_always_opt) return; | 3789 if (i::FLAG_always_opt) return; |
| 3754 CcTest::InitializeVM(); | 3790 CcTest::InitializeVM(); |
| 3755 v8::HandleScope scope(CcTest::isolate()); | 3791 v8::HandleScope scope(CcTest::isolate()); |
| 3756 | 3792 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3757 // Prepare function f that contains a monomorphic IC for object | 3793 // Prepare function f that contains a monomorphic IC for object |
| 3758 // originating from the same native context. | 3794 // originating from the same native context. |
| 3759 CompileRun( | 3795 CompileRun( |
| 3760 "function fun() { this.x = 1; };" | 3796 "function fun() { this.x = 1; };" |
| 3761 "function f(o) { return new o(); } f(fun); f(fun);"); | 3797 "function f(o) { return new o(); } f(fun); f(fun);"); |
| 3762 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 3798 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 3763 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 3799 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 3764 | 3800 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
| 3765 | 3801 |
| 3766 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector()); | 3802 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector()); |
| 3767 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); | 3803 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); |
| 3768 | 3804 |
| 3769 SimulateIncrementalMarking(CcTest::heap()); | 3805 SimulateIncrementalMarking(CcTest::heap()); |
| 3770 CcTest::heap()->CollectAllGarbage(); | 3806 CcTest::heap()->CollectAllGarbage(); |
| 3771 | 3807 |
| 3772 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); | 3808 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); |
| 3773 } | 3809 } |
| 3774 | 3810 |
| 3775 | 3811 |
| 3776 TEST(IncrementalMarkingClearsMonomorphicConstructor) { | 3812 TEST(IncrementalMarkingClearsMonomorphicConstructor) { |
| 3777 if (i::FLAG_always_opt) return; | 3813 if (i::FLAG_always_opt) return; |
| 3778 CcTest::InitializeVM(); | 3814 CcTest::InitializeVM(); |
| 3779 Isolate* isolate = CcTest::i_isolate(); | 3815 Isolate* isolate = CcTest::i_isolate(); |
| 3780 v8::HandleScope scope(CcTest::isolate()); | 3816 v8::HandleScope scope(CcTest::isolate()); |
| 3781 v8::Local<v8::Value> fun1; | 3817 v8::Local<v8::Value> fun1; |
| 3818 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3782 | 3819 |
| 3783 { | 3820 { |
| 3784 LocalContext env; | 3821 LocalContext env; |
| 3785 CompileRun("function fun() { this.x = 1; };"); | 3822 CompileRun("function fun() { this.x = 1; };"); |
| 3786 fun1 = env->Global()->Get(v8_str("fun")); | 3823 fun1 = env->Global()->Get(env.local(), v8_str("fun")).ToLocalChecked(); |
| 3787 } | 3824 } |
| 3788 | 3825 |
| 3789 // Prepare function f that contains a monomorphic constructor for object | 3826 // Prepare function f that contains a monomorphic constructor for object |
| 3790 // originating from a different native context. | 3827 // originating from a different native context. |
| 3791 CcTest::global()->Set(v8_str("fun1"), fun1); | 3828 CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust()); |
| 3792 CompileRun( | 3829 CompileRun( |
| 3793 "function fun() { this.x = 1; };" | 3830 "function fun() { this.x = 1; };" |
| 3794 "function f(o) { return new o(); } f(fun1); f(fun1);"); | 3831 "function f(o) { return new o(); } f(fun1); f(fun1);"); |
| 3795 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 3832 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 3796 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 3833 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 3834 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
| 3797 | 3835 |
| 3798 | 3836 |
| 3799 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector()); | 3837 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector()); |
| 3800 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); | 3838 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); |
| 3801 | 3839 |
| 3802 // Fire context dispose notification. | 3840 // Fire context dispose notification. |
| 3803 CcTest::isolate()->ContextDisposedNotification(); | 3841 CcTest::isolate()->ContextDisposedNotification(); |
| 3804 SimulateIncrementalMarking(CcTest::heap()); | 3842 SimulateIncrementalMarking(CcTest::heap()); |
| 3805 CcTest::heap()->CollectAllGarbage(); | 3843 CcTest::heap()->CollectAllGarbage(); |
| 3806 | 3844 |
| 3807 CHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(isolate), | 3845 CHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(isolate), |
| 3808 vector->Get(FeedbackVectorSlot(0))); | 3846 vector->Get(FeedbackVectorSlot(0))); |
| 3809 } | 3847 } |
| 3810 | 3848 |
| 3811 | 3849 |
| 3812 TEST(IncrementalMarkingPreservesMonomorphicIC) { | 3850 TEST(IncrementalMarkingPreservesMonomorphicIC) { |
| 3813 if (i::FLAG_always_opt) return; | 3851 if (i::FLAG_always_opt) return; |
| 3814 CcTest::InitializeVM(); | 3852 CcTest::InitializeVM(); |
| 3815 v8::HandleScope scope(CcTest::isolate()); | 3853 v8::HandleScope scope(CcTest::isolate()); |
| 3816 | 3854 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3817 // Prepare function f that contains a monomorphic IC for object | 3855 // Prepare function f that contains a monomorphic IC for object |
| 3818 // originating from the same native context. | 3856 // originating from the same native context. |
| 3819 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" | 3857 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" |
| 3820 "function f(o) { return o.x; } f(obj); f(obj);"); | 3858 "function f(o) { return o.x; } f(obj); f(obj);"); |
| 3821 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 3859 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 3822 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 3860 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 3861 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
| 3823 | 3862 |
| 3824 CheckVectorIC(f, 0, MONOMORPHIC); | 3863 CheckVectorIC(f, 0, MONOMORPHIC); |
| 3825 | 3864 |
| 3826 SimulateIncrementalMarking(CcTest::heap()); | 3865 SimulateIncrementalMarking(CcTest::heap()); |
| 3827 CcTest::heap()->CollectAllGarbage(); | 3866 CcTest::heap()->CollectAllGarbage(); |
| 3828 | 3867 |
| 3829 CheckVectorIC(f, 0, MONOMORPHIC); | 3868 CheckVectorIC(f, 0, MONOMORPHIC); |
| 3830 } | 3869 } |
| 3831 | 3870 |
| 3832 | 3871 |
| 3833 TEST(IncrementalMarkingClearsMonomorphicIC) { | 3872 TEST(IncrementalMarkingClearsMonomorphicIC) { |
| 3834 if (i::FLAG_always_opt) return; | 3873 if (i::FLAG_always_opt) return; |
| 3835 CcTest::InitializeVM(); | 3874 CcTest::InitializeVM(); |
| 3836 v8::HandleScope scope(CcTest::isolate()); | 3875 v8::HandleScope scope(CcTest::isolate()); |
| 3837 v8::Local<v8::Value> obj1; | 3876 v8::Local<v8::Value> obj1; |
| 3877 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3838 | 3878 |
| 3839 { | 3879 { |
| 3840 LocalContext env; | 3880 LocalContext env; |
| 3841 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); | 3881 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); |
| 3842 obj1 = env->Global()->Get(v8_str("obj")); | 3882 obj1 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); |
| 3843 } | 3883 } |
| 3844 | 3884 |
| 3845 // Prepare function f that contains a monomorphic IC for object | 3885 // Prepare function f that contains a monomorphic IC for object |
| 3846 // originating from a different native context. | 3886 // originating from a different native context. |
| 3847 CcTest::global()->Set(v8_str("obj1"), obj1); | 3887 CHECK(CcTest::global()->Set(ctx, v8_str("obj1"), obj1).FromJust()); |
| 3848 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1);"); | 3888 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1);"); |
| 3849 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 3889 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 3850 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 3890 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 3891 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
| 3851 | 3892 |
| 3852 CheckVectorIC(f, 0, MONOMORPHIC); | 3893 CheckVectorIC(f, 0, MONOMORPHIC); |
| 3853 | 3894 |
| 3854 // Fire context dispose notification. | 3895 // Fire context dispose notification. |
| 3855 CcTest::isolate()->ContextDisposedNotification(); | 3896 CcTest::isolate()->ContextDisposedNotification(); |
| 3856 SimulateIncrementalMarking(CcTest::heap()); | 3897 SimulateIncrementalMarking(CcTest::heap()); |
| 3857 CcTest::heap()->CollectAllGarbage(); | 3898 CcTest::heap()->CollectAllGarbage(); |
| 3858 | 3899 |
| 3859 CheckVectorICCleared(f, 0); | 3900 CheckVectorICCleared(f, 0); |
| 3860 } | 3901 } |
| 3861 | 3902 |
| 3862 | 3903 |
| 3863 TEST(IncrementalMarkingPreservesPolymorphicIC) { | 3904 TEST(IncrementalMarkingPreservesPolymorphicIC) { |
| 3864 if (i::FLAG_always_opt) return; | 3905 if (i::FLAG_always_opt) return; |
| 3865 CcTest::InitializeVM(); | 3906 CcTest::InitializeVM(); |
| 3866 v8::HandleScope scope(CcTest::isolate()); | 3907 v8::HandleScope scope(CcTest::isolate()); |
| 3867 v8::Local<v8::Value> obj1, obj2; | 3908 v8::Local<v8::Value> obj1, obj2; |
| 3909 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3868 | 3910 |
| 3869 { | 3911 { |
| 3870 LocalContext env; | 3912 LocalContext env; |
| 3871 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); | 3913 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); |
| 3872 obj1 = env->Global()->Get(v8_str("obj")); | 3914 obj1 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); |
| 3873 } | 3915 } |
| 3874 | 3916 |
| 3875 { | 3917 { |
| 3876 LocalContext env; | 3918 LocalContext env; |
| 3877 CompileRun("function fun() { this.x = 2; }; var obj = new fun();"); | 3919 CompileRun("function fun() { this.x = 2; }; var obj = new fun();"); |
| 3878 obj2 = env->Global()->Get(v8_str("obj")); | 3920 obj2 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); |
| 3879 } | 3921 } |
| 3880 | 3922 |
| 3881 // Prepare function f that contains a polymorphic IC for objects | 3923 // Prepare function f that contains a polymorphic IC for objects |
| 3882 // originating from two different native contexts. | 3924 // originating from two different native contexts. |
| 3883 CcTest::global()->Set(v8_str("obj1"), obj1); | 3925 CHECK(CcTest::global()->Set(ctx, v8_str("obj1"), obj1).FromJust()); |
| 3884 CcTest::global()->Set(v8_str("obj2"), obj2); | 3926 CHECK(CcTest::global()->Set(ctx, v8_str("obj2"), obj2).FromJust()); |
| 3885 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);"); | 3927 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);"); |
| 3886 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 3928 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 3887 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 3929 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 3930 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
| 3888 | 3931 |
| 3889 CheckVectorIC(f, 0, POLYMORPHIC); | 3932 CheckVectorIC(f, 0, POLYMORPHIC); |
| 3890 | 3933 |
| 3891 // Fire context dispose notification. | 3934 // Fire context dispose notification. |
| 3892 SimulateIncrementalMarking(CcTest::heap()); | 3935 SimulateIncrementalMarking(CcTest::heap()); |
| 3893 CcTest::heap()->CollectAllGarbage(); | 3936 CcTest::heap()->CollectAllGarbage(); |
| 3894 | 3937 |
| 3895 CheckVectorIC(f, 0, POLYMORPHIC); | 3938 CheckVectorIC(f, 0, POLYMORPHIC); |
| 3896 } | 3939 } |
| 3897 | 3940 |
| 3898 | 3941 |
| 3899 TEST(IncrementalMarkingClearsPolymorphicIC) { | 3942 TEST(IncrementalMarkingClearsPolymorphicIC) { |
| 3900 if (i::FLAG_always_opt) return; | 3943 if (i::FLAG_always_opt) return; |
| 3901 CcTest::InitializeVM(); | 3944 CcTest::InitializeVM(); |
| 3902 v8::HandleScope scope(CcTest::isolate()); | 3945 v8::HandleScope scope(CcTest::isolate()); |
| 3903 v8::Local<v8::Value> obj1, obj2; | 3946 v8::Local<v8::Value> obj1, obj2; |
| 3947 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
| 3904 | 3948 |
| 3905 { | 3949 { |
| 3906 LocalContext env; | 3950 LocalContext env; |
| 3907 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); | 3951 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); |
| 3908 obj1 = env->Global()->Get(v8_str("obj")); | 3952 obj1 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); |
| 3909 } | 3953 } |
| 3910 | 3954 |
| 3911 { | 3955 { |
| 3912 LocalContext env; | 3956 LocalContext env; |
| 3913 CompileRun("function fun() { this.x = 2; }; var obj = new fun();"); | 3957 CompileRun("function fun() { this.x = 2; }; var obj = new fun();"); |
| 3914 obj2 = env->Global()->Get(v8_str("obj")); | 3958 obj2 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); |
| 3915 } | 3959 } |
| 3916 | 3960 |
| 3917 // Prepare function f that contains a polymorphic IC for objects | 3961 // Prepare function f that contains a polymorphic IC for objects |
| 3918 // originating from two different native contexts. | 3962 // originating from two different native contexts. |
| 3919 CcTest::global()->Set(v8_str("obj1"), obj1); | 3963 CHECK(CcTest::global()->Set(ctx, v8_str("obj1"), obj1).FromJust()); |
| 3920 CcTest::global()->Set(v8_str("obj2"), obj2); | 3964 CHECK(CcTest::global()->Set(ctx, v8_str("obj2"), obj2).FromJust()); |
| 3921 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);"); | 3965 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);"); |
| 3922 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 3966 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 3923 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 3967 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 3968 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
| 3924 | 3969 |
| 3925 CheckVectorIC(f, 0, POLYMORPHIC); | 3970 CheckVectorIC(f, 0, POLYMORPHIC); |
| 3926 | 3971 |
| 3927 // Fire context dispose notification. | 3972 // Fire context dispose notification. |
| 3928 CcTest::isolate()->ContextDisposedNotification(); | 3973 CcTest::isolate()->ContextDisposedNotification(); |
| 3929 SimulateIncrementalMarking(CcTest::heap()); | 3974 SimulateIncrementalMarking(CcTest::heap()); |
| 3930 CcTest::heap()->CollectAllGarbage(); | 3975 CcTest::heap()->CollectAllGarbage(); |
| 3931 | 3976 |
| 3932 CheckVectorICCleared(f, 0); | 3977 CheckVectorICCleared(f, 0); |
| 3933 } | 3978 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3959 const char* accessor) { | 4004 const char* accessor) { |
| 3960 // Test that the data retained by the Error.stack accessor is released | 4005 // Test that the data retained by the Error.stack accessor is released |
| 3961 // after the first time the accessor is fired. We use external string | 4006 // after the first time the accessor is fired. We use external string |
| 3962 // to check whether the data is being released since the external string | 4007 // to check whether the data is being released since the external string |
| 3963 // resource's callback is fired when the external string is GC'ed. | 4008 // resource's callback is fired when the external string is GC'ed. |
| 3964 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 4009 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 3965 v8::HandleScope scope(isolate); | 4010 v8::HandleScope scope(isolate); |
| 3966 SourceResource* resource = new SourceResource(i::StrDup(source)); | 4011 SourceResource* resource = new SourceResource(i::StrDup(source)); |
| 3967 { | 4012 { |
| 3968 v8::HandleScope scope(isolate); | 4013 v8::HandleScope scope(isolate); |
| 3969 v8::Handle<v8::String> source_string = | 4014 v8::Local<v8::Context> ctx = isolate->GetCurrentContext(); |
| 3970 v8::String::NewExternal(isolate, resource); | 4015 v8::Local<v8::String> source_string = |
| 4016 v8::String::NewExternalOneByte(isolate, resource).ToLocalChecked(); |
| 3971 i_isolate->heap()->CollectAllAvailableGarbage(); | 4017 i_isolate->heap()->CollectAllAvailableGarbage(); |
| 3972 v8::Script::Compile(source_string)->Run(); | 4018 v8::Script::Compile(ctx, source_string) |
| 4019 .ToLocalChecked() |
| 4020 ->Run(ctx) |
| 4021 .ToLocalChecked(); |
| 3973 CHECK(!resource->IsDisposed()); | 4022 CHECK(!resource->IsDisposed()); |
| 3974 } | 4023 } |
| 3975 // i_isolate->heap()->CollectAllAvailableGarbage(); | 4024 // i_isolate->heap()->CollectAllAvailableGarbage(); |
| 3976 CHECK(!resource->IsDisposed()); | 4025 CHECK(!resource->IsDisposed()); |
| 3977 | 4026 |
| 3978 CompileRun(accessor); | 4027 CompileRun(accessor); |
| 3979 i_isolate->heap()->CollectAllAvailableGarbage(); | 4028 i_isolate->heap()->CollectAllAvailableGarbage(); |
| 3980 | 4029 |
| 3981 // External source has been released. | 4030 // External source has been released. |
| 3982 CHECK(resource->IsDisposed()); | 4031 CHECK(resource->IsDisposed()); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4040 ReleaseStackTraceDataTest(isolate, source4, getter); | 4089 ReleaseStackTraceDataTest(isolate, source4, getter); |
| 4041 } | 4090 } |
| 4042 isolate->Dispose(); | 4091 isolate->Dispose(); |
| 4043 } | 4092 } |
| 4044 | 4093 |
| 4045 | 4094 |
| 4046 TEST(Regress159140) { | 4095 TEST(Regress159140) { |
| 4047 i::FLAG_allow_natives_syntax = true; | 4096 i::FLAG_allow_natives_syntax = true; |
| 4048 CcTest::InitializeVM(); | 4097 CcTest::InitializeVM(); |
| 4049 Isolate* isolate = CcTest::i_isolate(); | 4098 Isolate* isolate = CcTest::i_isolate(); |
| 4099 LocalContext env; |
| 4050 Heap* heap = isolate->heap(); | 4100 Heap* heap = isolate->heap(); |
| 4051 HandleScope scope(isolate); | 4101 HandleScope scope(isolate); |
| 4052 | 4102 |
| 4053 // Perform one initial GC to enable code flushing. | 4103 // Perform one initial GC to enable code flushing. |
| 4054 heap->CollectAllGarbage(); | 4104 heap->CollectAllGarbage(); |
| 4055 | 4105 |
| 4056 // Prepare several closures that are all eligible for code flushing | 4106 // Prepare several closures that are all eligible for code flushing |
| 4057 // because all reachable ones are not optimized. Make sure that the | 4107 // because all reachable ones are not optimized. Make sure that the |
| 4058 // optimized code object is directly reachable through a handle so | 4108 // optimized code object is directly reachable through a handle so |
| 4059 // that it is marked black during incremental marking. | 4109 // that it is marked black during incremental marking. |
| 4060 Handle<Code> code; | 4110 Handle<Code> code; |
| 4061 { | 4111 { |
| 4062 HandleScope inner_scope(isolate); | 4112 HandleScope inner_scope(isolate); |
| 4063 CompileRun("function h(x) {}" | 4113 CompileRun("function h(x) {}" |
| 4064 "function mkClosure() {" | 4114 "function mkClosure() {" |
| 4065 " return function(x) { return x + 1; };" | 4115 " return function(x) { return x + 1; };" |
| 4066 "}" | 4116 "}" |
| 4067 "var f = mkClosure();" | 4117 "var f = mkClosure();" |
| 4068 "var g = mkClosure();" | 4118 "var g = mkClosure();" |
| 4069 "f(1); f(2);" | 4119 "f(1); f(2);" |
| 4070 "g(1); g(2);" | 4120 "g(1); g(2);" |
| 4071 "h(1); h(2);" | 4121 "h(1); h(2);" |
| 4072 "%OptimizeFunctionOnNextCall(f); f(3);" | 4122 "%OptimizeFunctionOnNextCall(f); f(3);" |
| 4073 "%OptimizeFunctionOnNextCall(h); h(3);"); | 4123 "%OptimizeFunctionOnNextCall(h); h(3);"); |
| 4074 | 4124 |
| 4075 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4125 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 4076 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 4126 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4127 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); |
| 4077 CHECK(f->is_compiled()); | 4128 CHECK(f->is_compiled()); |
| 4078 CompileRun("f = null;"); | 4129 CompileRun("f = null;"); |
| 4079 | 4130 |
| 4080 Handle<JSFunction> g = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4131 Handle<JSFunction> g = Handle<JSFunction>::cast( |
| 4081 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("g"))))); | 4132 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4133 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); |
| 4082 CHECK(g->is_compiled()); | 4134 CHECK(g->is_compiled()); |
| 4083 const int kAgingThreshold = 6; | 4135 const int kAgingThreshold = 6; |
| 4084 for (int i = 0; i < kAgingThreshold; i++) { | 4136 for (int i = 0; i < kAgingThreshold; i++) { |
| 4085 g->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 4137 g->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); |
| 4086 } | 4138 } |
| 4087 | 4139 |
| 4088 code = inner_scope.CloseAndEscape(Handle<Code>(f->code())); | 4140 code = inner_scope.CloseAndEscape(Handle<Code>(f->code())); |
| 4089 } | 4141 } |
| 4090 | 4142 |
| 4091 // Simulate incremental marking so that the functions are enqueued as | 4143 // Simulate incremental marking so that the functions are enqueued as |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4108 HandleScope scope(isolate); | 4160 HandleScope scope(isolate); |
| 4109 | 4161 |
| 4110 // Perform one initial GC to enable code flushing. | 4162 // Perform one initial GC to enable code flushing. |
| 4111 heap->CollectAllGarbage(); | 4163 heap->CollectAllGarbage(); |
| 4112 | 4164 |
| 4113 // Prepare an optimized closure that the optimized code map will get | 4165 // Prepare an optimized closure that the optimized code map will get |
| 4114 // populated. Then age the unoptimized code to trigger code flushing | 4166 // populated. Then age the unoptimized code to trigger code flushing |
| 4115 // but make sure the optimized code is unreachable. | 4167 // but make sure the optimized code is unreachable. |
| 4116 { | 4168 { |
| 4117 HandleScope inner_scope(isolate); | 4169 HandleScope inner_scope(isolate); |
| 4170 LocalContext env; |
| 4118 CompileRun("function mkClosure() {" | 4171 CompileRun("function mkClosure() {" |
| 4119 " return function(x) { return x + 1; };" | 4172 " return function(x) { return x + 1; };" |
| 4120 "}" | 4173 "}" |
| 4121 "var f = mkClosure();" | 4174 "var f = mkClosure();" |
| 4122 "f(1); f(2);" | 4175 "f(1); f(2);" |
| 4123 "%OptimizeFunctionOnNextCall(f); f(3);"); | 4176 "%OptimizeFunctionOnNextCall(f); f(3);"); |
| 4124 | 4177 |
| 4125 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4178 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 4126 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 4179 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4180 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); |
| 4127 CHECK(f->is_compiled()); | 4181 CHECK(f->is_compiled()); |
| 4128 const int kAgingThreshold = 6; | 4182 const int kAgingThreshold = 6; |
| 4129 for (int i = 0; i < kAgingThreshold; i++) { | 4183 for (int i = 0; i < kAgingThreshold; i++) { |
| 4130 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 4184 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); |
| 4131 } | 4185 } |
| 4132 | 4186 |
| 4133 CompileRun("f = null;"); | 4187 CompileRun("f = null;"); |
| 4134 } | 4188 } |
| 4135 | 4189 |
| 4136 // Simulate incremental marking so that unoptimized code is flushed | 4190 // Simulate incremental marking so that unoptimized code is flushed |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4154 HandleScope scope(isolate); | 4208 HandleScope scope(isolate); |
| 4155 | 4209 |
| 4156 // Perform one initial GC to enable code flushing. | 4210 // Perform one initial GC to enable code flushing. |
| 4157 heap->CollectAllGarbage(); | 4211 heap->CollectAllGarbage(); |
| 4158 | 4212 |
| 4159 // Prepare a shared function info eligible for code flushing for which | 4213 // Prepare a shared function info eligible for code flushing for which |
| 4160 // the unoptimized code will be replaced during optimization. | 4214 // the unoptimized code will be replaced during optimization. |
| 4161 Handle<SharedFunctionInfo> shared1; | 4215 Handle<SharedFunctionInfo> shared1; |
| 4162 { | 4216 { |
| 4163 HandleScope inner_scope(isolate); | 4217 HandleScope inner_scope(isolate); |
| 4218 LocalContext env; |
| 4164 CompileRun("function f() { return 'foobar'; }" | 4219 CompileRun("function f() { return 'foobar'; }" |
| 4165 "function g(x) { if (x) f(); }" | 4220 "function g(x) { if (x) f(); }" |
| 4166 "f();" | 4221 "f();" |
| 4167 "g(false);" | 4222 "g(false);" |
| 4168 "g(false);"); | 4223 "g(false);"); |
| 4169 | 4224 |
| 4170 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4225 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 4171 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 4226 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4227 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); |
| 4172 CHECK(f->is_compiled()); | 4228 CHECK(f->is_compiled()); |
| 4173 const int kAgingThreshold = 6; | 4229 const int kAgingThreshold = 6; |
| 4174 for (int i = 0; i < kAgingThreshold; i++) { | 4230 for (int i = 0; i < kAgingThreshold; i++) { |
| 4175 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 4231 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); |
| 4176 } | 4232 } |
| 4177 | 4233 |
| 4178 shared1 = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); | 4234 shared1 = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); |
| 4179 } | 4235 } |
| 4180 | 4236 |
| 4181 // Prepare a shared function info eligible for code flushing that will | 4237 // Prepare a shared function info eligible for code flushing that will |
| 4182 // represent the dangling tail of the candidate list. | 4238 // represent the dangling tail of the candidate list. |
| 4183 Handle<SharedFunctionInfo> shared2; | 4239 Handle<SharedFunctionInfo> shared2; |
| 4184 { | 4240 { |
| 4185 HandleScope inner_scope(isolate); | 4241 HandleScope inner_scope(isolate); |
| 4242 LocalContext env; |
| 4186 CompileRun("function flushMe() { return 0; }" | 4243 CompileRun("function flushMe() { return 0; }" |
| 4187 "flushMe(1);"); | 4244 "flushMe(1);"); |
| 4188 | 4245 |
| 4189 Handle<JSFunction> f = Handle<JSFunction>::cast( | 4246 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( |
| 4190 v8::Utils::OpenHandle(*v8::Handle<v8::Function>::Cast( | 4247 *v8::Local<v8::Function>::Cast(CcTest::global() |
| 4191 CcTest::global()->Get(v8_str("flushMe"))))); | 4248 ->Get(env.local(), v8_str("flushMe")) |
| 4249 .ToLocalChecked()))); |
| 4192 CHECK(f->is_compiled()); | 4250 CHECK(f->is_compiled()); |
| 4193 const int kAgingThreshold = 6; | 4251 const int kAgingThreshold = 6; |
| 4194 for (int i = 0; i < kAgingThreshold; i++) { | 4252 for (int i = 0; i < kAgingThreshold; i++) { |
| 4195 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 4253 f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); |
| 4196 } | 4254 } |
| 4197 | 4255 |
| 4198 shared2 = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); | 4256 shared2 = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); |
| 4199 } | 4257 } |
| 4200 | 4258 |
| 4201 // Simulate incremental marking and collect code flushing candidates. | 4259 // Simulate incremental marking and collect code flushing candidates. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4213 heap->CollectAllGarbage(); | 4271 heap->CollectAllGarbage(); |
| 4214 CHECK(shared1->code()->gc_metadata() == NULL); | 4272 CHECK(shared1->code()->gc_metadata() == NULL); |
| 4215 } | 4273 } |
| 4216 | 4274 |
| 4217 | 4275 |
| 4218 TEST(Regress169928) { | 4276 TEST(Regress169928) { |
| 4219 i::FLAG_allow_natives_syntax = true; | 4277 i::FLAG_allow_natives_syntax = true; |
| 4220 i::FLAG_crankshaft = false; | 4278 i::FLAG_crankshaft = false; |
| 4221 CcTest::InitializeVM(); | 4279 CcTest::InitializeVM(); |
| 4222 Isolate* isolate = CcTest::i_isolate(); | 4280 Isolate* isolate = CcTest::i_isolate(); |
| 4281 LocalContext env; |
| 4223 Factory* factory = isolate->factory(); | 4282 Factory* factory = isolate->factory(); |
| 4224 v8::HandleScope scope(CcTest::isolate()); | 4283 v8::HandleScope scope(CcTest::isolate()); |
| 4225 | 4284 |
| 4226 // Some flags turn Scavenge collections into Mark-sweep collections | 4285 // Some flags turn Scavenge collections into Mark-sweep collections |
| 4227 // and hence are incompatible with this test case. | 4286 // and hence are incompatible with this test case. |
| 4228 if (FLAG_gc_global || FLAG_stress_compaction) return; | 4287 if (FLAG_gc_global || FLAG_stress_compaction) return; |
| 4229 | 4288 |
| 4230 // Prepare the environment | 4289 // Prepare the environment |
| 4231 CompileRun("function fastliteralcase(literal, value) {" | 4290 CompileRun("function fastliteralcase(literal, value) {" |
| 4232 " literal[0] = value;" | 4291 " literal[0] = value;" |
| 4233 " return literal;" | 4292 " return literal;" |
| 4234 "}" | 4293 "}" |
| 4235 "function get_standard_literal() {" | 4294 "function get_standard_literal() {" |
| 4236 " var literal = [1, 2, 3];" | 4295 " var literal = [1, 2, 3];" |
| 4237 " return literal;" | 4296 " return literal;" |
| 4238 "}" | 4297 "}" |
| 4239 "obj = fastliteralcase(get_standard_literal(), 1);" | 4298 "obj = fastliteralcase(get_standard_literal(), 1);" |
| 4240 "obj = fastliteralcase(get_standard_literal(), 1.5);" | 4299 "obj = fastliteralcase(get_standard_literal(), 1.5);" |
| 4241 "obj = fastliteralcase(get_standard_literal(), 2);"); | 4300 "obj = fastliteralcase(get_standard_literal(), 2);"); |
| 4242 | 4301 |
| 4243 // prepare the heap | 4302 // prepare the heap |
| 4244 v8::Local<v8::String> mote_code_string = | 4303 v8::Local<v8::String> mote_code_string = |
| 4245 v8_str("fastliteralcase(mote, 2.5);"); | 4304 v8_str("fastliteralcase(mote, 2.5);"); |
| 4246 | 4305 |
| 4247 v8::Local<v8::String> array_name = v8_str("mote"); | 4306 v8::Local<v8::String> array_name = v8_str("mote"); |
| 4248 CcTest::global()->Set(array_name, v8::Int32::New(CcTest::isolate(), 0)); | 4307 CHECK(CcTest::global() |
| 4308 ->Set(env.local(), array_name, v8::Int32::New(CcTest::isolate(), 0)) |
| 4309 .FromJust()); |
| 4249 | 4310 |
| 4250 // First make sure we flip spaces | 4311 // First make sure we flip spaces |
| 4251 CcTest::heap()->CollectGarbage(NEW_SPACE); | 4312 CcTest::heap()->CollectGarbage(NEW_SPACE); |
| 4252 | 4313 |
| 4253 // Allocate the object. | 4314 // Allocate the object. |
| 4254 Handle<FixedArray> array_data = factory->NewFixedArray(2, NOT_TENURED); | 4315 Handle<FixedArray> array_data = factory->NewFixedArray(2, NOT_TENURED); |
| 4255 array_data->set(0, Smi::FromInt(1)); | 4316 array_data->set(0, Smi::FromInt(1)); |
| 4256 array_data->set(1, Smi::FromInt(2)); | 4317 array_data->set(1, Smi::FromInt(2)); |
| 4257 | 4318 |
| 4258 AllocateAllButNBytes(CcTest::heap()->new_space(), | 4319 AllocateAllButNBytes(CcTest::heap()->new_space(), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4270 HeapObject* obj = NULL; | 4331 HeapObject* obj = NULL; |
| 4271 AllocationResult allocation = | 4332 AllocationResult allocation = |
| 4272 CcTest::heap()->new_space()->AllocateRawUnaligned( | 4333 CcTest::heap()->new_space()->AllocateRawUnaligned( |
| 4273 AllocationMemento::kSize + kPointerSize); | 4334 AllocationMemento::kSize + kPointerSize); |
| 4274 CHECK(allocation.To(&obj)); | 4335 CHECK(allocation.To(&obj)); |
| 4275 Address addr_obj = obj->address(); | 4336 Address addr_obj = obj->address(); |
| 4276 CcTest::heap()->CreateFillerObjectAt( | 4337 CcTest::heap()->CreateFillerObjectAt( |
| 4277 addr_obj, AllocationMemento::kSize + kPointerSize); | 4338 addr_obj, AllocationMemento::kSize + kPointerSize); |
| 4278 | 4339 |
| 4279 // Give the array a name, making sure not to allocate strings. | 4340 // Give the array a name, making sure not to allocate strings. |
| 4280 v8::Handle<v8::Object> array_obj = v8::Utils::ToLocal(array); | 4341 v8::Local<v8::Object> array_obj = v8::Utils::ToLocal(array); |
| 4281 CcTest::global()->Set(array_name, array_obj); | 4342 CHECK(CcTest::global()->Set(env.local(), array_name, array_obj).FromJust()); |
| 4282 | 4343 |
| 4283 // This should crash with a protection violation if we are running a build | 4344 // This should crash with a protection violation if we are running a build |
| 4284 // with the bug. | 4345 // with the bug. |
| 4285 AlwaysAllocateScope aa_scope(isolate); | 4346 AlwaysAllocateScope aa_scope(isolate); |
| 4286 v8::Script::Compile(mote_code_string)->Run(); | 4347 v8::Script::Compile(env.local(), mote_code_string) |
| 4348 .ToLocalChecked() |
| 4349 ->Run(env.local()) |
| 4350 .ToLocalChecked(); |
| 4287 } | 4351 } |
| 4288 | 4352 |
| 4289 | 4353 |
| 4290 #ifdef DEBUG | 4354 #ifdef DEBUG |
| 4291 TEST(Regress513507) { | 4355 TEST(Regress513507) { |
| 4292 i::FLAG_flush_optimized_code_cache = false; | 4356 i::FLAG_flush_optimized_code_cache = false; |
| 4293 i::FLAG_allow_natives_syntax = true; | 4357 i::FLAG_allow_natives_syntax = true; |
| 4294 i::FLAG_gc_global = true; | 4358 i::FLAG_gc_global = true; |
| 4295 CcTest::InitializeVM(); | 4359 CcTest::InitializeVM(); |
| 4296 Isolate* isolate = CcTest::i_isolate(); | 4360 Isolate* isolate = CcTest::i_isolate(); |
| 4361 LocalContext env; |
| 4297 Heap* heap = isolate->heap(); | 4362 Heap* heap = isolate->heap(); |
| 4298 HandleScope scope(isolate); | 4363 HandleScope scope(isolate); |
| 4299 | 4364 |
| 4300 // Prepare function whose optimized code map we can use. | 4365 // Prepare function whose optimized code map we can use. |
| 4301 Handle<SharedFunctionInfo> shared; | 4366 Handle<SharedFunctionInfo> shared; |
| 4302 { | 4367 { |
| 4303 HandleScope inner_scope(isolate); | 4368 HandleScope inner_scope(isolate); |
| 4304 CompileRun("function f() { return 1 }" | 4369 CompileRun("function f() { return 1 }" |
| 4305 "f(); %OptimizeFunctionOnNextCall(f); f();"); | 4370 "f(); %OptimizeFunctionOnNextCall(f); f();"); |
| 4306 | 4371 |
| 4307 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4372 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 4308 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 4373 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4374 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); |
| 4309 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); | 4375 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); |
| 4310 CompileRun("f = null"); | 4376 CompileRun("f = null"); |
| 4311 } | 4377 } |
| 4312 | 4378 |
| 4313 // Prepare optimized code that we can use. | 4379 // Prepare optimized code that we can use. |
| 4314 Handle<Code> code; | 4380 Handle<Code> code; |
| 4315 { | 4381 { |
| 4316 HandleScope inner_scope(isolate); | 4382 HandleScope inner_scope(isolate); |
| 4317 CompileRun("function g() { return 2 }" | 4383 CompileRun("function g() { return 2 }" |
| 4318 "g(); %OptimizeFunctionOnNextCall(g); g();"); | 4384 "g(); %OptimizeFunctionOnNextCall(g); g();"); |
| 4319 | 4385 |
| 4320 Handle<JSFunction> g = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4386 Handle<JSFunction> g = Handle<JSFunction>::cast( |
| 4321 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("g"))))); | 4387 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4388 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); |
| 4322 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); | 4389 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); |
| 4323 if (!code->is_optimized_code()) return; | 4390 if (!code->is_optimized_code()) return; |
| 4324 } | 4391 } |
| 4325 | 4392 |
| 4326 Handle<TypeFeedbackVector> vector = handle(shared->feedback_vector()); | 4393 Handle<TypeFeedbackVector> vector = handle(shared->feedback_vector()); |
| 4327 Handle<LiteralsArray> lit = | 4394 Handle<LiteralsArray> lit = |
| 4328 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED); | 4395 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED); |
| 4329 Handle<Context> context(isolate->context()); | 4396 Handle<Context> context(isolate->context()); |
| 4330 | 4397 |
| 4331 // Add the new code several times to the optimized code map and also set an | 4398 // Add the new code several times to the optimized code map and also set an |
| 4332 // allocation timeout so that expanding the code map will trigger a GC. | 4399 // allocation timeout so that expanding the code map will trigger a GC. |
| 4333 heap->set_allocation_timeout(5); | 4400 heap->set_allocation_timeout(5); |
| 4334 FLAG_gc_interval = 1000; | 4401 FLAG_gc_interval = 1000; |
| 4335 for (int i = 0; i < 10; ++i) { | 4402 for (int i = 0; i < 10; ++i) { |
| 4336 BailoutId id = BailoutId(i); | 4403 BailoutId id = BailoutId(i); |
| 4337 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); | 4404 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); |
| 4338 } | 4405 } |
| 4339 } | 4406 } |
| 4340 #endif // DEBUG | 4407 #endif // DEBUG |
| 4341 | 4408 |
| 4342 | 4409 |
| 4343 TEST(Regress514122) { | 4410 TEST(Regress514122) { |
| 4344 i::FLAG_flush_optimized_code_cache = false; | 4411 i::FLAG_flush_optimized_code_cache = false; |
| 4345 i::FLAG_allow_natives_syntax = true; | 4412 i::FLAG_allow_natives_syntax = true; |
| 4346 CcTest::InitializeVM(); | 4413 CcTest::InitializeVM(); |
| 4347 Isolate* isolate = CcTest::i_isolate(); | 4414 Isolate* isolate = CcTest::i_isolate(); |
| 4415 LocalContext env; |
| 4348 Heap* heap = isolate->heap(); | 4416 Heap* heap = isolate->heap(); |
| 4349 HandleScope scope(isolate); | 4417 HandleScope scope(isolate); |
| 4350 | 4418 |
| 4351 // Perfrom one initial GC to enable code flushing. | 4419 // Perfrom one initial GC to enable code flushing. |
| 4352 CcTest::heap()->CollectAllGarbage(); | 4420 CcTest::heap()->CollectAllGarbage(); |
| 4353 | 4421 |
| 4354 // Prepare function whose optimized code map we can use. | 4422 // Prepare function whose optimized code map we can use. |
| 4355 Handle<SharedFunctionInfo> shared; | 4423 Handle<SharedFunctionInfo> shared; |
| 4356 { | 4424 { |
| 4357 HandleScope inner_scope(isolate); | 4425 HandleScope inner_scope(isolate); |
| 4358 CompileRun("function f() { return 1 }" | 4426 CompileRun("function f() { return 1 }" |
| 4359 "f(); %OptimizeFunctionOnNextCall(f); f();"); | 4427 "f(); %OptimizeFunctionOnNextCall(f); f();"); |
| 4360 | 4428 |
| 4361 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4429 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 4362 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 4430 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4431 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked()))); |
| 4363 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); | 4432 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); |
| 4364 CompileRun("f = null"); | 4433 CompileRun("f = null"); |
| 4365 } | 4434 } |
| 4366 | 4435 |
| 4367 // Prepare optimized code that we can use. | 4436 // Prepare optimized code that we can use. |
| 4368 Handle<Code> code; | 4437 Handle<Code> code; |
| 4369 { | 4438 { |
| 4370 HandleScope inner_scope(isolate); | 4439 HandleScope inner_scope(isolate); |
| 4371 CompileRun("function g() { return 2 }" | 4440 CompileRun("function g() { return 2 }" |
| 4372 "g(); %OptimizeFunctionOnNextCall(g); g();"); | 4441 "g(); %OptimizeFunctionOnNextCall(g); g();"); |
| 4373 | 4442 |
| 4374 Handle<JSFunction> g = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4443 Handle<JSFunction> g = Handle<JSFunction>::cast( |
| 4375 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("g"))))); | 4444 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4445 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); |
| 4376 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); | 4446 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); |
| 4377 if (!code->is_optimized_code()) return; | 4447 if (!code->is_optimized_code()) return; |
| 4378 } | 4448 } |
| 4379 | 4449 |
| 4380 Handle<TypeFeedbackVector> vector = handle(shared->feedback_vector()); | 4450 Handle<TypeFeedbackVector> vector = handle(shared->feedback_vector()); |
| 4381 Handle<LiteralsArray> lit = | 4451 Handle<LiteralsArray> lit = |
| 4382 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED); | 4452 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED); |
| 4383 Handle<Context> context(isolate->context()); | 4453 Handle<Context> context(isolate->context()); |
| 4384 | 4454 |
| 4385 // Add the code several times to the optimized code map. | 4455 // Add the code several times to the optimized code map. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4439 HandleScope scope(isolate); | 4509 HandleScope scope(isolate); |
| 4440 | 4510 |
| 4441 // Perfrom one initial GC to enable code flushing. | 4511 // Perfrom one initial GC to enable code flushing. |
| 4442 CcTest::heap()->CollectAllGarbage(); | 4512 CcTest::heap()->CollectAllGarbage(); |
| 4443 | 4513 |
| 4444 // Prepare an optimized closure with containing an inlined function. Then age | 4514 // Prepare an optimized closure with containing an inlined function. Then age |
| 4445 // the inlined unoptimized code to trigger code flushing but make sure the | 4515 // the inlined unoptimized code to trigger code flushing but make sure the |
| 4446 // outer optimized code is kept in the optimized code map. | 4516 // outer optimized code is kept in the optimized code map. |
| 4447 Handle<SharedFunctionInfo> shared; | 4517 Handle<SharedFunctionInfo> shared; |
| 4448 { | 4518 { |
| 4519 LocalContext context; |
| 4449 HandleScope inner_scope(isolate); | 4520 HandleScope inner_scope(isolate); |
| 4450 CompileRun( | 4521 CompileRun( |
| 4451 "function g(x) { return x + 1 }" | 4522 "function g(x) { return x + 1 }" |
| 4452 "function mkClosure() {" | 4523 "function mkClosure() {" |
| 4453 " return function(x) { return g(x); };" | 4524 " return function(x) { return g(x); };" |
| 4454 "}" | 4525 "}" |
| 4455 "var f = mkClosure();" | 4526 "var f = mkClosure();" |
| 4456 "f(1); f(2);" | 4527 "f(1); f(2);" |
| 4457 "%OptimizeFunctionOnNextCall(f); f(3);"); | 4528 "%OptimizeFunctionOnNextCall(f); f(3);"); |
| 4458 | 4529 |
| 4459 Handle<JSFunction> g = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4530 Handle<JSFunction> g = Handle<JSFunction>::cast(v8::Utils::OpenHandle( |
| 4460 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("g"))))); | 4531 *v8::Local<v8::Function>::Cast(CcTest::global() |
| 4532 ->Get(context.local(), v8_str("g")) |
| 4533 .ToLocalChecked()))); |
| 4461 CHECK(g->shared()->is_compiled()); | 4534 CHECK(g->shared()->is_compiled()); |
| 4462 const int kAgingThreshold = 6; | 4535 const int kAgingThreshold = 6; |
| 4463 for (int i = 0; i < kAgingThreshold; i++) { | 4536 for (int i = 0; i < kAgingThreshold; i++) { |
| 4464 g->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); | 4537 g->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2)); |
| 4465 } | 4538 } |
| 4466 | 4539 |
| 4467 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4540 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( |
| 4468 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 4541 *v8::Local<v8::Function>::Cast(CcTest::global() |
| 4542 ->Get(context.local(), v8_str("f")) |
| 4543 .ToLocalChecked()))); |
| 4469 CHECK(f->is_compiled()); | 4544 CHECK(f->is_compiled()); |
| 4470 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); | 4545 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); |
| 4471 CompileRun("f = null"); | 4546 CompileRun("f = null"); |
| 4472 } | 4547 } |
| 4473 | 4548 |
| 4474 // Lookup the optimized code and keep it alive. | 4549 // Lookup the optimized code and keep it alive. |
| 4475 CodeAndLiterals result = shared->SearchOptimizedCodeMap( | 4550 CodeAndLiterals result = shared->SearchOptimizedCodeMap( |
| 4476 isolate->context()->native_context(), BailoutId::None()); | 4551 isolate->context()->native_context(), BailoutId::None()); |
| 4477 Handle<Code> optimized_code(result.code, isolate); | 4552 Handle<Code> optimized_code(result.code, isolate); |
| 4478 | 4553 |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4646 | 4721 |
| 4647 CompileRun("%OptimizeFunctionOnNextCall(bar); bar();"); | 4722 CompileRun("%OptimizeFunctionOnNextCall(bar); bar();"); |
| 4648 | 4723 |
| 4649 DependentCode::GroupStartIndexes starts(site->dependent_code()); | 4724 DependentCode::GroupStartIndexes starts(site->dependent_code()); |
| 4650 CHECK_GE(starts.number_of_entries(), 1); | 4725 CHECK_GE(starts.number_of_entries(), 1); |
| 4651 int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); | 4726 int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); |
| 4652 CHECK(site->dependent_code()->object_at(index)->IsWeakCell()); | 4727 CHECK(site->dependent_code()->object_at(index)->IsWeakCell()); |
| 4653 Code* function_bar = Code::cast( | 4728 Code* function_bar = Code::cast( |
| 4654 WeakCell::cast(site->dependent_code()->object_at(index))->value()); | 4729 WeakCell::cast(site->dependent_code()->object_at(index))->value()); |
| 4655 Handle<JSFunction> bar_handle = Handle<JSFunction>::cast( | 4730 Handle<JSFunction> bar_handle = Handle<JSFunction>::cast( |
| 4656 v8::Utils::OpenHandle(*v8::Handle<v8::Function>::Cast( | 4731 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4657 CcTest::global()->Get(v8_str("bar"))))); | 4732 CcTest::global() |
| 4733 ->Get(context.local(), v8_str("bar")) |
| 4734 .ToLocalChecked()))); |
| 4658 CHECK_EQ(bar_handle->code(), function_bar); | 4735 CHECK_EQ(bar_handle->code(), function_bar); |
| 4659 } | 4736 } |
| 4660 | 4737 |
| 4661 // Now make sure that a gc should get rid of the function, even though we | 4738 // Now make sure that a gc should get rid of the function, even though we |
| 4662 // still have the allocation site alive. | 4739 // still have the allocation site alive. |
| 4663 for (int i = 0; i < 4; i++) { | 4740 for (int i = 0; i < 4; i++) { |
| 4664 heap->CollectAllGarbage(); | 4741 heap->CollectAllGarbage(); |
| 4665 } | 4742 } |
| 4666 | 4743 |
| 4667 // The site still exists because of our global handle, but the code is no | 4744 // The site still exists because of our global handle, but the code is no |
| (...skipping 26 matching lines...) Expand all Loading... |
| 4694 " };" | 4771 " };" |
| 4695 " var foo = function(x) { with (x) { return 1 + x; } };" | 4772 " var foo = function(x) { with (x) { return 1 + x; } };" |
| 4696 " bar(foo);" | 4773 " bar(foo);" |
| 4697 " bar(foo);" | 4774 " bar(foo);" |
| 4698 " bar(foo);" | 4775 " bar(foo);" |
| 4699 " %OptimizeFunctionOnNextCall(bar);" | 4776 " %OptimizeFunctionOnNextCall(bar);" |
| 4700 " bar(foo);" | 4777 " bar(foo);" |
| 4701 " return bar;})();"); | 4778 " return bar;})();"); |
| 4702 | 4779 |
| 4703 Handle<JSFunction> bar = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4780 Handle<JSFunction> bar = Handle<JSFunction>::cast(v8::Utils::OpenHandle( |
| 4704 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("bar"))))); | 4781 *v8::Local<v8::Function>::Cast(CcTest::global() |
| 4782 ->Get(context.local(), v8_str("bar")) |
| 4783 .ToLocalChecked()))); |
| 4705 code = scope.CloseAndEscape(Handle<Code>(bar->code())); | 4784 code = scope.CloseAndEscape(Handle<Code>(bar->code())); |
| 4706 } | 4785 } |
| 4707 | 4786 |
| 4708 // Now make sure that a gc should get rid of the function | 4787 // Now make sure that a gc should get rid of the function |
| 4709 for (int i = 0; i < 4; i++) { | 4788 for (int i = 0; i < 4; i++) { |
| 4710 heap->CollectAllGarbage(); | 4789 heap->CollectAllGarbage(); |
| 4711 } | 4790 } |
| 4712 | 4791 |
| 4713 DCHECK(code->marked_for_deoptimization()); | 4792 DCHECK(code->marked_for_deoptimization()); |
| 4714 } | 4793 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4733 " return foo(1);" | 4812 " return foo(1);" |
| 4734 "};" | 4813 "};" |
| 4735 "function foo(x) { with (x) { return 1 + x; } };" | 4814 "function foo(x) { with (x) { return 1 + x; } };" |
| 4736 "bar();" | 4815 "bar();" |
| 4737 "bar();" | 4816 "bar();" |
| 4738 "bar();" | 4817 "bar();" |
| 4739 "%OptimizeFunctionOnNextCall(bar);" | 4818 "%OptimizeFunctionOnNextCall(bar);" |
| 4740 "bar();"); | 4819 "bar();"); |
| 4741 | 4820 |
| 4742 Handle<JSFunction> bar = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4821 Handle<JSFunction> bar = Handle<JSFunction>::cast(v8::Utils::OpenHandle( |
| 4743 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("bar"))))); | 4822 *v8::Local<v8::Function>::Cast(CcTest::global() |
| 4823 ->Get(context.local(), v8_str("bar")) |
| 4824 .ToLocalChecked()))); |
| 4744 code = scope.CloseAndEscape(Handle<Code>(bar->code())); | 4825 code = scope.CloseAndEscape(Handle<Code>(bar->code())); |
| 4745 } | 4826 } |
| 4746 | 4827 |
| 4747 // Now make sure that a gc should get rid of the function | 4828 // Now make sure that a gc should get rid of the function |
| 4748 for (int i = 0; i < 4; i++) { | 4829 for (int i = 0; i < 4; i++) { |
| 4749 heap->CollectAllGarbage(); | 4830 heap->CollectAllGarbage(); |
| 4750 } | 4831 } |
| 4751 | 4832 |
| 4752 DCHECK(code->marked_for_deoptimization()); | 4833 DCHECK(code->marked_for_deoptimization()); |
| 4753 } | 4834 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4797 } | 4878 } |
| 4798 int elements = 0; | 4879 int elements = 0; |
| 4799 if (heap->weak_object_to_code_table()->IsHashTable()) { | 4880 if (heap->weak_object_to_code_table()->IsHashTable()) { |
| 4800 WeakHashTable* t = WeakHashTable::cast(heap->weak_object_to_code_table()); | 4881 WeakHashTable* t = WeakHashTable::cast(heap->weak_object_to_code_table()); |
| 4801 elements = t->NumberOfElements(); | 4882 elements = t->NumberOfElements(); |
| 4802 } | 4883 } |
| 4803 CHECK_EQ(0, elements); | 4884 CHECK_EQ(0, elements); |
| 4804 } | 4885 } |
| 4805 | 4886 |
| 4806 | 4887 |
| 4807 static Handle<JSFunction> OptimizeDummyFunction(const char* name) { | 4888 static Handle<JSFunction> OptimizeDummyFunction(v8::Isolate* isolate, |
| 4889 const char* name) { |
| 4808 EmbeddedVector<char, 256> source; | 4890 EmbeddedVector<char, 256> source; |
| 4809 SNPrintF(source, | 4891 SNPrintF(source, |
| 4810 "function %s() { return 0; }" | 4892 "function %s() { return 0; }" |
| 4811 "%s(); %s();" | 4893 "%s(); %s();" |
| 4812 "%%OptimizeFunctionOnNextCall(%s);" | 4894 "%%OptimizeFunctionOnNextCall(%s);" |
| 4813 "%s();", name, name, name, name, name); | 4895 "%s();", name, name, name, name, name); |
| 4814 CompileRun(source.start()); | 4896 CompileRun(source.start()); |
| 4815 Handle<JSFunction> fun = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4897 i::Handle<JSFunction> fun = Handle<JSFunction>::cast( |
| 4816 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str(name))))); | 4898 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4899 CcTest::global() |
| 4900 ->Get(isolate->GetCurrentContext(), v8_str(name)) |
| 4901 .ToLocalChecked()))); |
| 4817 return fun; | 4902 return fun; |
| 4818 } | 4903 } |
| 4819 | 4904 |
| 4820 | 4905 |
| 4821 static int GetCodeChainLength(Code* code) { | 4906 static int GetCodeChainLength(Code* code) { |
| 4822 int result = 0; | 4907 int result = 0; |
| 4823 while (code->next_code_link()->IsCode()) { | 4908 while (code->next_code_link()->IsCode()) { |
| 4824 result++; | 4909 result++; |
| 4825 code = Code::cast(code->next_code_link()); | 4910 code = Code::cast(code->next_code_link()); |
| 4826 } | 4911 } |
| 4827 return result; | 4912 return result; |
| 4828 } | 4913 } |
| 4829 | 4914 |
| 4830 | 4915 |
| 4831 TEST(NextCodeLinkIsWeak) { | 4916 TEST(NextCodeLinkIsWeak) { |
| 4832 i::FLAG_always_opt = false; | 4917 i::FLAG_always_opt = false; |
| 4833 i::FLAG_allow_natives_syntax = true; | 4918 i::FLAG_allow_natives_syntax = true; |
| 4834 CcTest::InitializeVM(); | 4919 CcTest::InitializeVM(); |
| 4835 Isolate* isolate = CcTest::i_isolate(); | 4920 Isolate* isolate = CcTest::i_isolate(); |
| 4836 v8::internal::Heap* heap = CcTest::heap(); | 4921 v8::internal::Heap* heap = CcTest::heap(); |
| 4837 | 4922 |
| 4838 if (!isolate->use_crankshaft()) return; | 4923 if (!isolate->use_crankshaft()) return; |
| 4839 HandleScope outer_scope(heap->isolate()); | 4924 HandleScope outer_scope(heap->isolate()); |
| 4840 Handle<Code> code; | 4925 Handle<Code> code; |
| 4841 heap->CollectAllAvailableGarbage(); | 4926 heap->CollectAllAvailableGarbage(); |
| 4842 int code_chain_length_before, code_chain_length_after; | 4927 int code_chain_length_before, code_chain_length_after; |
| 4843 { | 4928 { |
| 4844 HandleScope scope(heap->isolate()); | 4929 HandleScope scope(heap->isolate()); |
| 4845 Handle<JSFunction> mortal = OptimizeDummyFunction("mortal"); | 4930 Handle<JSFunction> mortal = |
| 4846 Handle<JSFunction> immortal = OptimizeDummyFunction("immortal"); | 4931 OptimizeDummyFunction(CcTest::isolate(), "mortal"); |
| 4932 Handle<JSFunction> immortal = |
| 4933 OptimizeDummyFunction(CcTest::isolate(), "immortal"); |
| 4847 CHECK_EQ(immortal->code()->next_code_link(), mortal->code()); | 4934 CHECK_EQ(immortal->code()->next_code_link(), mortal->code()); |
| 4848 code_chain_length_before = GetCodeChainLength(immortal->code()); | 4935 code_chain_length_before = GetCodeChainLength(immortal->code()); |
| 4849 // Keep the immortal code and let the mortal code die. | 4936 // Keep the immortal code and let the mortal code die. |
| 4850 code = scope.CloseAndEscape(Handle<Code>(immortal->code())); | 4937 code = scope.CloseAndEscape(Handle<Code>(immortal->code())); |
| 4851 CompileRun("mortal = null; immortal = null;"); | 4938 CompileRun("mortal = null; immortal = null;"); |
| 4852 } | 4939 } |
| 4853 heap->CollectAllAvailableGarbage(); | 4940 heap->CollectAllAvailableGarbage(); |
| 4854 // Now mortal code should be dead. | 4941 // Now mortal code should be dead. |
| 4855 code_chain_length_after = GetCodeChainLength(*code); | 4942 code_chain_length_after = GetCodeChainLength(*code); |
| 4856 CHECK_EQ(code_chain_length_before - 1, code_chain_length_after); | 4943 CHECK_EQ(code_chain_length_before - 1, code_chain_length_after); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4907 weak_ic_cleared = true; | 4994 weak_ic_cleared = true; |
| 4908 data.GetParameter()->Reset(); | 4995 data.GetParameter()->Reset(); |
| 4909 } | 4996 } |
| 4910 | 4997 |
| 4911 | 4998 |
| 4912 TEST(WeakFunctionInConstructor) { | 4999 TEST(WeakFunctionInConstructor) { |
| 4913 if (i::FLAG_always_opt) return; | 5000 if (i::FLAG_always_opt) return; |
| 4914 i::FLAG_stress_compaction = false; | 5001 i::FLAG_stress_compaction = false; |
| 4915 CcTest::InitializeVM(); | 5002 CcTest::InitializeVM(); |
| 4916 v8::Isolate* isolate = CcTest::isolate(); | 5003 v8::Isolate* isolate = CcTest::isolate(); |
| 5004 LocalContext env; |
| 4917 v8::HandleScope scope(isolate); | 5005 v8::HandleScope scope(isolate); |
| 4918 CompileRun( | 5006 CompileRun( |
| 4919 "function createObj(obj) {" | 5007 "function createObj(obj) {" |
| 4920 " return new obj();" | 5008 " return new obj();" |
| 4921 "}"); | 5009 "}"); |
| 4922 Handle<JSFunction> createObj = Handle<JSFunction>::cast( | 5010 i::Handle<JSFunction> createObj = Handle<JSFunction>::cast( |
| 4923 v8::Utils::OpenHandle(*v8::Handle<v8::Function>::Cast( | 5011 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4924 CcTest::global()->Get(v8_str("createObj"))))); | 5012 CcTest::global() |
| 5013 ->Get(env.local(), v8_str("createObj")) |
| 5014 .ToLocalChecked()))); |
| 4925 | 5015 |
| 4926 v8::Persistent<v8::Object> garbage; | 5016 v8::Persistent<v8::Object> garbage; |
| 4927 { | 5017 { |
| 4928 v8::HandleScope scope(isolate); | 5018 v8::HandleScope scope(isolate); |
| 4929 const char* source = | 5019 const char* source = |
| 4930 " (function() {" | 5020 " (function() {" |
| 4931 " function hat() { this.x = 5; }" | 5021 " function hat() { this.x = 5; }" |
| 4932 " createObj(hat);" | 5022 " createObj(hat);" |
| 4933 " createObj(hat);" | 5023 " createObj(hat);" |
| 4934 " return hat;" | 5024 " return hat;" |
| 4935 " })();"; | 5025 " })();"; |
| 4936 garbage.Reset(isolate, CompileRun(source)->ToObject(isolate)); | 5026 garbage.Reset(isolate, CompileRun(env.local(), source) |
| 5027 .ToLocalChecked() |
| 5028 ->ToObject(env.local()) |
| 5029 .ToLocalChecked()); |
| 4937 } | 5030 } |
| 4938 weak_ic_cleared = false; | 5031 weak_ic_cleared = false; |
| 4939 garbage.SetWeak(&garbage, &ClearWeakIC, v8::WeakCallbackType::kParameter); | 5032 garbage.SetWeak(&garbage, &ClearWeakIC, v8::WeakCallbackType::kParameter); |
| 4940 Heap* heap = CcTest::i_isolate()->heap(); | 5033 Heap* heap = CcTest::i_isolate()->heap(); |
| 4941 heap->CollectAllGarbage(); | 5034 heap->CollectAllGarbage(); |
| 4942 CHECK(weak_ic_cleared); | 5035 CHECK(weak_ic_cleared); |
| 4943 | 5036 |
| 4944 // We've determined the constructor in createObj has had it's weak cell | 5037 // We've determined the constructor in createObj has had it's weak cell |
| 4945 // cleared. Now, verify that one additional call with a new function | 5038 // cleared. Now, verify that one additional call with a new function |
| 4946 // allows monomorphicity. | 5039 // allows monomorphicity. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4961 slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); | 5054 slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); |
| 4962 CHECK(slot_value->IsWeakCell() && !WeakCell::cast(slot_value)->cleared()); | 5055 CHECK(slot_value->IsWeakCell() && !WeakCell::cast(slot_value)->cleared()); |
| 4963 } | 5056 } |
| 4964 | 5057 |
| 4965 | 5058 |
| 4966 // Checks that the value returned by execution of the source is weak. | 5059 // Checks that the value returned by execution of the source is weak. |
| 4967 void CheckWeakness(const char* source) { | 5060 void CheckWeakness(const char* source) { |
| 4968 i::FLAG_stress_compaction = false; | 5061 i::FLAG_stress_compaction = false; |
| 4969 CcTest::InitializeVM(); | 5062 CcTest::InitializeVM(); |
| 4970 v8::Isolate* isolate = CcTest::isolate(); | 5063 v8::Isolate* isolate = CcTest::isolate(); |
| 5064 LocalContext env; |
| 4971 v8::HandleScope scope(isolate); | 5065 v8::HandleScope scope(isolate); |
| 4972 v8::Persistent<v8::Object> garbage; | 5066 v8::Persistent<v8::Object> garbage; |
| 4973 { | 5067 { |
| 4974 v8::HandleScope scope(isolate); | 5068 v8::HandleScope scope(isolate); |
| 4975 garbage.Reset(isolate, CompileRun(source)->ToObject(isolate)); | 5069 garbage.Reset(isolate, CompileRun(env.local(), source) |
| 5070 .ToLocalChecked() |
| 5071 ->ToObject(env.local()) |
| 5072 .ToLocalChecked()); |
| 4976 } | 5073 } |
| 4977 weak_ic_cleared = false; | 5074 weak_ic_cleared = false; |
| 4978 garbage.SetWeak(&garbage, &ClearWeakIC, v8::WeakCallbackType::kParameter); | 5075 garbage.SetWeak(&garbage, &ClearWeakIC, v8::WeakCallbackType::kParameter); |
| 4979 Heap* heap = CcTest::i_isolate()->heap(); | 5076 Heap* heap = CcTest::i_isolate()->heap(); |
| 4980 heap->CollectAllGarbage(); | 5077 heap->CollectAllGarbage(); |
| 4981 CHECK(weak_ic_cleared); | 5078 CHECK(weak_ic_cleared); |
| 4982 } | 5079 } |
| 4983 | 5080 |
| 4984 | 5081 |
| 4985 // Each of the following "weak IC" tests creates an IC that embeds a map with | 5082 // Each of the following "weak IC" tests creates an IC that embeds a map with |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5308 TEST(AddInstructionChangesNewSpacePromotion) { | 5405 TEST(AddInstructionChangesNewSpacePromotion) { |
| 5309 i::FLAG_allow_natives_syntax = true; | 5406 i::FLAG_allow_natives_syntax = true; |
| 5310 i::FLAG_expose_gc = true; | 5407 i::FLAG_expose_gc = true; |
| 5311 i::FLAG_stress_compaction = true; | 5408 i::FLAG_stress_compaction = true; |
| 5312 i::FLAG_gc_interval = 1000; | 5409 i::FLAG_gc_interval = 1000; |
| 5313 CcTest::InitializeVM(); | 5410 CcTest::InitializeVM(); |
| 5314 if (!i::FLAG_allocation_site_pretenuring) return; | 5411 if (!i::FLAG_allocation_site_pretenuring) return; |
| 5315 v8::HandleScope scope(CcTest::isolate()); | 5412 v8::HandleScope scope(CcTest::isolate()); |
| 5316 Isolate* isolate = CcTest::i_isolate(); | 5413 Isolate* isolate = CcTest::i_isolate(); |
| 5317 Heap* heap = isolate->heap(); | 5414 Heap* heap = isolate->heap(); |
| 5318 | 5415 LocalContext env; |
| 5319 CompileRun( | 5416 CompileRun( |
| 5320 "function add(a, b) {" | 5417 "function add(a, b) {" |
| 5321 " return a + b;" | 5418 " return a + b;" |
| 5322 "}" | 5419 "}" |
| 5323 "add(1, 2);" | 5420 "add(1, 2);" |
| 5324 "add(\"a\", \"b\");" | 5421 "add(\"a\", \"b\");" |
| 5325 "var oldSpaceObject;" | 5422 "var oldSpaceObject;" |
| 5326 "gc();" | 5423 "gc();" |
| 5327 "function crash(x) {" | 5424 "function crash(x) {" |
| 5328 " var object = {a: null, b: null};" | 5425 " var object = {a: null, b: null};" |
| 5329 " var result = add(1.5, x | 0);" | 5426 " var result = add(1.5, x | 0);" |
| 5330 " object.a = result;" | 5427 " object.a = result;" |
| 5331 " oldSpaceObject = object;" | 5428 " oldSpaceObject = object;" |
| 5332 " return object;" | 5429 " return object;" |
| 5333 "}" | 5430 "}" |
| 5334 "crash(1);" | 5431 "crash(1);" |
| 5335 "crash(1);" | 5432 "crash(1);" |
| 5336 "%OptimizeFunctionOnNextCall(crash);" | 5433 "%OptimizeFunctionOnNextCall(crash);" |
| 5337 "crash(1);"); | 5434 "crash(1);"); |
| 5338 | 5435 |
| 5339 v8::Handle<v8::Object> global = CcTest::global(); | 5436 v8::Local<v8::Object> global = CcTest::global(); |
| 5340 v8::Handle<v8::Function> g = | 5437 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( |
| 5341 v8::Handle<v8::Function>::Cast(global->Get(v8_str("crash"))); | 5438 global->Get(env.local(), v8_str("crash")).ToLocalChecked()); |
| 5342 v8::Handle<v8::Value> args1[] = { v8_num(1) }; | 5439 v8::Local<v8::Value> args1[] = {v8_num(1)}; |
| 5343 heap->DisableInlineAllocation(); | 5440 heap->DisableInlineAllocation(); |
| 5344 heap->set_allocation_timeout(1); | 5441 heap->set_allocation_timeout(1); |
| 5345 g->Call(global, 1, args1); | 5442 g->Call(env.local(), global, 1, args1).ToLocalChecked(); |
| 5346 heap->CollectAllGarbage(); | 5443 heap->CollectAllGarbage(); |
| 5347 } | 5444 } |
| 5348 | 5445 |
| 5349 | 5446 |
| 5350 void OnFatalErrorExpectOOM(const char* location, const char* message) { | 5447 void OnFatalErrorExpectOOM(const char* location, const char* message) { |
| 5351 // Exit with 0 if the location matches our expectation. | 5448 // Exit with 0 if the location matches our expectation. |
| 5352 exit(strcmp(location, "CALL_AND_RETRY_LAST")); | 5449 exit(strcmp(location, "CALL_AND_RETRY_LAST")); |
| 5353 } | 5450 } |
| 5354 | 5451 |
| 5355 | 5452 |
| 5356 TEST(CEntryStubOOM) { | 5453 TEST(CEntryStubOOM) { |
| 5357 i::FLAG_allow_natives_syntax = true; | 5454 i::FLAG_allow_natives_syntax = true; |
| 5358 CcTest::InitializeVM(); | 5455 CcTest::InitializeVM(); |
| 5359 v8::HandleScope scope(CcTest::isolate()); | 5456 v8::HandleScope scope(CcTest::isolate()); |
| 5360 v8::V8::SetFatalErrorHandler(OnFatalErrorExpectOOM); | 5457 CcTest::isolate()->SetFatalErrorHandler(OnFatalErrorExpectOOM); |
| 5361 | 5458 |
| 5362 v8::Handle<v8::Value> result = CompileRun( | 5459 v8::Local<v8::Value> result = CompileRun( |
| 5363 "%SetFlags('--gc-interval=1');" | 5460 "%SetFlags('--gc-interval=1');" |
| 5364 "var a = [];" | 5461 "var a = [];" |
| 5365 "a.__proto__ = [];" | 5462 "a.__proto__ = [];" |
| 5366 "a.unshift(1)"); | 5463 "a.unshift(1)"); |
| 5367 | 5464 |
| 5368 CHECK(result->IsNumber()); | 5465 CHECK(result->IsNumber()); |
| 5369 } | 5466 } |
| 5370 | 5467 |
| 5371 #endif // DEBUG | 5468 #endif // DEBUG |
| 5372 | 5469 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5408 } | 5505 } |
| 5409 isolate->Exit(); | 5506 isolate->Exit(); |
| 5410 isolate->Dispose(); | 5507 isolate->Dispose(); |
| 5411 } | 5508 } |
| 5412 | 5509 |
| 5413 | 5510 |
| 5414 TEST(Regress357137) { | 5511 TEST(Regress357137) { |
| 5415 CcTest::InitializeVM(); | 5512 CcTest::InitializeVM(); |
| 5416 v8::Isolate* isolate = CcTest::isolate(); | 5513 v8::Isolate* isolate = CcTest::isolate(); |
| 5417 v8::HandleScope hscope(isolate); | 5514 v8::HandleScope hscope(isolate); |
| 5418 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); | 5515 v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); |
| 5419 global->Set(v8::String::NewFromUtf8(isolate, "interrupt"), | 5516 global->Set( |
| 5420 v8::FunctionTemplate::New(isolate, RequestInterrupt)); | 5517 v8::String::NewFromUtf8(isolate, "interrupt", v8::NewStringType::kNormal) |
| 5518 .ToLocalChecked(), |
| 5519 v8::FunctionTemplate::New(isolate, RequestInterrupt)); |
| 5421 v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global); | 5520 v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global); |
| 5422 DCHECK(!context.IsEmpty()); | 5521 DCHECK(!context.IsEmpty()); |
| 5423 v8::Context::Scope cscope(context); | 5522 v8::Context::Scope cscope(context); |
| 5424 | 5523 |
| 5425 v8::Local<v8::Value> result = CompileRun( | 5524 v8::Local<v8::Value> result = CompileRun( |
| 5426 "var locals = '';" | 5525 "var locals = '';" |
| 5427 "for (var i = 0; i < 512; i++) locals += 'var v' + i + '= 42;';" | 5526 "for (var i = 0; i < 512; i++) locals += 'var v' + i + '= 42;';" |
| 5428 "eval('function f() {' + locals + 'return function() { return v0; }; }');" | 5527 "eval('function f() {' + locals + 'return function() { return v0; }; }');" |
| 5429 "interrupt();" // This triggers a fake stack overflow in f. | 5528 "interrupt();" // This triggers a fake stack overflow in f. |
| 5430 "f()()"); | 5529 "f()()"); |
| 5431 CHECK_EQ(42.0, result->ToNumber(isolate)->Value()); | 5530 CHECK_EQ(42.0, result->ToNumber(context).ToLocalChecked()->Value()); |
| 5432 } | 5531 } |
| 5433 | 5532 |
| 5434 | 5533 |
| 5435 TEST(Regress507979) { | 5534 TEST(Regress507979) { |
| 5436 const int kFixedArrayLen = 10; | 5535 const int kFixedArrayLen = 10; |
| 5437 CcTest::InitializeVM(); | 5536 CcTest::InitializeVM(); |
| 5438 Isolate* isolate = CcTest::i_isolate(); | 5537 Isolate* isolate = CcTest::i_isolate(); |
| 5439 Heap* heap = isolate->heap(); | 5538 Heap* heap = isolate->heap(); |
| 5440 HandleScope handle_scope(isolate); | 5539 HandleScope handle_scope(isolate); |
| 5441 | 5540 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 5467 v8::Local<v8::Value> result = CompileRun( | 5566 v8::Local<v8::Value> result = CompileRun( |
| 5468 "var array = new Array(400);" | 5567 "var array = new Array(400);" |
| 5469 "var tmp = new Array(1000);" | 5568 "var tmp = new Array(1000);" |
| 5470 "array[0] = 10;" | 5569 "array[0] = 10;" |
| 5471 "gc();" | 5570 "gc();" |
| 5472 "gc();" | 5571 "gc();" |
| 5473 "array.shift();" | 5572 "array.shift();" |
| 5474 "array;"); | 5573 "array;"); |
| 5475 | 5574 |
| 5476 Handle<JSObject> o = | 5575 Handle<JSObject> o = |
| 5477 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result)); | 5576 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(result)); |
| 5478 CHECK(heap->InOldSpace(o->elements())); | 5577 CHECK(heap->InOldSpace(o->elements())); |
| 5479 CHECK(heap->InOldSpace(*o)); | 5578 CHECK(heap->InOldSpace(*o)); |
| 5480 Page* page = Page::FromAddress(o->elements()->address()); | 5579 Page* page = Page::FromAddress(o->elements()->address()); |
| 5481 CHECK(page->parallel_sweeping_state().Value() <= | 5580 CHECK(page->parallel_sweeping_state().Value() <= |
| 5482 MemoryChunk::kSweepingFinalize || | 5581 MemoryChunk::kSweepingFinalize || |
| 5483 Marking::IsBlack(Marking::MarkBitFrom(o->elements()))); | 5582 Marking::IsBlack(Marking::MarkBitFrom(o->elements()))); |
| 5484 } | 5583 } |
| 5485 | 5584 |
| 5486 | 5585 |
| 5487 UNINITIALIZED_TEST(PromotionQueue) { | 5586 UNINITIALIZED_TEST(PromotionQueue) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5616 " var key = {'k' : i + 0.1};" | 5715 " var key = {'k' : i + 0.1};" |
| 5617 " weak_map.set(key, 1);" | 5716 " weak_map.set(key, 1);" |
| 5618 " future_keys.push({'x' : i + 0.2});" | 5717 " future_keys.push({'x' : i + 0.2});" |
| 5619 "}" | 5718 "}" |
| 5620 "weak_map"); | 5719 "weak_map"); |
| 5621 if (marking->IsStopped()) { | 5720 if (marking->IsStopped()) { |
| 5622 CcTest::heap()->StartIncrementalMarking(); | 5721 CcTest::heap()->StartIncrementalMarking(); |
| 5623 } | 5722 } |
| 5624 // Incrementally mark the backing store. | 5723 // Incrementally mark the backing store. |
| 5625 Handle<JSObject> obj = | 5724 Handle<JSObject> obj = |
| 5626 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result)); | 5725 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(result)); |
| 5627 Handle<JSWeakCollection> weak_map(reinterpret_cast<JSWeakCollection*>(*obj)); | 5726 Handle<JSWeakCollection> weak_map(reinterpret_cast<JSWeakCollection*>(*obj)); |
| 5628 while (!Marking::IsBlack( | 5727 while (!Marking::IsBlack( |
| 5629 Marking::MarkBitFrom(HeapObject::cast(weak_map->table()))) && | 5728 Marking::MarkBitFrom(HeapObject::cast(weak_map->table()))) && |
| 5630 !marking->IsStopped()) { | 5729 !marking->IsStopped()) { |
| 5631 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); | 5730 marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 5632 } | 5731 } |
| 5633 // Stash the backing store in a handle. | 5732 // Stash the backing store in a handle. |
| 5634 Handle<Object> save(weak_map->table(), isolate); | 5733 Handle<Object> save(weak_map->table(), isolate); |
| 5635 // The following line will update the backing store. | 5734 // The following line will update the backing store. |
| 5636 CompileRun( | 5735 CompileRun( |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5676 Isolate* isolate = CcTest::i_isolate(); | 5775 Isolate* isolate = CcTest::i_isolate(); |
| 5677 Heap* heap = isolate->heap(); | 5776 Heap* heap = isolate->heap(); |
| 5678 Factory* factory = isolate->factory(); | 5777 Factory* factory = isolate->factory(); |
| 5679 HandleScope scope(isolate); | 5778 HandleScope scope(isolate); |
| 5680 CompileRun("function cls() { this.x = 10; }"); | 5779 CompileRun("function cls() { this.x = 10; }"); |
| 5681 Handle<WeakCell> weak_prototype; | 5780 Handle<WeakCell> weak_prototype; |
| 5682 { | 5781 { |
| 5683 HandleScope inner_scope(isolate); | 5782 HandleScope inner_scope(isolate); |
| 5684 v8::Local<v8::Value> result = CompileRun("cls.prototype"); | 5783 v8::Local<v8::Value> result = CompileRun("cls.prototype"); |
| 5685 Handle<JSObject> proto = | 5784 Handle<JSObject> proto = |
| 5686 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result)); | 5785 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(result)); |
| 5687 weak_prototype = inner_scope.CloseAndEscape(factory->NewWeakCell(proto)); | 5786 weak_prototype = inner_scope.CloseAndEscape(factory->NewWeakCell(proto)); |
| 5688 } | 5787 } |
| 5689 CHECK(!weak_prototype->cleared()); | 5788 CHECK(!weak_prototype->cleared()); |
| 5690 CompileRun( | 5789 CompileRun( |
| 5691 "var a = { };" | 5790 "var a = { };" |
| 5692 "a.x = new cls();" | 5791 "a.x = new cls();" |
| 5693 "cls.prototype = null;"); | 5792 "cls.prototype = null;"); |
| 5694 for (int i = 0; i < 4; i++) { | 5793 for (int i = 0; i < 4; i++) { |
| 5695 heap->CollectAllGarbage(); | 5794 heap->CollectAllGarbage(); |
| 5696 } | 5795 } |
| 5697 // The map of a.x keeps prototype alive | 5796 // The map of a.x keeps prototype alive |
| 5698 CHECK(!weak_prototype->cleared()); | 5797 CHECK(!weak_prototype->cleared()); |
| 5699 // Change the map of a.x and make the previous map garbage collectable. | 5798 // Change the map of a.x and make the previous map garbage collectable. |
| 5700 CompileRun("a.x.__proto__ = {};"); | 5799 CompileRun("a.x.__proto__ = {};"); |
| 5701 for (int i = 0; i < 4; i++) { | 5800 for (int i = 0; i < 4; i++) { |
| 5702 heap->CollectAllGarbage(); | 5801 heap->CollectAllGarbage(); |
| 5703 } | 5802 } |
| 5704 CHECK(weak_prototype->cleared()); | 5803 CHECK(weak_prototype->cleared()); |
| 5705 } | 5804 } |
| 5706 | 5805 |
| 5707 | 5806 |
| 5708 Handle<WeakCell> AddRetainedMap(Isolate* isolate, Heap* heap) { | 5807 Handle<WeakCell> AddRetainedMap(Isolate* isolate, Heap* heap) { |
| 5709 HandleScope inner_scope(isolate); | 5808 HandleScope inner_scope(isolate); |
| 5710 Handle<Map> map = Map::Create(isolate, 1); | 5809 Handle<Map> map = Map::Create(isolate, 1); |
| 5711 v8::Local<v8::Value> result = | 5810 v8::Local<v8::Value> result = |
| 5712 CompileRun("(function () { return {x : 10}; })();"); | 5811 CompileRun("(function () { return {x : 10}; })();"); |
| 5713 Handle<JSObject> proto = | 5812 Handle<JSObject> proto = |
| 5714 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result)); | 5813 v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(result)); |
| 5715 Map::SetPrototype(map, proto); | 5814 Map::SetPrototype(map, proto); |
| 5716 heap->AddRetainedMap(map); | 5815 heap->AddRetainedMap(map); |
| 5717 return inner_scope.CloseAndEscape(Map::WeakCellForMap(map)); | 5816 return inner_scope.CloseAndEscape(Map::WeakCellForMap(map)); |
| 5718 } | 5817 } |
| 5719 | 5818 |
| 5720 | 5819 |
| 5721 void CheckMapRetainingFor(int n) { | 5820 void CheckMapRetainingFor(int n) { |
| 5722 FLAG_retain_maps_for_n_gc = n; | 5821 FLAG_retain_maps_for_n_gc = n; |
| 5723 Isolate* isolate = CcTest::i_isolate(); | 5822 Isolate* isolate = CcTest::i_isolate(); |
| 5724 Heap* heap = isolate->heap(); | 5823 Heap* heap = isolate->heap(); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5892 data.GetParameter()->Reset(); | 5991 data.GetParameter()->Reset(); |
| 5893 } | 5992 } |
| 5894 | 5993 |
| 5895 | 5994 |
| 5896 TEST(BootstrappingExports) { | 5995 TEST(BootstrappingExports) { |
| 5897 // Expose utils object and delete it to observe that it is indeed | 5996 // Expose utils object and delete it to observe that it is indeed |
| 5898 // being garbage-collected. | 5997 // being garbage-collected. |
| 5899 FLAG_expose_natives_as = "utils"; | 5998 FLAG_expose_natives_as = "utils"; |
| 5900 CcTest::InitializeVM(); | 5999 CcTest::InitializeVM(); |
| 5901 v8::Isolate* isolate = CcTest::isolate(); | 6000 v8::Isolate* isolate = CcTest::isolate(); |
| 6001 LocalContext env; |
| 5902 | 6002 |
| 5903 if (Snapshot::HaveASnapshotToStartFrom(CcTest::i_isolate())) return; | 6003 if (Snapshot::HaveASnapshotToStartFrom(CcTest::i_isolate())) return; |
| 5904 | 6004 |
| 5905 utils_has_been_collected = false; | 6005 utils_has_been_collected = false; |
| 5906 | 6006 |
| 5907 v8::Persistent<v8::Object> utils; | 6007 v8::Persistent<v8::Object> utils; |
| 5908 | 6008 |
| 5909 { | 6009 { |
| 5910 v8::HandleScope scope(isolate); | 6010 v8::HandleScope scope(isolate); |
| 5911 v8::Local<v8::String> name = v8_str("utils"); | 6011 v8::Local<v8::String> name = v8_str("utils"); |
| 5912 utils.Reset(isolate, CcTest::global()->Get(name)->ToObject(isolate)); | 6012 utils.Reset(isolate, CcTest::global() |
| 5913 CcTest::global()->Delete(name); | 6013 ->Get(env.local(), name) |
| 6014 .ToLocalChecked() |
| 6015 ->ToObject(env.local()) |
| 6016 .ToLocalChecked()); |
| 6017 CHECK(CcTest::global()->Delete(env.local(), name).FromJust()); |
| 5914 } | 6018 } |
| 5915 | 6019 |
| 5916 utils.SetWeak(&utils, UtilsHasBeenCollected, | 6020 utils.SetWeak(&utils, UtilsHasBeenCollected, |
| 5917 v8::WeakCallbackType::kParameter); | 6021 v8::WeakCallbackType::kParameter); |
| 5918 | 6022 |
| 5919 CcTest::heap()->CollectAllAvailableGarbage("fire weak callbacks"); | 6023 CcTest::heap()->CollectAllAvailableGarbage("fire weak callbacks"); |
| 5920 | 6024 |
| 5921 CHECK(utils_has_been_collected); | 6025 CHECK(utils_has_been_collected); |
| 5922 } | 6026 } |
| 5923 | 6027 |
| 5924 | 6028 |
| 5925 TEST(Regress1878) { | 6029 TEST(Regress1878) { |
| 5926 FLAG_allow_natives_syntax = true; | 6030 FLAG_allow_natives_syntax = true; |
| 5927 CcTest::InitializeVM(); | 6031 CcTest::InitializeVM(); |
| 5928 v8::Isolate* isolate = CcTest::isolate(); | 6032 v8::Isolate* isolate = CcTest::isolate(); |
| 5929 v8::HandleScope scope(isolate); | 6033 v8::HandleScope scope(isolate); |
| 5930 v8::Local<v8::Function> constructor = v8::Utils::CallableToLocal( | 6034 v8::Local<v8::Function> constructor = v8::Utils::CallableToLocal( |
| 5931 CcTest::i_isolate()->internal_array_function()); | 6035 CcTest::i_isolate()->internal_array_function()); |
| 5932 CcTest::global()->Set(v8_str("InternalArray"), constructor); | 6036 LocalContext env; |
| 6037 CHECK(CcTest::global() |
| 6038 ->Set(env.local(), v8_str("InternalArray"), constructor) |
| 6039 .FromJust()); |
| 5933 | 6040 |
| 5934 v8::TryCatch try_catch(isolate); | 6041 v8::TryCatch try_catch(isolate); |
| 5935 | 6042 |
| 5936 CompileRun( | 6043 CompileRun( |
| 5937 "var a = Array();" | 6044 "var a = Array();" |
| 5938 "for (var i = 0; i < 1000; i++) {" | 6045 "for (var i = 0; i < 1000; i++) {" |
| 5939 " var ai = new InternalArray(10000);" | 6046 " var ai = new InternalArray(10000);" |
| 5940 " if (%HaveSameMap(ai, a)) throw Error();" | 6047 " if (%HaveSameMap(ai, a)) throw Error();" |
| 5941 " if (!%HasFastObjectElements(ai)) throw Error();" | 6048 " if (!%HasFastObjectElements(ai)) throw Error();" |
| 5942 "}" | 6049 "}" |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6076 Object* message = | 6183 Object* message = |
| 6077 *reinterpret_cast<Object**>(isolate->pending_message_obj_address()); | 6184 *reinterpret_cast<Object**>(isolate->pending_message_obj_address()); |
| 6078 CHECK(message->IsTheHole()); | 6185 CHECK(message->IsTheHole()); |
| 6079 } | 6186 } |
| 6080 | 6187 |
| 6081 | 6188 |
| 6082 TEST(MessageObjectLeak) { | 6189 TEST(MessageObjectLeak) { |
| 6083 CcTest::InitializeVM(); | 6190 CcTest::InitializeVM(); |
| 6084 v8::Isolate* isolate = CcTest::isolate(); | 6191 v8::Isolate* isolate = CcTest::isolate(); |
| 6085 v8::HandleScope scope(isolate); | 6192 v8::HandleScope scope(isolate); |
| 6086 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); | 6193 v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); |
| 6087 global->Set(v8::String::NewFromUtf8(isolate, "check"), | 6194 global->Set( |
| 6088 v8::FunctionTemplate::New(isolate, CheckLeak)); | 6195 v8::String::NewFromUtf8(isolate, "check", v8::NewStringType::kNormal) |
| 6196 .ToLocalChecked(), |
| 6197 v8::FunctionTemplate::New(isolate, CheckLeak)); |
| 6089 v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global); | 6198 v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global); |
| 6090 v8::Context::Scope cscope(context); | 6199 v8::Context::Scope cscope(context); |
| 6091 | 6200 |
| 6092 const char* test = | 6201 const char* test = |
| 6093 "try {" | 6202 "try {" |
| 6094 " throw 'message 1';" | 6203 " throw 'message 1';" |
| 6095 "} catch (e) {" | 6204 "} catch (e) {" |
| 6096 "}" | 6205 "}" |
| 6097 "check();" | 6206 "check();" |
| 6098 "L: try {" | 6207 "L: try {" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 6129 fun->ReplaceCode(*isolate->builtins()->CompileLazy()); | 6238 fun->ReplaceCode(*isolate->builtins()->CompileLazy()); |
| 6130 fun->shared()->ReplaceCode(*isolate->builtins()->CompileLazy()); | 6239 fun->shared()->ReplaceCode(*isolate->builtins()->CompileLazy()); |
| 6131 isolate->heap()->CollectAllAvailableGarbage("remove code and gc"); | 6240 isolate->heap()->CollectAllAvailableGarbage("remove code and gc"); |
| 6132 } | 6241 } |
| 6133 | 6242 |
| 6134 | 6243 |
| 6135 TEST(CanonicalSharedFunctionInfo) { | 6244 TEST(CanonicalSharedFunctionInfo) { |
| 6136 CcTest::InitializeVM(); | 6245 CcTest::InitializeVM(); |
| 6137 v8::Isolate* isolate = CcTest::isolate(); | 6246 v8::Isolate* isolate = CcTest::isolate(); |
| 6138 v8::HandleScope scope(isolate); | 6247 v8::HandleScope scope(isolate); |
| 6139 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); | 6248 v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); |
| 6140 global->Set(isolate, "check", v8::FunctionTemplate::New( | 6249 global->Set(isolate, "check", v8::FunctionTemplate::New( |
| 6141 isolate, CheckEqualSharedFunctionInfos)); | 6250 isolate, CheckEqualSharedFunctionInfos)); |
| 6142 global->Set(isolate, "remove", | 6251 global->Set(isolate, "remove", |
| 6143 v8::FunctionTemplate::New(isolate, RemoveCodeAndGC)); | 6252 v8::FunctionTemplate::New(isolate, RemoveCodeAndGC)); |
| 6144 v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global); | 6253 v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global); |
| 6145 v8::Context::Scope cscope(context); | 6254 v8::Context::Scope cscope(context); |
| 6146 CompileRun( | 6255 CompileRun( |
| 6147 "function f() { return function g() {}; }" | 6256 "function f() { return function g() {}; }" |
| 6148 "var g1 = f();" | 6257 "var g1 = f();" |
| 6149 "remove(f);" | 6258 "remove(f);" |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6340 isolate->IncrementJsCallsFromApiCounter(); | 6449 isolate->IncrementJsCallsFromApiCounter(); |
| 6341 isolate->IncrementJsCallsFromApiCounter(); | 6450 isolate->IncrementJsCallsFromApiCounter(); |
| 6342 isolate->IncrementJsCallsFromApiCounter(); | 6451 isolate->IncrementJsCallsFromApiCounter(); |
| 6343 calls_per_ms = memory_reducer->SampleAndGetJsCallsPerMs(4); | 6452 calls_per_ms = memory_reducer->SampleAndGetJsCallsPerMs(4); |
| 6344 CheckDoubleEquals(2, calls_per_ms); | 6453 CheckDoubleEquals(2, calls_per_ms); |
| 6345 } | 6454 } |
| 6346 | 6455 |
| 6347 | 6456 |
| 6348 } // namespace internal | 6457 } // namespace internal |
| 6349 } // namespace v8 | 6458 } // namespace v8 |
| OLD | NEW |