Endian changes, support 64bit big endian

These are some changes split off from https://codereview.chromium.org/422063005

frames-inl.h, frames.h
based on https://github.com/andrewlow/v8ppc/commit/05db7d2d714c44bd4e0b710fdaa51d34938aaa27
On 64bit big endian systems, the integer value is in the second slot, thus we need a new offset.

objects-inl.h, objects.h
based on https://github.com/andrewlow/v8ppc/commit/09b680b2af7412fe8fa5a3a01f1b8e29698d7797
Similarly, the hash slot is an integer field and we need to do the right thing on 64bit big endian systems

objects.cc
based on: https://github.com/andrewlow/v8ppc/commit/065742b0783b0705d9f9711198248a92bac11d85
Prettier printing of constant pools

test-strings.cc
based on:  https://github.com/andrewlow/v8ppc/commit/9889d60cd6e68e0d248c4a362ffdff0755b92aec
endian fixes

BUG=
R=svenpanne@chromium.org

Review URL: https://codereview.chromium.org/551803004

Patch from Andrew Low <andrew_low@ca.ibm.com>.

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24365 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent bedfa9e7
...@@ -76,13 +76,13 @@ inline bool StackHandler::is_finally() const { ...@@ -76,13 +76,13 @@ inline bool StackHandler::is_finally() const {
inline StackHandler::Kind StackHandler::kind() const { inline StackHandler::Kind StackHandler::kind() const {
const int offset = StackHandlerConstants::kStateOffset; const int offset = StackHandlerConstants::kStateIntOffset;
return KindField::decode(Memory::unsigned_at(address() + offset)); return KindField::decode(Memory::unsigned_at(address() + offset));
} }
inline unsigned StackHandler::index() const { inline unsigned StackHandler::index() const {
const int offset = StackHandlerConstants::kStateOffset; const int offset = StackHandlerConstants::kStateIntOffset;
return IndexField::decode(Memory::unsigned_at(address() + offset)); return IndexField::decode(Memory::unsigned_at(address() + offset));
} }
......
...@@ -71,6 +71,11 @@ class StackHandlerConstants : public AllStatic { ...@@ -71,6 +71,11 @@ class StackHandlerConstants : public AllStatic {
static const int kNextOffset = 0 * kPointerSize; static const int kNextOffset = 0 * kPointerSize;
static const int kCodeOffset = 1 * kPointerSize; static const int kCodeOffset = 1 * kPointerSize;
static const int kStateOffset = 2 * kPointerSize; static const int kStateOffset = 2 * kPointerSize;
#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
static const int kStateIntOffset = kStateOffset;
#else
static const int kStateIntOffset = kStateOffset + kIntSize;
#endif
static const int kContextOffset = 3 * kPointerSize; static const int kContextOffset = 3 * kPointerSize;
static const int kFPOffset = 4 * kPointerSize; static const int kFPOffset = 4 * kPointerSize;
......
...@@ -2635,13 +2635,13 @@ void ConstantPoolArray::InitExtended(const NumberOfEntries& small, ...@@ -2635,13 +2635,13 @@ void ConstantPoolArray::InitExtended(const NumberOfEntries& small,
// Initialize the extended layout fields. // Initialize the extended layout fields.
int extended_header_offset = get_extended_section_header_offset(); int extended_header_offset = get_extended_section_header_offset();
WRITE_INT_FIELD(this, extended_header_offset + kExtendedInt64CountOffset, WRITE_INT32_FIELD(this, extended_header_offset + kExtendedInt64CountOffset,
extended.count_of(INT64)); extended.count_of(INT64));
WRITE_INT_FIELD(this, extended_header_offset + kExtendedCodePtrCountOffset, WRITE_INT32_FIELD(this, extended_header_offset + kExtendedCodePtrCountOffset,
extended.count_of(CODE_PTR)); extended.count_of(CODE_PTR));
WRITE_INT_FIELD(this, extended_header_offset + kExtendedHeapPtrCountOffset, WRITE_INT32_FIELD(this, extended_header_offset + kExtendedHeapPtrCountOffset,
extended.count_of(HEAP_PTR)); extended.count_of(HEAP_PTR));
WRITE_INT_FIELD(this, extended_header_offset + kExtendedInt32CountOffset, WRITE_INT32_FIELD(this, extended_header_offset + kExtendedInt32CountOffset,
extended.count_of(INT32)); extended.count_of(INT32));
} }
...@@ -3314,7 +3314,11 @@ uint32_t Name::hash_field() { ...@@ -3314,7 +3314,11 @@ uint32_t Name::hash_field() {
void Name::set_hash_field(uint32_t value) { void Name::set_hash_field(uint32_t value) {
WRITE_UINT32_FIELD(this, kHashFieldOffset, value); WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
#if V8_HOST_ARCH_64_BIT #if V8_HOST_ARCH_64_BIT
WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0); #if V8_TARGET_LITTLE_ENDIAN
WRITE_UINT32_FIELD(this, kHashFieldSlot + kIntSize, 0);
#else
WRITE_UINT32_FIELD(this, kHashFieldSlot, 0);
#endif
#endif #endif
} }
...@@ -5485,8 +5489,16 @@ SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset) ...@@ -5485,8 +5489,16 @@ SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
#else #else
#if V8_TARGET_LITTLE_ENDIAN
#define PSEUDO_SMI_LO_ALIGN 0
#define PSEUDO_SMI_HI_ALIGN kIntSize
#else
#define PSEUDO_SMI_LO_ALIGN kIntSize
#define PSEUDO_SMI_HI_ALIGN 0
#endif
#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \ #define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
STATIC_ASSERT(holder::offset % kPointerSize == 0); \ STATIC_ASSERT(holder::offset % kPointerSize == PSEUDO_SMI_LO_ALIGN); \
int holder::name() const { \ int holder::name() const { \
int value = READ_INT_FIELD(this, offset); \ int value = READ_INT_FIELD(this, offset); \
DCHECK(kHeapObjectTag == 1); \ DCHECK(kHeapObjectTag == 1); \
...@@ -5495,15 +5507,12 @@ SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset) ...@@ -5495,15 +5507,12 @@ SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
} \ } \
void holder::set_##name(int value) { \ void holder::set_##name(int value) { \
DCHECK(kHeapObjectTag == 1); \ DCHECK(kHeapObjectTag == 1); \
DCHECK((value & 0xC0000000) == 0xC0000000 || \ DCHECK((value & 0xC0000000) == 0xC0000000 || (value & 0xC0000000) == 0x0); \
(value & 0xC0000000) == 0x0); \ WRITE_INT_FIELD(this, offset, (value << 1) & ~kHeapObjectTag); \
WRITE_INT_FIELD(this, \
offset, \
(value << 1) & ~kHeapObjectTag); \
} }
#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \ #define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \ STATIC_ASSERT(holder::offset % kPointerSize == PSEUDO_SMI_HI_ALIGN); \
INT_ACCESSORS(holder, name, offset) INT_ACCESSORS(holder, name, offset)
...@@ -6632,7 +6641,7 @@ void String::SetForwardedInternalizedString(String* canonical) { ...@@ -6632,7 +6641,7 @@ void String::SetForwardedInternalizedString(String* canonical) {
DCHECK(SlowEquals(canonical)); DCHECK(SlowEquals(canonical));
DCHECK(canonical->IsInternalizedString()); DCHECK(canonical->IsInternalizedString());
DCHECK(canonical->HasHashCode()); DCHECK(canonical->HasHashCode());
WRITE_FIELD(this, kHashFieldOffset, canonical); WRITE_FIELD(this, kHashFieldSlot, canonical);
// Setting the hash field to a tagged value sets the LSB, causing the hash // Setting the hash field to a tagged value sets the LSB, causing the hash
// code to be interpreted as uninitialized. We use this fact to recognize // code to be interpreted as uninitialized. We use this fact to recognize
// that we have a forwarded string. // that we have a forwarded string.
...@@ -6643,7 +6652,7 @@ void String::SetForwardedInternalizedString(String* canonical) { ...@@ -6643,7 +6652,7 @@ void String::SetForwardedInternalizedString(String* canonical) {
String* String::GetForwardedInternalizedString() { String* String::GetForwardedInternalizedString() {
DCHECK(IsInternalizedString()); DCHECK(IsInternalizedString());
if (HasHashCode()) return this; if (HasHashCode()) return this;
String* canonical = String::cast(READ_FIELD(this, kHashFieldOffset)); String* canonical = String::cast(READ_FIELD(this, kHashFieldSlot));
DCHECK(canonical->IsInternalizedString()); DCHECK(canonical->IsInternalizedString());
DCHECK(SlowEquals(canonical)); DCHECK(SlowEquals(canonical));
DCHECK(canonical->HasHashCode()); DCHECK(canonical->HasHashCode());
......
...@@ -10966,6 +10966,17 @@ void Code::Disassemble(const char* name, std::ostream& os) { // NOLINT ...@@ -10966,6 +10966,17 @@ void Code::Disassemble(const char* name, std::ostream& os) { // NOLINT
it.rinfo()->Print(GetIsolate(), os); it.rinfo()->Print(GetIsolate(), os);
} }
os << "\n"; os << "\n";
#ifdef OBJECT_PRINT
if (FLAG_enable_ool_constant_pool) {
ConstantPoolArray* pool = constant_pool();
if (pool->length()) {
os << "Constant Pool\n";
pool->Print(os);
os << "\n";
}
}
#endif
} }
#endif // ENABLE_DISASSEMBLER #endif // ENABLE_DISASSEMBLER
......
...@@ -2843,13 +2843,13 @@ class ConstantPoolArray: public HeapObject { ...@@ -2843,13 +2843,13 @@ class ConstantPoolArray: public HeapObject {
// get_extended_section_header_offset(). // get_extended_section_header_offset().
static const int kExtendedInt64CountOffset = 0; static const int kExtendedInt64CountOffset = 0;
static const int kExtendedCodePtrCountOffset = static const int kExtendedCodePtrCountOffset =
kExtendedInt64CountOffset + kPointerSize; kExtendedInt64CountOffset + kInt32Size;
static const int kExtendedHeapPtrCountOffset = static const int kExtendedHeapPtrCountOffset =
kExtendedCodePtrCountOffset + kPointerSize; kExtendedCodePtrCountOffset + kInt32Size;
static const int kExtendedInt32CountOffset = static const int kExtendedInt32CountOffset =
kExtendedHeapPtrCountOffset + kPointerSize; kExtendedHeapPtrCountOffset + kInt32Size;
static const int kExtendedFirstOffset = static const int kExtendedFirstOffset =
kExtendedInt32CountOffset + kPointerSize; kExtendedInt32CountOffset + kInt32Size;
// Dispatched behavior. // Dispatched behavior.
void ConstantPoolIterateBody(ObjectVisitor* v); void ConstantPoolIterateBody(ObjectVisitor* v);
...@@ -5365,7 +5365,7 @@ class Code: public HeapObject { ...@@ -5365,7 +5365,7 @@ class Code: public HeapObject {
static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize; static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
static const int kConstantPoolOffset = kPrologueOffset + kPointerSize; static const int kConstantPoolOffset = kPrologueOffset + kPointerSize;
static const int kHeaderPaddingStart = kConstantPoolOffset + kIntSize; static const int kHeaderPaddingStart = kConstantPoolOffset + kPointerSize;
// Add padding 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.
...@@ -6936,10 +6936,11 @@ class SharedFunctionInfo: public HeapObject { ...@@ -6936,10 +6936,11 @@ class SharedFunctionInfo: public HeapObject {
// garbage collections. // garbage collections.
// To avoid wasting space on 64-bit architectures we use // To avoid wasting space on 64-bit architectures we use
// the following trick: we group integer fields into pairs // the following trick: we group integer fields into pairs
// First integer in each pair is shifted left by 1. // The least significant integer in each pair is shifted left by 1.
// By doing this we guarantee that LSB of each kPointerSize aligned // By doing this we guarantee that LSB of each kPointerSize aligned
// word is not set and thus this word cannot be treated as pointer // word is not set and thus this word cannot be treated as pointer
// to HeapObject during old space traversal. // to HeapObject during old space traversal.
#if V8_TARGET_LITTLE_ENDIAN
static const int kLengthOffset = static const int kLengthOffset =
kFeedbackVectorOffset + kPointerSize; kFeedbackVectorOffset + kPointerSize;
static const int kFormalParameterCountOffset = static const int kFormalParameterCountOffset =
...@@ -6973,7 +6974,37 @@ class SharedFunctionInfo: public HeapObject { ...@@ -6973,7 +6974,37 @@ class SharedFunctionInfo: public HeapObject {
// Total size. // Total size.
static const int kSize = kProfilerTicksOffset + kIntSize; static const int kSize = kProfilerTicksOffset + kIntSize;
#endif #elif V8_TARGET_BIG_ENDIAN
static const int kFormalParameterCountOffset =
kFeedbackVectorOffset + kPointerSize;
static const int kLengthOffset = kFormalParameterCountOffset + kIntSize;
static const int kNumLiteralsOffset = kLengthOffset + kIntSize;
static const int kExpectedNofPropertiesOffset = kNumLiteralsOffset + kIntSize;
static const int kStartPositionAndTypeOffset =
kExpectedNofPropertiesOffset + kIntSize;
static const int kEndPositionOffset = kStartPositionAndTypeOffset + kIntSize;
static const int kCompilerHintsOffset = kEndPositionOffset + kIntSize;
static const int kFunctionTokenPositionOffset =
kCompilerHintsOffset + kIntSize;
static const int kCountersOffset = kFunctionTokenPositionOffset + kIntSize;
static const int kOptCountAndBailoutReasonOffset = kCountersOffset + kIntSize;
static const int kProfilerTicksOffset =
kOptCountAndBailoutReasonOffset + kIntSize;
static const int kAstNodeCountOffset = kProfilerTicksOffset + kIntSize;
// Total size.
static const int kSize = kAstNodeCountOffset + kIntSize;
#else
#error Unknown byte ordering
#endif // Big endian
#endif // 64-bit
static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize); static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
...@@ -8482,8 +8513,13 @@ class Name: public HeapObject { ...@@ -8482,8 +8513,13 @@ class Name: public HeapObject {
DECLARE_PRINTER(Name) DECLARE_PRINTER(Name)
// Layout description. // Layout description.
static const int kHashFieldOffset = HeapObject::kHeaderSize; static const int kHashFieldSlot = HeapObject::kHeaderSize;
static const int kSize = kHashFieldOffset + kPointerSize; #if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
static const int kHashFieldOffset = kHashFieldSlot;
#else
static const int kHashFieldOffset = kHashFieldSlot + kIntSize;
#endif
static const int kSize = kHashFieldSlot + kPointerSize;
// Mask constant for checking if a name has a computed hash code // Mask constant for checking if a name has a computed hash code
// and if it is a string that is an array index. The least significant bit // and if it is a string that is an array index. The least significant bit
......
...@@ -27,6 +27,11 @@ ...@@ -27,6 +27,11 @@
// Flags: --allow-natives-syntax // Flags: --allow-natives-syntax
// Helper to determine endian - returns true on little endian platforms
function isLittleEndian() {
return ((new Uint32Array((new Uint8Array([4,3,2,1])).buffer))[0])
== 0x01020304;
}
// Test that both kinds of NaNs (signaling or quiet) do not signal // Test that both kinds of NaNs (signaling or quiet) do not signal
...@@ -41,7 +46,11 @@ function TestAllModes(f) { ...@@ -41,7 +46,11 @@ function TestAllModes(f) {
function TestDoubleSignalingNan() { function TestDoubleSignalingNan() {
// NaN with signal bit set // NaN with signal bit set
function f() { function f() {
if(isLittleEndian()) {
var bytes = new Uint32Array([1, 0x7FF00000]); var bytes = new Uint32Array([1, 0x7FF00000]);
} else {
var bytes = new Uint32Array([0x7FF00000, 1]);
}
var doubles = new Float64Array(bytes.buffer); var doubles = new Float64Array(bytes.buffer);
assertTrue(isNaN(doubles[0])); assertTrue(isNaN(doubles[0]));
assertTrue(isNaN(doubles[0]*2.0)); assertTrue(isNaN(doubles[0]*2.0));
...@@ -56,7 +65,11 @@ TestDoubleSignalingNan(); ...@@ -56,7 +65,11 @@ TestDoubleSignalingNan();
function TestDoubleQuietNan() { function TestDoubleQuietNan() {
// NaN with signal bit cleared // NaN with signal bit cleared
function f() { function f() {
if(isLittleEndian()) {
var bytes = new Uint32Array([0, 0x7FF80000]); var bytes = new Uint32Array([0, 0x7FF80000]);
} else {
var bytes = new Uint32Array([0x7FF80000, 0]);
}
var doubles = new Float64Array(bytes.buffer); var doubles = new Float64Array(bytes.buffer);
assertTrue(isNaN(doubles[0])); assertTrue(isNaN(doubles[0]));
assertTrue(isNaN(doubles[0]*2.0)); assertTrue(isNaN(doubles[0]*2.0));
......
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