From: ulan@chromium.org Date: Mon, 20 Aug 2012 12:09:03 +0000 (+0000) Subject: Flush monomorphic ICs on context disposal instead of context exit. X-Git-Tag: upstream/4.7.83~16130 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=27fb8c2cf6bc802083ff2e85be70390ce5c50a3f;p=platform%2Fupstream%2Fv8.git Flush monomorphic ICs on context disposal instead of context exit. R=mstarzinger@chromium.org Review URL: https://chromiumcodereview.appspot.com/10836189 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12342 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/heap.cc b/src/heap.cc index a9be4c9..abbeff2 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -97,6 +97,7 @@ Heap::Heap() linear_allocation_scope_depth_(0), contexts_disposed_(0), global_ic_age_(0), + flush_monomorphic_ics_(false), scan_on_scavenge_pages_(0), new_space_(this), old_pointer_space_(NULL), @@ -992,7 +993,7 @@ void Heap::MarkCompact(GCTracer* tracer) { contexts_disposed_ = 0; - isolate_->set_context_exit_happened(false); + flush_monomorphic_ics_ = false; } diff --git a/src/heap.h b/src/heap.h index e2ab81a..ae97914 100644 --- a/src/heap.h +++ b/src/heap.h @@ -1074,7 +1074,10 @@ class Heap { void EnsureHeapIsIterable(); // Notify the heap that a context has been disposed. - int NotifyContextDisposed() { return ++contexts_disposed_; } + int NotifyContextDisposed() { + flush_monomorphic_ics_ = true; + return ++contexts_disposed_; + } // Utility to invoke the scavenger. This is needed in test code to // ensure correct callback for weak global handles. @@ -1604,6 +1607,8 @@ class Heap { global_ic_age_ = (global_ic_age_ + 1) & SharedFunctionInfo::ICAgeBits::kMax; } + bool flush_monomorphic_ics() { return flush_monomorphic_ics_; } + intptr_t amount_of_external_allocated_memory() { return amount_of_external_allocated_memory_; } @@ -1689,6 +1694,8 @@ class Heap { int global_ic_age_; + bool flush_monomorphic_ics_; + int scan_on_scavenge_pages_; #if defined(V8_TARGET_ARCH_X64) diff --git a/src/objects-visiting-inl.h b/src/objects-visiting-inl.h index 856ae06..1f1033f 100644 --- a/src/objects-visiting-inl.h +++ b/src/objects-visiting-inl.h @@ -217,9 +217,8 @@ void StaticMarkingVisitor::VisitCodeTarget( // when they might be keeping a Context alive, or when the heap is about // to be serialized. if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub() - && (target->ic_state() == MEGAMORPHIC || Serializer::enabled() || - heap->isolate()->context_exit_happened() || - target->ic_age() != heap->global_ic_age())) { + && (target->ic_state() == MEGAMORPHIC || heap->flush_monomorphic_ics() || + Serializer::enabled() || target->ic_age() != heap->global_ic_age())) { IC::Clear(rinfo->pc()); target = Code::GetCodeFromTargetAddress(rinfo->target_address()); } diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 41befa8..19a7d20 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -1,4 +1,5 @@ // Copyright 2012 the V8 project authors. All rights reserved. + // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -10777,18 +10778,24 @@ TEST(DontLeakGlobalObjects) { { v8::HandleScope scope; LocalContext context; } + // Fire context disposed notification to force clearing monomorphic ICs. + v8::V8::ContextDisposedNotification(); CheckSurvivingGlobalObjectsCount(0); { v8::HandleScope scope; LocalContext context; v8_compile("Date")->Run(); } + // Fire context disposed notification to force clearing monomorphic ICs. + v8::V8::ContextDisposedNotification(); CheckSurvivingGlobalObjectsCount(0); { v8::HandleScope scope; LocalContext context; v8_compile("/aaa/")->Run(); } + // Fire context disposed notification to force clearing monomorphic ICs. + v8::V8::ContextDisposedNotification(); CheckSurvivingGlobalObjectsCount(0); { v8::HandleScope scope; @@ -10797,6 +10804,8 @@ TEST(DontLeakGlobalObjects) { LocalContext context(&extensions); v8_compile("gc();")->Run(); } + // Fire context disposed notification to force clearing monomorphic ICs. + v8::V8::ContextDisposedNotification(); CheckSurvivingGlobalObjectsCount(0); } } @@ -14626,6 +14635,7 @@ TEST(Regress528) { context->Exit(); } context.Dispose(); + v8::V8::ContextDisposedNotification(); for (gc_count = 1; gc_count < 10; gc_count++) { other_context->Enter(); CompileRun(source_exception); diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc index ec2fb3d..28da712 100644 --- a/test/cctest/test-heap.cc +++ b/test/cctest/test-heap.cc @@ -4,6 +4,7 @@ #include "v8.h" +#include "compilation-cache.h" #include "execution.h" #include "factory.h" #include "macro-assembler.h" @@ -1065,6 +1066,7 @@ TEST(TestInternalWeakLists) { } // Mark compact handles the weak references. + ISOLATE->compilation_cache()->Clear(); HEAP->CollectAllGarbage(Heap::kNoGCFlags); CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i])); @@ -1395,6 +1397,7 @@ TEST(LeakNativeContextViaMap) { ctx2->Exit(); ctx1->Exit(); ctx1.Dispose(); + v8::V8::ContextDisposedNotification(); } HEAP->CollectAllAvailableGarbage(); CHECK_EQ(2, NumberOfGlobalObjects()); @@ -1432,6 +1435,7 @@ TEST(LeakNativeContextViaFunction) { ctx2->Exit(); ctx1->Exit(); ctx1.Dispose(); + v8::V8::ContextDisposedNotification(); } HEAP->CollectAllAvailableGarbage(); CHECK_EQ(2, NumberOfGlobalObjects()); @@ -1467,6 +1471,7 @@ TEST(LeakNativeContextViaMapKeyed) { ctx2->Exit(); ctx1->Exit(); ctx1.Dispose(); + v8::V8::ContextDisposedNotification(); } HEAP->CollectAllAvailableGarbage(); CHECK_EQ(2, NumberOfGlobalObjects()); @@ -1506,6 +1511,7 @@ TEST(LeakNativeContextViaMapProto) { ctx2->Exit(); ctx1->Exit(); ctx1.Dispose(); + v8::V8::ContextDisposedNotification(); } HEAP->CollectAllAvailableGarbage(); CHECK_EQ(2, NumberOfGlobalObjects()); @@ -2100,8 +2106,6 @@ TEST(IncrementalMarkingPreservesMonomorhpicIC) { Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); CHECK(ic_before->ic_state() == MONOMORPHIC); - // Fire context dispose notification. - v8::V8::ContextDisposedNotification(); SimulateIncrementalMarking(); HEAP->CollectAllGarbage(Heap::kNoGCFlags); diff --git a/test/mjsunit/debug-script.js b/test/mjsunit/debug-script.js index d7ffb56..082a08f 100644 --- a/test/mjsunit/debug-script.js +++ b/test/mjsunit/debug-script.js @@ -25,9 +25,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --expose-debug-as debug --expose-gc --noparallel-recompilation +// Flags: --expose-debug-as debug --expose-gc --noparallel-recompilation +// Flags: --send-idle-notification // Get the Debug object exposed from the debug context global object. -Debug = debug.Debug +Debug = debug.Debug; Date(); RegExp(); diff --git a/test/mjsunit/elements-transition-hoisting.js b/test/mjsunit/elements-transition-hoisting.js index 5fb3889..878beab 100644 --- a/test/mjsunit/elements-transition-hoisting.js +++ b/test/mjsunit/elements-transition-hoisting.js @@ -25,8 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc -// Flags: --noparallel-recompilation +// Flags: --allow-natives-syntax --smi-only-arrays --noparallel-recompilation // Ensure that ElementsKind transitions in various situations are hoisted (or // not hoisted) correctly, don't change the semantics programs and don't trigger @@ -40,11 +39,6 @@ if (support_smi_only_arrays) { print("Tests do NOT include smi-only arrays."); } -// Force existing ICs from previous stress runs to be flushed, otherwise the -// assumptions in this test about when deoptimizations get triggered are not -// valid. -gc(); - if (support_smi_only_arrays) { // Make sure that a simple elements array transitions inside a loop before // stores to an array gets hoisted in a way that doesn't generate a deopt in @@ -66,6 +60,7 @@ if (support_smi_only_arrays) { testDoubleConversion4(new Array(5)); testDoubleConversion4(new Array(5)); assertTrue(2 != %GetOptimizationStatus(testDoubleConversion4)); + %ClearFunctionTypeFeedback(testDoubleConversion4); // Make sure that non-element related map checks that are not preceded by // transitions in a loop still get hoisted in a way that doesn't generate a @@ -91,6 +86,7 @@ if (support_smi_only_arrays) { testExactMapHoisting(new Array(5)); testExactMapHoisting(new Array(5)); assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting)); + %ClearFunctionTypeFeedback(testExactMapHoisting); // Make sure that non-element related map checks do NOT get hoisted if they // depend on an elements transition before them and it's not possible to hoist @@ -122,6 +118,7 @@ if (support_smi_only_arrays) { testExactMapHoisting2(new Array(5)); // Temporarily disabled - see bug 2176. // assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting2)); + %ClearFunctionTypeFeedback(testExactMapHoisting2); // Make sure that non-element related map checks do get hoisted if they use // the transitioned map for the check and all transitions that they depend @@ -150,6 +147,7 @@ if (support_smi_only_arrays) { testExactMapHoisting3(new Array(5)); testExactMapHoisting3(new Array(5)); assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting3)); + %ClearFunctionTypeFeedback(testExactMapHoisting3); function testDominatingTransitionHoisting1(a) { var object = new Object(); @@ -172,6 +170,7 @@ if (support_smi_only_arrays) { testDominatingTransitionHoisting1(new Array(5)); testDominatingTransitionHoisting1(new Array(5)); assertTrue(2 != %GetOptimizationStatus(testDominatingTransitionHoisting1)); + %ClearFunctionTypeFeedback(testDominatingTransitionHoisting1); function testHoistingWithSideEffect(a) { var object = new Object(); @@ -191,8 +190,9 @@ if (support_smi_only_arrays) { testHoistingWithSideEffect(new Array(5)); testHoistingWithSideEffect(new Array(5)); assertTrue(2 != %GetOptimizationStatus(testHoistingWithSideEffect)); + %ClearFunctionTypeFeedback(testHoistingWithSideEffect); - function testStraightLineDupeElinination(a,b,c,d,e,f) { + function testStraightLineDupeElimination(a,b,c,d,e,f) { var count = 3; do { assertTrue(true); @@ -205,28 +205,29 @@ if (support_smi_only_arrays) { } while (--count > 3); } - testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,0,0,0,.5); - testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,0,0,.5,0); - testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,0,.5,0,0); - testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,.5,0,0,0); - testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),.5,0,0,0,0); - testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,0,0,0,.5); - testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,0,0,.5,0); - testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,0,.5,0,0); - testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,.5,0,0,0); - testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),.5,0,0,0,0); - testStraightLineDupeElinination(new Array(5),.5,0,0,0,0); - testStraightLineDupeElinination(new Array(5),0,.5,0,0,0); - testStraightLineDupeElinination(new Array(5),0,0,.5,0,0); - testStraightLineDupeElinination(new Array(5),0,0,0,.5,0); - testStraightLineDupeElinination(new Array(5),0,0,0,0,.5); - testStraightLineDupeElinination(new Array(5),.5,0,0,0,0); - testStraightLineDupeElinination(new Array(5),0,.5,0,0,0); - testStraightLineDupeElinination(new Array(5),0,0,.5,0,0); - testStraightLineDupeElinination(new Array(5),0,0,0,.5,0); - testStraightLineDupeElinination(new Array(5),0,0,0,0,.5); - %OptimizeFunctionOnNextCall(testStraightLineDupeElinination); - testStraightLineDupeElinination(new Array(5)); - testStraightLineDupeElinination(new Array(5)); - assertTrue(2 != %GetOptimizationStatus(testStraightLineDupeElinination)); + testStraightLineDupeElimination(new Array(0, 0, 0, 0, 0),0,0,0,0,.5); + testStraightLineDupeElimination(new Array(0, 0, 0, 0, 0),0,0,0,.5,0); + testStraightLineDupeElimination(new Array(0, 0, 0, 0, 0),0,0,.5,0,0); + testStraightLineDupeElimination(new Array(0, 0, 0, 0, 0),0,.5,0,0,0); + testStraightLineDupeElimination(new Array(0, 0, 0, 0, 0),.5,0,0,0,0); + testStraightLineDupeElimination(new Array(.1,.1,.1,.1,.1),0,0,0,0,.5); + testStraightLineDupeElimination(new Array(.1,.1,.1,.1,.1),0,0,0,.5,0); + testStraightLineDupeElimination(new Array(.1,.1,.1,.1,.1),0,0,.5,0,0); + testStraightLineDupeElimination(new Array(.1,.1,.1,.1,.1),0,.5,0,0,0); + testStraightLineDupeElimination(new Array(.1,.1,.1,.1,.1),.5,0,0,0,0); + testStraightLineDupeElimination(new Array(5),.5,0,0,0,0); + testStraightLineDupeElimination(new Array(5),0,.5,0,0,0); + testStraightLineDupeElimination(new Array(5),0,0,.5,0,0); + testStraightLineDupeElimination(new Array(5),0,0,0,.5,0); + testStraightLineDupeElimination(new Array(5),0,0,0,0,.5); + testStraightLineDupeElimination(new Array(5),.5,0,0,0,0); + testStraightLineDupeElimination(new Array(5),0,.5,0,0,0); + testStraightLineDupeElimination(new Array(5),0,0,.5,0,0); + testStraightLineDupeElimination(new Array(5),0,0,0,.5,0); + testStraightLineDupeElimination(new Array(5),0,0,0,0,.5); + %OptimizeFunctionOnNextCall(testStraightLineDupeElimination); + testStraightLineDupeElimination(new Array(5)); + testStraightLineDupeElimination(new Array(5)); + assertTrue(2 != %GetOptimizationStatus(testStraightLineDupeElimination)); + %ClearFunctionTypeFeedback(testStraightLineDupeElimination); }