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

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

Issue 1668103002: Type Feedback Vector lives in the closure (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Created 4 years, 10 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
« no previous file with comments | « test/cctest/compiler/test-run-jscalls.cc ('k') | test/cctest/interpreter/test-interpreter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after
1509 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();"); 1509 CompileRun("%OptimizeFunctionOnNextCall(foo); foo();");
1510 } 1510 }
1511 1511
1512 // Simulate one final GC to make sure the candidate queue is sane. 1512 // Simulate one final GC to make sure the candidate queue is sane.
1513 heap->CollectAllGarbage(); 1513 heap->CollectAllGarbage();
1514 CHECK(function->shared()->is_compiled() || !function->IsOptimized()); 1514 CHECK(function->shared()->is_compiled() || !function->IsOptimized());
1515 CHECK(function->is_compiled() || !function->IsOptimized()); 1515 CHECK(function->is_compiled() || !function->IsOptimized());
1516 } 1516 }
1517 1517
1518 TEST(TestUseOfIncrementalBarrierOnCompileLazy) { 1518 TEST(TestUseOfIncrementalBarrierOnCompileLazy) {
1519 // This test requires us to run the CompileLazy builtin, which won't be run
1520 // when the interpreter is used.
1521 if (i::FLAG_ignition) return;
1519 // Turn off always_opt because it interferes with running the built-in for 1522 // Turn off always_opt because it interferes with running the built-in for
1520 // the last call to g(). 1523 // the last call to g().
1521 i::FLAG_always_opt = false; 1524 i::FLAG_always_opt = false;
1522 i::FLAG_allow_natives_syntax = true; 1525 i::FLAG_allow_natives_syntax = true;
1523 CcTest::InitializeVM(); 1526 CcTest::InitializeVM();
1524 Isolate* isolate = CcTest::i_isolate(); 1527 Isolate* isolate = CcTest::i_isolate();
1525 Factory* factory = isolate->factory(); 1528 Factory* factory = isolate->factory();
1526 Heap* heap = isolate->heap(); 1529 Heap* heap = isolate->heap();
1527 v8::HandleScope scope(CcTest::isolate()); 1530 v8::HandleScope scope(CcTest::isolate());
1528 1531
1529 CompileRun( 1532 CompileRun(
1530 "function make_closure(x) {" 1533 "function make_closure(x) {"
1531 " return function() { return x + 3 };" 1534 " return function() { return x + 3 };"
1532 "}" 1535 "}"
1533 "var f = make_closure(5); f();" 1536 "var f = make_closure(5); f();"
1534 "var g = make_closure(5);"); 1537 "var g = make_closure(5);");
1535 1538
1536 // Check f is compiled. 1539 // Check f is compiled.
1537 Handle<String> f_name = factory->InternalizeUtf8String("f"); 1540 Handle<String> f_name = factory->InternalizeUtf8String("f");
1538 Handle<Object> f_value = 1541 Handle<Object> f_value =
1539 Object::GetProperty(isolate->global_object(), f_name).ToHandleChecked(); 1542 Object::GetProperty(isolate->global_object(), f_name).ToHandleChecked();
1540 Handle<JSFunction> f_function = Handle<JSFunction>::cast(f_value); 1543 Handle<JSFunction> f_function = Handle<JSFunction>::cast(f_value);
1541 CHECK(f_function->is_compiled()); 1544 CHECK(f_function->is_compiled());
1542 1545
1543 // Check g is not compiled. 1546 // Check g is not compiled.
1544 Handle<String> g_name = factory->InternalizeUtf8String("g"); 1547 Handle<String> g_name = factory->InternalizeUtf8String("g");
1545 Handle<Object> g_value = 1548 Handle<Object> g_value =
1546 Object::GetProperty(isolate->global_object(), g_name).ToHandleChecked(); 1549 Object::GetProperty(isolate->global_object(), g_name).ToHandleChecked();
1547 Handle<JSFunction> g_function = Handle<JSFunction>::cast(g_value); 1550 Handle<JSFunction> g_function = Handle<JSFunction>::cast(g_value);
1548 // TODO(mvstanton): change to check that g is *not* compiled when optimized 1551 CHECK(!g_function->is_compiled());
1549 // cache
1550 // map lookup moves to the compile lazy builtin.
1551 CHECK(g_function->is_compiled());
1552 1552
1553 SimulateIncrementalMarking(heap); 1553 SimulateIncrementalMarking(heap);
1554 CompileRun("%OptimizeFunctionOnNextCall(f); f();"); 1554 CompileRun("%OptimizeFunctionOnNextCall(f); f();");
1555 1555
1556 // g should now have available an optimized function, unmarked by gc. The 1556 // g should now have available an optimized function, unmarked by gc. The
1557 // CompileLazy built-in will discover it and install it in the closure, and 1557 // CompileLazy built-in will discover it and install it in the closure, and
1558 // the incremental write barrier should be used. 1558 // the incremental write barrier should be used.
1559 CompileRun("g();"); 1559 CompileRun("g();");
1560 CHECK(g_function->is_compiled()); 1560 CHECK(g_function->is_compiled());
1561 } 1561 }
(...skipping 2109 matching lines...) Expand 10 before | Expand all | Expand 10 after
3671 3671
3672 // Prepare function f that contains type feedback for the two closures. 3672 // Prepare function f that contains type feedback for the two closures.
3673 CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust()); 3673 CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust());
3674 CHECK(CcTest::global()->Set(ctx, v8_str("fun2"), fun2).FromJust()); 3674 CHECK(CcTest::global()->Set(ctx, v8_str("fun2"), fun2).FromJust());
3675 CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);"); 3675 CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);");
3676 3676
3677 Handle<JSFunction> f = Handle<JSFunction>::cast( 3677 Handle<JSFunction> f = Handle<JSFunction>::cast(
3678 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 3678 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
3679 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); 3679 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
3680 3680
3681 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); 3681 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector());
3682 FeedbackVectorHelper feedback_helper(feedback_vector); 3682 FeedbackVectorHelper feedback_helper(feedback_vector);
3683 3683
3684 int expected_slots = 2; 3684 int expected_slots = 2;
3685 CHECK_EQ(expected_slots, feedback_helper.slot_count()); 3685 CHECK_EQ(expected_slots, feedback_helper.slot_count());
3686 int slot1 = 0; 3686 int slot1 = 0;
3687 int slot2 = 1; 3687 int slot2 = 1;
3688 CHECK(feedback_vector->Get(feedback_helper.slot(slot1))->IsWeakCell()); 3688 CHECK(feedback_vector->Get(feedback_helper.slot(slot1))->IsWeakCell());
3689 CHECK(feedback_vector->Get(feedback_helper.slot(slot2))->IsWeakCell()); 3689 CHECK(feedback_vector->Get(feedback_helper.slot(slot2))->IsWeakCell());
3690 3690
3691 SimulateIncrementalMarking(CcTest::heap()); 3691 SimulateIncrementalMarking(CcTest::heap());
(...skipping 16 matching lines...) Expand all
3708 return target; 3708 return target;
3709 } 3709 }
3710 } 3710 }
3711 return NULL; 3711 return NULL;
3712 } 3712 }
3713 3713
3714 3714
3715 static void CheckVectorIC(Handle<JSFunction> f, int slot_index, 3715 static void CheckVectorIC(Handle<JSFunction> f, int slot_index,
3716 InlineCacheState desired_state) { 3716 InlineCacheState desired_state) {
3717 Handle<TypeFeedbackVector> vector = 3717 Handle<TypeFeedbackVector> vector =
3718 Handle<TypeFeedbackVector>(f->shared()->feedback_vector()); 3718 Handle<TypeFeedbackVector>(f->feedback_vector());
3719 FeedbackVectorHelper helper(vector); 3719 FeedbackVectorHelper helper(vector);
3720 FeedbackVectorSlot slot = helper.slot(slot_index); 3720 FeedbackVectorSlot slot = helper.slot(slot_index);
3721 if (vector->GetKind(slot) == FeedbackVectorSlotKind::LOAD_IC) { 3721 if (vector->GetKind(slot) == FeedbackVectorSlotKind::LOAD_IC) {
3722 LoadICNexus nexus(vector, slot); 3722 LoadICNexus nexus(vector, slot);
3723 CHECK(nexus.StateFromFeedback() == desired_state); 3723 CHECK(nexus.StateFromFeedback() == desired_state);
3724 } else { 3724 } else {
3725 CHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot)); 3725 CHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
3726 KeyedLoadICNexus nexus(vector, slot); 3726 KeyedLoadICNexus nexus(vector, slot);
3727 CHECK(nexus.StateFromFeedback() == desired_state); 3727 CHECK(nexus.StateFromFeedback() == desired_state);
3728 } 3728 }
3729 } 3729 }
3730 3730
3731 3731
3732 static void CheckVectorICCleared(Handle<JSFunction> f, int slot_index) {
3733 Handle<TypeFeedbackVector> vector =
3734 Handle<TypeFeedbackVector>(f->shared()->feedback_vector());
3735 FeedbackVectorSlot slot(slot_index);
3736 LoadICNexus nexus(vector, slot);
3737 CHECK(IC::IsCleared(&nexus));
3738 }
3739
3740
3741 TEST(IncrementalMarkingPreservesMonomorphicConstructor) { 3732 TEST(IncrementalMarkingPreservesMonomorphicConstructor) {
3742 if (i::FLAG_always_opt) return; 3733 if (i::FLAG_always_opt) return;
3743 CcTest::InitializeVM(); 3734 CcTest::InitializeVM();
3744 v8::HandleScope scope(CcTest::isolate()); 3735 v8::HandleScope scope(CcTest::isolate());
3745 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); 3736 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
3746 // Prepare function f that contains a monomorphic IC for object 3737 // Prepare function f that contains a monomorphic IC for object
3747 // originating from the same native context. 3738 // originating from the same native context.
3748 CompileRun( 3739 CompileRun(
3749 "function fun() { this.x = 1; };" 3740 "function fun() { this.x = 1; };"
3750 "function f(o) { return new o(); } f(fun); f(fun);"); 3741 "function f(o) { return new o(); } f(fun); f(fun);");
3751 Handle<JSFunction> f = Handle<JSFunction>::cast( 3742 Handle<JSFunction> f = Handle<JSFunction>::cast(
3752 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 3743 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
3753 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); 3744 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
3754 3745
3755 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector()); 3746 Handle<TypeFeedbackVector> vector(f->feedback_vector());
3756 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); 3747 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell());
3757 3748
3758 SimulateIncrementalMarking(CcTest::heap()); 3749 SimulateIncrementalMarking(CcTest::heap());
3759 CcTest::heap()->CollectAllGarbage(); 3750 CcTest::heap()->CollectAllGarbage();
3760 3751
3761 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell()); 3752 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell());
3762 } 3753 }
3763 3754
3764 3755
3765 TEST(IncrementalMarkingClearsMonomorphicConstructor) {
3766 if (i::FLAG_always_opt) return;
3767 CcTest::InitializeVM();
3768 Isolate* isolate = CcTest::i_isolate();
3769 v8::HandleScope scope(CcTest::isolate());
3770 v8::Local<v8::Value> fun1;
3771 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
3772
3773 {
3774 LocalContext env;
3775 CompileRun("function fun() { this.x = 1; };");
3776 fun1 = env->Global()->Get(env.local(), v8_str("fun")).ToLocalChecked();
3777 }
3778
3779 // Prepare function f that contains a monomorphic constructor for object
3780 // originating from a different native context.
3781 CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust());
3782 CompileRun(
3783 "function fun() { this.x = 1; };"
3784 "function f(o) { return new o(); } f(fun1); f(fun1);");
3785 Handle<JSFunction> f = Handle<JSFunction>::cast(
3786 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
3787 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
3788
3789
3790 Handle<TypeFeedbackVector> vector(f->shared()->feedback_vector());
3791 CHECK(vector->Get(FeedbackVectorSlot(0))->IsWeakCell());
3792
3793 // Fire context dispose notification.
3794 CcTest::isolate()->ContextDisposedNotification();
3795 SimulateIncrementalMarking(CcTest::heap());
3796 CcTest::heap()->CollectAllGarbage();
3797
3798 CHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(isolate),
3799 vector->Get(FeedbackVectorSlot(0)));
3800 }
3801
3802
3803 TEST(IncrementalMarkingPreservesMonomorphicIC) { 3756 TEST(IncrementalMarkingPreservesMonomorphicIC) {
3804 if (i::FLAG_always_opt) return; 3757 if (i::FLAG_always_opt) return;
3805 CcTest::InitializeVM(); 3758 CcTest::InitializeVM();
3806 v8::HandleScope scope(CcTest::isolate()); 3759 v8::HandleScope scope(CcTest::isolate());
3807 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); 3760 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
3808 // Prepare function f that contains a monomorphic IC for object 3761 // Prepare function f that contains a monomorphic IC for object
3809 // originating from the same native context. 3762 // originating from the same native context.
3810 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" 3763 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"
3811 "function f(o) { return o.x; } f(obj); f(obj);"); 3764 "function f(o) { return o.x; } f(obj); f(obj);");
3812 Handle<JSFunction> f = Handle<JSFunction>::cast( 3765 Handle<JSFunction> f = Handle<JSFunction>::cast(
3813 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 3766 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
3814 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); 3767 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
3815 3768
3816 CheckVectorIC(f, 0, MONOMORPHIC); 3769 CheckVectorIC(f, 0, MONOMORPHIC);
3817 3770
3818 SimulateIncrementalMarking(CcTest::heap()); 3771 SimulateIncrementalMarking(CcTest::heap());
3819 CcTest::heap()->CollectAllGarbage(); 3772 CcTest::heap()->CollectAllGarbage();
3820 3773
3821 CheckVectorIC(f, 0, MONOMORPHIC); 3774 CheckVectorIC(f, 0, MONOMORPHIC);
3822 } 3775 }
3823 3776
3824 3777
3825 TEST(IncrementalMarkingClearsMonomorphicIC) {
3826 if (i::FLAG_always_opt) return;
3827 CcTest::InitializeVM();
3828 v8::HandleScope scope(CcTest::isolate());
3829 v8::Local<v8::Value> obj1;
3830 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
3831
3832 {
3833 LocalContext env;
3834 CompileRun("function fun() { this.x = 1; }; var obj = new fun();");
3835 obj1 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked();
3836 }
3837
3838 // Prepare function f that contains a monomorphic IC for object
3839 // originating from a different native context.
3840 CHECK(CcTest::global()->Set(ctx, v8_str("obj1"), obj1).FromJust());
3841 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1);");
3842 Handle<JSFunction> f = Handle<JSFunction>::cast(
3843 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
3844 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
3845
3846 CheckVectorIC(f, 0, MONOMORPHIC);
3847
3848 // Fire context dispose notification.
3849 CcTest::isolate()->ContextDisposedNotification();
3850 SimulateIncrementalMarking(CcTest::heap());
3851 CcTest::heap()->CollectAllGarbage();
3852
3853 CheckVectorICCleared(f, 0);
3854 }
3855
3856
3857 TEST(IncrementalMarkingPreservesPolymorphicIC) { 3778 TEST(IncrementalMarkingPreservesPolymorphicIC) {
3858 if (i::FLAG_always_opt) return; 3779 if (i::FLAG_always_opt) return;
3859 CcTest::InitializeVM(); 3780 CcTest::InitializeVM();
3860 v8::HandleScope scope(CcTest::isolate()); 3781 v8::HandleScope scope(CcTest::isolate());
3861 v8::Local<v8::Value> obj1, obj2; 3782 v8::Local<v8::Value> obj1, obj2;
3862 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); 3783 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
3863 3784
3864 { 3785 {
3865 LocalContext env; 3786 LocalContext env;
3866 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); 3787 CompileRun("function fun() { this.x = 1; }; var obj = new fun();");
(...skipping 17 matching lines...) Expand all
3884 3805
3885 CheckVectorIC(f, 0, POLYMORPHIC); 3806 CheckVectorIC(f, 0, POLYMORPHIC);
3886 3807
3887 // Fire context dispose notification. 3808 // Fire context dispose notification.
3888 SimulateIncrementalMarking(CcTest::heap()); 3809 SimulateIncrementalMarking(CcTest::heap());
3889 CcTest::heap()->CollectAllGarbage(); 3810 CcTest::heap()->CollectAllGarbage();
3890 3811
3891 CheckVectorIC(f, 0, POLYMORPHIC); 3812 CheckVectorIC(f, 0, POLYMORPHIC);
3892 } 3813 }
3893 3814
3894 3815 TEST(ContextDisposeDoesntClearPolymorphicIC) {
3895 TEST(IncrementalMarkingClearsPolymorphicIC) {
3896 if (i::FLAG_always_opt) return; 3816 if (i::FLAG_always_opt) return;
3897 CcTest::InitializeVM(); 3817 CcTest::InitializeVM();
3898 v8::HandleScope scope(CcTest::isolate()); 3818 v8::HandleScope scope(CcTest::isolate());
3899 v8::Local<v8::Value> obj1, obj2; 3819 v8::Local<v8::Value> obj1, obj2;
3900 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); 3820 v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
3901 3821
3902 { 3822 {
3903 LocalContext env; 3823 LocalContext env;
3904 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); 3824 CompileRun("function fun() { this.x = 1; }; var obj = new fun();");
3905 obj1 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); 3825 obj1 = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked();
(...skipping 14 matching lines...) Expand all
3920 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 3840 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
3921 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked()))); 3841 CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
3922 3842
3923 CheckVectorIC(f, 0, POLYMORPHIC); 3843 CheckVectorIC(f, 0, POLYMORPHIC);
3924 3844
3925 // Fire context dispose notification. 3845 // Fire context dispose notification.
3926 CcTest::isolate()->ContextDisposedNotification(); 3846 CcTest::isolate()->ContextDisposedNotification();
3927 SimulateIncrementalMarking(CcTest::heap()); 3847 SimulateIncrementalMarking(CcTest::heap());
3928 CcTest::heap()->CollectAllGarbage(); 3848 CcTest::heap()->CollectAllGarbage();
3929 3849
3930 CheckVectorICCleared(f, 0); 3850 CheckVectorIC(f, 0, POLYMORPHIC);
3931 } 3851 }
3932 3852
3933 3853
3934 class SourceResource : public v8::String::ExternalOneByteStringResource { 3854 class SourceResource : public v8::String::ExternalOneByteStringResource {
3935 public: 3855 public:
3936 explicit SourceResource(const char* data) 3856 explicit SourceResource(const char* data)
3937 : data_(data), length_(strlen(data)) { } 3857 : data_(data), length_(strlen(data)) { }
3938 3858
3939 virtual void Dispose() { 3859 virtual void Dispose() {
3940 i::DeleteArray(data_); 3860 i::DeleteArray(data_);
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
4336 CompileRun("function g() { return 2 }" 4256 CompileRun("function g() { return 2 }"
4337 "g(); %OptimizeFunctionOnNextCall(g); g();"); 4257 "g(); %OptimizeFunctionOnNextCall(g); g();");
4338 4258
4339 Handle<JSFunction> g = Handle<JSFunction>::cast( 4259 Handle<JSFunction> g = Handle<JSFunction>::cast(
4340 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 4260 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
4341 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); 4261 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked())));
4342 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); 4262 code = inner_scope.CloseAndEscape(handle(g->code(), isolate));
4343 if (!code->is_optimized_code()) return; 4263 if (!code->is_optimized_code()) return;
4344 } 4264 }
4345 4265
4346 Handle<TypeFeedbackVector> vector = handle(shared->feedback_vector()); 4266 Handle<TypeFeedbackVector> vector =
4267 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
4347 Handle<LiteralsArray> lit = 4268 Handle<LiteralsArray> lit =
4348 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED); 4269 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED);
4349 Handle<Context> context(isolate->context()); 4270 Handle<Context> context(isolate->context());
4350 4271
4351 // Add the new code several times to the optimized code map and also set an 4272 // Add the new code several times to the optimized code map and also set an
4352 // allocation timeout so that expanding the code map will trigger a GC. 4273 // allocation timeout so that expanding the code map will trigger a GC.
4353 heap->set_allocation_timeout(5); 4274 heap->set_allocation_timeout(5);
4354 FLAG_gc_interval = 1000; 4275 FLAG_gc_interval = 1000;
4355 for (int i = 0; i < 10; ++i) { 4276 for (int i = 0; i < 10; ++i) {
4356 BailoutId id = BailoutId(i); 4277 BailoutId id = BailoutId(i);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
4393 CompileRun("function g() { return 2 }" 4314 CompileRun("function g() { return 2 }"
4394 "g(); %OptimizeFunctionOnNextCall(g); g();"); 4315 "g(); %OptimizeFunctionOnNextCall(g); g();");
4395 4316
4396 Handle<JSFunction> g = Handle<JSFunction>::cast( 4317 Handle<JSFunction> g = Handle<JSFunction>::cast(
4397 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 4318 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
4398 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); 4319 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked())));
4399 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); 4320 code = inner_scope.CloseAndEscape(handle(g->code(), isolate));
4400 if (!code->is_optimized_code()) return; 4321 if (!code->is_optimized_code()) return;
4401 } 4322 }
4402 4323
4403 Handle<TypeFeedbackVector> vector = handle(shared->feedback_vector()); 4324 Handle<TypeFeedbackVector> vector =
4325 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
4404 Handle<LiteralsArray> lit = 4326 Handle<LiteralsArray> lit =
4405 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED); 4327 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED);
4406 Handle<Context> context(isolate->context()); 4328 Handle<Context> context(isolate->context());
4407 4329
4408 // Add the code several times to the optimized code map. 4330 // Add the code several times to the optimized code map.
4409 for (int i = 0; i < 3; ++i) { 4331 for (int i = 0; i < 3; ++i) {
4410 HandleScope inner_scope(isolate); 4332 HandleScope inner_scope(isolate);
4411 BailoutId id = BailoutId(i); 4333 BailoutId id = BailoutId(i);
4412 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); 4334 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id);
4413 } 4335 }
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
5097 weak_ic_cleared = false; 5019 weak_ic_cleared = false;
5098 garbage.SetWeak(&garbage, &ClearWeakIC, v8::WeakCallbackType::kParameter); 5020 garbage.SetWeak(&garbage, &ClearWeakIC, v8::WeakCallbackType::kParameter);
5099 Heap* heap = CcTest::i_isolate()->heap(); 5021 Heap* heap = CcTest::i_isolate()->heap();
5100 heap->CollectAllGarbage(); 5022 heap->CollectAllGarbage();
5101 CHECK(weak_ic_cleared); 5023 CHECK(weak_ic_cleared);
5102 5024
5103 // We've determined the constructor in createObj has had it's weak cell 5025 // We've determined the constructor in createObj has had it's weak cell
5104 // cleared. Now, verify that one additional call with a new function 5026 // cleared. Now, verify that one additional call with a new function
5105 // allows monomorphicity. 5027 // allows monomorphicity.
5106 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>( 5028 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>(
5107 createObj->shared()->feedback_vector(), CcTest::i_isolate()); 5029 createObj->feedback_vector(), CcTest::i_isolate());
5108 for (int i = 0; i < 20; i++) { 5030 for (int i = 0; i < 20; i++) {
5109 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); 5031 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0));
5110 CHECK(slot_value->IsWeakCell()); 5032 CHECK(slot_value->IsWeakCell());
5111 if (WeakCell::cast(slot_value)->cleared()) break; 5033 if (WeakCell::cast(slot_value)->cleared()) break;
5112 heap->CollectAllGarbage(); 5034 heap->CollectAllGarbage();
5113 } 5035 }
5114 5036
5115 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0)); 5037 Object* slot_value = feedback_vector->Get(FeedbackVectorSlot(0));
5116 CHECK(slot_value->IsWeakCell() && WeakCell::cast(slot_value)->cleared()); 5038 CHECK(slot_value->IsWeakCell() && WeakCell::cast(slot_value)->cleared());
5117 CompileRun( 5039 CompileRun(
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
5298 } 5220 }
5299 5221
5300 5222
5301 Handle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) { 5223 Handle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) {
5302 Handle<String> str = isolate->factory()->InternalizeUtf8String(name); 5224 Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
5303 Handle<Object> obj = 5225 Handle<Object> obj =
5304 Object::GetProperty(isolate->global_object(), str).ToHandleChecked(); 5226 Object::GetProperty(isolate->global_object(), str).ToHandleChecked();
5305 return Handle<JSFunction>::cast(obj); 5227 return Handle<JSFunction>::cast(obj);
5306 } 5228 }
5307 5229
5308 5230 void CheckIC(Handle<JSFunction> function, Code::Kind kind, int slot_index,
5309 void CheckIC(Code* code, Code::Kind kind, SharedFunctionInfo* shared, 5231 InlineCacheState state) {
5310 int slot_index, InlineCacheState state) {
5311 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC || 5232 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC ||
5312 kind == Code::CALL_IC) { 5233 kind == Code::CALL_IC) {
5313 TypeFeedbackVector* vector = shared->feedback_vector(); 5234 TypeFeedbackVector* vector = function->feedback_vector();
5314 FeedbackVectorSlot slot(slot_index); 5235 FeedbackVectorSlot slot(slot_index);
5315 if (kind == Code::LOAD_IC) { 5236 if (kind == Code::LOAD_IC) {
5316 LoadICNexus nexus(vector, slot); 5237 LoadICNexus nexus(vector, slot);
5317 CHECK_EQ(nexus.StateFromFeedback(), state); 5238 CHECK_EQ(nexus.StateFromFeedback(), state);
5318 } else if (kind == Code::KEYED_LOAD_IC) { 5239 } else if (kind == Code::KEYED_LOAD_IC) {
5319 KeyedLoadICNexus nexus(vector, slot); 5240 KeyedLoadICNexus nexus(vector, slot);
5320 CHECK_EQ(nexus.StateFromFeedback(), state); 5241 CHECK_EQ(nexus.StateFromFeedback(), state);
5321 } else if (kind == Code::CALL_IC) { 5242 } else if (kind == Code::CALL_IC) {
5322 CallICNexus nexus(vector, slot); 5243 CallICNexus nexus(vector, slot);
5323 CHECK_EQ(nexus.StateFromFeedback(), state); 5244 CHECK_EQ(nexus.StateFromFeedback(), state);
5324 } 5245 }
5325 } else { 5246 } else {
5326 Code* ic = FindFirstIC(code, kind); 5247 Code* ic = FindFirstIC(function->code(), kind);
5327 CHECK(ic->is_inline_cache_stub()); 5248 CHECK(ic->is_inline_cache_stub());
5328 CHECK(ic->ic_state() == state); 5249 CHECK(ic->ic_state() == state);
5329 } 5250 }
5330 } 5251 }
5331 5252
5332 5253
5333 TEST(MonomorphicStaysMonomorphicAfterGC) { 5254 TEST(MonomorphicStaysMonomorphicAfterGC) {
5334 if (FLAG_always_opt) return; 5255 if (FLAG_always_opt) return;
5335 CcTest::InitializeVM(); 5256 CcTest::InitializeVM();
5336 Isolate* isolate = CcTest::i_isolate(); 5257 Isolate* isolate = CcTest::i_isolate();
(...skipping 10 matching lines...) Expand all
5347 " loadIC(obj);" 5268 " loadIC(obj);"
5348 " loadIC(obj);" 5269 " loadIC(obj);"
5349 " return proto;" 5270 " return proto;"
5350 "};"); 5271 "};");
5351 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC"); 5272 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC");
5352 { 5273 {
5353 v8::HandleScope scope(CcTest::isolate()); 5274 v8::HandleScope scope(CcTest::isolate());
5354 CompileRun("(testIC())"); 5275 CompileRun("(testIC())");
5355 } 5276 }
5356 heap->CollectAllGarbage(); 5277 heap->CollectAllGarbage();
5357 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC); 5278 CheckIC(loadIC, Code::LOAD_IC, 0, MONOMORPHIC);
5358 { 5279 {
5359 v8::HandleScope scope(CcTest::isolate()); 5280 v8::HandleScope scope(CcTest::isolate());
5360 CompileRun("(testIC())"); 5281 CompileRun("(testIC())");
5361 } 5282 }
5362 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, MONOMORPHIC); 5283 CheckIC(loadIC, Code::LOAD_IC, 0, MONOMORPHIC);
5363 } 5284 }
5364 5285
5365 5286
5366 TEST(PolymorphicStaysPolymorphicAfterGC) { 5287 TEST(PolymorphicStaysPolymorphicAfterGC) {
5367 if (FLAG_always_opt) return; 5288 if (FLAG_always_opt) return;
5368 CcTest::InitializeVM(); 5289 CcTest::InitializeVM();
5369 Isolate* isolate = CcTest::i_isolate(); 5290 Isolate* isolate = CcTest::i_isolate();
5370 Heap* heap = isolate->heap(); 5291 Heap* heap = isolate->heap();
5371 v8::HandleScope scope(CcTest::isolate()); 5292 v8::HandleScope scope(CcTest::isolate());
5372 CompileRun( 5293 CompileRun(
(...skipping 10 matching lines...) Expand all
5383 " poly.x = true;" 5304 " poly.x = true;"
5384 " loadIC(poly);" 5305 " loadIC(poly);"
5385 " return proto;" 5306 " return proto;"
5386 "};"); 5307 "};");
5387 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC"); 5308 Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC");
5388 { 5309 {
5389 v8::HandleScope scope(CcTest::isolate()); 5310 v8::HandleScope scope(CcTest::isolate());
5390 CompileRun("(testIC())"); 5311 CompileRun("(testIC())");
5391 } 5312 }
5392 heap->CollectAllGarbage(); 5313 heap->CollectAllGarbage();
5393 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC); 5314 CheckIC(loadIC, Code::LOAD_IC, 0, POLYMORPHIC);
5394 { 5315 {
5395 v8::HandleScope scope(CcTest::isolate()); 5316 v8::HandleScope scope(CcTest::isolate());
5396 CompileRun("(testIC())"); 5317 CompileRun("(testIC())");
5397 } 5318 }
5398 CheckIC(loadIC->code(), Code::LOAD_IC, loadIC->shared(), 0, POLYMORPHIC); 5319 CheckIC(loadIC, Code::LOAD_IC, 0, POLYMORPHIC);
5399 } 5320 }
5400 5321
5401 5322
5402 TEST(WeakCell) { 5323 TEST(WeakCell) {
5403 CcTest::InitializeVM(); 5324 CcTest::InitializeVM();
5404 Isolate* isolate = CcTest::i_isolate(); 5325 Isolate* isolate = CcTest::i_isolate();
5405 v8::internal::Heap* heap = CcTest::heap(); 5326 v8::internal::Heap* heap = CcTest::heap();
5406 v8::internal::Factory* factory = isolate->factory(); 5327 v8::internal::Factory* factory = isolate->factory();
5407 5328
5408 HandleScope outer_scope(isolate); 5329 HandleScope outer_scope(isolate);
(...skipping 1082 matching lines...) Expand 10 before | Expand all | Expand 10 after
6491 isolate->IncrementJsCallsFromApiCounter(); 6412 isolate->IncrementJsCallsFromApiCounter();
6492 isolate->IncrementJsCallsFromApiCounter(); 6413 isolate->IncrementJsCallsFromApiCounter();
6493 isolate->IncrementJsCallsFromApiCounter(); 6414 isolate->IncrementJsCallsFromApiCounter();
6494 calls_per_ms = memory_reducer->SampleAndGetJsCallsPerMs(4); 6415 calls_per_ms = memory_reducer->SampleAndGetJsCallsPerMs(4);
6495 CheckDoubleEquals(2, calls_per_ms); 6416 CheckDoubleEquals(2, calls_per_ms);
6496 } 6417 }
6497 6418
6498 6419
6499 } // namespace internal 6420 } // namespace internal
6500 } // namespace v8 6421 } // namespace v8
OLDNEW
« no previous file with comments | « test/cctest/compiler/test-run-jscalls.cc ('k') | test/cctest/interpreter/test-interpreter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698