| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 //     * Redistributions of source code must retain the above copyright | 6 //     * Redistributions of source code must retain the above copyright | 
| 7 //       notice, this list of conditions and the following disclaimer. | 7 //       notice, this list of conditions and the following disclaimer. | 
| 8 //     * Redistributions in binary form must reproduce the above | 8 //     * Redistributions in binary form must reproduce the above | 
| 9 //       copyright notice, this list of conditions and the following | 9 //       copyright notice, this list of conditions and the following | 
| 10 //       disclaimer in the documentation and/or other materials provided | 10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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 | 
| OLD | NEW | 
|---|