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

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

Issue 1563213002: Type Feedback Vector lives in the closure (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Ports. Created 4 years, 11 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 3601 matching lines...) Expand 10 before | Expand all | Expand 10 after
3612 3612
3613 // Prepare function f that contains type feedback for the two closures. 3613 // Prepare function f that contains type feedback for the two closures.
3614 CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust()); 3614 CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust());
3615 CHECK(CcTest::global()->Set(ctx, v8_str("fun2"), fun2).FromJust()); 3615 CHECK(CcTest::global()->Set(ctx, v8_str("fun2"), fun2).FromJust());
3616 CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);"); 3616 CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);");
3617 3617
3618 Handle<JSFunction> f = Handle<JSFunction>::cast( 3618 Handle<JSFunction> f = Handle<JSFunction>::cast(
3619 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 3619 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
3620 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); 3620 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
3621 3621
3622 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); 3622 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector());
3623 FeedbackVectorHelper feedback_helper(feedback_vector); 3623 FeedbackVectorHelper feedback_helper(feedback_vector);
3624 3624
3625 int expected_slots = 2; 3625 int expected_slots = 2;
3626 CHECK_EQ(expected_slots, feedback_helper.slot_count()); 3626 CHECK_EQ(expected_slots, feedback_helper.slot_count());
3627 int slot1 = 0; 3627 int slot1 = 0;
3628 int slot2 = 1; 3628 int slot2 = 1;
3629 CHECK(feedback_vector->Get(feedback_helper.slot(slot1))->IsWeakCell()); 3629 CHECK(feedback_vector->Get(feedback_helper.slot(slot1))->IsWeakCell());
3630 CHECK(feedback_vector->Get(feedback_helper.slot(slot2))->IsWeakCell()); 3630 CHECK(feedback_vector->Get(feedback_helper.slot(slot2))->IsWeakCell());
3631 3631
3632 SimulateIncrementalMarking(CcTest::heap()); 3632 SimulateIncrementalMarking(CcTest::heap());
(...skipping 16 matching lines...) Expand all
3649 return target; 3649 return target;
3650 } 3650 }
3651 } 3651 }
3652 return NULL; 3652 return NULL;
3653 } 3653 }
3654 3654
3655 3655
3656 static void CheckVectorIC(Handle<JSFunction> f, int slot_index, 3656 static void CheckVectorIC(Handle<JSFunction> f, int slot_index,
3657 InlineCacheState desired_state) { 3657 InlineCacheState desired_state) {
3658 Handle<TypeFeedbackVector> vector = 3658 Handle<TypeFeedbackVector> vector =
3659 Handle<TypeFeedbackVector>(f->shared()->feedback_vector()); 3659 Handle<TypeFeedbackVector>(f->feedback_vector());
3660 FeedbackVectorHelper helper(vector); 3660 FeedbackVectorHelper helper(vector);
3661 FeedbackVectorSlot slot = helper.slot(slot_index); 3661 FeedbackVectorSlot slot = helper.slot(slot_index);
3662 if (vector->GetKind(slot) == FeedbackVectorSlotKind::LOAD_IC) { 3662 if (vector->GetKind(slot) == FeedbackVectorSlotKind::LOAD_IC) {
3663 LoadICNexus nexus(vector, slot); 3663 LoadICNexus nexus(vector, slot);
3664 CHECK(nexus.StateFromFeedback() == desired_state); 3664 CHECK(nexus.StateFromFeedback() == desired_state);
3665 } else { 3665 } else {
3666 CHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot)); 3666 CHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
3667 KeyedLoadICNexus nexus(vector, slot); 3667 KeyedLoadICNexus nexus(vector, slot);
3668 CHECK(nexus.StateFromFeedback() == desired_state); 3668 CHECK(nexus.StateFromFeedback() == desired_state);
3669 } 3669 }
3670 } 3670 }
3671 3671
3672 3672
3673 static void CheckVectorICCleared(Handle<JSFunction> f, int slot_index) {
3674 Handle<TypeFeedbackVector> vector =
3675 Handle<TypeFeedbackVector>(f->shared()->feedback_vector());
3676 FeedbackVectorSlot slot(slot_index);
3677 LoadICNexus nexus(vector, slot);
3678 CHECK(IC::IsCleared(&nexus));
3679 }
3680
3681
3682 TEST(IncrementalMarkingPreservesMonomorphicConstructor) { 3673 TEST(IncrementalMarkingPreservesMonomorphicConstructor) {
3683 if (i::FLAG_always_opt) return; 3674 if (i::FLAG_always_opt) return;
3684 CcTest::InitializeVM(); 3675 CcTest::InitializeVM();
3685 v8::HandleScope scope(CcTest::isolate()); 3676 v8::HandleScope scope(CcTest::isolate());
3686 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); 3677 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
3687 // Prepare function f that contains a monomorphic IC for object 3678 // Prepare function f that contains a monomorphic IC for object
3688 // originating from the same native context. 3679 // originating from the same native context.
3689 CompileRun( 3680 CompileRun(
3690 "function fun() { this.x = 1; };" 3681 "function fun() { this.x = 1; };"
3691 "function f(o) { return new o(); } f(fun); f(fun);"); 3682 "function f(o) { return new o(); } f(fun); f(fun);");
3692 Handle<JSFunction> f = Handle<JSFunction>::cast( 3683 Handle<JSFunction> f = Handle<JSFunction>::cast(
3693 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 3684 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
3694 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); 3685 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
3695 3686
3696 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector()); 3687 Handle<TypeFeedbackVector> vector(f->feedback_vector());
3697 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); 3688 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell());
3698 3689
3699 SimulateIncrementalMarking(CcTest::heap()); 3690 SimulateIncrementalMarking(CcTest::heap());
3700 CcTest::heap()->CollectAllGarbage(); 3691 CcTest::heap()->CollectAllGarbage();
3701 3692
3702 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); 3693 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell());
3703 } 3694 }
3704 3695
3705 3696
3706 TEST(IncrementalMarkingClearsMonomorphicConstructor) {
3707 if (i::FLAG_always_opt) return;
3708 CcTest::InitializeVM();
3709 Isolate* isolate = CcTest::i_isolate();
3710 v8::HandleScope scope(CcTest::isolate());
3711 v8::Local<v8::Value> fun1;
3712 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
3713
3714 {
3715 LocalContext env;
3716 CompileRun("function fun() { this.x = 1; };");
3717 fun1 = env->Global()->Get(env.local(), v8_str("fun")).ToLocalChecked();
3718 }
3719
3720 // Prepare function f that contains a monomorphic constructor for object
3721 // originating from a different native context.
3722 CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust());
3723 CompileRun(
3724 "function fun() { this.x = 1; };"
3725 "function f(o) { return new o(); } f(fun1); f(fun1);");
3726 Handle<JSFunction> f = Handle<JSFunction>::cast(
3727 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
3728 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
3729
3730
3731 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector());
3732 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell());
3733
3734 // Fire context dispose notification.
3735 CcTest::isolate()->ContextDisposedNotification();
3736 SimulateIncrementalMarking(CcTest::heap());
3737 CcTest::heap()->CollectAllGarbage();
3738
3739 CHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(isolate),
3740 vector->Get(FeedbackVectorSlot(0)));
3741 }
3742
3743
3744 TEST(IncrementalMarkingPreservesMonomorphicIC) { 3697 TEST(IncrementalMarkingPreservesMonomorphicIC) {
3745 if (i::FLAG_always_opt) return; 3698 if (i::FLAG_always_opt) return;
3746 CcTest::InitializeVM(); 3699 CcTest::InitializeVM();
3747 v8::HandleScope scope(CcTest::isolate()); 3700 v8::HandleScope scope(CcTest::isolate());
3748 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); 3701 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
3749 // Prepare function f that contains a monomorphic IC for object 3702 // Prepare function f that contains a monomorphic IC for object
3750 // originating from the same native context. 3703 // originating from the same native context.
3751 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" 3704 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"
3752 "function f(o) { return o.x; } f(obj); f(obj);"); 3705 "function f(o) { return o.x; } f(obj); f(obj);");
3753 Handle<JSFunction> f = Handle<JSFunction>::cast( 3706 Handle<JSFunction> f = Handle<JSFunction>::cast(
3754 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 3707 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
3755 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); 3708 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
3756 3709
3757 CheckVectorIC(f, 0, MONOMORPHIC); 3710 CheckVectorIC(f, 0, MONOMORPHIC);
3758 3711
3759 SimulateIncrementalMarking(CcTest::heap()); 3712 SimulateIncrementalMarking(CcTest::heap());
3760 CcTest::heap()->CollectAllGarbage(); 3713 CcTest::heap()->CollectAllGarbage();
3761 3714
3762 CheckVectorIC(f, 0, MONOMORPHIC); 3715 CheckVectorIC(f, 0, MONOMORPHIC);
3763 } 3716 }
3764 3717
3765 3718
3766 TEST(IncrementalMarkingClearsMonomorphicIC) {
3767 if (i::FLAG_always_opt) return;
3768 CcTest::InitializeVM();
3769 v8::HandleScope scope(CcTest::isolate());
3770 v8::Local<v8::Value> obj1;
3771 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
3772
3773 {
3774 LocalContext env;
3775 CompileRun("function fun() { this.x = 1; }; var obj = new fun();");
3776 obj1 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked();
3777 }
3778
3779 // Prepare function f that contains a monomorphic IC for object
3780 // originating from a different native context.
3781 CHECK(CcTest::global()->Set(ctx, v8_str("obj1"), obj1).FromJust());
3782 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1);");
3783 Handle<JSFunction> f = Handle<JSFunction>::cast(
3784 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
3785 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
3786
3787 CheckVectorIC(f, 0, MONOMORPHIC);
3788
3789 // Fire context dispose notification.
3790 CcTest::isolate()->ContextDisposedNotification();
3791 SimulateIncrementalMarking(CcTest::heap());
3792 CcTest::heap()->CollectAllGarbage();
3793
3794 CheckVectorICCleared(f, 0);
3795 }
3796
3797
3798 TEST(IncrementalMarkingPreservesPolymorphicIC) { 3719 TEST(IncrementalMarkingPreservesPolymorphicIC) {
3799 if (i::FLAG_always_opt) return; 3720 if (i::FLAG_always_opt) return;
3800 CcTest::InitializeVM(); 3721 CcTest::InitializeVM();
3801 v8::HandleScope scope(CcTest::isolate()); 3722 v8::HandleScope scope(CcTest::isolate());
3802 v8::Local<v8::Value> obj1, obj2; 3723 v8::Local<v8::Value> obj1, obj2;
3803 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); 3724 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
3804 3725
3805 { 3726 {
3806 LocalContext env; 3727 LocalContext env;
3807 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); 3728 CompileRun("function fun() { this.x = 1; }; var obj = new fun();");
(...skipping 18 matching lines...) Expand all
3826 CheckVectorIC(f, 0, POLYMORPHIC); 3747 CheckVectorIC(f, 0, POLYMORPHIC);
3827 3748
3828 // Fire context dispose notification. 3749 // Fire context dispose notification.
3829 SimulateIncrementalMarking(CcTest::heap()); 3750 SimulateIncrementalMarking(CcTest::heap());
3830 CcTest::heap()->CollectAllGarbage(); 3751 CcTest::heap()->CollectAllGarbage();
3831 3752
3832 CheckVectorIC(f, 0, POLYMORPHIC); 3753 CheckVectorIC(f, 0, POLYMORPHIC);
3833 } 3754 }
3834 3755
3835 3756
3836 TEST(IncrementalMarkingClearsPolymorphicIC) { 3757 TEST(ContextDisposeDoesntClearPolymorphicIC) {
3837 if (i::FLAG_always_opt) return; 3758 if (i::FLAG_always_opt) return;
3838 CcTest::InitializeVM(); 3759 CcTest::InitializeVM();
3839 v8::HandleScope scope(CcTest::isolate()); 3760 v8::HandleScope scope(CcTest::isolate());
3840 v8::Local<v8::Value> obj1, obj2; 3761 v8::Local<v8::Value> obj1, obj2;
3841 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); 3762 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
3842 3763
3843 { 3764 {
3844 LocalContext env; 3765 LocalContext env;
3845 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); 3766 CompileRun("function fun() { this.x = 1; }; var obj = new fun();");
3846 obj1 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); 3767 obj1 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked();
(...skipping 14 matching lines...) Expand all
3861 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 3782 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
3862 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); 3783 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
3863 3784
3864 CheckVectorIC(f, 0, POLYMORPHIC); 3785 CheckVectorIC(f, 0, POLYMORPHIC);
3865 3786
3866 // Fire context dispose notification. 3787 // Fire context dispose notification.
3867 CcTest::isolate()->ContextDisposedNotification(); 3788 CcTest::isolate()->ContextDisposedNotification();
3868 SimulateIncrementalMarking(CcTest::heap()); 3789 SimulateIncrementalMarking(CcTest::heap());
3869 CcTest::heap()->CollectAllGarbage(); 3790 CcTest::heap()->CollectAllGarbage();
3870 3791
3871 CheckVectorICCleared(f, 0); 3792 CheckVectorIC(f, 0, POLYMORPHIC);
3872 } 3793 }
3873 3794
3874 3795
3875 class SourceResource : public v8::String::ExternalOneByteStringResource { 3796 class SourceResource : public v8::String::ExternalOneByteStringResource {
3876 public: 3797 public:
3877 explicit SourceResource(const char* data) 3798 explicit SourceResource(const char* data)
3878 : data_(data), length_(strlen(data)) { } 3799 : data_(data), length_(strlen(data)) { }
3879 3800
3880 virtual void Dispose() { 3801 virtual void Dispose() {
3881 i::DeleteArray(data_); 3802 i::DeleteArray(data_);
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
4277 CompileRun("function g() { return 2 }" 4198 CompileRun("function g() { return 2 }"
4278 "g(); %OptimizeFunctionOnNextCall(g); g();"); 4199 "g(); %OptimizeFunctionOnNextCall(g); g();");
4279 4200
4280 Handle<JSFunction> g = Handle<JSFunction>::cast( 4201 Handle<JSFunction> g = Handle<JSFunction>::cast(
4281 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 4202 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
4282 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); 4203 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked())));
4283 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); 4204 code = inner_scope.CloseAndEscape(handle(g->code(), isolate));
4284 if (!code->is_optimized_code()) return; 4205 if (!code->is_optimized_code()) return;
4285 } 4206 }
4286 4207
4287 Handle<TypeFeedbackVector> vector = handle(shared->feedback_vector()); 4208 Handle<TypeFeedbackVector> vector =
4209 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
4288 Handle<LiteralsArray> lit = 4210 Handle<LiteralsArray> lit =
4289 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED); 4211 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED);
4290 Handle<Context> context(isolate->context()); 4212 Handle<Context> context(isolate->context());
4291 4213
4292 // Add the new code several times to the optimized code map and also set an 4214 // Add the new code several times to the optimized code map and also set an
4293 // allocation timeout so that expanding the code map will trigger a GC. 4215 // allocation timeout so that expanding the code map will trigger a GC.
4294 heap->set_allocation_timeout(5); 4216 heap->set_allocation_timeout(5);
4295 FLAG_gc_interval = 1000; 4217 FLAG_gc_interval = 1000;
4296 for (int i = 0; i < 10; ++i) { 4218 for (int i = 0; i < 10; ++i) {
4297 BailoutId id = BailoutId(i); 4219 BailoutId id = BailoutId(i);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
4334 CompileRun("function g() { return 2 }" 4256 CompileRun("function g() { return 2 }"
4335 "g(); %OptimizeFunctionOnNextCall(g); g();"); 4257 "g(); %OptimizeFunctionOnNextCall(g); g();");
4336 4258
4337 Handle<JSFunction> g = Handle<JSFunction>::cast( 4259 Handle<JSFunction> g = Handle<JSFunction>::cast(
4338 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 4260 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
4339 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); 4261 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked())));
4340 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); 4262 code = inner_scope.CloseAndEscape(handle(g->code(), isolate));
4341 if (!code->is_optimized_code()) return; 4263 if (!code->is_optimized_code()) return;
4342 } 4264 }
4343 4265
4344 Handle<TypeFeedbackVector> vector = handle(shared->feedback_vector()); 4266 Handle<TypeFeedbackVector> vector =
4267 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
4345 Handle<LiteralsArray> lit = 4268 Handle<LiteralsArray> lit =
4346 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED); 4269 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED);
4347 Handle<Context> context(isolate->context()); 4270 Handle<Context> context(isolate->context());
4348 4271
4349 // Add the code several times to the optimized code map. 4272 // Add the code several times to the optimized code map.
4350 for (int i = 0; i < 3; ++i) { 4273 for (int i = 0; i < 3; ++i) {
4351 HandleScope inner_scope(isolate); 4274 HandleScope inner_scope(isolate);
4352 BailoutId id = BailoutId(i); 4275 BailoutId id = BailoutId(i);
4353 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); 4276 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id);
4354 } 4277 }
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
5038 weak_ic_cleared = false; 4961 weak_ic_cleared = false;
5039 garbage.SetWeak(&garbage, &ClearWeakIC, v8::WeakCallbackType::kParameter); 4962 garbage.SetWeak(&garbage, &ClearWeakIC, v8::WeakCallbackType::kParameter);
5040 Heap* heap = CcTest::i_isolate()->heap(); 4963 Heap* heap = CcTest::i_isolate()->heap();
5041 heap->CollectAllGarbage(); 4964 heap->CollectAllGarbage();
5042 CHECK(weak_ic_cleared); 4965 CHECK(weak_ic_cleared);
5043 4966
5044 // We've determined the constructor in createObj has had it's weak cell 4967 // We've determined the constructor in createObj has had it's weak cell
5045 // cleared. Now, verify that one additional call with a new function 4968 // cleared. Now, verify that one additional call with a new function
5046 // allows monomorphicity. 4969 // allows monomorphicity.
5047 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>( 4970 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>(
5048 createObj->shared()->feedback_vector(), CcTest::i_isolate()); 4971 createObj->feedback_vector(), CcTest::i_isolate());
5049 for (int i = 0; i < 20; i++) { 4972 for (int i = 0; i < 20; i++) {
5050 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); 4973 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0));
5051 CHECK(slot_value->IsWeakCell()); 4974 CHECK(slot_value->IsWeakCell());
5052 if (WeakCell::cast(slot_value)->cleared()) break; 4975 if (WeakCell::cast(slot_value)->cleared()) break;
5053 heap->CollectAllGarbage(); 4976 heap->CollectAllGarbage();
5054 } 4977 }
5055 4978
5056 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); 4979 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0));
5057 CHECK(slot_value->IsWeakCell() && WeakCell::cast(slot_value)->cleared()); 4980 CHECK(slot_value->IsWeakCell() && WeakCell::cast(slot_value)->cleared());
5058 CompileRun( 4981 CompileRun(
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
5240 5163
5241 5164
5242 Handle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) { 5165 Handle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) {
5243 Handle<String> str = isolate->factory()->InternalizeUtf8String(name); 5166 Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
5244 Handle<Object> obj = 5167 Handle<Object> obj =
5245 Object::GetProperty(isolate->global_object(), str).ToHandleChecked(); 5168 Object::GetProperty(isolate->global_object(), str).ToHandleChecked();
5246 return Handle<JSFunction>::cast(obj); 5169 return Handle<JSFunction>::cast(obj);
5247 } 5170 }
5248 5171
5249 5172
5250 void CheckIC(Code* code, Code::Kind kind, SharedFunctionInfo* shared, 5173 void CheckIC(Handle<JSFunction> function, Code::Kind kind, int slot_index,
5251 int slot_index, InlineCacheState state) { 5174 InlineCacheState state) {
5252 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC || 5175 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC ||
5253 kind == Code::CALL_IC) { 5176 kind == Code::CALL_IC) {
5254 TypeFeedbackVector* vector = shared->feedback_vector(); 5177 TypeFeedbackVector* vector = function->feedback_vector();
5255 FeedbackVectorSlot slot(slot_index); 5178 FeedbackVectorSlot slot(slot_index);
5256 if (kind == Code::LOAD_IC) { 5179 if (kind == Code::LOAD_IC) {
5257 LoadICNexus nexus(vector, slot); 5180 LoadICNexus nexus(vector, slot);
5258 CHECK_EQ(nexus.StateFromFeedback(), state); 5181 CHECK_EQ(nexus.StateFromFeedback(), state);
5259 } else if (kind == Code::KEYED_LOAD_IC) { 5182 } else if (kind == Code::KEYED_LOAD_IC) {
5260 KeyedLoadICNexus nexus(vector, slot); 5183 KeyedLoadICNexus nexus(vector, slot);
5261 CHECK_EQ(nexus.StateFromFeedback(), state); 5184 CHECK_EQ(nexus.StateFromFeedback(), state);
5262 } else if (kind == Code::CALL_IC) { 5185 } else if (kind == Code::CALL_IC) {
5263 CallICNexus nexus(vector, slot); 5186 CallICNexus nexus(vector, slot);
5264 CHECK_EQ(nexus.StateFromFeedback(), state); 5187 CHECK_EQ(nexus.StateFromFeedback(), state);
5265 } 5188 }
5266 } else { 5189 } else {
5267 Code* ic = FindFirstIC(code, kind); 5190 Code* ic = FindFirstIC(function->code(), kind);
5268 CHECK(ic->is_inline_cache_stub()); 5191 CHECK(ic->is_inline_cache_stub());
5269 CHECK(ic->ic_state() == state); 5192 CHECK(ic->ic_state() == state);
5270 } 5193 }
5271 } 5194 }
5272 5195
5273 5196
5274 TEST(MonomorphicStaysMonomorphicAfterGC) { 5197 TEST(MonomorphicStaysMonomorphicAfterGC) {
5275 if (FLAG_always_opt) return; 5198 if (FLAG_always_opt) return;
5276 CcTest::InitializeVM(); 5199 CcTest::InitializeVM();
5277 Isolate* isolate = CcTest::i_isolate(); 5200 Isolate* isolate = CcTest::i_isolate();
(...skipping 10 matching lines...) Expand all
5288 " loadIC(obj);" 5211 " loadIC(obj);"
5289 " loadIC(obj);" 5212 " loadIC(obj);"
5290 " return proto;" 5213 " return proto;"
5291 "};"); 5214 "};");
5292 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC"); 5215 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC");
5293 { 5216 {
5294 v8::HandleScope scope(CcTest::isolate()); 5217 v8::HandleScope scope(CcTest::isolate());
5295 CompileRun("(testIC())"); 5218 CompileRun("(testIC())");
5296 } 5219 }
5297 heap->CollectAllGarbage(); 5220 heap->CollectAllGarbage();
5298 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC); 5221 CheckIC(loadIC, Code::LOAD_IC, 0, MONOMORPHIC);
5299 { 5222 {
5300 v8::HandleScope scope(CcTest::isolate()); 5223 v8::HandleScope scope(CcTest::isolate());
5301 CompileRun("(testIC())"); 5224 CompileRun("(testIC())");
5302 } 5225 }
5303 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC); 5226 CheckIC(loadIC, Code::LOAD_IC, 0, MONOMORPHIC);
5304 } 5227 }
5305 5228
5306 5229
5307 TEST(PolymorphicStaysPolymorphicAfterGC) { 5230 TEST(PolymorphicStaysPolymorphicAfterGC) {
5308 if (FLAG_always_opt) return; 5231 if (FLAG_always_opt) return;
5309 CcTest::InitializeVM(); 5232 CcTest::InitializeVM();
5310 Isolate* isolate = CcTest::i_isolate(); 5233 Isolate* isolate = CcTest::i_isolate();
5311 Heap* heap = isolate->heap(); 5234 Heap* heap = isolate->heap();
5312 v8::HandleScope scope(CcTest::isolate()); 5235 v8::HandleScope scope(CcTest::isolate());
5313 CompileRun( 5236 CompileRun(
(...skipping 10 matching lines...) Expand all
5324 " poly.x = true;" 5247 " poly.x = true;"
5325 " loadIC(poly);" 5248 " loadIC(poly);"
5326 " return proto;" 5249 " return proto;"
5327 "};"); 5250 "};");
5328 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC"); 5251 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC");
5329 { 5252 {
5330 v8::HandleScope scope(CcTest::isolate()); 5253 v8::HandleScope scope(CcTest::isolate());
5331 CompileRun("(testIC())"); 5254 CompileRun("(testIC())");
5332 } 5255 }
5333 heap->CollectAllGarbage(); 5256 heap->CollectAllGarbage();
5334 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC); 5257 CheckIC(loadIC, Code::LOAD_IC, 0, POLYMORPHIC);
5335 { 5258 {
5336 v8::HandleScope scope(CcTest::isolate()); 5259 v8::HandleScope scope(CcTest::isolate());
5337 CompileRun("(testIC())"); 5260 CompileRun("(testIC())");
5338 } 5261 }
5339 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC); 5262 CheckIC(loadIC, Code::LOAD_IC, 0, POLYMORPHIC);
5340 } 5263 }
5341 5264
5342 5265
5343 TEST(WeakCell) { 5266 TEST(WeakCell) {
5344 CcTest::InitializeVM(); 5267 CcTest::InitializeVM();
5345 Isolate* isolate = CcTest::i_isolate(); 5268 Isolate* isolate = CcTest::i_isolate();
5346 v8::internal::Heap* heap = CcTest::heap(); 5269 v8::internal::Heap* heap = CcTest::heap();
5347 v8::internal::Factory* factory = isolate->factory(); 5270 v8::internal::Factory* factory = isolate->factory();
5348 5271
5349 HandleScope outer_scope(isolate); 5272 HandleScope outer_scope(isolate);
(...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after
6458 isolate->IncrementJsCallsFromApiCounter(); 6381 isolate->IncrementJsCallsFromApiCounter();
6459 isolate->IncrementJsCallsFromApiCounter(); 6382 isolate->IncrementJsCallsFromApiCounter();
6460 isolate->IncrementJsCallsFromApiCounter(); 6383 isolate->IncrementJsCallsFromApiCounter();
6461 calls_per_ms = memory_reducer->SampleAndGetJsCallsPerMs(4); 6384 calls_per_ms = memory_reducer->SampleAndGetJsCallsPerMs(4);
6462 CheckDoubleEquals(2, calls_per_ms); 6385 CheckDoubleEquals(2, calls_per_ms);
6463 } 6386 }
6464 6387
6465 6388
6466 } // namespace internal 6389 } // namespace internal
6467 } // namespace v8 6390 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698