From: svenpanne@chromium.org Date: Wed, 1 Oct 2014 13:14:14 +0000 (+0000) Subject: Endian changes, support 64bit big endian X-Git-Tag: upstream/4.7.83~6580 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d6eea5742df4ab58268187dba03cd86a94815128;p=platform%2Fupstream%2Fv8.git 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 . git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24365 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/frames-inl.h b/src/frames-inl.h index 9241a44..d7f2f75 100644 --- a/src/frames-inl.h +++ b/src/frames-inl.h @@ -76,13 +76,13 @@ inline bool StackHandler::is_finally() 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)); } inline unsigned StackHandler::index() const { - const int offset = StackHandlerConstants::kStateOffset; + const int offset = StackHandlerConstants::kStateIntOffset; return IndexField::decode(Memory::unsigned_at(address() + offset)); } diff --git a/src/frames.h b/src/frames.h index f7e60ae..03d53dd 100644 --- a/src/frames.h +++ b/src/frames.h @@ -71,6 +71,11 @@ class StackHandlerConstants : public AllStatic { static const int kNextOffset = 0 * kPointerSize; static const int kCodeOffset = 1 * 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 kFPOffset = 4 * kPointerSize; diff --git a/src/objects-inl.h b/src/objects-inl.h index 59efdf0..cff5b61 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -2635,14 +2635,14 @@ void ConstantPoolArray::InitExtended(const NumberOfEntries& small, // Initialize the extended layout fields. int extended_header_offset = get_extended_section_header_offset(); - WRITE_INT_FIELD(this, extended_header_offset + kExtendedInt64CountOffset, - extended.count_of(INT64)); - WRITE_INT_FIELD(this, extended_header_offset + kExtendedCodePtrCountOffset, - extended.count_of(CODE_PTR)); - WRITE_INT_FIELD(this, extended_header_offset + kExtendedHeapPtrCountOffset, - extended.count_of(HEAP_PTR)); - WRITE_INT_FIELD(this, extended_header_offset + kExtendedInt32CountOffset, - extended.count_of(INT32)); + WRITE_INT32_FIELD(this, extended_header_offset + kExtendedInt64CountOffset, + extended.count_of(INT64)); + WRITE_INT32_FIELD(this, extended_header_offset + kExtendedCodePtrCountOffset, + extended.count_of(CODE_PTR)); + WRITE_INT32_FIELD(this, extended_header_offset + kExtendedHeapPtrCountOffset, + extended.count_of(HEAP_PTR)); + WRITE_INT32_FIELD(this, extended_header_offset + kExtendedInt32CountOffset, + extended.count_of(INT32)); } @@ -3314,7 +3314,11 @@ uint32_t Name::hash_field() { void Name::set_hash_field(uint32_t value) { WRITE_UINT32_FIELD(this, kHashFieldOffset, value); #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 } @@ -5485,25 +5489,30 @@ SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset) #else -#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \ - STATIC_ASSERT(holder::offset % kPointerSize == 0); \ - int holder::name() const { \ - int value = READ_INT_FIELD(this, offset); \ - DCHECK(kHeapObjectTag == 1); \ - DCHECK((value & kHeapObjectTag) == 0); \ - return value >> 1; \ - } \ - void holder::set_##name(int value) { \ - DCHECK(kHeapObjectTag == 1); \ - DCHECK((value & 0xC0000000) == 0xC0000000 || \ - (value & 0xC0000000) == 0x0); \ - WRITE_INT_FIELD(this, \ - offset, \ - (value << 1) & ~kHeapObjectTag); \ - } - -#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \ - STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \ +#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) \ + STATIC_ASSERT(holder::offset % kPointerSize == PSEUDO_SMI_LO_ALIGN); \ + int holder::name() const { \ + int value = READ_INT_FIELD(this, offset); \ + DCHECK(kHeapObjectTag == 1); \ + DCHECK((value & kHeapObjectTag) == 0); \ + return value >> 1; \ + } \ + void holder::set_##name(int value) { \ + DCHECK(kHeapObjectTag == 1); \ + DCHECK((value & 0xC0000000) == 0xC0000000 || (value & 0xC0000000) == 0x0); \ + WRITE_INT_FIELD(this, offset, (value << 1) & ~kHeapObjectTag); \ + } + +#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \ + STATIC_ASSERT(holder::offset % kPointerSize == PSEUDO_SMI_HI_ALIGN); \ INT_ACCESSORS(holder, name, offset) @@ -6632,7 +6641,7 @@ void String::SetForwardedInternalizedString(String* canonical) { DCHECK(SlowEquals(canonical)); DCHECK(canonical->IsInternalizedString()); 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 // code to be interpreted as uninitialized. We use this fact to recognize // that we have a forwarded string. @@ -6643,7 +6652,7 @@ void String::SetForwardedInternalizedString(String* canonical) { String* String::GetForwardedInternalizedString() { DCHECK(IsInternalizedString()); if (HasHashCode()) return this; - String* canonical = String::cast(READ_FIELD(this, kHashFieldOffset)); + String* canonical = String::cast(READ_FIELD(this, kHashFieldSlot)); DCHECK(canonical->IsInternalizedString()); DCHECK(SlowEquals(canonical)); DCHECK(canonical->HasHashCode()); diff --git a/src/objects.cc b/src/objects.cc index f6ec456..9f25145 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -10966,6 +10966,17 @@ void Code::Disassemble(const char* name, std::ostream& os) { // NOLINT it.rinfo()->Print(GetIsolate(), os); } 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 diff --git a/src/objects.h b/src/objects.h index 0e8d2b4..103e93e 100644 --- a/src/objects.h +++ b/src/objects.h @@ -2843,13 +2843,13 @@ class ConstantPoolArray: public HeapObject { // get_extended_section_header_offset(). static const int kExtendedInt64CountOffset = 0; static const int kExtendedCodePtrCountOffset = - kExtendedInt64CountOffset + kPointerSize; + kExtendedInt64CountOffset + kInt32Size; static const int kExtendedHeapPtrCountOffset = - kExtendedCodePtrCountOffset + kPointerSize; + kExtendedCodePtrCountOffset + kInt32Size; static const int kExtendedInt32CountOffset = - kExtendedHeapPtrCountOffset + kPointerSize; + kExtendedHeapPtrCountOffset + kInt32Size; static const int kExtendedFirstOffset = - kExtendedInt32CountOffset + kPointerSize; + kExtendedInt32CountOffset + kInt32Size; // Dispatched behavior. void ConstantPoolIterateBody(ObjectVisitor* v); @@ -5365,7 +5365,7 @@ class Code: public HeapObject { static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize; 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 // the Code object header. @@ -6936,10 +6936,11 @@ class SharedFunctionInfo: public HeapObject { // garbage collections. // To avoid wasting space on 64-bit architectures we use // the following trick: we group integer fields into pairs - // First integer in each pair is shifted left by 1. - // By doing this we guarantee that LSB of each kPointerSize aligned - // word is not set and thus this word cannot be treated as pointer - // to HeapObject during old space traversal. +// The least significant integer in each pair is shifted left by 1. +// By doing this we guarantee that LSB of each kPointerSize aligned +// word is not set and thus this word cannot be treated as pointer +// to HeapObject during old space traversal. +#if V8_TARGET_LITTLE_ENDIAN static const int kLengthOffset = kFeedbackVectorOffset + kPointerSize; static const int kFormalParameterCountOffset = @@ -6973,7 +6974,37 @@ class SharedFunctionInfo: public HeapObject { // Total size. 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); @@ -8482,8 +8513,13 @@ class Name: public HeapObject { DECLARE_PRINTER(Name) // Layout description. - static const int kHashFieldOffset = HeapObject::kHeaderSize; - static const int kSize = kHashFieldOffset + kPointerSize; + static const int kHashFieldSlot = HeapObject::kHeaderSize; +#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 // and if it is a string that is an array index. The least significant bit diff --git a/test/mjsunit/nans.js b/test/mjsunit/nans.js index 987ad6e..5630e5b 100644 --- a/test/mjsunit/nans.js +++ b/test/mjsunit/nans.js @@ -27,6 +27,11 @@ // 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 @@ -41,7 +46,11 @@ function TestAllModes(f) { function TestDoubleSignalingNan() { // NaN with signal bit set function f() { - var bytes = new Uint32Array([1, 0x7FF00000]); + if(isLittleEndian()) { + var bytes = new Uint32Array([1, 0x7FF00000]); + } else { + var bytes = new Uint32Array([0x7FF00000, 1]); + } var doubles = new Float64Array(bytes.buffer); assertTrue(isNaN(doubles[0])); assertTrue(isNaN(doubles[0]*2.0)); @@ -56,7 +65,11 @@ TestDoubleSignalingNan(); function TestDoubleQuietNan() { // NaN with signal bit cleared function f() { - var bytes = new Uint32Array([0, 0x7FF80000]); + if(isLittleEndian()) { + var bytes = new Uint32Array([0, 0x7FF80000]); + } else { + var bytes = new Uint32Array([0x7FF80000, 0]); + } var doubles = new Float64Array(bytes.buffer); assertTrue(isNaN(doubles[0])); assertTrue(isNaN(doubles[0]*2.0));