Endian changes, support 64bit big endian
authorsvenpanne@chromium.org <svenpanne@chromium.org>
Wed, 1 Oct 2014 13:14:14 +0000 (13:14 +0000)
committersvenpanne@chromium.org <svenpanne@chromium.org>
Wed, 1 Oct 2014 13:14:14 +0000 (13:14 +0000)
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

src/frames-inl.h
src/frames.h
src/objects-inl.h
src/objects.cc
src/objects.h
test/mjsunit/nans.js

index 9241a449f4c0802fb42492697e88e349facd9ccb..d7f2f75d364e1d2556c5649cfb332bea73439af3 100644 (file)
@@ -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));
 }
 
index f7e60aef33b1b0fd67342bfa66ea78a5e8bb89b7..03d53dd6a1cbdf0990205760bc398bb96b4416b1 100644 (file)
@@ -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;
 
index 59efdf0a89269799f4b9bd5ddc8ef766f04b77e6..cff5b61b527bec83db46b2efbc99d85898e0a1ae 100644 (file)
@@ -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());
index f6ec456bd4ddebf0349bf77a6b235aae48c3d784..9f25145bf2c197048ee858906c251158c8e8570e 100644 (file)
@@ -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
 
index 0e8d2b460cb263f2896b4fb89007e16d5b94e551..103e93e8c4ac2547bea8167c190803000071ea6a 100644 (file)
@@ -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
index 987ad6e78ef9ed4682ca3d081db0db8bb0dc43dc..5630e5b061c6a677855b4ff574740ae3aae53f62 100644 (file)
 
 // 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));