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 |
(...skipping 2648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2659 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 2659 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
2660 | 2660 |
2661 // Count number of live transitions after marking. Note that one transition | 2661 // Count number of live transitions after marking. Note that one transition |
2662 // is left, because 'o' still holds an instance of one transition target. | 2662 // is left, because 'o' still holds an instance of one transition target. |
2663 int transitions_after = CountMapTransitions(root->map()); | 2663 int transitions_after = CountMapTransitions(root->map()); |
2664 CompileRun("%DebugPrint(root);"); | 2664 CompileRun("%DebugPrint(root);"); |
2665 CHECK_EQ(1, transitions_after); | 2665 CHECK_EQ(1, transitions_after); |
2666 } | 2666 } |
2667 | 2667 |
2668 | 2668 |
| 2669 static void AddTransitions(int transitions_count) { |
| 2670 AlwaysAllocateScope always_allocate(CcTest::i_isolate()); |
| 2671 for (int i = 0; i < transitions_count; i++) { |
| 2672 EmbeddedVector<char, 64> buffer; |
| 2673 OS::SNPrintF(buffer, "var o = new Object; o.prop%d = %d;", i, i); |
| 2674 CompileRun(buffer.start()); |
| 2675 } |
| 2676 } |
| 2677 |
| 2678 |
| 2679 static Handle<JSObject> GetByName(const char* name) { |
| 2680 return v8::Utils::OpenHandle( |
| 2681 *v8::Handle<v8::Object>::Cast( |
| 2682 CcTest::global()->Get(v8_str(name)))); |
| 2683 } |
| 2684 |
| 2685 |
| 2686 static void AddPropertyTo( |
| 2687 int gc_count, Handle<JSObject> object, const char* property_name) { |
| 2688 Isolate* isolate = CcTest::i_isolate(); |
| 2689 Factory* factory = isolate->factory(); |
| 2690 Handle<String> prop_name = factory->InternalizeUtf8String(property_name); |
| 2691 Handle<Smi> twenty_three(Smi::FromInt(23), isolate); |
| 2692 i::FLAG_gc_interval = gc_count; |
| 2693 i::FLAG_gc_global = true; |
| 2694 CcTest::heap()->set_allocation_timeout(gc_count); |
| 2695 JSReceiver::SetProperty( |
| 2696 object, prop_name, twenty_three, NONE, SLOPPY).Check(); |
| 2697 } |
| 2698 |
| 2699 |
| 2700 TEST(TransitionArrayShrinksDuringAllocToZero) { |
| 2701 i::FLAG_stress_compaction = false; |
| 2702 i::FLAG_allow_natives_syntax = true; |
| 2703 CcTest::InitializeVM(); |
| 2704 v8::HandleScope scope(CcTest::isolate()); |
| 2705 static const int transitions_count = 10; |
| 2706 AddTransitions(transitions_count); |
| 2707 CompileRun("var root = new Object;"); |
| 2708 Handle<JSObject> root = GetByName("root"); |
| 2709 |
| 2710 // Count number of live transitions before marking. |
| 2711 int transitions_before = CountMapTransitions(root->map()); |
| 2712 CHECK_EQ(transitions_count, transitions_before); |
| 2713 |
| 2714 // Get rid of o |
| 2715 CompileRun("o = new Object;" |
| 2716 "root = new Object"); |
| 2717 root = GetByName("root"); |
| 2718 AddPropertyTo(2, root, "funny"); |
| 2719 |
| 2720 // Count number of live transitions after marking. Note that one transition |
| 2721 // is left, because 'o' still holds an instance of one transition target. |
| 2722 int transitions_after = CountMapTransitions( |
| 2723 Map::cast(root->map()->GetBackPointer())); |
| 2724 CHECK_EQ(1, transitions_after); |
| 2725 } |
| 2726 |
| 2727 |
| 2728 TEST(TransitionArrayShrinksDuringAllocToOne) { |
| 2729 i::FLAG_stress_compaction = false; |
| 2730 i::FLAG_allow_natives_syntax = true; |
| 2731 CcTest::InitializeVM(); |
| 2732 v8::HandleScope scope(CcTest::isolate()); |
| 2733 static const int transitions_count = 10; |
| 2734 AddTransitions(transitions_count); |
| 2735 CompileRun("var root = new Object;"); |
| 2736 Handle<JSObject> root = GetByName("root"); |
| 2737 |
| 2738 // Count number of live transitions before marking. |
| 2739 int transitions_before = CountMapTransitions(root->map()); |
| 2740 CHECK_EQ(transitions_count, transitions_before); |
| 2741 |
| 2742 root = GetByName("root"); |
| 2743 AddPropertyTo(2, root, "funny"); |
| 2744 |
| 2745 // Count number of live transitions after marking. Note that one transition |
| 2746 // is left, because 'o' still holds an instance of one transition target. |
| 2747 int transitions_after = CountMapTransitions( |
| 2748 Map::cast(root->map()->GetBackPointer())); |
| 2749 CHECK_EQ(2, transitions_after); |
| 2750 } |
| 2751 |
| 2752 |
| 2753 TEST(TransitionArrayShrinksDuringAllocToOnePropertyFound) { |
| 2754 i::FLAG_stress_compaction = false; |
| 2755 i::FLAG_allow_natives_syntax = true; |
| 2756 CcTest::InitializeVM(); |
| 2757 v8::HandleScope scope(CcTest::isolate()); |
| 2758 static const int transitions_count = 10; |
| 2759 AddTransitions(transitions_count); |
| 2760 CompileRun("var root = new Object;"); |
| 2761 Handle<JSObject> root = GetByName("root"); |
| 2762 |
| 2763 // Count number of live transitions before marking. |
| 2764 int transitions_before = CountMapTransitions(root->map()); |
| 2765 CHECK_EQ(transitions_count, transitions_before); |
| 2766 |
| 2767 root = GetByName("root"); |
| 2768 AddPropertyTo(0, root, "prop9"); |
| 2769 |
| 2770 // Count number of live transitions after marking. Note that one transition |
| 2771 // is left, because 'o' still holds an instance of one transition target. |
| 2772 int transitions_after = CountMapTransitions( |
| 2773 Map::cast(root->map()->GetBackPointer())); |
| 2774 CHECK_EQ(1, transitions_after); |
| 2775 } |
| 2776 |
| 2777 |
| 2778 TEST(TransitionArraySimpleToFull) { |
| 2779 i::FLAG_stress_compaction = false; |
| 2780 i::FLAG_allow_natives_syntax = true; |
| 2781 CcTest::InitializeVM(); |
| 2782 v8::HandleScope scope(CcTest::isolate()); |
| 2783 static const int transitions_count = 1; |
| 2784 AddTransitions(transitions_count); |
| 2785 CompileRun("var root = new Object;"); |
| 2786 Handle<JSObject> root = GetByName("root"); |
| 2787 |
| 2788 // Count number of live transitions before marking. |
| 2789 int transitions_before = CountMapTransitions(root->map()); |
| 2790 CHECK_EQ(transitions_count, transitions_before); |
| 2791 |
| 2792 CompileRun("o = new Object;" |
| 2793 "root = new Object"); |
| 2794 root = GetByName("root"); |
| 2795 ASSERT(root->map()->transitions()->IsSimpleTransition()); |
| 2796 AddPropertyTo(2, root, "happy"); |
| 2797 |
| 2798 // Count number of live transitions after marking. Note that one transition |
| 2799 // is left, because 'o' still holds an instance of one transition target. |
| 2800 int transitions_after = CountMapTransitions( |
| 2801 Map::cast(root->map()->GetBackPointer())); |
| 2802 CHECK_EQ(1, transitions_after); |
| 2803 } |
| 2804 |
| 2805 |
2669 TEST(Regress2143a) { | 2806 TEST(Regress2143a) { |
2670 i::FLAG_collect_maps = true; | 2807 i::FLAG_collect_maps = true; |
2671 i::FLAG_incremental_marking = true; | 2808 i::FLAG_incremental_marking = true; |
2672 CcTest::InitializeVM(); | 2809 CcTest::InitializeVM(); |
2673 v8::HandleScope scope(CcTest::isolate()); | 2810 v8::HandleScope scope(CcTest::isolate()); |
2674 | 2811 |
2675 // Prepare a map transition from the root object together with a yet | 2812 // Prepare a map transition from the root object together with a yet |
2676 // untransitioned root object. | 2813 // untransitioned root object. |
2677 CompileRun("var root = new Object;" | 2814 CompileRun("var root = new Object;" |
2678 "root.foo = 0;" | 2815 "root.foo = 0;" |
(...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3935 v8::Context::Scope cscope(context); | 4072 v8::Context::Scope cscope(context); |
3936 | 4073 |
3937 v8::Local<v8::Value> result = CompileRun( | 4074 v8::Local<v8::Value> result = CompileRun( |
3938 "var locals = '';" | 4075 "var locals = '';" |
3939 "for (var i = 0; i < 512; i++) locals += 'var v' + i + '= 42;';" | 4076 "for (var i = 0; i < 512; i++) locals += 'var v' + i + '= 42;';" |
3940 "eval('function f() {' + locals + 'return function() { return v0; }; }');" | 4077 "eval('function f() {' + locals + 'return function() { return v0; }; }');" |
3941 "interrupt();" // This triggers a fake stack overflow in f. | 4078 "interrupt();" // This triggers a fake stack overflow in f. |
3942 "f()()"); | 4079 "f()()"); |
3943 CHECK_EQ(42.0, result->ToNumber()->Value()); | 4080 CHECK_EQ(42.0, result->ToNumber()->Value()); |
3944 } | 4081 } |
OLD | NEW |