| 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 2124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2135 v8::Handle<v8::Function> g = | 2135 v8::Handle<v8::Function> g = |
| 2136 v8::Handle<v8::Function>::Cast(global->Get(v8_str("g"))); | 2136 v8::Handle<v8::Function>::Cast(global->Get(v8_str("g"))); |
| 2137 g->Call(global, 0, NULL); | 2137 g->Call(global, 0, NULL); |
| 2138 } | 2138 } |
| 2139 | 2139 |
| 2140 CcTest::heap()->incremental_marking()->set_should_hurry(true); | 2140 CcTest::heap()->incremental_marking()->set_should_hurry(true); |
| 2141 CcTest::heap()->CollectGarbage(OLD_POINTER_SPACE); | 2141 CcTest::heap()->CollectGarbage(OLD_POINTER_SPACE); |
| 2142 } | 2142 } |
| 2143 | 2143 |
| 2144 | 2144 |
| 2145 static int NumberOfProtoTransitions(Map* map) { |
| 2146 return TransitionArray::NumberOfPrototypeTransitions( |
| 2147 TransitionArray::GetPrototypeTransitions(map)); |
| 2148 } |
| 2149 |
| 2150 |
| 2145 TEST(PrototypeTransitionClearing) { | 2151 TEST(PrototypeTransitionClearing) { |
| 2146 if (FLAG_never_compact) return; | 2152 if (FLAG_never_compact) return; |
| 2147 CcTest::InitializeVM(); | 2153 CcTest::InitializeVM(); |
| 2148 Isolate* isolate = CcTest::i_isolate(); | 2154 Isolate* isolate = CcTest::i_isolate(); |
| 2149 Factory* factory = isolate->factory(); | 2155 Factory* factory = isolate->factory(); |
| 2150 v8::HandleScope scope(CcTest::isolate()); | 2156 v8::HandleScope scope(CcTest::isolate()); |
| 2151 | 2157 |
| 2152 CompileRun("var base = {};"); | 2158 CompileRun("var base = {};"); |
| 2153 Handle<JSObject> baseObject = | 2159 Handle<JSObject> baseObject = |
| 2154 v8::Utils::OpenHandle( | 2160 v8::Utils::OpenHandle( |
| 2155 *v8::Handle<v8::Object>::Cast( | 2161 *v8::Handle<v8::Object>::Cast( |
| 2156 CcTest::global()->Get(v8_str("base")))); | 2162 CcTest::global()->Get(v8_str("base")))); |
| 2157 int initialTransitions = baseObject->map()->NumberOfProtoTransitions(); | 2163 int initialTransitions = NumberOfProtoTransitions(baseObject->map()); |
| 2158 | 2164 |
| 2159 CompileRun( | 2165 CompileRun( |
| 2160 "var live = [];" | 2166 "var live = [];" |
| 2161 "for (var i = 0; i < 10; i++) {" | 2167 "for (var i = 0; i < 10; i++) {" |
| 2162 " var object = {};" | 2168 " var object = {};" |
| 2163 " var prototype = {};" | 2169 " var prototype = {};" |
| 2164 " object.__proto__ = prototype;" | 2170 " object.__proto__ = prototype;" |
| 2165 " if (i >= 3) live.push(object, prototype);" | 2171 " if (i >= 3) live.push(object, prototype);" |
| 2166 "}"); | 2172 "}"); |
| 2167 | 2173 |
| 2168 // Verify that only dead prototype transitions are cleared. | 2174 // Verify that only dead prototype transitions are cleared. |
| 2169 CHECK_EQ(initialTransitions + 10, | 2175 CHECK_EQ(initialTransitions + 10, |
| 2170 baseObject->map()->NumberOfProtoTransitions()); | 2176 NumberOfProtoTransitions(baseObject->map())); |
| 2171 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 2177 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 2172 const int transitions = 10 - 3; | 2178 const int transitions = 10 - 3; |
| 2173 CHECK_EQ(initialTransitions + transitions, | 2179 CHECK_EQ(initialTransitions + transitions, |
| 2174 baseObject->map()->NumberOfProtoTransitions()); | 2180 NumberOfProtoTransitions(baseObject->map())); |
| 2175 | 2181 |
| 2176 // Verify that prototype transitions array was compacted. | 2182 // Verify that prototype transitions array was compacted. |
| 2177 FixedArray* trans = baseObject->map()->GetPrototypeTransitions(); | 2183 FixedArray* trans = |
| 2184 TransitionArray::GetPrototypeTransitions(baseObject->map()); |
| 2178 for (int i = initialTransitions; i < initialTransitions + transitions; i++) { | 2185 for (int i = initialTransitions; i < initialTransitions + transitions; i++) { |
| 2179 int j = Map::kProtoTransitionHeaderSize + i; | 2186 int j = TransitionArray::kProtoTransitionHeaderSize + i; |
| 2180 CHECK(trans->get(j)->IsMap()); | 2187 CHECK(trans->get(j)->IsMap()); |
| 2181 } | 2188 } |
| 2182 | 2189 |
| 2183 // Make sure next prototype is placed on an old-space evacuation candidate. | 2190 // Make sure next prototype is placed on an old-space evacuation candidate. |
| 2184 Handle<JSObject> prototype; | 2191 Handle<JSObject> prototype; |
| 2185 PagedSpace* space = CcTest::heap()->old_pointer_space(); | 2192 PagedSpace* space = CcTest::heap()->old_pointer_space(); |
| 2186 { | 2193 { |
| 2187 AlwaysAllocateScope always_allocate(isolate); | 2194 AlwaysAllocateScope always_allocate(isolate); |
| 2188 SimulateFullSpace(space); | 2195 SimulateFullSpace(space); |
| 2189 prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED); | 2196 prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED); |
| 2190 } | 2197 } |
| 2191 | 2198 |
| 2192 // Add a prototype on an evacuation candidate and verify that transition | 2199 // Add a prototype on an evacuation candidate and verify that transition |
| 2193 // clearing correctly records slots in prototype transition array. | 2200 // clearing correctly records slots in prototype transition array. |
| 2194 i::FLAG_always_compact = true; | 2201 i::FLAG_always_compact = true; |
| 2195 Handle<Map> map(baseObject->map()); | 2202 Handle<Map> map(baseObject->map()); |
| 2196 CHECK(!space->LastPage()->Contains( | 2203 CHECK(!space->LastPage()->Contains( |
| 2197 map->GetPrototypeTransitions()->address())); | 2204 TransitionArray::GetPrototypeTransitions(*map)->address())); |
| 2198 CHECK(space->LastPage()->Contains(prototype->address())); | 2205 CHECK(space->LastPage()->Contains(prototype->address())); |
| 2199 } | 2206 } |
| 2200 | 2207 |
| 2201 | 2208 |
| 2202 TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { | 2209 TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { |
| 2203 i::FLAG_stress_compaction = false; | 2210 i::FLAG_stress_compaction = false; |
| 2204 i::FLAG_allow_natives_syntax = true; | 2211 i::FLAG_allow_natives_syntax = true; |
| 2205 #ifdef VERIFY_HEAP | 2212 #ifdef VERIFY_HEAP |
| 2206 i::FLAG_verify_heap = true; | 2213 i::FLAG_verify_heap = true; |
| 2207 #endif | 2214 #endif |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2870 v8::Object::Cast(*res)->Get(v8_str("0"))->Int32Value()); | 2877 v8::Object::Cast(*res)->Get(v8_str("0"))->Int32Value()); |
| 2871 | 2878 |
| 2872 Handle<JSObject> o = | 2879 Handle<JSObject> o = |
| 2873 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); | 2880 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); |
| 2874 | 2881 |
| 2875 CHECK(CcTest::heap()->InNewSpace(o->elements())); | 2882 CHECK(CcTest::heap()->InNewSpace(o->elements())); |
| 2876 } | 2883 } |
| 2877 | 2884 |
| 2878 | 2885 |
| 2879 static int CountMapTransitions(Map* map) { | 2886 static int CountMapTransitions(Map* map) { |
| 2880 return map->transitions()->number_of_transitions(); | 2887 return TransitionArray::NumberOfTransitions(map->raw_transitions()); |
| 2881 } | 2888 } |
| 2882 | 2889 |
| 2883 | 2890 |
| 2884 // Test that map transitions are cleared and maps are collected with | 2891 // Test that map transitions are cleared and maps are collected with |
| 2885 // incremental marking as well. | 2892 // incremental marking as well. |
| 2886 TEST(Regress1465) { | 2893 TEST(Regress1465) { |
| 2887 i::FLAG_stress_compaction = false; | 2894 i::FLAG_stress_compaction = false; |
| 2888 i::FLAG_allow_natives_syntax = true; | 2895 i::FLAG_allow_natives_syntax = true; |
| 2889 i::FLAG_trace_incremental_marking = true; | 2896 i::FLAG_trace_incremental_marking = true; |
| 2890 i::FLAG_retain_maps_for_n_gc = 0; | 2897 i::FLAG_retain_maps_for_n_gc = 0; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3051 CompileRun("var root = new F;"); | 3058 CompileRun("var root = new F;"); |
| 3052 Handle<JSObject> root = GetByName("root"); | 3059 Handle<JSObject> root = GetByName("root"); |
| 3053 | 3060 |
| 3054 // Count number of live transitions before marking. | 3061 // Count number of live transitions before marking. |
| 3055 int transitions_before = CountMapTransitions(root->map()); | 3062 int transitions_before = CountMapTransitions(root->map()); |
| 3056 CHECK_EQ(transitions_count, transitions_before); | 3063 CHECK_EQ(transitions_count, transitions_before); |
| 3057 | 3064 |
| 3058 CompileRun("o = new F;" | 3065 CompileRun("o = new F;" |
| 3059 "root = new F"); | 3066 "root = new F"); |
| 3060 root = GetByName("root"); | 3067 root = GetByName("root"); |
| 3061 DCHECK(root->map()->transitions()->IsSimpleTransition()); | 3068 DCHECK(TransitionArray::IsSimpleTransition(root->map()->raw_transitions())); |
| 3062 AddPropertyTo(2, root, "happy"); | 3069 AddPropertyTo(2, root, "happy"); |
| 3063 | 3070 |
| 3064 // Count number of live transitions after marking. Note that one transition | 3071 // Count number of live transitions after marking. Note that one transition |
| 3065 // is left, because 'o' still holds an instance of one transition target. | 3072 // is left, because 'o' still holds an instance of one transition target. |
| 3066 int transitions_after = CountMapTransitions( | 3073 int transitions_after = CountMapTransitions( |
| 3067 Map::cast(root->map()->GetBackPointer())); | 3074 Map::cast(root->map()->GetBackPointer())); |
| 3068 CHECK_EQ(1, transitions_after); | 3075 CHECK_EQ(1, transitions_after); |
| 3069 } | 3076 } |
| 3070 #endif // DEBUG | 3077 #endif // DEBUG |
| 3071 | 3078 |
| (...skipping 2059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5131 | 5138 |
| 5132 TEST(WritableVsImmortalRoots) { | 5139 TEST(WritableVsImmortalRoots) { |
| 5133 for (int i = 0; i < Heap::kStrongRootListLength; ++i) { | 5140 for (int i = 0; i < Heap::kStrongRootListLength; ++i) { |
| 5134 Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(i); | 5141 Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(i); |
| 5135 bool writable = Heap::RootCanBeWrittenAfterInitialization(root_index); | 5142 bool writable = Heap::RootCanBeWrittenAfterInitialization(root_index); |
| 5136 bool immortal = Heap::RootIsImmortalImmovable(root_index); | 5143 bool immortal = Heap::RootIsImmortalImmovable(root_index); |
| 5137 // A root value can be writable, immortal, or neither, but not both. | 5144 // A root value can be writable, immortal, or neither, but not both. |
| 5138 CHECK(!immortal || !writable); | 5145 CHECK(!immortal || !writable); |
| 5139 } | 5146 } |
| 5140 } | 5147 } |
| OLD | NEW |