Reviewers: Hannes Payer,
Message:
For discussion. In my local testing (V8 test suite; loading a handful of
websites in Chrome), this didn't flush out any issues. Do we want to land it
anyway, for the benefit of future/broader coverage?
Description:
Introduce --zap-cpp-pointers (off by default)
On GC, zaps heap pointers in C++ stack frames.
Please review this at https://codereview.chromium.org/1108013003/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+81, -0 lines):
M src/flag-definitions.h
M src/frames.h
M src/frames.cc
M src/heap/heap.cc
M src/heap/incremental-marking.cc
Index: src/flag-definitions.h
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index
c16b2d63c167d342b2955a7a7e5b6da993460422..bfc1076b7272fe844e3a9e29b99ab92023896c84
100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -558,6 +558,8 @@ DEFINE_INT(stack_size, V8_DEFAULT_STACK_SIZE_KB,
// frames.cc
DEFINE_INT(max_stack_trace_source_length, 300,
"maximum length of function source code printed in a stack
trace.")
+DEFINE_BOOL(zap_cpp_pointers, false,
+ "zap heap pointers on the C++ stack during GC (Debug mode
only)")
// full-codegen.cc
DEFINE_BOOL(always_inline_smi_code, false,
Index: src/frames.cc
diff --git a/src/frames.cc b/src/frames.cc
index
f52b3ce4e47a1bf0fd099723fb36d0f0ac604128..9ac127bf0ea372fac67ffd7894ff4d99b577f7c5
100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -1520,4 +1520,70 @@ Vector<StackFrame*> CreateStackMap(Isolate* isolate,
Zone* zone) {
}
+#ifdef DEBUG
+
+void ZapHeapPointersInCppFrames(Isolate* isolate, ThreadLocalTop* t) {
+ DCHECK(FLAG_zap_cpp_pointers);
+ if (t == NULL) t = isolate->thread_local_top();
+ for (StackFrameIterator it(isolate, t); !it.done(); it.Advance()) {
+ if (it.frame()->type() != StackFrame::ENTRY) continue;
+
+ EntryFrame* frame = reinterpret_cast<EntryFrame*>(it.frame());
+ // Stack layout (in case there is an exit frame):
+ // - entry frame's FP <-- frame->fp()
+ // - saved C++ PC
+ // - last C++ stack slot <-- cpp_start
+ // [C++ stuff...]
+ // - saved FP <-- cpp_limit (exclusive)
+ // - saved CEntry PC
+ // - exit frame's SP <-- caller_sp
+ // [exit frame's contents...]
+ // - exit frame's FP <-- caller_fp
+
+ // Add 2 * kPointerSize for next FP and caller's PC.
+ Address cpp_start = frame->fp() + 2 * kPointerSize;
+
+ Address cpp_limit;
+ const int offset = EntryFrameConstants::kCallerFPOffset;
+ Address caller_fp = Memory::Address_at(frame->fp() + offset);
+
+ if (caller_fp != NULL) {
+ // If there's a previous JavaScript exit frame, stop iterating at
its top.
+ const int sp_offset = ExitFrameConstants::kSPOffset;
+ Address caller_sp = Memory::Address_at(caller_fp + sp_offset);
+ // Subtract 2 * kPointerSize for CEntry PC and next FP.
+ cpp_limit = caller_sp - 2 * kPointerSize;
+ } else {
+ DCHECK(caller_fp == NULL);
+ // Reverse the original calculation how the C stack limit was set
+ // in StackGuard::ThreadLocal::Initialize() to estimate the base of
+ // the process' stack.
+ uintptr_t climit = isolate->stack_guard()->real_climit();
+ cpp_limit = reinterpret_cast<Address>(climit) + FLAG_stack_size * KB;
+ }
+
+ PrintF("Iterating EntryFrame, fp=%p, caller_fp=%p\n", frame->fp(),
+ caller_fp);
+ PrintF("Iterating from %p to %p\n", cpp_start, cpp_limit);
+
+ Heap* heap = isolate->heap();
+ NewSpace* new_space = heap->new_space();
+ OldSpace* old_space = heap->old_space();
+ MapSpace* map_space = heap->map_space();
+ LargeObjectSpace* lo_space = heap->lo_space();
+ Object* start_obj = reinterpret_cast<Object*>(cpp_start);
+ Object* limit_obj = reinterpret_cast<Object*>(cpp_limit);
+ for (Object** p = &start_obj; p < &limit_obj; ++p) {
+ if (!(*p)->IsHeapObject()) continue;
+ HeapObject* obj = HeapObject::cast(*p);
+ if (new_space->Contains(obj) || old_space->Contains(obj) ||
+ map_space->Contains(obj) || lo_space->Contains(obj)) {
+ PrintF("Found heap pointer: %p, zapping it!\n", obj);
+ *p = reinterpret_cast<Object*>(kZapValue);
+ }
+ }
+ }
+}
+
+#endif
} } // namespace v8::internal
Index: src/frames.h
diff --git a/src/frames.h b/src/frames.h
index
397c7b5db9cf7f912d7c3fe53a9392141b913ae2..fb1771baae7ec548088ce90f0b5a4d7c7c419130
100644
--- a/src/frames.h
+++ b/src/frames.h
@@ -901,6 +901,13 @@ class StackFrameLocator BASE_EMBEDDED {
// zone memory.
Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
+#ifdef DEBUG
+// Walks the stack, finds sections belonging to C++ frames, looks for
values
+// that look like heap pointers inside them, and zaps them. Intended to
flush
+// out GC safety issues; only call this when the program must be prepared
for
+// GC to happen.
+void ZapHeapPointersInCppFrames(Isolate* isolate, ThreadLocalTop* t =
NULL);
+#endif
} } // namespace v8::internal
#endif // V8_FRAMES_H_
Index: src/heap/heap.cc
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index
8d34738dae81757b9e5918875d6adf41cecf98bb..b3e50b8493502f45207641c2e2cd89c6a3027fda
100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -857,6 +857,8 @@ bool Heap::CollectGarbage(GarbageCollector collector,
const char* gc_reason,
// assume that a garbage collection will allow the subsequent
// allocation attempts to go through.
allocation_timeout_ = Max(6, FLAG_gc_interval);
+
+ if (FLAG_zap_cpp_pointers) ZapHeapPointersInCppFrames(isolate());
#endif
EnsureFillerObjectAtTop();
Index: src/heap/incremental-marking.cc
diff --git a/src/heap/incremental-marking.cc
b/src/heap/incremental-marking.cc
index
2ba969432d0a009690f08226e19af6086e8da719..4524ce45a6515c7d8944ecc61301f9db4b25871f
100644
--- a/src/heap/incremental-marking.cc
+++ b/src/heap/incremental-marking.cc
@@ -899,6 +899,10 @@ intptr_t IncrementalMarking::Step(intptr_t
allocated_bytes,
return 0;
}
+#ifdef DEBUG
+ if (FLAG_zap_cpp_pointers) ZapHeapPointersInCppFrames(heap_->isolate());
+#endif
+
allocated_ += allocated_bytes;
if (marking == DO_NOT_FORCE_MARKING && allocated_ < kAllocatedThreshold
&&
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.