Bugfix: dependent code field in AllocationSite was keeping code objects alive even after context death.

BUG=320532
LOG=Y
R=ulan@chromium.org

Review URL: https://codereview.chromium.org/62803008

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17856 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mvstanton@chromium.org 2013-11-19 10:17:33 +00:00
parent e2613ce7ba
commit bff41483dc
6 changed files with 89 additions and 5 deletions

View File

@ -1784,6 +1784,8 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
mark_compact_collector()->is_compacting();
ProcessArrayBuffers(retainer, record_slots);
ProcessNativeContexts(retainer, record_slots);
// TODO(mvstanton): AllocationSites only need to be processed during
// MARK_COMPACT, as they live in old space. Verify and address.
ProcessAllocationSites(retainer, record_slots);
}
@ -1889,7 +1891,7 @@ struct WeakListVisitor<AllocationSite> {
}
static void VisitLiveObject(Heap* heap,
AllocationSite* array_buffer,
AllocationSite* site,
WeakObjectRetainer* retainer,
bool record_slots) {}

View File

@ -2541,6 +2541,17 @@ void MarkCompactCollector::ClearNonLiveReferences() {
}
}
// Iterate over allocation sites, removing dependent code that is not
// otherwise kept alive by strong references.
Object* undefined = heap()->undefined_value();
for (Object* site = heap()->allocation_sites_list();
site != undefined;
site = AllocationSite::cast(site)->weak_next()) {
if (IsMarked(site)) {
ClearNonLiveDependentCode(AllocationSite::cast(site)->dependent_code());
}
}
if (heap_->weak_object_to_code_table()->IsHashTable()) {
WeakHashTable* table =
WeakHashTable::cast(heap_->weak_object_to_code_table());

View File

@ -189,10 +189,7 @@ void StaticMarkingVisitor<StaticVisitor>::Initialize() {
table_.Register(kVisitNativeContext, &VisitNativeContext);
table_.Register(kVisitAllocationSite,
&FixedBodyVisitor<StaticVisitor,
AllocationSite::BodyDescriptor,
void>::Visit);
table_.Register(kVisitAllocationSite, &VisitAllocationSite);
table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
@ -388,6 +385,31 @@ void StaticMarkingVisitor<StaticVisitor>::VisitPropertyCell(
}
template<typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitAllocationSite(
Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
Object** slot =
HeapObject::RawField(object, AllocationSite::kDependentCodeOffset);
if (FLAG_collect_maps) {
// Mark allocation site dependent codes array but do not push it onto
// marking stack, this will make references from it weak. We will clean
// dead codes when we iterate over allocation sites in
// ClearNonLiveReferences.
HeapObject* obj = HeapObject::cast(*slot);
heap->mark_compact_collector()->RecordSlot(slot, slot, obj);
StaticVisitor::MarkObjectWithoutPush(heap, obj);
} else {
StaticVisitor::VisitPointer(heap, slot);
}
StaticVisitor::VisitPointers(heap,
HeapObject::RawField(object, AllocationSite::kPointerFieldsBeginOffset),
HeapObject::RawField(object, AllocationSite::kPointerFieldsEndOffset));
}
template<typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitCode(
Map* map, HeapObject* object) {

View File

@ -399,6 +399,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
}
INLINE(static void VisitPropertyCell(Map* map, HeapObject* object));
INLINE(static void VisitAllocationSite(Map* map, HeapObject* object));
INLINE(static void VisitCodeEntry(Heap* heap, Address entry_address));
INLINE(static void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo));
INLINE(static void VisitCell(Heap* heap, RelocInfo* rinfo));

View File

@ -8189,6 +8189,12 @@ class AllocationSite: public Struct {
static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize;
static const int kSize = kWeakNextOffset + kPointerSize;
// During mark compact we need to take special care for the dependent code
// field.
static const int kPointerFieldsBeginOffset = kTransitionInfoOffset;
static const int kPointerFieldsEndOffset = kDependentCodeOffset;
// For other visitors, use the fixed body descriptor below.
typedef FixedBodyDescriptor<HeapObject::kHeaderSize,
kDependentCodeOffset + kPointerSize,
kSize> BodyDescriptor;

View File

@ -0,0 +1,42 @@
// Copyright 2013 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:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (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: --track-allocation-sites --noalways-opt
// Flags: --stress-runs=8 --send-idle-notification --gc-global
function bar() { return new Array(); }
bar();
bar();
%OptimizeFunctionOnNextCall(bar);
a = bar();
function foo(len) { return new Array(len); }
foo(0);
foo(0);
%OptimizeFunctionOnNextCall(bar);
foo(0);