Commit 13a96b3a authored by lrn@chromium.org's avatar lrn@chromium.org

X64: Checked and slightly modified Object layouts to be compatible with 64-bit pointers.

Review URL: http://codereview.chromium.org/113522


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1986 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 81af5bee
...@@ -123,9 +123,12 @@ const int kPointerSizeLog2 = 2; ...@@ -123,9 +123,12 @@ const int kPointerSizeLog2 = 2;
#endif #endif
const int kObjectAlignmentBits = kPointerSizeLog2; const int kObjectAlignmentBits = kPointerSizeLog2;
const intptr_t kObjectAlignmentMask = (1 << kObjectAlignmentBits) - 1;
const intptr_t kObjectAlignment = 1 << kObjectAlignmentBits; const intptr_t kObjectAlignment = 1 << kObjectAlignmentBits;
const intptr_t kObjectAlignmentMask = kObjectAlignment - 1;
// Desired alignment for pointers.
const intptr_t kPointerAlignment = (1 << kPointerSizeLog2);
const intptr_t kPointerAlignmentMask = kPointerAlignment - 1;
// Tag information for HeapObject. // Tag information for HeapObject.
const int kHeapObjectTag = 1; const int kHeapObjectTag = 1;
...@@ -419,7 +422,11 @@ enum StateTag { ...@@ -419,7 +422,11 @@ enum StateTag {
// OBJECT_SIZE_ALIGN returns the value aligned HeapObject size // OBJECT_SIZE_ALIGN returns the value aligned HeapObject size
#define OBJECT_SIZE_ALIGN(value) \ #define OBJECT_SIZE_ALIGN(value) \
((value + kObjectAlignmentMask) & ~kObjectAlignmentMask) (((value) + kObjectAlignmentMask) & ~kObjectAlignmentMask)
// POINTER_SIZE_ALIGN returns the value aligned as a pointer.
#define POINTER_SIZE_ALIGN(value) \
(((value) + kPointerAlignmentMask) & ~kPointerAlignmentMask)
// The expression OFFSET_OF(type, field) computes the byte-offset // The expression OFFSET_OF(type, field) computes the byte-offset
// of the specified field relative to the containing type. This // of the specified field relative to the containing type. This
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#include "regexp-macro-assembler-irregexp.h" #include "regexp-macro-assembler-irregexp.h"
#include "regexp-stack.h" #include "regexp-stack.h"
#ifdef V8_TARGET_ARCH_IA32 #if V8_TARGET_ARCH_IA32
#include "ia32/macro-assembler-ia32.h" #include "ia32/macro-assembler-ia32.h"
#include "ia32/regexp-macro-assembler-ia32.h" #include "ia32/regexp-macro-assembler-ia32.h"
#elif V8_TARGET_ARCH_X64 #elif V8_TARGET_ARCH_X64
......
...@@ -1266,7 +1266,7 @@ static const char* StateToString(StateTag state) { ...@@ -1266,7 +1266,7 @@ static const char* StateToString(StateTag state) {
VMState::VMState(StateTag state) { VMState::VMState(StateTag state) {
#if !defined(ENABLE_HEAP_PROTECTION) #if !defined(ENABLE_HEAP_PROTECTION)
// When not protecting the heap, there is no difference between // When not protecting the heap, there is no difference between
// EXTERNAL and OTHER. As an optimizatin in that case, we will not // EXTERNAL and OTHER. As an optimization in that case, we will not
// perform EXTERNAL->OTHER transitions through the API. We thus // perform EXTERNAL->OTHER transitions through the API. We thus
// compress the two states into one. // compress the two states into one.
if (state == EXTERNAL) state = OTHER; if (state == EXTERNAL) state = OTHER;
......
...@@ -1794,7 +1794,7 @@ int HeapObject::SizeFromMap(Map* map) { ...@@ -1794,7 +1794,7 @@ int HeapObject::SizeFromMap(Map* map) {
void Map::set_instance_size(int value) { void Map::set_instance_size(int value) {
ASSERT((value & ~(kPointerSize - 1)) == value); ASSERT_EQ(0, value & (kPointerSize - 1));
value >>= kPointerSizeLog2; value >>= kPointerSizeLog2;
ASSERT(0 <= value && value < 256); ASSERT(0 <= value && value < 256);
WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value)); WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
......
...@@ -50,7 +50,6 @@ ...@@ -50,7 +50,6 @@
// - JSBuiltinsObject // - JSBuiltinsObject
// - JSGlobalProxy // - JSGlobalProxy
// - JSValue // - JSValue
// - Script
// - Array // - Array
// - ByteArray // - ByteArray
// - FixedArray // - FixedArray
...@@ -83,8 +82,10 @@ ...@@ -83,8 +82,10 @@
// - AccessCheckInfo // - AccessCheckInfo
// - InterceptorInfo // - InterceptorInfo
// - CallHandlerInfo // - CallHandlerInfo
// - TemplateInfo
// - FunctionTemplateInfo // - FunctionTemplateInfo
// - ObjectTemplateInfo // - ObjectTemplateInfo
// - Script
// - SignatureInfo // - SignatureInfo
// - TypeSwitchInfo // - TypeSwitchInfo
// - DebugInfo // - DebugInfo
...@@ -771,8 +772,10 @@ class Object BASE_EMBEDDED { ...@@ -771,8 +772,10 @@ class Object BASE_EMBEDDED {
// Smi represents integer Numbers that can be stored in 31 bits. // Smi represents integer Numbers that can be stored in 31 bits.
// TODO(X64) Increase to 53 bits?
// Smis are immediate which means they are NOT allocated in the heap. // Smis are immediate which means they are NOT allocated in the heap.
// The this pointer has the following format: [31 bit signed int] 0 // The this pointer has the following format: [31 bit signed int] 0
// TODO(X64): 31 bits signed int sign-extended to 63 bits.
// Smi stands for small integer. // Smi stands for small integer.
class Smi: public Object { class Smi: public Object {
public: public:
...@@ -1596,6 +1599,9 @@ class FixedArray: public Array { ...@@ -1596,6 +1599,9 @@ class FixedArray: public Array {
// Casting. // Casting.
static inline FixedArray* cast(Object* obj); static inline FixedArray* cast(Object* obj);
// Align data at kPointerSize, even if Array.kHeaderSize isn't aligned.
static const int kHeaderSize = POINTER_SIZE_ALIGN(Array::kHeaderSize);
// Dispatched behavior. // Dispatched behavior.
int FixedArraySize() { return SizeFor(length()); } int FixedArraySize() { return SizeFor(length()); }
void FixedArrayIterateBody(ObjectVisitor* v); void FixedArrayIterateBody(ObjectVisitor* v);
...@@ -2147,7 +2153,7 @@ class ByteArray: public Array { ...@@ -2147,7 +2153,7 @@ class ByteArray: public Array {
inline int get_int(int index); inline int get_int(int index);
static int SizeFor(int length) { static int SizeFor(int length) {
return kHeaderSize + OBJECT_SIZE_ALIGN(length); return OBJECT_SIZE_ALIGN(kHeaderSize + length);
} }
// We use byte arrays for free blocks in the heap. Given a desired size in // We use byte arrays for free blocks in the heap. Given a desired size in
// bytes that is a multiple of the word size and big enough to hold a byte // bytes that is a multiple of the word size and big enough to hold a byte
...@@ -2344,6 +2350,9 @@ class Code: public HeapObject { ...@@ -2344,6 +2350,9 @@ class Code: public HeapObject {
void CodePrint(); void CodePrint();
void CodeVerify(); void CodeVerify();
#endif #endif
// Code entry points are aligned to 32 bytes.
static const int kCodeAlignment = 32;
static const int kCodeAlignmentMask = kCodeAlignment - 1;
// Layout description. // Layout description.
static const int kInstructionSizeOffset = HeapObject::kHeaderSize; static const int kInstructionSizeOffset = HeapObject::kHeaderSize;
...@@ -2351,14 +2360,11 @@ class Code: public HeapObject { ...@@ -2351,14 +2360,11 @@ class Code: public HeapObject {
static const int kSInfoSizeOffset = kRelocationSizeOffset + kIntSize; static const int kSInfoSizeOffset = kRelocationSizeOffset + kIntSize;
static const int kFlagsOffset = kSInfoSizeOffset + kIntSize; static const int kFlagsOffset = kSInfoSizeOffset + kIntSize;
static const int kKindSpecificFlagsOffset = kFlagsOffset + kIntSize; static const int kKindSpecificFlagsOffset = kFlagsOffset + kIntSize;
// Add filler objects to align the instruction start following right after // Add padding to align the instruction start following right after
// the Code object header. // the Code object header.
static const int kFiller6Offset = kKindSpecificFlagsOffset + kIntSize; static const int kHeaderSize =
static const int kFiller7Offset = kFiller6Offset + kIntSize; (kKindSpecificFlagsOffset + kIntSize + kCodeAlignmentMask) &
static const int kHeaderSize = kFiller7Offset + kIntSize; ~kCodeAlignmentMask;
// Code entry points are aligned to 32 bytes.
static const int kCodeAlignment = 32;
// Byte offsets within kKindSpecificFlagsOffset. // Byte offsets within kKindSpecificFlagsOffset.
static const int kICFlagOffset = kKindSpecificFlagsOffset + 0; static const int kICFlagOffset = kKindSpecificFlagsOffset + 0;
...@@ -2567,7 +2573,7 @@ class Map: public HeapObject { ...@@ -2567,7 +2573,7 @@ class Map: public HeapObject {
static const int kInstanceDescriptorsOffset = static const int kInstanceDescriptorsOffset =
kConstructorOffset + kPointerSize; kConstructorOffset + kPointerSize;
static const int kCodeCacheOffset = kInstanceDescriptorsOffset + kPointerSize; static const int kCodeCacheOffset = kInstanceDescriptorsOffset + kPointerSize;
static const int kSize = kCodeCacheOffset + kIntSize; static const int kSize = kCodeCacheOffset + kPointerSize;
// Byte offsets within kInstanceSizesOffset. // Byte offsets within kInstanceSizesOffset.
static const int kInstanceSizeOffset = kInstanceSizesOffset + 0; static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
...@@ -2776,21 +2782,23 @@ class SharedFunctionInfo: public HeapObject { ...@@ -2776,21 +2782,23 @@ class SharedFunctionInfo: public HeapObject {
static const int kDontAdaptArgumentsSentinel = -1; static const int kDontAdaptArgumentsSentinel = -1;
// Layout description. // Layout description.
// (An even number of integers has a size that is a multiple of a pointer.)
static const int kNameOffset = HeapObject::kHeaderSize; static const int kNameOffset = HeapObject::kHeaderSize;
static const int kCodeOffset = kNameOffset + kPointerSize; static const int kCodeOffset = kNameOffset + kPointerSize;
static const int kLengthOffset = kCodeOffset + kPointerSize; static const int kLengthOffset = kCodeOffset + kPointerSize;
static const int kFormalParameterCountOffset = kLengthOffset + kIntSize; static const int kFormalParameterCountOffset = kLengthOffset + kIntSize;
static const int kExpectedNofPropertiesOffset = static const int kExpectedNofPropertiesOffset =
kFormalParameterCountOffset + kIntSize; kFormalParameterCountOffset + kIntSize;
static const int kInstanceClassNameOffset = static const int kStartPositionAndTypeOffset =
kExpectedNofPropertiesOffset + kIntSize; kExpectedNofPropertiesOffset + kIntSize;
static const int kEndPositionOffset = kStartPositionAndTypeOffset + kIntSize;
static const int kFunctionTokenPositionOffset = kEndPositionOffset + kIntSize;
static const int kInstanceClassNameOffset =
kFunctionTokenPositionOffset + kIntSize;
static const int kExternalReferenceDataOffset = static const int kExternalReferenceDataOffset =
kInstanceClassNameOffset + kPointerSize; kInstanceClassNameOffset + kPointerSize;
static const int kScriptOffset = kExternalReferenceDataOffset + kPointerSize; static const int kScriptOffset = kExternalReferenceDataOffset + kPointerSize;
static const int kStartPositionAndTypeOffset = kScriptOffset + kPointerSize; static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
static const int kEndPositionOffset = kStartPositionAndTypeOffset + kIntSize;
static const int kFunctionTokenPositionOffset = kEndPositionOffset + kIntSize;
static const int kDebugInfoOffset = kFunctionTokenPositionOffset + kIntSize;
static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize; static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
static const int kSize = kInferredNameOffset + kPointerSize; static const int kSize = kInferredNameOffset + kPointerSize;
...@@ -3100,7 +3108,7 @@ class JSRegExp: public JSObject { ...@@ -3100,7 +3108,7 @@ class JSRegExp: public JSObject {
#endif #endif
static const int kDataOffset = JSObject::kHeaderSize; static const int kDataOffset = JSObject::kHeaderSize;
static const int kSize = kDataOffset + kIntSize; static const int kSize = kDataOffset + kPointerSize;
// Indices in the data array. // Indices in the data array.
static const int kTagIndex = 0; static const int kTagIndex = 0;
...@@ -3513,7 +3521,7 @@ class SeqAsciiString: public SeqString { ...@@ -3513,7 +3521,7 @@ class SeqAsciiString: public SeqString {
// Computes the size for an AsciiString instance of a given length. // Computes the size for an AsciiString instance of a given length.
static int SizeFor(int length) { static int SizeFor(int length) {
return kHeaderSize + OBJECT_SIZE_ALIGN(length * kCharSize); return OBJECT_SIZE_ALIGN(kHeaderSize + length * kCharSize);
} }
// Layout description. // Layout description.
...@@ -3558,7 +3566,7 @@ class SeqTwoByteString: public SeqString { ...@@ -3558,7 +3566,7 @@ class SeqTwoByteString: public SeqString {
// Computes the size for a TwoByteString instance of a given length. // Computes the size for a TwoByteString instance of a given length.
static int SizeFor(int length) { static int SizeFor(int length) {
return kHeaderSize + OBJECT_SIZE_ALIGN(length * kShortSize); return OBJECT_SIZE_ALIGN(kHeaderSize + length * kShortSize);
} }
// Layout description. // Layout description.
...@@ -3612,7 +3620,7 @@ class ConsString: public String { ...@@ -3612,7 +3620,7 @@ class ConsString: public String {
void ConsStringIterateBody(ObjectVisitor* v); void ConsStringIterateBody(ObjectVisitor* v);
// Layout description. // Layout description.
static const int kFirstOffset = String::kSize; static const int kFirstOffset = POINTER_SIZE_ALIGN(String::kSize);
static const int kSecondOffset = kFirstOffset + kPointerSize; static const int kSecondOffset = kFirstOffset + kPointerSize;
static const int kSize = kSecondOffset + kPointerSize; static const int kSize = kSecondOffset + kPointerSize;
...@@ -3656,9 +3664,18 @@ class SlicedString: public String { ...@@ -3656,9 +3664,18 @@ class SlicedString: public String {
void SlicedStringIterateBody(ObjectVisitor* v); void SlicedStringIterateBody(ObjectVisitor* v);
// Layout description // Layout description
#if V8_HOST_ARCH_64_BIT
// Optimizations expect buffer to be located at same offset as a ConsString's
// first substring. In 64 bit mode we have room for the size before the
// buffer.
static const int kStartOffset = String::kSize;
static const int kBufferOffset = kStartOffset + kIntSize;
static const int kSize = kBufferOffset + kPointerSize;
#else
static const int kBufferOffset = String::kSize; static const int kBufferOffset = String::kSize;
static const int kStartOffset = kBufferOffset + kPointerSize; static const int kStartOffset = kBufferOffset + kPointerSize;
static const int kSize = kStartOffset + kIntSize; static const int kSize = kStartOffset + kIntSize;
#endif
// Support for StringInputBuffer. // Support for StringInputBuffer.
inline const unibrow::byte* SlicedStringReadBlock(ReadBlockBuffer* buffer, inline const unibrow::byte* SlicedStringReadBlock(ReadBlockBuffer* buffer,
...@@ -3688,7 +3705,7 @@ class ExternalString: public String { ...@@ -3688,7 +3705,7 @@ class ExternalString: public String {
static inline ExternalString* cast(Object* obj); static inline ExternalString* cast(Object* obj);
// Layout description. // Layout description.
static const int kResourceOffset = String::kSize; static const int kResourceOffset = POINTER_SIZE_ALIGN(String::kSize);
static const int kSize = kResourceOffset + kPointerSize; static const int kSize = kResourceOffset + kPointerSize;
private: private:
...@@ -4148,7 +4165,7 @@ class ObjectTemplateInfo: public TemplateInfo { ...@@ -4148,7 +4165,7 @@ class ObjectTemplateInfo: public TemplateInfo {
static const int kConstructorOffset = TemplateInfo::kHeaderSize; static const int kConstructorOffset = TemplateInfo::kHeaderSize;
static const int kInternalFieldCountOffset = static const int kInternalFieldCountOffset =
kConstructorOffset + kPointerSize; kConstructorOffset + kPointerSize;
static const int kSize = kInternalFieldCountOffset + kHeaderSize; static const int kSize = kInternalFieldCountOffset + kPointerSize;
}; };
......
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