From 22602980c0452db6a92b9414c117fffeca03a6f9 Mon Sep 17 00:00:00 2001 From: "hpayer@chromium.org" Date: Mon, 17 Feb 2014 12:15:16 +0000 Subject: [PATCH] Added a special stack guard to deopt marked allocation sites. BUG= R=mvstanton@chromium.org, ulan@chromium.org Review URL: https://codereview.chromium.org/169563002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19404 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/execution.cc | 14 +++++++------- src/execution.h | 6 +++--- src/heap.cc | 31 +++++++++++++++++++++++++------ src/heap.h | 2 ++ src/objects-inl.h | 4 +--- src/objects.h | 17 +++++++++++++++-- 6 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/execution.cc b/src/execution.cc index 081cfb6..690a4e3 100644 --- a/src/execution.cc +++ b/src/execution.cc @@ -516,15 +516,15 @@ void StackGuard::FullDeopt() { } -bool StackGuard::IsDeoptMarkedCode() { +bool StackGuard::IsDeoptMarkedAllocationSites() { ExecutionAccess access(isolate_); - return (thread_local_.interrupt_flags_ & DEOPT_MARKED_CODE) != 0; + return (thread_local_.interrupt_flags_ & DEOPT_MARKED_ALLOCATION_SITES) != 0; } -void StackGuard::DeoptMarkedCode() { +void StackGuard::DeoptMarkedAllocationSites() { ExecutionAccess access(isolate_); - thread_local_.interrupt_flags_ |= DEOPT_MARKED_CODE; + thread_local_.interrupt_flags_ |= DEOPT_MARKED_ALLOCATION_SITES; set_interrupt_limits(access); } @@ -1040,9 +1040,9 @@ MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) { stack_guard->Continue(FULL_DEOPT); Deoptimizer::DeoptimizeAll(isolate); } - if (stack_guard->IsDeoptMarkedCode()) { - stack_guard->Continue(DEOPT_MARKED_CODE); - Deoptimizer::DeoptimizeMarkedCode(isolate); + if (stack_guard->IsDeoptMarkedAllocationSites()) { + stack_guard->Continue(DEOPT_MARKED_ALLOCATION_SITES); + isolate->heap()->DeoptMarkedAllocationSites(); } if (stack_guard->IsInstallCodeRequest()) { ASSERT(isolate->concurrent_recompilation_enabled()); diff --git a/src/execution.h b/src/execution.h index e86337c..b53a833 100644 --- a/src/execution.h +++ b/src/execution.h @@ -45,7 +45,7 @@ enum InterruptFlag { FULL_DEOPT = 1 << 6, INSTALL_CODE = 1 << 7, API_INTERRUPT = 1 << 8, - DEOPT_MARKED_CODE = 1 << 9 + DEOPT_MARKED_ALLOCATION_SITES = 1 << 9 }; @@ -223,8 +223,8 @@ class StackGuard { void RequestInstallCode(); bool IsFullDeopt(); void FullDeopt(); - bool IsDeoptMarkedCode(); - void DeoptMarkedCode(); + bool IsDeoptMarkedAllocationSites(); + void DeoptMarkedAllocationSites(); void Continue(InterruptFlag after_what); void RequestInterrupt(InterruptCallback callback, void* data); diff --git a/src/heap.cc b/src/heap.cc index 533e2f2..c7f3638 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -545,7 +545,9 @@ void Heap::ProcessPretenuringFeedback() { } } - if (trigger_deoptimization) isolate_->stack_guard()->DeoptMarkedCode(); + if (trigger_deoptimization) { + isolate_->stack_guard()->DeoptMarkedAllocationSites(); + } FlushAllocationSitesScratchpad(); @@ -567,6 +569,25 @@ void Heap::ProcessPretenuringFeedback() { } +void Heap::DeoptMarkedAllocationSites() { + // TODO(hpayer): If iterating over the allocation sites list becomes a + // performance issue, use a cache heap data structure instead (similar to the + // allocation sites scratchpad). + Object* list_element = allocation_sites_list(); + while (list_element->IsAllocationSite()) { + AllocationSite* site = AllocationSite::cast(list_element); + if (site->deopt_dependent_code()) { + site->dependent_code()->MarkCodeForDeoptimization( + isolate_, + DependentCode::kAllocationSiteTenuringChangedGroup); + site->set_deopt_dependent_code(false); + } + list_element = site->weak_next(); + } + Deoptimizer::DeoptimizeMarkedCode(isolate_); +} + + void Heap::GarbageCollectionEpilogue() { store_buffer()->GCEpilogue(); @@ -2000,14 +2021,12 @@ void Heap::ResetAllAllocationSitesDependentCode(PretenureFlag flag) { AllocationSite* casted = AllocationSite::cast(cur); if (casted->GetPretenureMode() == flag) { casted->ResetPretenureDecision(); - bool got_marked = casted->dependent_code()->MarkCodeForDeoptimization( - isolate_, - DependentCode::kAllocationSiteTenuringChangedGroup); - if (got_marked) marked = true; + casted->set_deopt_dependent_code(true); + marked = true; } cur = casted->weak_next(); } - if (marked) isolate_->stack_guard()->DeoptMarkedCode(); + if (marked) isolate_->stack_guard()->DeoptMarkedAllocationSites(); } diff --git a/src/heap.h b/src/heap.h index c19b743..2645d27 100644 --- a/src/heap.h +++ b/src/heap.h @@ -1847,6 +1847,8 @@ class Heap { return amount_of_external_allocated_memory_; } + void DeoptMarkedAllocationSites(); + // ObjectStats are kept in two arrays, counts and sizes. Related stats are // stored in a contiguous linear buffer. Stats groups are stored one after // another. diff --git a/src/objects-inl.h b/src/objects-inl.h index 625332a..ea0dfe1 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1554,9 +1554,7 @@ inline bool AllocationSite::DigestPretenuringFeedback() { set_pretenure_decision(result); if (current_mode != GetPretenureMode()) { decision_changed = true; - dependent_code()->MarkCodeForDeoptimization( - GetIsolate(), - DependentCode::kAllocationSiteTenuringChangedGroup); + set_deopt_dependent_code(true); } } diff --git a/src/objects.h b/src/objects.h index 7e88273..2400be3 100644 --- a/src/objects.h +++ b/src/objects.h @@ -8256,8 +8256,9 @@ class AllocationSite: public Struct { class DoNotInlineBit: public BitField {}; // Bitfields for pretenure_data - class MementoFoundCountBits: public BitField {}; - class PretenureDecisionBits: public BitField {}; + class MementoFoundCountBits: public BitField {}; + class PretenureDecisionBits: public BitField {}; + class DeoptDependentCodeBit: public BitField {}; STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue); // Increments the mementos found counter and returns true when the first @@ -8282,6 +8283,18 @@ class AllocationSite: public Struct { SKIP_WRITE_BARRIER); } + bool deopt_dependent_code() { + int value = pretenure_data()->value(); + return DeoptDependentCodeBit::decode(value); + } + + void set_deopt_dependent_code(bool deopt) { + int value = pretenure_data()->value(); + set_pretenure_data( + Smi::FromInt(DeoptDependentCodeBit::update(value, deopt)), + SKIP_WRITE_BARRIER); + } + int memento_found_count() { int value = pretenure_data()->value(); return MementoFoundCountBits::decode(value); -- 2.7.4