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 | 6555 #ifdef V8_HOST_CAN_READ_UNALIGNED |
6556 // dst is newly allocated and always aligned. | 6556 // Process the prefix of the input that requires no conversion one |
6557 DCHECK(IsAligned(reinterpret_cast<intptr_t>(dst), sizeof(uintptr_t))); | 6557 // (machine) word at a time. |
6558 // Only attempt processing one word at a time if src is also aligned. | 6558 while (src <= limit - sizeof(uintptr_t)) { |
6559 if (IsAligned(reinterpret_cast<intptr_t>(src), sizeof(uintptr_t))) { | 6559 const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src); |
6560 // Process the prefix of the input that requires no conversion one aligned | 6560 or_acc |= w; |
6561 // (machine) word at a time. | 6561 if (AsciiRangeMask(w, lo, hi) != 0) { |
6562 while (src <= limit - sizeof(uintptr_t)) { | 6562 changed = true; |
6563 const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src); | 6563 break; |
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); | |
6572 } | 6564 } |
6573 // Process the remainder of the input performing conversion when | 6565 *reinterpret_cast<uintptr_t*>(dst) = w; |
6574 // required one word at a time. | 6566 src += sizeof(uintptr_t); |
6575 while (src <= limit - sizeof(uintptr_t)) { | 6567 dst += 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 } | |
6586 } | 6568 } |
| 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 |
6587 // Process the last few bytes of the input (or the whole input if | 6583 // Process the last few bytes of the input (or the whole input if |
6588 // unaligned access is not supported). | 6584 // unaligned access is not supported). |
6589 while (src < limit) { | 6585 while (src < limit) { |
6590 char c = *src; | 6586 char c = *src; |
6591 or_acc |= c; | 6587 or_acc |= c; |
6592 if (lo < c && c < hi) { | 6588 if (lo < c && c < hi) { |
6593 c ^= (1 << 5); | 6589 c ^= (1 << 5); |
6594 changed = true; | 6590 changed = true; |
6595 } | 6591 } |
6596 *dst = c; | 6592 *dst = c; |
6597 ++src; | 6593 ++src; |
6598 ++dst; | 6594 ++dst; |
6599 } | 6595 } |
6600 | 6596 if ((or_acc & kAsciiMask) != 0) { |
6601 if ((or_acc & kAsciiMask) != 0) return false; | 6597 return false; |
| 6598 } |
6602 | 6599 |
6603 DCHECK(CheckFastAsciiConvert( | 6600 DCHECK(CheckFastAsciiConvert( |
6604 saved_dst, saved_src, length, changed, Converter::kIsToLower)); | 6601 saved_dst, saved_src, length, changed, Converter::kIsToLower)); |
6605 | 6602 |
6606 *changed_out = changed; | 6603 *changed_out = changed; |
6607 return true; | 6604 return true; |
6608 } | 6605 } |
6609 | 6606 |
6610 } // namespace | 6607 } // namespace |
6611 | 6608 |
(...skipping 9069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15681 } | 15678 } |
15682 return NULL; | 15679 return NULL; |
15683 } | 15680 } |
15684 | 15681 |
15685 | 15682 |
15686 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15683 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15687 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15684 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15688 } | 15685 } |
15689 | 15686 |
15690 } } // namespace v8::internal | 15687 } } // namespace v8::internal |
OLD | NEW |