Revision: 21533
Author:   [email protected]
Date:     Tue May 27 14:55:29 2014 UTC
Log:      Convert String array index/length hash to BitField

[email protected]

Review URL: https://codereview.chromium.org/300023011
http://code.google.com/p/v8/source/detail?r=21533

Modified:
 /branches/bleeding_edge/src/arm/macro-assembler-arm.cc
 /branches/bleeding_edge/src/arm/macro-assembler-arm.h
 /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc
 /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
 /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/x64/macro-assembler-x64.cc
 /branches/bleeding_edge/src/x64/macro-assembler-x64.h

=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue May 27 09:38:01 2014 UTC +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue May 27 14:55:29 2014 UTC
@@ -2439,10 +2439,7 @@
   // conflict.
   ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
          (1 << String::kArrayIndexValueBits));
- // We want the smi-tagged index in key. kArrayIndexValueMask has zeros in
-  // the low kHashShift bits.
-  Ubfx(hash, hash, String::kHashShift, String::kArrayIndexValueBits);
-  SmiTag(index, hash);
+  DecodeFieldToSmi<String::ArrayIndexValueBits>(index, hash);
 }


=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Mon May 26 11:28:08 2014 UTC +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Tue May 27 14:55:29 2014 UTC
@@ -1357,17 +1357,33 @@

   template<typename Field>
   void DecodeField(Register dst, Register src) {
+    Ubfx(dst, src, Field::kShift, Field::kSize);
+  }
+
+  template<typename Field>
+  void DecodeField(Register reg) {
+    DecodeField<Field>(reg, reg);
+  }
+
+  template<typename Field>
+  void DecodeFieldToSmi(Register dst, Register src) {
     static const int shift = Field::kShift;
-    static const int mask = Field::kMask >> shift;
-    static const int size = Field::kSize;
-    mov(dst, Operand(src, LSR, shift));
-    if (shift + size != 32) {
+    static const int mask = Field::kMask >> shift << kSmiTagSize;
+    STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0);
+    STATIC_ASSERT(kSmiTag == 0);
+    if (shift < kSmiTagSize) {
+      mov(dst, Operand(src, LSL, kSmiTagSize - shift));
       and_(dst, dst, Operand(mask));
+    } else if (shift > kSmiTagSize) {
+      mov(dst, Operand(src, LSR, shift - kSmiTagSize));
+      and_(dst, dst, Operand(mask));
+    } else {
+      and_(dst, src, Operand(mask));
     }
   }

   template<typename Field>
-  void DecodeField(Register reg) {
+  void DecodeFieldToSmi(Register reg) {
     DecodeField<Field>(reg, reg);
   }

=======================================
--- /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc Tue May 27 09:38:01 2014 UTC +++ /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc Tue May 27 14:55:29 2014 UTC
@@ -3975,11 +3975,8 @@
   // conflict.
   ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
          (1 << String::kArrayIndexValueBits));
- // We want the smi-tagged index in key. kArrayIndexValueMask has zeros in
-  // the low kHashShift bits.
-  STATIC_ASSERT(kSmiTag == 0);
-  Ubfx(hash, hash, String::kHashShift, String::kArrayIndexValueBits);
-  SmiTag(index, hash);
+  DecodeField<String::ArrayIndexValueBits>(index, hash);
+  SmiTag(index, index);
 }


=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Tue May 27 09:38:01 2014 UTC +++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Tue May 27 14:55:29 2014 UTC
@@ -2047,16 +2047,10 @@
   // reserved for it does not conflict.
   ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
          (1 << String::kArrayIndexValueBits));
- // We want the smi-tagged index in key. kArrayIndexValueMask has zeros in
-  // the low kHashShift bits.
-  and_(hash, String::kArrayIndexValueMask);
-  STATIC_ASSERT(String::kHashShift >= kSmiTagSize && kSmiTag == 0);
-  if (String::kHashShift > kSmiTagSize) {
-    shr(hash, String::kHashShift - kSmiTagSize);
-  }
   if (!index.is(hash)) {
     mov(index, hash);
   }
+  DecodeFieldToSmi<String::ArrayIndexValueBits>(index);
 }


=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Mon May 26 11:28:08 2014 UTC +++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Tue May 27 14:55:29 2014 UTC
@@ -497,9 +497,26 @@
   void DecodeField(Register reg) {
     static const int shift = Field::kShift;
     static const int mask = Field::kMask >> Field::kShift;
-    sar(reg, shift);
+    if (shift != 0) {
+      sar(reg, shift);
+    }
+    and_(reg, Immediate(mask));
+  }
+
+  template<typename Field>
+  void DecodeFieldToSmi(Register reg) {
+    static const int shift = Field::kShift;
+    static const int mask = (Field::kMask >> Field::kShift) << kSmiTagSize;
+    STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0);
+    STATIC_ASSERT(kSmiTag == 0);
+    if (shift < kSmiTagSize) {
+      shl(reg, kSmiTagSize - shift);
+    } else if (shift > kSmiTagSize) {
+      sar(reg, shift - kSmiTagSize);
+    }
     and_(reg, Immediate(mask));
   }
