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

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

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