OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 6534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6545 DisallowHeapAllocation no_gc; | 6545 DisallowHeapAllocation no_gc; |
6546 // We rely on the distance between upper and lower case letters | 6546 // We rely on the distance between upper and lower case letters |
6547 // being a known power of 2. | 6547 // being a known power of 2. |
6548 DCHECK('a' - 'A' == (1 << 5)); | 6548 DCHECK('a' - 'A' == (1 << 5)); |
6549 // Boundaries for the range of input characters than require conversion. | 6549 // Boundaries for the range of input characters than require conversion. |
6550 static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1; | 6550 static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1; |
6551 static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1; | 6551 static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1; |
6552 bool changed = false; | 6552 bool changed = false; |
6553 uintptr_t or_acc = 0; | 6553 uintptr_t or_acc = 0; |
6554 const char* const limit = src + length; | 6554 const char* const limit = src + length; |
6555 #ifdef V8_HOST_CAN_READ_UNALIGNED | 6555 |
6556 // Process the prefix of the input that requires no conversion one | 6556 // dst is newly allocated and always aligned. |
6557 // (machine) word at a time. | 6557 DCHECK(IsAligned(reinterpret_cast<intptr_t>(dst), sizeof(uintptr_t))); |
6558 while (src <= limit - sizeof(uintptr_t)) { | 6558 // Only attempt processing one word at a time if src is also aligned. |
6559 const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src); | 6559 if (IsAligned(reinterpret_cast<intptr_t>(src), sizeof(uintptr_t))) { |
6560 or_acc |= w; | 6560 // Process the prefix of the input that requires no conversion one aligned |
6561 if (AsciiRangeMask(w, lo, hi) != 0) { | 6561 // (machine) word at a time. |
6562 changed = true; | 6562 while (src <= limit - sizeof(uintptr_t)) { |
6563 break; | 6563 const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src); |
| 6564 or_acc |= w; |
| 6565 if (AsciiRangeMask(w, lo, hi) != 0) { |
| 6566 changed = true; |
| 6567 break; |
| 6568 } |
| 6569 *reinterpret_cast<uintptr_t*>(dst) = w; |
| 6570 src += sizeof(uintptr_t); |
| 6571 dst += sizeof(uintptr_t); |
6564 } | 6572 } |
6565 *reinterpret_cast<uintptr_t*>(dst) = w; | 6573 // Process the remainder of the input performing conversion when |
6566 src += sizeof(uintptr_t); | 6574 // required one word at a time. |
6567 dst += sizeof(uintptr_t); | 6575 while (src <= limit - sizeof(uintptr_t)) { |
| 6576 const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src); |
| 6577 or_acc |= w; |
| 6578 uintptr_t m = AsciiRangeMask(w, lo, hi); |
| 6579 // The mask has high (7th) bit set in every byte that needs |
| 6580 // conversion and we know that the distance between cases is |
| 6581 // 1 << 5. |
| 6582 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); |
| 6583 src += sizeof(uintptr_t); |
| 6584 dst += sizeof(uintptr_t); |
| 6585 } |
6568 } | 6586 } |
6569 // Process the remainder of the input performing conversion when | |
6570 // required one word at a time. | |
6571 while (src <= limit - sizeof(uintptr_t)) { | |
6572 const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src); | |
6573 or_acc |= w; | |
6574 uintptr_t m = AsciiRangeMask(w, lo, hi); | |
6575 // The mask has high (7th) bit set in every byte that needs | |
6576 // conversion and we know that the distance between cases is | |
6577 // 1 << 5. | |
6578 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); | |
6579 src += sizeof(uintptr_t); | |
6580 dst += sizeof(uintptr_t); | |
6581 } | |
6582 #endif | |
6583 // Process the last few bytes of the input (or the whole input if | 6587 // Process the last few bytes of the input (or the whole input if |
6584 // unaligned access is not supported). | 6588 // unaligned access is not supported). |
6585 while (src < limit) { | 6589 while (src < limit) { |
6586 char c = *src; | 6590 char c = *src; |
6587 or_acc |= c; | 6591 or_acc |= c; |
6588 if (lo < c && c < hi) { | 6592 if (lo < c && c < hi) { |
6589 c ^= (1 << 5); | 6593 c ^= (1 << 5); |
6590 changed = true; | 6594 changed = true; |
6591 } | 6595 } |
6592 *dst = c; | 6596 *dst = c; |
6593 ++src; | 6597 ++src; |
6594 ++dst; | 6598 ++dst; |
6595 } | 6599 } |
6596 if ((or_acc & kAsciiMask) != 0) { | 6600 |
6597 return false; | 6601 if ((or_acc & kAsciiMask) != 0) return false; |
6598 } | |
6599 | 6602 |
6600 DCHECK(CheckFastAsciiConvert( | 6603 DCHECK(CheckFastAsciiConvert( |
6601 saved_dst, saved_src, length, changed, Converter::kIsToLower)); | 6604 saved_dst, saved_src, length, changed, Converter::kIsToLower)); |
6602 | 6605 |
6603 *changed_out = changed; | 6606 *changed_out = changed; |
6604 return true; | 6607 return true; |
6605 } | 6608 } |
6606 | 6609 |
6607 } // namespace | 6610 } // namespace |
6608 | 6611 |
(...skipping 9069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15678 } | 15681 } |
15679 return NULL; | 15682 return NULL; |
15680 } | 15683 } |
15681 | 15684 |
15682 | 15685 |
15683 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15686 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15684 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15687 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15685 } | 15688 } |
15686 | 15689 |
15687 } } // namespace v8::internal | 15690 } } // namespace v8::internal |
OLD | NEW |