From 1db0a6a000cdefa452d4b9ac5bc8e99c95e06e78 Mon Sep 17 00:00:00 2001 From: "vegorov@chromium.org" Date: Wed, 19 Jan 2011 11:42:43 +0000 Subject: [PATCH] Make V8 more Valgrind-friendly. While we don't have to flush icache on Intel CPUs when we patch code we still have to call CPU::FlushICache() to notify Valgrind otherwise Valgrind will run incorrect translations which will lead to strange crashes. Review URL: http://codereview.chromium.org/6271008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6391 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ia32/assembler-ia32-inl.h | 10 ++++++++++ src/x64/assembler-x64-inl.h | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/ia32/assembler-ia32-inl.h b/src/ia32/assembler-ia32-inl.h index 54cfb5c..d5fd7b8 100644 --- a/src/ia32/assembler-ia32-inl.h +++ b/src/ia32/assembler-ia32-inl.h @@ -49,20 +49,24 @@ void RelocInfo::apply(intptr_t delta) { if (rmode_ == RUNTIME_ENTRY || IsCodeTarget(rmode_)) { int32_t* p = reinterpret_cast(pc_); *p -= delta; // Relocate entry. + CPU::FlushICache(p, sizeof(uint32_t)); } else if (rmode_ == JS_RETURN && IsPatchedReturnSequence()) { // Special handling of js_return when a break point is set (call // instruction has been inserted). int32_t* p = reinterpret_cast(pc_ + 1); *p -= delta; // Relocate entry. + CPU::FlushICache(p, sizeof(uint32_t)); } else if (rmode_ == DEBUG_BREAK_SLOT && IsPatchedDebugBreakSlotSequence()) { // Special handling of a debug break slot when a break point is set (call // instruction has been inserted). int32_t* p = reinterpret_cast(pc_ + 1); *p -= delta; // Relocate entry. + CPU::FlushICache(p, sizeof(uint32_t)); } else if (IsInternalReference(rmode_)) { // absolute code pointer inside code object moves with the code object. int32_t* p = reinterpret_cast(pc_); *p += delta; // Relocate entry. + CPU::FlushICache(p, sizeof(uint32_t)); } } @@ -111,6 +115,7 @@ Object** RelocInfo::target_object_address() { void RelocInfo::set_target_object(Object* target) { ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); Memory::Object_at(pc_) = target; + CPU::FlushICache(pc_, sizeof(Address)); } @@ -141,6 +146,7 @@ void RelocInfo::set_target_cell(JSGlobalPropertyCell* cell) { ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); Address address = cell->address() + JSGlobalPropertyCell::kValueOffset; Memory::Address_at(pc_) = address; + CPU::FlushICache(pc_, sizeof(Address)); } @@ -189,12 +195,14 @@ void RelocInfo::Visit(ObjectVisitor* visitor) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { visitor->VisitPointer(target_object_address()); + CPU::FlushICache(pc_, sizeof(Address)); } else if (RelocInfo::IsCodeTarget(mode)) { visitor->VisitCodeTarget(this); } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { visitor->VisitGlobalPropertyCell(this); } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { visitor->VisitExternalReference(target_reference_address()); + CPU::FlushICache(pc_, sizeof(Address)); #ifdef ENABLE_DEBUGGER_SUPPORT } else if (Debug::has_break_points() && ((RelocInfo::IsJSReturn(mode) && @@ -214,12 +222,14 @@ void RelocInfo::Visit() { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { StaticVisitor::VisitPointer(target_object_address()); + CPU::FlushICache(pc_, sizeof(Address)); } else if (RelocInfo::IsCodeTarget(mode)) { StaticVisitor::VisitCodeTarget(this); } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { StaticVisitor::VisitGlobalPropertyCell(this); } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { StaticVisitor::VisitExternalReference(target_reference_address()); + CPU::FlushICache(pc_, sizeof(Address)); #ifdef ENABLE_DEBUGGER_SUPPORT } else if (Debug::has_break_points() && ((RelocInfo::IsJSReturn(mode) && diff --git a/src/x64/assembler-x64-inl.h b/src/x64/assembler-x64-inl.h index 1fe9eed..70b40e0 100644 --- a/src/x64/assembler-x64-inl.h +++ b/src/x64/assembler-x64-inl.h @@ -199,8 +199,10 @@ void RelocInfo::apply(intptr_t delta) { if (IsInternalReference(rmode_)) { // absolute code pointer inside code object moves with the code object. Memory::Address_at(pc_) += static_cast(delta); + CPU::FlushICache(pc_, sizeof(Address)); } else if (IsCodeTarget(rmode_)) { Memory::int32_at(pc_) -= static_cast(delta); + CPU::FlushICache(pc_, sizeof(int32_t)); } } @@ -236,6 +238,7 @@ void RelocInfo::set_target_address(Address target) { Assembler::set_target_address_at(pc_, target); } else { Memory::Address_at(pc_) = target; + CPU::FlushICache(pc_, sizeof(Address)); } } @@ -271,6 +274,7 @@ Address* RelocInfo::target_reference_address() { void RelocInfo::set_target_object(Object* target) { ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); *reinterpret_cast(pc_) = target; + CPU::FlushICache(pc_, sizeof(Address)); } @@ -295,6 +299,7 @@ void RelocInfo::set_target_cell(JSGlobalPropertyCell* cell) { ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); Address address = cell->address() + JSGlobalPropertyCell::kValueOffset; Memory::Address_at(pc_) = address; + CPU::FlushICache(pc_, sizeof(Address)); } @@ -331,6 +336,8 @@ void RelocInfo::set_call_address(Address target) { (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); Memory::Address_at(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset) = target; + CPU::FlushICache(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset, + sizeof(Address)); } @@ -356,10 +363,12 @@ void RelocInfo::Visit(ObjectVisitor* visitor) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { visitor->VisitPointer(target_object_address()); + CPU::FlushICache(pc_, sizeof(Address)); } else if (RelocInfo::IsCodeTarget(mode)) { visitor->VisitCodeTarget(this); } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { visitor->VisitExternalReference(target_reference_address()); + CPU::FlushICache(pc_, sizeof(Address)); #ifdef ENABLE_DEBUGGER_SUPPORT } else if (Debug::has_break_points() && ((RelocInfo::IsJSReturn(mode) && @@ -379,10 +388,12 @@ void RelocInfo::Visit() { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { StaticVisitor::VisitPointer(target_object_address()); + CPU::FlushICache(pc_, sizeof(Address)); } else if (RelocInfo::IsCodeTarget(mode)) { StaticVisitor::VisitCodeTarget(this); } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { StaticVisitor::VisitExternalReference(target_reference_address()); + CPU::FlushICache(pc_, sizeof(Address)); #ifdef ENABLE_DEBUGGER_SUPPORT } else if (Debug::has_break_points() && ((RelocInfo::IsJSReturn(mode) && -- 2.7.4