Commit 52cef3f0 authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

Orthogonalize the byte codes used for the snapshot so that

the issue of how the pointee is found and how the pointer
is encoded are separated out.  This will make it simpler to
support various pointers from and to code in the future.
Review URL: http://codereview.chromium.org/2069013

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4687 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 355d3166
...@@ -108,6 +108,15 @@ void CpuFeatures::Probe() { ...@@ -108,6 +108,15 @@ void CpuFeatures::Probe() {
const int RelocInfo::kApplyMask = 0; const int RelocInfo::kApplyMask = 0;
bool RelocInfo::IsCodedSpecially() {
// The deserializer needs to know whether a pointer is specially coded. Being
// specially coded on ARM means that it is a movw/movt instruction. We don't
// generate those yet.
return false;
}
void RelocInfo::PatchCode(byte* instructions, int instruction_count) { void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
// Patch the code at the current address with the supplied instructions. // Patch the code at the current address with the supplied instructions.
Instr* pc = reinterpret_cast<Instr*>(pc_); Instr* pc = reinterpret_cast<Instr*>(pc_);
......
...@@ -184,6 +184,11 @@ class RelocInfo BASE_EMBEDDED { ...@@ -184,6 +184,11 @@ class RelocInfo BASE_EMBEDDED {
// Apply a relocation by delta bytes // Apply a relocation by delta bytes
INLINE(void apply(intptr_t delta)); INLINE(void apply(intptr_t delta));
// Is the pointer this relocation info refers to coded like a plain pointer
// or is it strange in some way (eg relative or patched into a series of
// instructions).
bool IsCodedSpecially();
// Read/modify the code target in the branch/call instruction // Read/modify the code target in the branch/call instruction
// this relocation applies to; // this relocation applies to;
// can only be called if IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY // can only be called if IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY
......
...@@ -162,6 +162,15 @@ const int RelocInfo::kApplyMask = ...@@ -162,6 +162,15 @@ const int RelocInfo::kApplyMask =
1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE; 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE;
bool RelocInfo::IsCodedSpecially() {
// The deserializer needs to know whether a pointer is specially coded. Being
// specially coded on IA32 means that it is a relative address, as used by
// branch instructions. These are also the ones that need changing when a
// code object moves.
return (1 << rmode_) & kApplyMask;
}
void RelocInfo::PatchCode(byte* instructions, int instruction_count) { void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
// Patch the code at the current address with the supplied instructions. // Patch the code at the current address with the supplied instructions.
for (int i = 0; i < instruction_count; i++) { for (int i = 0; i < instruction_count; i++) {
......
This diff is collapsed.
...@@ -137,17 +137,23 @@ class SnapshotByteSource { ...@@ -137,17 +137,23 @@ class SnapshotByteSource {
}; };
// It is very common to have a reference to the object at word 10 in space 2, // It is very common to have a reference to objects at certain offsets in the
// the object at word 5 in space 2 and the object at word 28 in space 4. This // heap. These offsets have been determined experimentally. We code
// only works for objects in the first page of a space. // references to such objects in a single byte that encodes the way the pointer
#define COMMON_REFERENCE_PATTERNS(f) \ // is written (only plain pointers allowed), the space number and the offset.
f(kNumberOfSpaces, 2, 10) \ // This only works for objects in the first page of a space. Don't use this for
f(kNumberOfSpaces + 1, 2, 5) \ // things in newspace since it bypasses the write barrier.
f(kNumberOfSpaces + 2, 4, 28) \
f(kNumberOfSpaces + 3, 2, 21) \ static const int k64 = (sizeof(uintptr_t) - 4) / 4;
f(kNumberOfSpaces + 4, 2, 98) \
f(kNumberOfSpaces + 5, 2, 67) \ #define COMMON_REFERENCE_PATTERNS(f) \
f(kNumberOfSpaces + 6, 4, 132) f(kNumberOfSpaces, 2, 11 - k64) \
f(kNumberOfSpaces + 1, 2, 0) \
f(kNumberOfSpaces + 2, 2, 142 - 16 * k64) \
f(kNumberOfSpaces + 3, 2, 74 - 15 * k64) \
f(kNumberOfSpaces + 4, 2, 5) \
f(kNumberOfSpaces + 5, 1, 135) \
f(kNumberOfSpaces + 6, 2, 228 - 39 * k64)
#define COMMON_RAW_LENGTHS(f) \ #define COMMON_RAW_LENGTHS(f) \
f(1, 1) \ f(1, 1) \
...@@ -175,37 +181,63 @@ class SerializerDeserializer: public ObjectVisitor { ...@@ -175,37 +181,63 @@ class SerializerDeserializer: public ObjectVisitor {
static void SetSnapshotCacheSize(int size); static void SetSnapshotCacheSize(int size);
protected: protected:
enum DataType { // Where the pointed-to object can be found:
RAW_DATA_SERIALIZATION = 0, enum Where {
// And 15 common raw lengths. kNewObject = 0, // Object is next in snapshot.
OBJECT_SERIALIZATION = 16, // 1-8 One per space.
// One variant per space. kRootArray = 0x9, // Object is found in root array.
CODE_OBJECT_SERIALIZATION = 25, kPartialSnapshotCache = 0xa, // Object is in the cache.
// One per space (only code spaces in use). kExternalReference = 0xb, // Pointer to an external reference.
EXTERNAL_REFERENCE_SERIALIZATION = 34, // 0xc-0xf Free.
EXTERNAL_BRANCH_TARGET_SERIALIZATION = 35, kBackref = 0x10, // Object is described relative to end.
SYNCHRONIZE = 36, // 0x11-0x18 One per space.
START_NEW_PAGE_SERIALIZATION = 37, // 0x19-0x1f Common backref offsets.
NATIVES_STRING_RESOURCE = 38, kFromStart = 0x20, // Object is described relative to start.
ROOT_SERIALIZATION = 39, // 0x21-0x28 One per space.
PARTIAL_SNAPSHOT_CACHE_ENTRY = 40, // 0x29-0x2f Free.
// Free: 41-47. // 0x30-0x3f Used by misc tags below.
BACKREF_SERIALIZATION = 48, kPointedToMask = 0x3f
// One per space, must be kSpaceMask aligned.
// Free: 57-63.
REFERENCE_SERIALIZATION = 64,
// One per space and common references. Must be kSpaceMask aligned.
CODE_BACKREF_SERIALIZATION = 80,
// One per space, must be kSpaceMask aligned.
// Free: 89-95.
CODE_REFERENCE_SERIALIZATION = 96
// One per space, must be kSpaceMask aligned.
// Free: 105-255.
}; };
// How to code the pointer to the object.
enum HowToCode {
kPlain = 0, // Straight pointer.
// What this means depends on the architecture:
kFromCode = 0x40, // A pointer inlined in code.
kHowToCodeMask = 0x40
};
// Where to point within the object.
enum WhereToPoint {
kStartOfObject = 0,
kFirstInstruction = 0x80,
kWhereToPointMask = 0x80
};
// Misc.
// Raw data to be copied from the snapshot.
static const int kRawData = 0x30;
// Some common raw lengths: 0x31-0x3f
// A tag emitted at strategic points in the snapshot to delineate sections.
// If the deserializer does not find these at the expected moments then it
// is an indication that the snapshot and the VM do not fit together.
// Examine the build process for architecture, version or configuration
// mismatches.
static const int kSynchronize = 0x70;
// Used for the source code of the natives, which is in the executable, but
// is referred to from external strings in the snapshot.
static const int kNativesStringResource = 0x71;
static const int kNewPage = 0x72;
// 0x73-0x7f Free.
// 0xb0-0xbf Free.
// 0xf0-0xff Free.
static const int kLargeData = LAST_SPACE; static const int kLargeData = LAST_SPACE;
static const int kLargeCode = kLargeData + 1; static const int kLargeCode = kLargeData + 1;
static const int kLargeFixedArray = kLargeCode + 1; static const int kLargeFixedArray = kLargeCode + 1;
static const int kNumberOfSpaces = kLargeFixedArray + 1; static const int kNumberOfSpaces = kLargeFixedArray + 1;
static const int kAnyOldSpace = -1;
// A bitmask for getting the space out of an instruction. // A bitmask for getting the space out of an instruction.
static const int kSpaceMask = 15; static const int kSpaceMask = 15;
...@@ -396,10 +428,6 @@ class Serializer : public SerializerDeserializer { ...@@ -396,10 +428,6 @@ class Serializer : public SerializerDeserializer {
#endif #endif
protected: protected:
enum ReferenceRepresentation {
TAGGED_REPRESENTATION, // A tagged object reference.
CODE_TARGET_REPRESENTATION // A reference to first instruction in target.
};
static const int kInvalidRootIndex = -1; static const int kInvalidRootIndex = -1;
virtual int RootIndex(HeapObject* heap_object) = 0; virtual int RootIndex(HeapObject* heap_object) = 0;
virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) = 0; virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) = 0;
...@@ -409,11 +437,12 @@ class Serializer : public SerializerDeserializer { ...@@ -409,11 +437,12 @@ class Serializer : public SerializerDeserializer {
ObjectSerializer(Serializer* serializer, ObjectSerializer(Serializer* serializer,
Object* o, Object* o,
SnapshotByteSink* sink, SnapshotByteSink* sink,
ReferenceRepresentation representation) HowToCode how_to_code,
WhereToPoint where_to_point)
: serializer_(serializer), : serializer_(serializer),
object_(HeapObject::cast(o)), object_(HeapObject::cast(o)),
sink_(sink), sink_(sink),
reference_representation_(representation), reference_representation_(how_to_code + where_to_point),
bytes_processed_so_far_(0) { } bytes_processed_so_far_(0) { }
void Serialize(); void Serialize();
void VisitPointers(Object** start, Object** end); void VisitPointers(Object** start, Object** end);
...@@ -435,16 +464,18 @@ class Serializer : public SerializerDeserializer { ...@@ -435,16 +464,18 @@ class Serializer : public SerializerDeserializer {
Serializer* serializer_; Serializer* serializer_;
HeapObject* object_; HeapObject* object_;
SnapshotByteSink* sink_; SnapshotByteSink* sink_;
ReferenceRepresentation reference_representation_; int reference_representation_;
int bytes_processed_so_far_; int bytes_processed_so_far_;
}; };
virtual void SerializeObject(Object* o, virtual void SerializeObject(Object* o,
ReferenceRepresentation representation) = 0; HowToCode how_to_code,
WhereToPoint where_to_point) = 0;
void SerializeReferenceToPreviousObject( void SerializeReferenceToPreviousObject(
int space, int space,
int address, int address,
ReferenceRepresentation reference_representation); HowToCode how_to_code,
WhereToPoint where_to_point);
void InitializeAllocators(); void InitializeAllocators();
// This will return the space for an object. If the object is in large // This will return the space for an object. If the object is in large
// object space it may return kLargeCode or kLargeFixedArray in order // object space it may return kLargeCode or kLargeFixedArray in order
...@@ -492,7 +523,8 @@ class PartialSerializer : public Serializer { ...@@ -492,7 +523,8 @@ class PartialSerializer : public Serializer {
// Serialize the objects reachable from a single object pointer. // Serialize the objects reachable from a single object pointer.
virtual void Serialize(Object** o); virtual void Serialize(Object** o);
virtual void SerializeObject(Object* o, virtual void SerializeObject(Object* o,
ReferenceRepresentation representation); HowToCode how_to_code,
WhereToPoint where_to_point);
protected: protected:
virtual int RootIndex(HeapObject* o); virtual int RootIndex(HeapObject* o);
...@@ -528,7 +560,8 @@ class StartupSerializer : public Serializer { ...@@ -528,7 +560,8 @@ class StartupSerializer : public Serializer {
// 3) Weak references (eg the symbol table). // 3) Weak references (eg the symbol table).
virtual void SerializeStrongReferences(); virtual void SerializeStrongReferences();
virtual void SerializeObject(Object* o, virtual void SerializeObject(Object* o,
ReferenceRepresentation representation); HowToCode how_to_code,
WhereToPoint where_to_point);
void SerializeWeakReferences(); void SerializeWeakReferences();
void Serialize() { void Serialize() {
SerializeStrongReferences(); SerializeStrongReferences();
......
...@@ -2800,6 +2800,16 @@ const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | ...@@ -2800,6 +2800,16 @@ const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
1 << RelocInfo::INTERNAL_REFERENCE | 1 << RelocInfo::INTERNAL_REFERENCE |
1 << RelocInfo::JS_RETURN; 1 << RelocInfo::JS_RETURN;
bool RelocInfo::IsCodedSpecially() {
// The deserializer needs to know whether a pointer is specially coded. Being
// specially coded on x64 means that it is a relative 32 bit address, as used
// by branch instructions.
return (1 << rmode_) & kApplyMask;
}
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_TARGET_ARCH_X64 #endif // V8_TARGET_ARCH_X64
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment