summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormlippautz <mlippautz@chromium.org>2016-06-30 12:50:19 +0200
committerMSe <mse1969@posteo.de>2017-05-26 17:14:24 +0200
commit006c8369fb84fe650fbaf01d889a6a692d3eb05d (patch)
tree52e5a2cd0a20bfb074ec978a6398fc3ebaefa436
parent57a14c9a8621270b0e6c697dce28a9c453ebe55f (diff)
downloadandroid_external_v8-cm-13.0_20181118.tar.gz
android_external_v8-cm-13.0_20181118.tar.bz2
android_external_v8-cm-13.0_20181118.zip
[Backport] Version 5.2.361.32 (cherry-pick)replicant-6.0-0002cm-13.0_20181118
Merged d800a65967b115c6e1aa6c3ba08861a304383088 Merged 7a88ff3cc096ecd681e9d10ad0a75c7d3daf027e Merged a7159577b7d092ef6283c51f8bb2c456b0e23a38 [heap] Filter out stale left-trimmed handles [heap] Filter out stale left-trimmed handles for scavenges [heap] Iterate handles with special left-trim visitor BUG=chromium:620553,chromium:620553,chromium:621869 LOG=N R=hablich@chromium.org, hpayer@chromium.org NOTRY=true NOPRESUBMIT=true Change-Id: I99887c9c197708817a1c69acf4135a7e29a7508b Review-Url: https://codereview.chromium.org/2111133002 Cr-Commit-Position: refs/branch-heads/5.2@{#38} Cr-Branched-From: 2cd36d6d0439ddfbe84cd90e112dced85084ec95-refs/heads/5.2.361@{#1} Cr-Branched-From: 3fef34e02388e07d46067c516320f1ff12304c8e-refs/heads/master@{#36332}
-rw-r--r--src/heap/heap.cc45
-rw-r--r--src/heap/mark-compact.cc2
-rw-r--r--src/objects-inl.h3
-rw-r--r--src/objects.h2
-rw-r--r--test/mjsunit/regress/regress-620553.js17
-rw-r--r--test/mjsunit/regress/regress-621869.js18
6 files changed, 83 insertions, 4 deletions
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index dfe60fed..0e259e6f 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -4743,6 +4743,49 @@ void Heap::IterateSmiRoots(ObjectVisitor* v) {
v->Synchronize(VisitorSynchronization::kSmiRootList);
}
+// We cannot avoid stale handles to left-trimmed objects, but can only make
+// sure all handles still needed are updated. Filter out a stale pointer
+// and clear the slot to allow post processing of handles (needed because
+// the sweeper might actually free the underlying page).
+class FixStaleLeftTrimmedHandlesVisitor : public ObjectVisitor {
+ public:
+ explicit FixStaleLeftTrimmedHandlesVisitor(Heap* heap) : heap_(heap) {
+ USE(heap_);
+ }
+
+ void VisitPointer(Object** p) override { FixHandle(p); }
+
+ void VisitPointers(Object** start, Object** end) override {
+ for (Object** p = start; p < end; p++) FixHandle(p);
+ }
+
+ private:
+ inline void FixHandle(Object** p) {
+ HeapObject* current = reinterpret_cast<HeapObject*>(*p);
+ if (!current->IsHeapObject()) return;
+ const MapWord map_word = current->map_word();
+ if (!map_word.IsForwardingAddress() && current->IsFiller()) {
+#ifdef DEBUG
+ // We need to find a FixedArrayBase map after walking the fillers.
+ while (current->IsFiller()) {
+ Address next = reinterpret_cast<Address>(current);
+ if (current->map() == heap_->one_pointer_filler_map()) {
+ next += kPointerSize;
+ } else if (current->map() == heap_->two_pointer_filler_map()) {
+ next += 2 * kPointerSize;
+ } else {
+ next += current->Size();
+ }
+ current = reinterpret_cast<HeapObject*>(next);
+ }
+ DCHECK(current->IsFixedArrayBase());
+#endif // DEBUG
+ *p = nullptr;
+ }
+ }
+
+ Heap* heap_;
+};
void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
@@ -4766,6 +4809,8 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
v->Synchronize(VisitorSynchronization::kCompilationCache);
// Iterate over local handles in handle scopes.
+ FixStaleLeftTrimmedHandlesVisitor left_trim_visitor(this);
+ isolate_->handle_scope_implementer()->Iterate(&left_trim_visitor);
isolate_->handle_scope_implementer()->Iterate(v);
isolate_->IterateDeferredHandles(v);
v->Synchronize(VisitorSynchronization::kHandleScope);
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index 9f9a658c..ca4d8d74 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -1787,8 +1787,8 @@ class RootMarkingVisitor : public ObjectVisitor {
void MarkObjectByPointer(Object** p) {
if (!(*p)->IsHeapObject()) return;
- // Replace flat cons strings in place.
HeapObject* object = ShortCircuitConsString(p);
+
MarkBit mark_bit = Marking::MarkBitFrom(object);
if (mark_bit.Get()) return;
diff --git a/src/objects-inl.h b/src/objects-inl.h
index e46dd8e7..e4cb2d28 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1347,8 +1347,7 @@ Map* MapWord::ToMap() {
return reinterpret_cast<Map*>(value_);
}
-
-bool MapWord::IsForwardingAddress() {
+bool MapWord::IsForwardingAddress() const {
return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
}
diff --git a/src/objects.h b/src/objects.h
index 33403501..df782f9e 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1294,7 +1294,7 @@ class MapWord BASE_EMBEDDED {
// True if this map word is a forwarding address for a scavenge
// collection. Only valid during a scavenge collection (specifically,
// when all map words are heap object pointers, i.e. not during a full GC).
- inline bool IsForwardingAddress();
+ inline bool IsForwardingAddress() const;
// Create a map word from a forwarding address.
static inline MapWord FromForwardingAddress(HeapObject* object);
diff --git a/test/mjsunit/regress/regress-620553.js b/test/mjsunit/regress/regress-620553.js
new file mode 100644
index 00000000..461b9bb1
--- /dev/null
+++ b/test/mjsunit/regress/regress-620553.js
@@ -0,0 +1,17 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-gc
+
+var o0 = [];
+var o1 = [];
+var cnt = 0;
+o1.__defineGetter__(0, function() {
+ if (cnt++ > 2) return;
+ o0.shift();
+ gc();
+ o0.push(0);
+ o0.concat(o1);
+});
+o1[0];
diff --git a/test/mjsunit/regress/regress-621869.js b/test/mjsunit/regress/regress-621869.js
new file mode 100644
index 00000000..db340644
--- /dev/null
+++ b/test/mjsunit/regress/regress-621869.js
@@ -0,0 +1,18 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-gc
+
+var o0 = [];
+var o1 = [];
+var cnt = 0;
+var only_scavenge = true;
+o1.__defineGetter__(0, function() {
+ if (cnt++ > 2) return;
+ o0.shift();
+ gc(only_scavenge);
+ o0.push((64));
+ o0.concat(o1);
+});
+o1[0];