Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: test/cctest/heap/test-heap.cc

Issue 1906823002: Move of the type feedback vector to the closure. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698