From bbbab4821cbf1c4b3005a199e8b2ebe1b04d73c0 Mon Sep 17 00:00:00 2001 From: "sgjesse@chromium.org" Date: Tue, 9 Dec 2008 12:53:59 +0000 Subject: [PATCH] Refactor the convertion of a target address into a code object from the debugger to the Code class. Review URL: http://codereview.chromium.org/13285 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@952 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/assembler.cc | 2 +- src/debug.cc | 18 +++++------------- src/debug.h | 1 - src/disassembler.cc | 2 +- src/ic-inl.h | 11 ++++------- src/objects-inl.h | 11 +++++++++++ src/objects.h | 2 ++ test/cctest/test-debug.cc | 2 +- 8 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/assembler.cc b/src/assembler.cc index 1fd0dc3..c56eb2f 100644 --- a/src/assembler.cc +++ b/src/assembler.cc @@ -450,7 +450,7 @@ void RelocInfo::Print() { ref_encoder.NameOfAddress(*target_reference_address()), *target_reference_address()); } else if (IsCodeTarget(rmode_)) { - Code* code = Debug::GetCodeTarget(target_address()); + Code* code = Code::GetCodeFromTargetAddress(target_address()); PrintF(" (%s) (%p)", Code::Kind2String(code->kind()), target_address()); } else if (IsPosition(rmode_)) { PrintF(" (%d)", data()); diff --git a/src/debug.cc b/src/debug.cc index 6952d8b..f31b475 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -113,7 +113,7 @@ void BreakLocationIterator::Next() { // be of a different kind than in the original code. if (RelocInfo::IsCodeTarget(rmode())) { Address target = original_rinfo()->target_address(); - Code* code = Debug::GetCodeTarget(target); + Code* code = Code::GetCodeFromTargetAddress(target); if (code->is_inline_cache_stub() || RelocInfo::IsConstructCall(rmode())) { break_point_++; return; @@ -325,7 +325,7 @@ void BreakLocationIterator::PrepareStepIn() { // Step in can only be prepared if currently positioned on an IC call or // construct call. Address target = rinfo()->target_address(); - Code* code = Debug::GetCodeTarget(target); + Code* code = Code::GetCodeFromTargetAddress(target); if (code->is_call_stub()) { // Step in through IC call is handled by the runtime system. Therefore make // sure that the any current IC is cleared and the runtime system is @@ -923,7 +923,7 @@ void Debug::PrepareStep(StepAction step_action, int step_count) { bool is_call_target = false; if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) { Address target = it.rinfo()->target_address(); - Code* code = Debug::GetCodeTarget(target); + Code* code = Code::GetCodeFromTargetAddress(target); if (code->is_call_stub()) is_call_target = true; } @@ -991,7 +991,7 @@ bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator, // Check whether the code object at the specified address is a debug break code // object. bool Debug::IsDebugBreak(Address addr) { - Code* code = GetCodeTarget(addr); + Code* code = Code::GetCodeFromTargetAddress(addr); return code->ic_state() == DEBUG_BREAK; } @@ -1021,7 +1021,7 @@ Handle Debug::FindDebugBreak(RelocInfo* rinfo) { if (RelocInfo::IsCodeTarget(mode)) { Address target = rinfo->target_address(); - Code* code = Debug::GetCodeTarget(target); + Code* code = Code::GetCodeFromTargetAddress(target); if (code->is_inline_cache_stub()) { if (code->is_call_stub()) { return ComputeCallDebugBreak(code->arguments_count()); @@ -1262,14 +1262,6 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { } -Code* Debug::GetCodeTarget(Address target) { - // Maybe this can be refactored with the stuff in ic-inl.h? - Code* result = - Code::cast(HeapObject::FromAddress(target - Code::kHeaderSize)); - return result; -} - - bool Debug::IsDebugGlobal(GlobalObject* global) { return IsLoaded() && global == Debug::debug_context()->global(); } diff --git a/src/debug.h b/src/debug.h index d1615a3..a5f9b20 100644 --- a/src/debug.h +++ b/src/debug.h @@ -194,7 +194,6 @@ class Debug { static Handle GetSourceBreakLocations( Handle shared); - static Code* GetCodeTarget(Address target); // Getter for the debug_context. inline static Handle debug_context() { return debug_context_; } diff --git a/src/disassembler.cc b/src/disassembler.cc index 53f594f..af7df26 100644 --- a/src/disassembler.cc +++ b/src/disassembler.cc @@ -228,7 +228,7 @@ static int DecodeIt(FILE* f, if (rmode == RelocInfo::CONSTRUCT_CALL) { out.AddFormatted(" constructor,"); } - Code* code = Debug::GetCodeTarget(relocinfo.target_address()); + Code* code = Code::GetCodeFromTargetAddress(relocinfo.target_address()); Code::Kind kind = code->kind(); if (code->is_inline_cache_stub()) { if (rmode == RelocInfo::CODE_TARGET_CONTEXT) { diff --git a/src/ic-inl.h b/src/ic-inl.h index 201048a..f5ce0ad 100644 --- a/src/ic-inl.h +++ b/src/ic-inl.h @@ -59,14 +59,11 @@ Address IC::address() { Code* IC::GetTargetAtAddress(Address address) { + // Get the target address of the IC. Address target = Assembler::target_address_at(address); - HeapObject* code = HeapObject::FromAddress(target - Code::kHeaderSize); - // GetTargetAtAddress is called from IC::Clear which in turn is - // called when marking objects during mark sweep. reinterpret_cast - // is therefore used instead of the more appropriate - // Code::cast. Code::cast does not work when the object's map is - // marked. - Code* result = reinterpret_cast(code); + // Convert target address to the code object. Code::GetCodeFromTargetAddress + // is safe for use during GC where the map might be marked. + Code* result = Code::GetCodeFromTargetAddress(target); ASSERT(result->is_inline_cache_stub()); return result; } diff --git a/src/objects-inl.h b/src/objects-inl.h index e8c4e91..5c70463 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1877,6 +1877,17 @@ Code::Flags Code::RemoveTypeFromFlags(Flags flags) { } +Code* Code::GetCodeFromTargetAddress(Address address) { + HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize); + // GetCodeFromTargetAddress might be called when marking objects during mark + // sweep. reinterpret_cast is therefore used instead of the more appropriate + // Code::cast. Code::cast does not work when the object's map is + // marked. + Code* result = reinterpret_cast(code); + return result; +} + + Object* Map::prototype() { return READ_FIELD(this, kPrototypeOffset); } diff --git a/src/objects.h b/src/objects.h index b7e77c2..f400e99 100644 --- a/src/objects.h +++ b/src/objects.h @@ -2201,6 +2201,8 @@ class Code: public HeapObject { static inline int ExtractArgumentsCountFromFlags(Flags flags); static inline Flags RemoveTypeFromFlags(Flags flags); + // Convert a target address into a code object. + static inline Code* GetCodeFromTargetAddress(Address address); // Returns the address of the first instruction. inline byte* instruction_start(); diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc index 81ce21f..570256e 100644 --- a/test/cctest/test-debug.cc +++ b/test/cctest/test-debug.cc @@ -397,7 +397,7 @@ void CheckDebugBreakFunction(DebugLocalContext* env, CHECK_EQ(mode, it1.it()->rinfo()->rmode()); if (mode != v8::internal::RelocInfo::JS_RETURN) { CHECK_EQ(debug_break, - Debug::GetCodeTarget(it1.it()->rinfo()->target_address())); + Code::GetCodeFromTargetAddress(it1.it()->rinfo()->target_address())); } else { // TODO(1240753): Make the test architecture independent or split // parts of the debugger into architecture dependent files. -- 2.7.4