The way reloc entries are visited by the ObjectVisitor is architecture

dependent, so we push it down to the architecture dependent files.
Currently all architectures visit in almost the same way, but this is
about to change on ARM with movw/movt.
Review URL: http://codereview.chromium.org/2218002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4721 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
erik.corry@gmail.com 2010-05-26 08:34:07 +00:00
parent 95939ada29
commit e66f276e46
6 changed files with 105 additions and 20 deletions

View File

@ -39,6 +39,7 @@
#include "arm/assembler-arm.h"
#include "cpu.h"
#include "debug.h"
namespace v8 {
@ -73,6 +74,11 @@ Address RelocInfo::target_address_address() {
}
int RelocInfo::target_address_size() {
return Assembler::kExternalTargetSize;
}
void RelocInfo::set_target_address(Address target) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
Assembler::set_target_address_at(pc_, target);
@ -162,6 +168,26 @@ bool RelocInfo::IsPatchedReturnSequence() {
}
void RelocInfo::Visit(ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitPointer(target_object_address());
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(target_reference_address());
#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (Debug::has_break_points() &&
RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) {
visitor->VisitDebugTarget(this);
#endif
} else if (mode == RelocInfo::RUNTIME_ENTRY) {
visitor->VisitRuntimeEntry(this);
}
}
Operand::Operand(int32_t immediate, RelocInfo::Mode rmode) {
rm_ = no_reg;
imm32_ = immediate;

View File

@ -38,6 +38,7 @@
#include "runtime.h"
#include "top.h"
#include "token.h"
#include "objects.h"
namespace v8 {
namespace internal {
@ -199,9 +200,23 @@ class RelocInfo BASE_EMBEDDED {
INLINE(Object** target_object_address());
INLINE(void set_target_object(Object* target));
// Read the address of the word containing the target_address. Can only
// be called if IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY.
// Read the address of the word containing the target_address in an
// instruction stream. What this means exactly is architecture-independent.
// The only architecture-independent user of this function is the serializer.
// The serializer uses it to find out how many raw bytes of instruction to
// output before the next target. Architecture-independent code shouldn't
// dereference the pointer it gets back from this.
INLINE(Address target_address_address());
// This indicates how much space a target takes up when deserializing a code
// stream. For most architectures this is just the size of a pointer. For
// an instruction like movw/movt where the target bits are mixed into the
// instruction bits the size of the target will be zero, indicating that the
// serializer should not step forwards in memory after a target is resolved
// and written. In this case the target_address_address function above
// should return the end of the instructions to be patched, allowing the
// deserializer to deserialize the instructions as raw bytes and put them in
// place, ready to be patched with the target.
INLINE(int target_address_size());
// Read/modify the reference in the instruction this relocation
// applies to; can only be called if rmode_ is external_reference
@ -216,6 +231,8 @@ class RelocInfo BASE_EMBEDDED {
INLINE(Object** call_object_address());
INLINE(void set_call_object(Object* target));
inline void Visit(ObjectVisitor* v);
// Patch the code with some other code.
void PatchCode(byte* instructions, int instruction_count);

View File

@ -38,6 +38,7 @@
#define V8_IA32_ASSEMBLER_IA32_INL_H_
#include "cpu.h"
#include "debug.h"
namespace v8 {
namespace internal {
@ -77,6 +78,11 @@ Address RelocInfo::target_address_address() {
}
int RelocInfo::target_address_size() {
return Assembler::kExternalTargetSize;
}
void RelocInfo::set_target_address(Address target) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
Assembler::set_target_address_at(pc_, target);
@ -148,6 +154,26 @@ bool RelocInfo::IsPatchedReturnSequence() {
}
void RelocInfo::Visit(ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitPointer(target_object_address());
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(target_reference_address());
#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (Debug::has_break_points() &&
RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) {
visitor->VisitDebugTarget(this);
#endif
} else if (mode == RelocInfo::RUNTIME_ENTRY) {
visitor->VisitRuntimeEntry(this);
}
}
Immediate::Immediate(int x) {
x_ = x;
rmode_ = RelocInfo::NONE;

View File

@ -5271,22 +5271,7 @@ void Code::CodeIterateBody(ObjectVisitor* v) {
RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
RelocInfo::Mode rmode = it.rinfo()->rmode();
if (rmode == RelocInfo::EMBEDDED_OBJECT) {
v->VisitPointer(it.rinfo()->target_object_address());
} else if (RelocInfo::IsCodeTarget(rmode)) {
v->VisitCodeTarget(it.rinfo());
} else if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
v->VisitExternalReference(it.rinfo()->target_reference_address());
#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (Debug::has_break_points() &&
RelocInfo::IsJSReturn(rmode) &&
it.rinfo()->IsPatchedReturnSequence()) {
v->VisitDebugTarget(it.rinfo());
#endif
} else if (rmode == RelocInfo::RUNTIME_ENTRY) {
v->VisitRuntimeEntry(it.rinfo());
}
it.rinfo()->Visit(v);
}
ScopeInfo<>::IterateScopeInfo(this, v);

View File

@ -1299,7 +1299,7 @@ void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
}
sink_->Put(kExternalReference + representation, "ExternalReference");
sink_->PutInt(encoding, "reference id");
bytes_processed_so_far_ += Assembler::kExternalTargetSize;
bytes_processed_so_far_ += rinfo->target_address_size();
}
@ -1309,7 +1309,7 @@ void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) {
OutputRawData(target_start);
Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
serializer_->SerializeObject(target, kFromCode, kFirstInstruction);
bytes_processed_so_far_ += Assembler::kCallTargetSize;
bytes_processed_so_far_ += rinfo->target_address_size();
}

View File

@ -29,6 +29,7 @@
#define V8_X64_ASSEMBLER_X64_INL_H_
#include "cpu.h"
#include "debug.h"
#include "memory.h"
namespace v8 {
@ -229,6 +230,15 @@ Address RelocInfo::target_address_address() {
}
int RelocInfo::target_address_size() {
if (IsCodedSpecially()) {
return Assembler::kCallTargetSize;
} else {
return Assembler::kExternalTargetSize;
}
}
void RelocInfo::set_target_address(Address target) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
if (IsCodeTarget(rmode_)) {
@ -320,6 +330,27 @@ Object** RelocInfo::call_object_address() {
pc_ + Assembler::kPatchReturnSequenceAddressOffset);
}
void RelocInfo::Visit(ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitPointer(target_object_address());
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(target_reference_address());
#ifdef ENABLE_DEBUGGER_SUPPORT
} else if (Debug::has_break_points() &&
RelocInfo::IsJSReturn(mode) &&
IsPatchedReturnSequence()) {
visitor->VisitDebugTarget(this);
#endif
} else if (mode == RelocInfo::RUNTIME_ENTRY) {
visitor->VisitRuntimeEntry(this);
}
}
// -----------------------------------------------------------------------------
// Implementation of Operand