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 3622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3633 | 3633 |
3634 // Prepare function f that contains type feedback for the two closures. | 3634 // Prepare function f that contains type feedback for the two closures. |
3635 CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust()); | 3635 CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust()); |
3636 CHECK(CcTest::global()->Set(ctx, v8_str("fun2"), fun2).FromJust()); | 3636 CHECK(CcTest::global()->Set(ctx, v8_str("fun2"), fun2).FromJust()); |
3637 CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);"); | 3637 CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);"); |
3638 | 3638 |
3639 Handle<JSFunction> f = Handle<JSFunction>::cast( | 3639 Handle<JSFunction> f = Handle<JSFunction>::cast( |
3640 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 3640 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
3641 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); | 3641 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
3642 | 3642 |
3643 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 3643 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
3644 FeedbackVectorHelper feedback_helper(feedback_vector); | 3644 FeedbackVectorHelper feedback_helper(feedback_vector); |
3645 | 3645 |
3646 int expected_slots = 2; | 3646 int expected_slots = 2; |
3647 CHECK_EQ(expected_slots, feedback_helper.slot_count()); | 3647 CHECK_EQ(expected_slots, feedback_helper.slot_count()); |
3648 int slot1 = 0; | 3648 int slot1 = 0; |
3649 int slot2 = 1; | 3649 int slot2 = 1; |
3650 CHECK(feedback_vector->Get(feedback_helper.slot(slot1))->IsWeakCell()); | 3650 CHECK(feedback_vector->Get(feedback_helper.slot(slot1))->IsWeakCell()); |
3651 CHECK(feedback_vector->Get(feedback_helper.slot(slot2))->IsWeakCell()); | 3651 CHECK(feedback_vector->Get(feedback_helper.slot(slot2))->IsWeakCell()); |
3652 | 3652 |
3653 SimulateIncrementalMarking(CcTest::heap()); | 3653 SimulateIncrementalMarking(CcTest::heap()); |
(...skipping 16 matching lines...) Expand all Loading... |
3670 return target; | 3670 return target; |
3671 } | 3671 } |
3672 } | 3672 } |
3673 return NULL; | 3673 return NULL; |
3674 } | 3674 } |
3675 | 3675 |
3676 | 3676 |
3677 static void CheckVectorIC(Handle<JSFunction> f, int slot_index, | 3677 static void CheckVectorIC(Handle<JSFunction> f, int slot_index, |
3678 InlineCacheState desired_state) { | 3678 InlineCacheState desired_state) { |
3679 Handle<TypeFeedbackVector> vector = | 3679 Handle<TypeFeedbackVector> vector = |
3680 Handle<TypeFeedbackVector>(f->shared()->feedback_vector()); | 3680 Handle<TypeFeedbackVector>(f->feedback_vector()); |
3681 FeedbackVectorHelper helper(vector); | 3681 FeedbackVectorHelper helper(vector); |
3682 FeedbackVectorSlot slot = helper.slot(slot_index); | 3682 FeedbackVectorSlot slot = helper.slot(slot_index); |
3683 if (vector->GetKind(slot) == FeedbackVectorSlotKind::LOAD_IC) { | 3683 if (vector->GetKind(slot) == FeedbackVectorSlotKind::LOAD_IC) { |
3684 LoadICNexus nexus(vector, slot); | 3684 LoadICNexus nexus(vector, slot); |
3685 CHECK(nexus.StateFromFeedback() == desired_state); | 3685 CHECK(nexus.StateFromFeedback() == desired_state); |
3686 } else { | 3686 } else { |
3687 CHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot)); | 3687 CHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot)); |
3688 KeyedLoadICNexus nexus(vector, slot); | 3688 KeyedLoadICNexus nexus(vector, slot); |
3689 CHECK(nexus.StateFromFeedback() == desired_state); | 3689 CHECK(nexus.StateFromFeedback() == desired_state); |
3690 } | 3690 } |
3691 } | 3691 } |
3692 | 3692 |
3693 | |
3694 static void CheckVectorICCleared(Handle<JSFunction> f, int slot_index) { | |
3695 Handle<TypeFeedbackVector> vector = | |
3696 Handle<TypeFeedbackVector>(f->shared()->feedback_vector()); | |
3697 FeedbackVectorSlot slot(slot_index); | |
3698 LoadICNexus nexus(vector, slot); | |
3699 CHECK(IC::IsCleared(&nexus)); | |
3700 } | |
3701 | |
3702 | |
3703 TEST(IncrementalMarkingPreservesMonomorphicConstructor) { | 3693 TEST(IncrementalMarkingPreservesMonomorphicConstructor) { |
3704 if (i::FLAG_always_opt) return; | 3694 if (i::FLAG_always_opt) return; |
3705 CcTest::InitializeVM(); | 3695 CcTest::InitializeVM(); |
3706 v8::HandleScope scope(CcTest::isolate()); | 3696 v8::HandleScope scope(CcTest::isolate()); |
3707 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); | 3697 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
3708 // Prepare function f that contains a monomorphic IC for object | 3698 // Prepare function f that contains a monomorphic IC for object |
3709 // originating from the same native context. | 3699 // originating from the same native context. |
3710 CompileRun( | 3700 CompileRun( |
3711 "function fun() { this.x = 1; };" | 3701 "function fun() { this.x = 1; };" |
3712 "function f(o) { return new o(); } f(fun); f(fun);"); | 3702 "function f(o) { return new o(); } f(fun); f(fun);"); |
3713 Handle<JSFunction> f = Handle<JSFunction>::cast( | 3703 Handle<JSFunction> f = Handle<JSFunction>::cast( |
3714 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 3704 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
3715 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); | 3705 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
3716 | 3706 |
3717 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector()); | 3707 Handle<TypeFeedbackVector> vector(f->feedback_vector()); |
3718 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); | 3708 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); |
3719 | 3709 |
3720 SimulateIncrementalMarking(CcTest::heap()); | 3710 SimulateIncrementalMarking(CcTest::heap()); |
3721 CcTest::heap()->CollectAllGarbage(); | 3711 CcTest::heap()->CollectAllGarbage(); |
3722 | 3712 |
3723 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); | 3713 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); |
3724 } | 3714 } |
3725 | 3715 |
3726 | |
3727 TEST(IncrementalMarkingClearsMonomorphicConstructor) { | |
3728 if (i::FLAG_always_opt) return; | |
3729 CcTest::InitializeVM(); | |
3730 Isolate* isolate = CcTest::i_isolate(); | |
3731 v8::HandleScope scope(CcTest::isolate()); | |
3732 v8::Local<v8::Value> fun1; | |
3733 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); | |
3734 | |
3735 { | |
3736 LocalContext env; | |
3737 CompileRun("function fun() { this.x = 1; };"); | |
3738 fun1 = env->Global()->Get(env.local(), v8_str("fun")).ToLocalChecked(); | |
3739 } | |
3740 | |
3741 // Prepare function f that contains a monomorphic constructor for object | |
3742 // originating from a different native context. | |
3743 CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust()); | |
3744 CompileRun( | |
3745 "function fun() { this.x = 1; };" | |
3746 "function f(o) { return new o(); } f(fun1); f(fun1);"); | |
3747 Handle<JSFunction> f = Handle<JSFunction>::cast( | |
3748 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | |
3749 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); | |
3750 | |
3751 | |
3752 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector()); | |
3753 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); | |
3754 | |
3755 // Fire context dispose notification. | |
3756 CcTest::isolate()->ContextDisposedNotification(); | |
3757 SimulateIncrementalMarking(CcTest::heap()); | |
3758 CcTest::heap()->CollectAllGarbage(); | |
3759 | |
3760 CHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(isolate), | |
3761 vector->Get(FeedbackVectorSlot(0))); | |
3762 } | |
3763 | |
3764 | |
3765 TEST(IncrementalMarkingPreservesMonomorphicIC) { | 3716 TEST(IncrementalMarkingPreservesMonomorphicIC) { |
3766 if (i::FLAG_always_opt) return; | 3717 if (i::FLAG_always_opt) return; |
3767 CcTest::InitializeVM(); | 3718 CcTest::InitializeVM(); |
3768 v8::HandleScope scope(CcTest::isolate()); | 3719 v8::HandleScope scope(CcTest::isolate()); |
3769 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); | 3720 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
3770 // Prepare function f that contains a monomorphic IC for object | 3721 // Prepare function f that contains a monomorphic IC for object |
3771 // originating from the same native context. | 3722 // originating from the same native context. |
3772 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" | 3723 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" |
3773 "function f(o) { return o.x; } f(obj); f(obj);"); | 3724 "function f(o) { return o.x; } f(obj); f(obj);"); |
3774 Handle<JSFunction> f = Handle<JSFunction>::cast( | 3725 Handle<JSFunction> f = Handle<JSFunction>::cast( |
3775 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 3726 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
3776 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); | 3727 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
3777 | 3728 |
3778 CheckVectorIC(f, 0, MONOMORPHIC); | 3729 CheckVectorIC(f, 0, MONOMORPHIC); |
3779 | 3730 |
3780 SimulateIncrementalMarking(CcTest::heap()); | 3731 SimulateIncrementalMarking(CcTest::heap()); |
3781 CcTest::heap()->CollectAllGarbage(); | 3732 CcTest::heap()->CollectAllGarbage(); |
3782 | 3733 |
3783 CheckVectorIC(f, 0, MONOMORPHIC); | 3734 CheckVectorIC(f, 0, MONOMORPHIC); |
3784 } | 3735 } |
3785 | 3736 |
3786 | |
3787 TEST(IncrementalMarkingClearsMonomorphicIC) { | |
3788 if (i::FLAG_always_opt) return; | |
3789 CcTest::InitializeVM(); | |
3790 v8::HandleScope scope(CcTest::isolate()); | |
3791 v8::Local<v8::Value> obj1; | |
3792 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); | |
3793 | |
3794 { | |
3795 LocalContext env; | |
3796 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); | |
3797 obj1 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); | |
3798 } | |
3799 | |
3800 // Prepare function f that contains a monomorphic IC for object | |
3801 // originating from a different native context. | |
3802 CHECK(CcTest::global()->Set(ctx, v8_str("obj1"), obj1).FromJust()); | |
3803 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1);"); | |
3804 Handle<JSFunction> f = Handle<JSFunction>::cast( | |
3805 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | |
3806 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); | |
3807 | |
3808 CheckVectorIC(f, 0, MONOMORPHIC); | |
3809 | |
3810 // Fire context dispose notification. | |
3811 CcTest::isolate()->ContextDisposedNotification(); | |
3812 SimulateIncrementalMarking(CcTest::heap()); | |
3813 CcTest::heap()->CollectAllGarbage(); | |
3814 | |
3815 CheckVectorICCleared(f, 0); | |
3816 } | |
3817 | |
3818 | |
3819 TEST(IncrementalMarkingPreservesPolymorphicIC) { | 3737 TEST(IncrementalMarkingPreservesPolymorphicIC) { |
3820 if (i::FLAG_always_opt) return; | 3738 if (i::FLAG_always_opt) return; |
3821 CcTest::InitializeVM(); | 3739 CcTest::InitializeVM(); |
3822 v8::HandleScope scope(CcTest::isolate()); | 3740 v8::HandleScope scope(CcTest::isolate()); |
3823 v8::Local<v8::Value> obj1, obj2; | 3741 v8::Local<v8::Value> obj1, obj2; |
3824 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); | 3742 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
3825 | 3743 |
3826 { | 3744 { |
3827 LocalContext env; | 3745 LocalContext env; |
3828 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); | 3746 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); |
(...skipping 17 matching lines...) Expand all Loading... |
3846 | 3764 |
3847 CheckVectorIC(f, 0, POLYMORPHIC); | 3765 CheckVectorIC(f, 0, POLYMORPHIC); |
3848 | 3766 |
3849 // Fire context dispose notification. | 3767 // Fire context dispose notification. |
3850 SimulateIncrementalMarking(CcTest::heap()); | 3768 SimulateIncrementalMarking(CcTest::heap()); |
3851 CcTest::heap()->CollectAllGarbage(); | 3769 CcTest::heap()->CollectAllGarbage(); |
3852 | 3770 |
3853 CheckVectorIC(f, 0, POLYMORPHIC); | 3771 CheckVectorIC(f, 0, POLYMORPHIC); |
3854 } | 3772 } |
3855 | 3773 |
3856 | 3774 TEST(ContextDisposeDoesntClearPolymorphicIC) { |
3857 TEST(IncrementalMarkingClearsPolymorphicIC) { | |
3858 if (i::FLAG_always_opt) return; | 3775 if (i::FLAG_always_opt) return; |
3859 CcTest::InitializeVM(); | 3776 CcTest::InitializeVM(); |
3860 v8::HandleScope scope(CcTest::isolate()); | 3777 v8::HandleScope scope(CcTest::isolate()); |
3861 v8::Local<v8::Value> obj1, obj2; | 3778 v8::Local<v8::Value> obj1, obj2; |
3862 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); | 3779 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); |
3863 | 3780 |
3864 { | 3781 { |
3865 LocalContext env; | 3782 LocalContext env; |
3866 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); | 3783 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); |
3867 obj1 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); | 3784 obj1 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); |
(...skipping 14 matching lines...) Expand all Loading... |
3882 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 3799 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
3883 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); | 3800 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); |
3884 | 3801 |
3885 CheckVectorIC(f, 0, POLYMORPHIC); | 3802 CheckVectorIC(f, 0, POLYMORPHIC); |
3886 | 3803 |
3887 // Fire context dispose notification. | 3804 // Fire context dispose notification. |
3888 CcTest::isolate()->ContextDisposedNotification(); | 3805 CcTest::isolate()->ContextDisposedNotification(); |
3889 SimulateIncrementalMarking(CcTest::heap()); | 3806 SimulateIncrementalMarking(CcTest::heap()); |
3890 CcTest::heap()->CollectAllGarbage(); | 3807 CcTest::heap()->CollectAllGarbage(); |
3891 | 3808 |
3892 CheckVectorICCleared(f, 0); | 3809 CheckVectorIC(f, 0, POLYMORPHIC); |
3893 } | 3810 } |
3894 | 3811 |
3895 | 3812 |
3896 class SourceResource : public v8::String::ExternalOneByteStringResource { | 3813 class SourceResource : public v8::String::ExternalOneByteStringResource { |
3897 public: | 3814 public: |
3898 explicit SourceResource(const char* data) | 3815 explicit SourceResource(const char* data) |
3899 : data_(data), length_(strlen(data)) { } | 3816 : data_(data), length_(strlen(data)) { } |
3900 | 3817 |
3901 virtual void Dispose() { | 3818 virtual void Dispose() { |
3902 i::DeleteArray(data_); | 3819 i::DeleteArray(data_); |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4296 CompileRun("function g() { return 2 }" | 4213 CompileRun("function g() { return 2 }" |
4297 "g(); %OptimizeFunctionOnNextCall(g); g();"); | 4214 "g(); %OptimizeFunctionOnNextCall(g); g();"); |
4298 | 4215 |
4299 Handle<JSFunction> g = Handle<JSFunction>::cast( | 4216 Handle<JSFunction> g = Handle<JSFunction>::cast( |
4300 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 4217 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
4301 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); | 4218 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); |
4302 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); | 4219 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); |
4303 if (!code->is_optimized_code()) return; | 4220 if (!code->is_optimized_code()) return; |
4304 } | 4221 } |
4305 | 4222 |
4306 Handle<TypeFeedbackVector> vector = handle(shared->feedback_vector()); | 4223 Handle<TypeFeedbackVector> vector = |
| 4224 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata())); |
4307 Handle<LiteralsArray> lit = | 4225 Handle<LiteralsArray> lit = |
4308 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED); | 4226 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED); |
4309 Handle<Context> context(isolate->context()); | 4227 Handle<Context> context(isolate->context()); |
4310 | 4228 |
4311 // Add the new code several times to the optimized code map and also set an | 4229 // Add the new code several times to the optimized code map and also set an |
4312 // allocation timeout so that expanding the code map will trigger a GC. | 4230 // allocation timeout so that expanding the code map will trigger a GC. |
4313 heap->set_allocation_timeout(5); | 4231 heap->set_allocation_timeout(5); |
4314 FLAG_gc_interval = 1000; | 4232 FLAG_gc_interval = 1000; |
4315 for (int i = 0; i < 10; ++i) { | 4233 for (int i = 0; i < 10; ++i) { |
4316 BailoutId id = BailoutId(i); | 4234 BailoutId id = BailoutId(i); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4353 CompileRun("function g() { return 2 }" | 4271 CompileRun("function g() { return 2 }" |
4354 "g(); %OptimizeFunctionOnNextCall(g); g();"); | 4272 "g(); %OptimizeFunctionOnNextCall(g); g();"); |
4355 | 4273 |
4356 Handle<JSFunction> g = Handle<JSFunction>::cast( | 4274 Handle<JSFunction> g = Handle<JSFunction>::cast( |
4357 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 4275 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
4358 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); | 4276 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); |
4359 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); | 4277 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); |
4360 if (!code->is_optimized_code()) return; | 4278 if (!code->is_optimized_code()) return; |
4361 } | 4279 } |
4362 | 4280 |
4363 Handle<TypeFeedbackVector> vector = handle(shared->feedback_vector()); | 4281 Handle<TypeFeedbackVector> vector = |
| 4282 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata())); |
4364 Handle<LiteralsArray> lit = | 4283 Handle<LiteralsArray> lit = |
4365 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED); | 4284 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED); |
4366 Handle<Context> context(isolate->context()); | 4285 Handle<Context> context(isolate->context()); |
4367 | 4286 |
4368 // Add the code several times to the optimized code map. | 4287 // Add the code several times to the optimized code map. |
4369 for (int i = 0; i < 3; ++i) { | 4288 for (int i = 0; i < 3; ++i) { |
4370 HandleScope inner_scope(isolate); | 4289 HandleScope inner_scope(isolate); |
4371 BailoutId id = BailoutId(i); | 4290 BailoutId id = BailoutId(i); |
4372 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); | 4291 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); |
4373 } | 4292 } |
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5058 weak_ic_cleared = false; | 4977 weak_ic_cleared = false; |
5059 garbage.SetWeak(&garbage, &ClearWeakIC, v8::WeakCallbackType::kParameter); | 4978 garbage.SetWeak(&garbage, &ClearWeakIC, v8::WeakCallbackType::kParameter); |
5060 Heap* heap = CcTest::i_isolate()->heap(); | 4979 Heap* heap = CcTest::i_isolate()->heap(); |
5061 heap->CollectAllGarbage(); | 4980 heap->CollectAllGarbage(); |
5062 CHECK(weak_ic_cleared); | 4981 CHECK(weak_ic_cleared); |
5063 | 4982 |
5064 // We've determined the constructor in createObj has had it's weak cell | 4983 // We've determined the constructor in createObj has had it's weak cell |
5065 // cleared. Now, verify that one additional call with a new function | 4984 // cleared. Now, verify that one additional call with a new function |
5066 // allows monomorphicity. | 4985 // allows monomorphicity. |
5067 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>( | 4986 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>( |
5068 createObj->shared()->feedback_vector(), CcTest::i_isolate()); | 4987 createObj->feedback_vector(), CcTest::i_isolate()); |
5069 for (int i = 0; i < 20; i++) { | 4988 for (int i = 0; i < 20; i++) { |
5070 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); | 4989 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); |
5071 CHECK(slot_value->IsWeakCell()); | 4990 CHECK(slot_value->IsWeakCell()); |
5072 if (WeakCell::cast(slot_value)->cleared()) break; | 4991 if (WeakCell::cast(slot_value)->cleared()) break; |
5073 heap->CollectAllGarbage(); | 4992 heap->CollectAllGarbage(); |
5074 } | 4993 } |
5075 | 4994 |
5076 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); | 4995 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); |
5077 CHECK(slot_value->IsWeakCell() && WeakCell::cast(slot_value)->cleared()); | 4996 CHECK(slot_value->IsWeakCell() && WeakCell::cast(slot_value)->cleared()); |
5078 CompileRun( | 4997 CompileRun( |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5259 } | 5178 } |
5260 | 5179 |
5261 | 5180 |
5262 Handle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) { | 5181 Handle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) { |
5263 Handle<String> str = isolate->factory()->InternalizeUtf8String(name); | 5182 Handle<String> str = isolate->factory()->InternalizeUtf8String(name); |
5264 Handle<Object> obj = | 5183 Handle<Object> obj = |
5265 Object::GetProperty(isolate->global_object(), str).ToHandleChecked(); | 5184 Object::GetProperty(isolate->global_object(), str).ToHandleChecked(); |
5266 return Handle<JSFunction>::cast(obj); | 5185 return Handle<JSFunction>::cast(obj); |
5267 } | 5186 } |
5268 | 5187 |
5269 | 5188 void CheckIC(Handle<JSFunction> function, Code::Kind kind, int slot_index, |
5270 void CheckIC(Code* code, Code::Kind kind, SharedFunctionInfo* shared, | 5189 InlineCacheState state) { |
5271 int slot_index, InlineCacheState state) { | |
5272 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC || | 5190 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC || |
5273 kind == Code::CALL_IC) { | 5191 kind == Code::CALL_IC) { |
5274 TypeFeedbackVector* vector = shared->feedback_vector(); | 5192 TypeFeedbackVector* vector = function->feedback_vector(); |
5275 FeedbackVectorSlot slot(slot_index); | 5193 FeedbackVectorSlot slot(slot_index); |
5276 if (kind == Code::LOAD_IC) { | 5194 if (kind == Code::LOAD_IC) { |
5277 LoadICNexus nexus(vector, slot); | 5195 LoadICNexus nexus(vector, slot); |
5278 CHECK_EQ(nexus.StateFromFeedback(), state); | 5196 CHECK_EQ(nexus.StateFromFeedback(), state); |
5279 } else if (kind == Code::KEYED_LOAD_IC) { | 5197 } else if (kind == Code::KEYED_LOAD_IC) { |
5280 KeyedLoadICNexus nexus(vector, slot); | 5198 KeyedLoadICNexus nexus(vector, slot); |
5281 CHECK_EQ(nexus.StateFromFeedback(), state); | 5199 CHECK_EQ(nexus.StateFromFeedback(), state); |
5282 } else if (kind == Code::CALL_IC) { | 5200 } else if (kind == Code::CALL_IC) { |
5283 CallICNexus nexus(vector, slot); | 5201 CallICNexus nexus(vector, slot); |
5284 CHECK_EQ(nexus.StateFromFeedback(), state); | 5202 CHECK_EQ(nexus.StateFromFeedback(), state); |
5285 } | 5203 } |
5286 } else { | 5204 } else { |
5287 Code* ic = FindFirstIC(code, kind); | 5205 Code* ic = FindFirstIC(function->code(), kind); |
5288 CHECK(ic->is_inline_cache_stub()); | 5206 CHECK(ic->is_inline_cache_stub()); |
5289 CHECK(ic->ic_state() == state); | 5207 CHECK(ic->ic_state() == state); |
5290 } | 5208 } |
5291 } | 5209 } |
5292 | 5210 |
5293 | 5211 |
5294 TEST(MonomorphicStaysMonomorphicAfterGC) { | 5212 TEST(MonomorphicStaysMonomorphicAfterGC) { |
5295 if (FLAG_always_opt) return; | 5213 if (FLAG_always_opt) return; |
5296 CcTest::InitializeVM(); | 5214 CcTest::InitializeVM(); |
5297 Isolate* isolate = CcTest::i_isolate(); | 5215 Isolate* isolate = CcTest::i_isolate(); |
(...skipping 10 matching lines...) Expand all Loading... |
5308 " loadIC(obj);" | 5226 " loadIC(obj);" |
5309 " loadIC(obj);" | 5227 " loadIC(obj);" |
5310 " return proto;" | 5228 " return proto;" |
5311 "};"); | 5229 "};"); |
5312 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC"); | 5230 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC"); |
5313 { | 5231 { |
5314 v8::HandleScope scope(CcTest::isolate()); | 5232 v8::HandleScope scope(CcTest::isolate()); |
5315 CompileRun("(testIC())"); | 5233 CompileRun("(testIC())"); |
5316 } | 5234 } |
5317 heap->CollectAllGarbage(); | 5235 heap->CollectAllGarbage(); |
5318 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC); | 5236 CheckIC(loadIC, Code::LOAD_IC, 0, MONOMORPHIC); |
5319 { | 5237 { |
5320 v8::HandleScope scope(CcTest::isolate()); | 5238 v8::HandleScope scope(CcTest::isolate()); |
5321 CompileRun("(testIC())"); | 5239 CompileRun("(testIC())"); |
5322 } | 5240 } |
5323 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC); | 5241 CheckIC(loadIC, Code::LOAD_IC, 0, MONOMORPHIC); |
5324 } | 5242 } |
5325 | 5243 |
5326 | 5244 |
5327 TEST(PolymorphicStaysPolymorphicAfterGC) { | 5245 TEST(PolymorphicStaysPolymorphicAfterGC) { |
5328 if (FLAG_always_opt) return; | 5246 if (FLAG_always_opt) return; |
5329 CcTest::InitializeVM(); | 5247 CcTest::InitializeVM(); |
5330 Isolate* isolate = CcTest::i_isolate(); | 5248 Isolate* isolate = CcTest::i_isolate(); |
5331 Heap* heap = isolate->heap(); | 5249 Heap* heap = isolate->heap(); |
5332 v8::HandleScope scope(CcTest::isolate()); | 5250 v8::HandleScope scope(CcTest::isolate()); |
5333 CompileRun( | 5251 CompileRun( |
(...skipping 10 matching lines...) Expand all Loading... |
5344 " poly.x = true;" | 5262 " poly.x = true;" |
5345 " loadIC(poly);" | 5263 " loadIC(poly);" |
5346 " return proto;" | 5264 " return proto;" |
5347 "};"); | 5265 "};"); |
5348 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC"); | 5266 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC"); |
5349 { | 5267 { |
5350 v8::HandleScope scope(CcTest::isolate()); | 5268 v8::HandleScope scope(CcTest::isolate()); |
5351 CompileRun("(testIC())"); | 5269 CompileRun("(testIC())"); |
5352 } | 5270 } |
5353 heap->CollectAllGarbage(); | 5271 heap->CollectAllGarbage(); |
5354 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC); | 5272 CheckIC(loadIC, Code::LOAD_IC, 0, POLYMORPHIC); |
5355 { | 5273 { |
5356 v8::HandleScope scope(CcTest::isolate()); | 5274 v8::HandleScope scope(CcTest::isolate()); |
5357 CompileRun("(testIC())"); | 5275 CompileRun("(testIC())"); |
5358 } | 5276 } |
5359 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC); | 5277 CheckIC(loadIC, Code::LOAD_IC, 0, POLYMORPHIC); |
5360 } | 5278 } |
5361 | 5279 |
5362 | 5280 |
5363 TEST(WeakCell) { | 5281 TEST(WeakCell) { |
5364 CcTest::InitializeVM(); | 5282 CcTest::InitializeVM(); |
5365 Isolate* isolate = CcTest::i_isolate(); | 5283 Isolate* isolate = CcTest::i_isolate(); |
5366 v8::internal::Heap* heap = CcTest::heap(); | 5284 v8::internal::Heap* heap = CcTest::heap(); |
5367 v8::internal::Factory* factory = isolate->factory(); | 5285 v8::internal::Factory* factory = isolate->factory(); |
5368 | 5286 |
5369 HandleScope outer_scope(isolate); | 5287 HandleScope outer_scope(isolate); |
(...skipping 1368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6738 // All objects need to be black after marking. If a white object crossed the | 6656 // All objects need to be black after marking. If a white object crossed the |
6739 // progress bar, we would fail here. | 6657 // progress bar, we would fail here. |
6740 for (int i = 0; i < arr.get()->length(); i++) { | 6658 for (int i = 0; i < arr.get()->length(); i++) { |
6741 CHECK(Marking::IsBlack( | 6659 CHECK(Marking::IsBlack( |
6742 Marking::MarkBitFrom(HeapObject::cast(arr.get()->get(i))))); | 6660 Marking::MarkBitFrom(HeapObject::cast(arr.get()->get(i))))); |
6743 } | 6661 } |
6744 } | 6662 } |
6745 | 6663 |
6746 } // namespace internal | 6664 } // namespace internal |
6747 } // namespace v8 | 6665 } // namespace v8 |
OLD | NEW |