Revision: 15023
Author:   [email protected]
Date:     Mon Jun 10 00:34:58 2013
Log:      do aligned reads in ContainsOnlyOneByte

[email protected]
BUG=

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

Modified:
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/src/api.cc  Fri Jun  7 08:02:20 2013
+++ /branches/bleeding_edge/src/api.cc  Mon Jun 10 00:34:58 2013
@@ -4315,17 +4315,49 @@
   void VisitOneByteString(const uint8_t* chars, int length) {
     // Nothing to do.
   }
-  // TODO(dcarney): do word aligned read.
   void VisitTwoByteString(const uint16_t* chars, int length) {
-    // Check whole string without breaking.
-    uint16_t total = 0;
-    for (int i = 0; i < length; i++) {
-      total |= chars[i] >> 8;
+    // Accumulated bits.
+    uintptr_t acc = 0;
+    // Align to uintptr_t.
+    const uint16_t* end = chars + length;
+    while (Unaligned(chars) && chars != end) {
+        acc |= *chars++;
     }
-    if (total != 0) is_one_byte_ = false;
+    // Read word aligned in blocks,
+    // checking the return value at the end of each block.
+    const uint16_t* aligned_end = Align(end);
+    const int increment = sizeof(uintptr_t)/sizeof(uint16_t);
+    const int inner_loops = 16;
+    while (chars + inner_loops*increment < aligned_end) {
+      for (int i = 0; i < inner_loops; i++) {
+        acc |= *reinterpret_cast<const uintptr_t*>(chars);
+        chars += increment;
+      }
+      // Check for early return.
+      if ((acc & kOneByteMask) != 0) {
+        is_one_byte_ = false;
+        return;
+      }
+    }
+    // Read the rest.
+    while (chars != end) {
+      acc |= *chars++;
+    }
+    // Check result.
+    if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
   }

  private:
+  static const uintptr_t kOneByteMask =
+      static_cast<uintptr_t>(0xFF00FF00FF00FF00ULL);
+  static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
+  static inline bool Unaligned(const uint16_t* chars) {
+    return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
+  }
+  static inline const uint16_t* Align(const uint16_t* chars) {
+    return reinterpret_cast<uint16_t*>(
+        reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask);
+  }
   bool CheckCons(i::ConsString* cons_string) {
     while (true) {
       // Check left side if flat.
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Fri Jun  7 08:02:20 2013
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Mon Jun 10 00:34:58 2013
@@ -17033,8 +17033,12 @@
   v8::Isolate* isolate = v8::Isolate::GetCurrent();
   v8::HandleScope scope(isolate);
   // Make a buffer long enough that it won't automatically be converted.
-  const int length = 200;
-  i::SmartArrayPointer<uint16_t> string_contents(new uint16_t[length]);
+  const int length = 512;
+  // Ensure word aligned assignment.
+  const int aligned_length = length*sizeof(uintptr_t)/sizeof(uint16_t);
+  i::SmartArrayPointer<uintptr_t>
+  aligned_contents(new uintptr_t[aligned_length]);
+ uint16_t* string_contents = reinterpret_cast<uint16_t*>(*aligned_contents);
   // Set to contain only one byte.
   for (int i = 0; i < length-1; i++) {
     string_contents[i] = 0x41;
@@ -17042,10 +17046,10 @@
   string_contents[length-1] = 0;
   // Simple case.
   Handle<String> string;
-  string = String::NewExternal(new TestResource(*string_contents));
+  string = String::NewExternal(new TestResource(string_contents));
   CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte());
   // Counter example.
-  string = String::NewFromTwoByte(isolate, *string_contents);
+  string = String::NewFromTwoByte(isolate, string_contents);
   CHECK(string->IsOneByte() && string->ContainsOnlyOneByte());
   // Test left right and balanced cons strings.
   Handle<String> base = String::NewFromUtf8(isolate, "a");
@@ -17059,7 +17063,7 @@
   balanced = String::Concat(balanced, right);
   Handle<String> cons_strings[] = {left, balanced, right};
   Handle<String> two_byte =
-      String::NewExternal(new TestResource(*string_contents));
+      String::NewExternal(new TestResource(string_contents));
   for (size_t i = 0; i < ARRAY_SIZE(cons_strings); i++) {
     // Base assumptions.
     string = cons_strings[i];
@@ -17070,6 +17074,24 @@
     string = String::Concat(cons_strings[i], two_byte);
     CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte());
   }
+  // Set bits in different positions
+  // for strings of different lengths and alignments.
+  for (int alignment = 0; alignment < 7; alignment++) {
+    for (int size = 2; alignment + size < length; size *= 2) {
+      int zero_offset = size + alignment;
+      string_contents[zero_offset] = 0;
+      for (int i = 0; i < size; i++) {
+        int shift = 8 + (i % 7);
+        string_contents[alignment + i] = 1 << shift;
+        string =
+ String::NewExternal(new TestResource(string_contents + alignment));
+        CHECK_EQ(size, string->Length());
+        CHECK(!string->ContainsOnlyOneByte());
+        string_contents[alignment + i] = 0x41;
+      }
+      string_contents[zero_offset] = 0x41;
+    }
+  }
 }


--
--
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/groups/opt_out.


Reply via email to