From cd203cd6290982bf0fd686a4dbc0f36c4c310518 Mon Sep 17 00:00:00 2001 From: ulan Date: Tue, 3 Feb 2015 09:46:15 -0800 Subject: [PATCH] Verify that code stubs and full code do not have pointers that can retain context. BUG=v8:3629 LOG=N Review URL: https://codereview.chromium.org/879273004 Cr-Commit-Position: refs/heads/master@{#26412} --- src/code-stubs.cc | 3 +++ src/full-codegen.cc | 2 +- src/ic/handler-compiler.cc | 3 +++ src/ic/ic-compiler.cc | 3 +++ src/objects-debug.cc | 45 +++++++++++++++++++++++++++++++++------------ src/objects.h | 3 ++- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/code-stubs.cc b/src/code-stubs.cc index 895569d..3a15fda 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -81,6 +81,9 @@ void CodeStub::RecordCodeGeneration(Handle code) { CodeCreateEvent(Logger::STUB_TAG, *code, os.str().c_str())); Counters* counters = isolate()->counters(); counters->total_stubs_code_size()->Increment(code->instruction_size()); +#ifdef DEBUG + code->VerifyEmbeddedObjects(); +#endif } diff --git a/src/full-codegen.cc b/src/full-codegen.cc index cc32c3e..81f3baa 100644 --- a/src/full-codegen.cc +++ b/src/full-codegen.cc @@ -351,7 +351,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) { #ifdef DEBUG // Check that no context-specific object has been embedded. - code->VerifyEmbeddedObjectsInFullCode(); + code->VerifyEmbeddedObjects(Code::kNoContextSpecificPointers); #endif // DEBUG return true; } diff --git a/src/ic/handler-compiler.cc b/src/ic/handler-compiler.cc index 00df7be..4b253af 100644 --- a/src/ic/handler-compiler.cc +++ b/src/ic/handler-compiler.cc @@ -75,6 +75,9 @@ Handle PropertyHandlerCompiler::GetCode(Code::Kind kind, Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder()); Handle code = GetCodeWithFlags(flags, name); PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, *name)); +#ifdef DEBUG + code->VerifyEmbeddedObjects(); +#endif return code; } diff --git a/src/ic/ic-compiler.cc b/src/ic/ic-compiler.cc index e087acf..7fca34b 100644 --- a/src/ic/ic-compiler.cc +++ b/src/ic/ic-compiler.cc @@ -381,6 +381,9 @@ Handle PropertyICCompiler::GetCode(Code::Kind kind, Code::StubType type, Code::ComputeFlags(kind, state, extra_ic_state_, type, cache_holder()); Handle code = GetCodeWithFlags(flags, name); PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); +#ifdef DEBUG + code->VerifyEmbeddedObjects(); +#endif return code; } diff --git a/src/objects-debug.cc b/src/objects-debug.cc index a8cbe9c..c31a79d 100644 --- a/src/objects-debug.cc +++ b/src/objects-debug.cc @@ -1236,20 +1236,41 @@ bool TransitionArray::IsConsistentWithBackPointers(Map* current_map) { } -void Code::VerifyEmbeddedObjectsInFullCode() { - // Check that no context-specific object has been embedded. +// Estimates if there is a path from the object to a context. +// This function is not precise, and can return false even if +// there is a path to a context. +bool CanLeak(Object* obj, Heap* heap, bool skip_weak_cell) { + if (!obj->IsHeapObject()) return false; + if (obj->IsWeakCell()) { + if (skip_weak_cell) return false; + return CanLeak(WeakCell::cast(obj)->value(), heap, skip_weak_cell); + } + if (obj->IsCell()) { + return CanLeak(Cell::cast(obj)->value(), heap, skip_weak_cell); + } + if (obj->IsPropertyCell()) { + return CanLeak(PropertyCell::cast(obj)->value(), heap, skip_weak_cell); + } + if (obj->IsContext()) return true; + if (obj->IsMap()) { + Map* map = Map::cast(obj); + for (int i = 0; i < Heap::kStrongRootListLength; i++) { + if (map == heap->roots_array_start()[i]) return false; + } + return true; + } + return CanLeak(HeapObject::cast(obj)->map(), heap, skip_weak_cell); +} + + +void Code::VerifyEmbeddedObjects(VerifyMode mode) { + if (kind() == OPTIMIZED_FUNCTION) return; Heap* heap = GetIsolate()->heap(); - int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); + int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | + RelocInfo::ModeMask(RelocInfo::CELL); + bool skip_weak_cell = (mode == kNoContextSpecificPointers) ? false : true; for (RelocIterator it(this, mask); !it.done(); it.next()) { - Object* obj = it.rinfo()->target_object(); - if (obj->IsCell()) obj = Cell::cast(obj)->value(); - if (obj->IsPropertyCell()) obj = PropertyCell::cast(obj)->value(); - if (!obj->IsHeapObject()) continue; - Map* map = obj->IsMap() ? Map::cast(obj) : HeapObject::cast(obj)->map(); - int i = 0; - while (map != heap->roots_array_start()[i++]) { - CHECK_LT(i, Heap::kStrongRootListLength); - } + CHECK(!CanLeak(it.rinfo()->target_object(), heap, skip_weak_cell)); } } diff --git a/src/objects.h b/src/objects.h index e5c55a9..7fa71d4 100644 --- a/src/objects.h +++ b/src/objects.h @@ -5401,7 +5401,8 @@ class Code: public HeapObject { #endif #ifdef DEBUG - void VerifyEmbeddedObjectsInFullCode(); + enum VerifyMode { kNoContextSpecificPointers, kNoContextRetainingPointers }; + void VerifyEmbeddedObjects(VerifyMode mode = kNoContextRetainingPointers); #endif // DEBUG inline bool CanContainWeakObjects() { -- 2.7.4