+
   void LoadPowerOf2(XMMRegister dst, Register scratch, int power);

   // Abort execution if argument is not a number, enabled via --debug-code.
=======================================
--- /branches/bleeding_edge/src/objects.cc      Tue May 27 07:57:22 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc      Tue May 27 14:55:29 2014 UTC
@@ -9668,7 +9668,7 @@
     uint32_t field = hash_field();
     if ((field & kIsNotArrayIndexMask) != 0) return false;
     // Isolate the array index form the full hash field.
-    *index = (kArrayIndexHashMask & field) >> kHashShift;
+    *index = ArrayIndexValueBits::decode(field);
     return true;
   } else {
     return ComputeArrayIndex(index);
@@ -9726,8 +9726,8 @@
   ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
          (1 << String::kArrayIndexValueBits));

-  value <<= String::kHashShift;
-  value |= length << String::kArrayIndexHashLengthShift;
+  value <<= String::ArrayIndexValueBits::kShift;
+  value |= length << String::ArrayIndexLengthBits::kShift;

   ASSERT((value & String::kIsNotArrayIndexMask) == 0);
   ASSERT((length > String::kMaxCachedArrayIndexLength) ||
=======================================
--- /branches/bleeding_edge/src/objects.h       Tue May 27 13:43:29 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Tue May 27 14:55:29 2014 UTC
@@ -8793,13 +8793,11 @@

   STATIC_ASSERT((kArrayIndexLengthBits > 0));

-  static const int kArrayIndexHashLengthShift =
-      kArrayIndexValueBits + kNofHashBitFields;
-
- static const int kArrayIndexHashMask = (1 << kArrayIndexHashLengthShift) - 1;
-
-  static const int kArrayIndexValueMask =
-      ((1 << kArrayIndexValueBits) - 1) << kHashShift;
+ class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
+      kArrayIndexValueBits> {};
+  class ArrayIndexLengthBits : public BitField<unsigned int,
+      kNofHashBitFields + kArrayIndexValueBits,
+      kArrayIndexLengthBits> {};

   // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
// could use a mask to test if the length of string is less than or equal to
@@ -8807,7 +8805,7 @@
   STATIC_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));

   static const unsigned int kContainsCachedArrayIndexMask =
-      (~kMaxCachedArrayIndexLength << kArrayIndexHashLengthShift) |
+      (~kMaxCachedArrayIndexLength << ArrayIndexLengthBits::kShift) |
       kIsNotArrayIndexMask;

   // Value of empty hash field indicating that the hash is not computed.
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Tue May 27 09:38:01 2014 UTC +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Tue May 27 14:55:29 2014 UTC
@@ -548,16 +548,10 @@
   // reserved for it does not conflict.
   ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
          (1 << String::kArrayIndexValueBits));
-  // We want the smi-tagged index in key. Even if we subsequently go to
-  // the slow case, converting the key to a smi is always valid.
-  // key: string key
-  // hash: key's hash field, including its array index value.
-  andp(hash, Immediate(String::kArrayIndexValueMask));
-  shrp(hash, Immediate(String::kHashShift));
-  // Here we actually clobber the key which will be used if calling into
- // runtime later. However as the new key is the numeric value of a string key
-  // there is no difference in using either key.
-  Integer32ToSmi(index, hash);
+  if (!hash.is(index)) {
+    movl(index, hash);
+  }
+  DecodeFieldToSmi<String::ArrayIndexValueBits>(index);
 }


=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.h Mon May 26 11:28:08 2014 UTC +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.h Tue May 27 14:55:29 2014 UTC
@@ -1014,9 +1014,17 @@
   void DecodeField(Register reg) {
     static const int shift = Field::kShift;
     static const int mask = Field::kMask >> Field::kShift;
-    shrp(reg, Immediate(shift));
+    if (shift != 0) {
+      shrp(reg, Immediate(shift));
+    }
     andp(reg, Immediate(mask));
   }
+
+  template<typename Field>
+  void DecodeFieldToSmi(Register reg) {
+    andp(reg, Immediate(Field::kMask));
+    shlp(reg, Immediate(kSmiShift - Field::kShift));
+  }

   // Abort execution if argument is not a number, enabled via --debug-code.
   void AssertNumber(Register object);

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to