diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index f88cdeddb2a237..89cf41c1f70d52 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 4 #define V8_MINOR_VERSION 5 #define V8_BUILD_NUMBER 103 -#define V8_PATCH_LEVEL 44 +#define V8_PATCH_LEVEL 45 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/heap/heap-inl.h b/deps/v8/src/heap/heap-inl.h index fdb1d7345b4d79..20540b9e88e992 100644 --- a/deps/v8/src/heap/heap-inl.h +++ b/deps/v8/src/heap/heap-inl.h @@ -393,13 +393,11 @@ bool Heap::AllowedToBeMigrated(HeapObject* obj, AllocationSpace dst) { return false; } - void Heap::CopyBlock(Address dst, Address src, int byte_size) { CopyWords(reinterpret_cast(dst), reinterpret_cast(src), static_cast(byte_size / kPointerSize)); } - void Heap::MoveBlock(Address dst, Address src, int byte_size) { DCHECK(IsAligned(byte_size, kPointerSize)); diff --git a/deps/v8/src/heap/heap.cc b/deps/v8/src/heap/heap.cc index 6bc200a0e59289..7730327b412d73 100644 --- a/deps/v8/src/heap/heap.cc +++ b/deps/v8/src/heap/heap.cc @@ -5316,6 +5316,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(*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
(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(next); + } + DCHECK(current->IsFixedArrayBase()); +#endif // DEBUG + *p = nullptr; + } + } + + Heap* heap_; +}; void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); @@ -5339,6 +5382,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/deps/v8/src/heap/mark-compact.cc b/deps/v8/src/heap/mark-compact.cc index dcc2fb943046d6..c827237598ee43 100644 --- a/deps/v8/src/heap/mark-compact.cc +++ b/deps/v8/src/heap/mark-compact.cc @@ -1648,8 +1648,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 (Marking::IsBlackOrGrey(mark_bit)) return; diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h index 3caf52bff4b086..3e91c2bac97051 100644 --- a/deps/v8/src/objects-inl.h +++ b/deps/v8/src/objects-inl.h @@ -1351,7 +1351,7 @@ Map* MapWord::ToMap() { } -bool MapWord::IsForwardingAddress() { +bool MapWord::IsForwardingAddress() const { return HAS_SMI_TAG(reinterpret_cast(value_)); } diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h index 1c5743eb838918..5481b1834de762 100644 --- a/deps/v8/src/objects.h +++ b/deps/v8/src/objects.h @@ -1382,7 +1382,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/deps/v8/test/mjsunit/regress/regress-620553.js b/deps/v8/test/mjsunit/regress/regress-620553.js new file mode 100644 index 00000000000000..461b9bb189e559 --- /dev/null +++ b/deps/v8/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/deps/v8/test/mjsunit/regress/regress-621869.js b/deps/v8/test/mjsunit/regress/regress-621869.js new file mode 100644 index 00000000000000..ee1b58b0266032 --- /dev/null +++ b/deps/v8/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]; \ No newline at end of file