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 3328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3339 Handle<TypeFeedbackVector> vector = | 3339 Handle<TypeFeedbackVector> vector = |
3340 Handle<TypeFeedbackVector>(f->shared()->feedback_vector()); | 3340 Handle<TypeFeedbackVector>(f->shared()->feedback_vector()); |
3341 FeedbackVectorICSlot slot(ic_slot_index); | 3341 FeedbackVectorICSlot slot(ic_slot_index); |
3342 LoadICNexus nexus(vector, slot); | 3342 LoadICNexus nexus(vector, slot); |
3343 CHECK(IC::IsCleared(&nexus)); | 3343 CHECK(IC::IsCleared(&nexus)); |
3344 } | 3344 } |
3345 | 3345 |
3346 | 3346 |
3347 TEST(IncrementalMarkingPreservesMonomorphicIC) { | 3347 TEST(IncrementalMarkingPreservesMonomorphicIC) { |
3348 if (i::FLAG_always_opt) return; | 3348 if (i::FLAG_always_opt) return; |
| 3349 // TODO(mvstanton): vector-ics need to treat maps weakly. |
| 3350 if (i::FLAG_vector_ics) return; |
3349 CcTest::InitializeVM(); | 3351 CcTest::InitializeVM(); |
3350 v8::HandleScope scope(CcTest::isolate()); | 3352 v8::HandleScope scope(CcTest::isolate()); |
3351 | 3353 |
3352 // Prepare function f that contains a monomorphic IC for object | 3354 // Prepare function f that contains a monomorphic IC for object |
3353 // originating from the same native context. | 3355 // originating from the same native context. |
3354 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" | 3356 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" |
3355 "function f(o) { return o.x; } f(obj); f(obj);"); | 3357 "function f(o) { return o.x; } f(obj); f(obj);"); |
3356 Handle<JSFunction> f = | 3358 Handle<JSFunction> f = |
3357 v8::Utils::OpenHandle( | 3359 v8::Utils::OpenHandle( |
3358 *v8::Handle<v8::Function>::Cast( | 3360 *v8::Handle<v8::Function>::Cast( |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3443 | 3445 |
3444 // Prepare function f that contains a polymorphic IC for objects | 3446 // Prepare function f that contains a polymorphic IC for objects |
3445 // originating from two different native contexts. | 3447 // originating from two different native contexts. |
3446 CcTest::global()->Set(v8_str("obj1"), obj1); | 3448 CcTest::global()->Set(v8_str("obj1"), obj1); |
3447 CcTest::global()->Set(v8_str("obj2"), obj2); | 3449 CcTest::global()->Set(v8_str("obj2"), obj2); |
3448 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);"); | 3450 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);"); |
3449 Handle<JSFunction> f = v8::Utils::OpenHandle( | 3451 Handle<JSFunction> f = v8::Utils::OpenHandle( |
3450 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f")))); | 3452 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f")))); |
3451 | 3453 |
3452 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 3454 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
3453 CHECK(ic_before->ic_state() == POLYMORPHIC); | 3455 if (FLAG_vector_ics) { |
| 3456 CheckVectorIC(f, 0, POLYMORPHIC); |
| 3457 CHECK(ic_before->ic_state() == DEFAULT); |
| 3458 } else { |
| 3459 CHECK(ic_before->ic_state() == POLYMORPHIC); |
| 3460 } |
3454 | 3461 |
3455 // Fire context dispose notification. | 3462 // Fire context dispose notification. |
3456 SimulateIncrementalMarking(CcTest::heap()); | 3463 SimulateIncrementalMarking(CcTest::heap()); |
3457 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); | 3464 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); |
3458 | 3465 |
3459 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); | 3466 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); |
3460 CHECK(ic_after->ic_state() == POLYMORPHIC); | 3467 if (FLAG_vector_ics) { |
| 3468 CheckVectorIC(f, 0, POLYMORPHIC); |
| 3469 CHECK(ic_after->ic_state() == DEFAULT); |
| 3470 } else { |
| 3471 CHECK(ic_after->ic_state() == POLYMORPHIC); |
| 3472 } |
3461 } | 3473 } |
3462 | 3474 |
3463 | 3475 |
3464 TEST(IncrementalMarkingClearsPolymorphicIC) { | 3476 TEST(IncrementalMarkingClearsPolymorphicIC) { |
3465 if (i::FLAG_always_opt) return; | 3477 if (i::FLAG_always_opt) return; |
3466 CcTest::InitializeVM(); | 3478 CcTest::InitializeVM(); |
3467 v8::HandleScope scope(CcTest::isolate()); | 3479 v8::HandleScope scope(CcTest::isolate()); |
3468 v8::Local<v8::Value> obj1, obj2; | 3480 v8::Local<v8::Value> obj1, obj2; |
3469 | 3481 |
3470 { | 3482 { |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3726 // Make a new closure that will get code installed from the code map. | 3738 // Make a new closure that will get code installed from the code map. |
3727 // Unoptimized code is missing and the deoptimizer will go ballistic. | 3739 // Unoptimized code is missing and the deoptimizer will go ballistic. |
3728 CompileRun("var g = mkClosure(); g('bozo');"); | 3740 CompileRun("var g = mkClosure(); g('bozo');"); |
3729 } | 3741 } |
3730 | 3742 |
3731 | 3743 |
3732 TEST(Regress169209) { | 3744 TEST(Regress169209) { |
3733 i::FLAG_stress_compaction = false; | 3745 i::FLAG_stress_compaction = false; |
3734 i::FLAG_allow_natives_syntax = true; | 3746 i::FLAG_allow_natives_syntax = true; |
3735 i::FLAG_flush_code_incrementally = true; | 3747 i::FLAG_flush_code_incrementally = true; |
| 3748 // TODO(mvstanton): vector ics need weak support. |
| 3749 if (i::FLAG_vector_ics) return; |
3736 | 3750 |
3737 CcTest::InitializeVM(); | 3751 CcTest::InitializeVM(); |
3738 Isolate* isolate = CcTest::i_isolate(); | 3752 Isolate* isolate = CcTest::i_isolate(); |
3739 Heap* heap = isolate->heap(); | 3753 Heap* heap = isolate->heap(); |
3740 HandleScope scope(isolate); | 3754 HandleScope scope(isolate); |
3741 | 3755 |
3742 // Perform one initial GC to enable code flushing. | 3756 // Perform one initial GC to enable code flushing. |
3743 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 3757 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
3744 | 3758 |
3745 // Prepare a shared function info eligible for code flushing for which | 3759 // Prepare a shared function info eligible for code flushing for which |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4079 for (Object* site = heap->allocation_sites_list(); | 4093 for (Object* site = heap->allocation_sites_list(); |
4080 !(site->IsUndefined()); | 4094 !(site->IsUndefined()); |
4081 site = AllocationSite::cast(site)->weak_next()) { | 4095 site = AllocationSite::cast(site)->weak_next()) { |
4082 count++; | 4096 count++; |
4083 } | 4097 } |
4084 return count; | 4098 return count; |
4085 } | 4099 } |
4086 | 4100 |
4087 | 4101 |
4088 TEST(EnsureAllocationSiteDependentCodesProcessed) { | 4102 TEST(EnsureAllocationSiteDependentCodesProcessed) { |
| 4103 // TODO(mvstanton): vector ics need weak support! |
| 4104 if (FLAG_vector_ics) return; |
4089 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; | 4105 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; |
4090 i::FLAG_allow_natives_syntax = true; | 4106 i::FLAG_allow_natives_syntax = true; |
4091 CcTest::InitializeVM(); | 4107 CcTest::InitializeVM(); |
4092 Isolate* isolate = CcTest::i_isolate(); | 4108 Isolate* isolate = CcTest::i_isolate(); |
4093 v8::internal::Heap* heap = CcTest::heap(); | 4109 v8::internal::Heap* heap = CcTest::heap(); |
4094 GlobalHandles* global_handles = isolate->global_handles(); | 4110 GlobalHandles* global_handles = isolate->global_handles(); |
4095 | 4111 |
4096 if (!isolate->use_crankshaft()) return; | 4112 if (!isolate->use_crankshaft()) return; |
4097 | 4113 |
4098 // The allocation site at the head of the list is ours. | 4114 // The allocation site at the head of the list is ours. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4141 // The site still exists because of our global handle, but the code is no | 4157 // The site still exists because of our global handle, but the code is no |
4142 // longer referred to by dependent_code(). | 4158 // longer referred to by dependent_code(). |
4143 DependentCode::GroupStartIndexes starts(site->dependent_code()); | 4159 DependentCode::GroupStartIndexes starts(site->dependent_code()); |
4144 int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); | 4160 int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); |
4145 CHECK(!(site->dependent_code()->is_code_at(index))); | 4161 CHECK(!(site->dependent_code()->is_code_at(index))); |
4146 } | 4162 } |
4147 | 4163 |
4148 | 4164 |
4149 TEST(CellsInOptimizedCodeAreWeak) { | 4165 TEST(CellsInOptimizedCodeAreWeak) { |
4150 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; | 4166 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; |
| 4167 // TODO(mvstanton): vector-ics need to treat maps weakly. |
| 4168 if (i::FLAG_vector_ics) return; |
4151 i::FLAG_weak_embedded_objects_in_optimized_code = true; | 4169 i::FLAG_weak_embedded_objects_in_optimized_code = true; |
4152 i::FLAG_allow_natives_syntax = true; | 4170 i::FLAG_allow_natives_syntax = true; |
4153 CcTest::InitializeVM(); | 4171 CcTest::InitializeVM(); |
4154 Isolate* isolate = CcTest::i_isolate(); | 4172 Isolate* isolate = CcTest::i_isolate(); |
4155 v8::internal::Heap* heap = CcTest::heap(); | 4173 v8::internal::Heap* heap = CcTest::heap(); |
4156 | 4174 |
4157 if (!isolate->use_crankshaft()) return; | 4175 if (!isolate->use_crankshaft()) return; |
4158 HandleScope outer_scope(heap->isolate()); | 4176 HandleScope outer_scope(heap->isolate()); |
4159 Handle<Code> code; | 4177 Handle<Code> code; |
4160 { | 4178 { |
(...skipping 22 matching lines...) Expand all Loading... |
4183 // Now make sure that a gc should get rid of the function | 4201 // Now make sure that a gc should get rid of the function |
4184 for (int i = 0; i < 4; i++) { | 4202 for (int i = 0; i < 4; i++) { |
4185 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 4203 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
4186 } | 4204 } |
4187 | 4205 |
4188 DCHECK(code->marked_for_deoptimization()); | 4206 DCHECK(code->marked_for_deoptimization()); |
4189 } | 4207 } |
4190 | 4208 |
4191 | 4209 |
4192 TEST(ObjectsInOptimizedCodeAreWeak) { | 4210 TEST(ObjectsInOptimizedCodeAreWeak) { |
| 4211 // TODO(mvstanton): vector ics need weak support! |
| 4212 if (FLAG_vector_ics) return; |
4193 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; | 4213 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; |
4194 i::FLAG_weak_embedded_objects_in_optimized_code = true; | 4214 i::FLAG_weak_embedded_objects_in_optimized_code = true; |
4195 i::FLAG_allow_natives_syntax = true; | 4215 i::FLAG_allow_natives_syntax = true; |
4196 CcTest::InitializeVM(); | 4216 CcTest::InitializeVM(); |
4197 Isolate* isolate = CcTest::i_isolate(); | 4217 Isolate* isolate = CcTest::i_isolate(); |
4198 v8::internal::Heap* heap = CcTest::heap(); | 4218 v8::internal::Heap* heap = CcTest::heap(); |
4199 | 4219 |
4200 if (!isolate->use_crankshaft()) return; | 4220 if (!isolate->use_crankshaft()) return; |
4201 HandleScope outer_scope(heap->isolate()); | 4221 HandleScope outer_scope(heap->isolate()); |
4202 Handle<Code> code; | 4222 Handle<Code> code; |
(...skipping 23 matching lines...) Expand all Loading... |
4226 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 4246 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
4227 } | 4247 } |
4228 | 4248 |
4229 DCHECK(code->marked_for_deoptimization()); | 4249 DCHECK(code->marked_for_deoptimization()); |
4230 } | 4250 } |
4231 | 4251 |
4232 | 4252 |
4233 TEST(NoWeakHashTableLeakWithIncrementalMarking) { | 4253 TEST(NoWeakHashTableLeakWithIncrementalMarking) { |
4234 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; | 4254 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; |
4235 if (!i::FLAG_incremental_marking) return; | 4255 if (!i::FLAG_incremental_marking) return; |
| 4256 // TODO(mvstanton): vector ics need weak support. |
| 4257 if (FLAG_vector_ics) return; |
4236 i::FLAG_weak_embedded_objects_in_optimized_code = true; | 4258 i::FLAG_weak_embedded_objects_in_optimized_code = true; |
4237 i::FLAG_allow_natives_syntax = true; | 4259 i::FLAG_allow_natives_syntax = true; |
4238 i::FLAG_compilation_cache = false; | 4260 i::FLAG_compilation_cache = false; |
4239 CcTest::InitializeVM(); | 4261 CcTest::InitializeVM(); |
4240 Isolate* isolate = CcTest::i_isolate(); | 4262 Isolate* isolate = CcTest::i_isolate(); |
4241 v8::internal::Heap* heap = CcTest::heap(); | 4263 v8::internal::Heap* heap = CcTest::heap(); |
4242 | 4264 |
4243 if (!isolate->use_crankshaft()) return; | 4265 if (!isolate->use_crankshaft()) return; |
4244 HandleScope outer_scope(heap->isolate()); | 4266 HandleScope outer_scope(heap->isolate()); |
4245 for (int i = 0; i < 3; i++) { | 4267 for (int i = 0; i < 3; i++) { |
4246 SimulateIncrementalMarking(heap); | 4268 SimulateIncrementalMarking(heap); |
4247 { | 4269 { |
4248 LocalContext context; | 4270 LocalContext context; |
4249 HandleScope scope(heap->isolate()); | 4271 HandleScope scope(heap->isolate()); |
4250 EmbeddedVector<char, 256> source; | 4272 EmbeddedVector<char, 256> source; |
4251 SNPrintF(source, | 4273 SNPrintF(source, |
4252 "function bar%d() {" | 4274 "function bar%d() {" |
4253 " return foo%d(1);" | 4275 " return foo%d(1);" |
4254 "};" | 4276 "};" |
4255 "function foo%d(x) { with (x) { return 1 + x; } };" | 4277 "function foo%d(x) { with (x) { return 1 + x; } };" |
4256 "bar%d();" | 4278 "bar%d();" |
4257 "bar%d();" | 4279 "bar%d();" |
4258 "bar%d();" | 4280 "bar%d();" |
4259 "%%OptimizeFunctionOnNextCall(bar%d);" | 4281 "%%OptimizeFwunctionOnNextCall(bar%d);" |
4260 "bar%d();", i, i, i, i, i, i, i, i); | 4282 "bar%d();", |
| 4283 i, i, i, i, i, i, i, i); |
4261 CompileRun(source.start()); | 4284 CompileRun(source.start()); |
4262 } | 4285 } |
4263 heap->CollectAllGarbage(i::Heap::kNoGCFlags); | 4286 heap->CollectAllGarbage(i::Heap::kNoGCFlags); |
4264 } | 4287 } |
4265 int elements = 0; | 4288 int elements = 0; |
4266 if (heap->weak_object_to_code_table()->IsHashTable()) { | 4289 if (heap->weak_object_to_code_table()->IsHashTable()) { |
4267 WeakHashTable* t = WeakHashTable::cast(heap->weak_object_to_code_table()); | 4290 WeakHashTable* t = WeakHashTable::cast(heap->weak_object_to_code_table()); |
4268 elements = t->NumberOfElements(); | 4291 elements = t->NumberOfElements(); |
4269 } | 4292 } |
4270 CHECK_EQ(0, elements); | 4293 CHECK_EQ(0, elements); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4412 " var obj = Object.create(proto);" | 4435 " var obj = Object.create(proto);" |
4413 " loadIC(obj);" | 4436 " loadIC(obj);" |
4414 " loadIC(obj);" | 4437 " loadIC(obj);" |
4415 " loadIC(obj);" | 4438 " loadIC(obj);" |
4416 " return proto;" | 4439 " return proto;" |
4417 " })();"); | 4440 " })();"); |
4418 } | 4441 } |
4419 | 4442 |
4420 | 4443 |
4421 TEST(WeakMapInPolymorphicLoadIC) { | 4444 TEST(WeakMapInPolymorphicLoadIC) { |
| 4445 // TODO(mvstanton): vector-ics need to treat maps weakly. |
| 4446 if (i::FLAG_vector_ics) return; |
4422 CheckWeakness( | 4447 CheckWeakness( |
4423 "function loadIC(obj) {" | 4448 "function loadIC(obj) {" |
4424 " return obj.name;" | 4449 " return obj.name;" |
4425 "}" | 4450 "}" |
4426 " (function() {" | 4451 " (function() {" |
4427 " var proto = {'name' : 'weak'};" | 4452 " var proto = {'name' : 'weak'};" |
4428 " var obj = Object.create(proto);" | 4453 " var obj = Object.create(proto);" |
4429 " loadIC(obj);" | 4454 " loadIC(obj);" |
4430 " loadIC(obj);" | 4455 " loadIC(obj);" |
4431 " loadIC(obj);" | 4456 " loadIC(obj);" |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4926 #ifdef DEBUG | 4951 #ifdef DEBUG |
4927 TEST(PathTracer) { | 4952 TEST(PathTracer) { |
4928 CcTest::InitializeVM(); | 4953 CcTest::InitializeVM(); |
4929 v8::HandleScope scope(CcTest::isolate()); | 4954 v8::HandleScope scope(CcTest::isolate()); |
4930 | 4955 |
4931 v8::Local<v8::Value> result = CompileRun("'abc'"); | 4956 v8::Local<v8::Value> result = CompileRun("'abc'"); |
4932 Handle<Object> o = v8::Utils::OpenHandle(*result); | 4957 Handle<Object> o = v8::Utils::OpenHandle(*result); |
4933 CcTest::i_isolate()->heap()->TracePathToObject(*o); | 4958 CcTest::i_isolate()->heap()->TracePathToObject(*o); |
4934 } | 4959 } |
4935 #endif // DEBUG | 4960 #endif // DEBUG |
OLD | NEW |