1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_PLATFORM_JSON_HELPER_INTERNAL_ARM64_H 17 #define ECMASCRIPT_PLATFORM_JSON_HELPER_INTERNAL_ARM64_H 18 #include <arm_neon.h> 19 #include "ecmascript/base/config.h" 20 21 namespace panda::ecmascript::base { 22 class JsonHelperInternal { 23 friend class JsonPlatformHelper; 24 private: 25 static constexpr uint8x16_t QUOTE_INDEX_MASK_DATA = { 26 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1 27 }; 28 static constexpr uint8x16_t BACKSLASH_INDEX_MASK_DATA = { 29 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2 30 }; 31 static constexpr uint8x16_t CONTROL_INDEX_MASK_DATA = { 32 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4 33 }; 34 static constexpr uint8x16_t QUOTE_VECTOR = { 35 '"', '"', '"', '"', '"', '"', '"', '"', '"', '"', '"', '"', '"', '"', '"', '"' 36 }; 37 static constexpr uint8x16_t BACKSLASH_VECTOR = { 38 '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' 39 }; 40 static constexpr uint8x16_t SPACE_VECTOR = { 41 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' 42 }; 43 static constexpr uint8x16_t ZERO_VECTOR = { 44 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 45 }; 46 static constexpr uint8x16_t COMPARE_VECTOR = { 47 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 48 }; 49 static constexpr uint8_t QUOTE_MASK = 0x01; 50 static constexpr uint8_t BACKSLASH_MASK = 0x02; 51 static constexpr uint8_t CONTROL_MASK = 0x04; 52 static constexpr uint8_t INDEX_MASK = 0xF0; 53 static constexpr uint8_t INDEX_SHIFT = 4; 54 static constexpr uint8_t QUOTE_CHAR = '"'; 55 static constexpr uint8_t BACKSLASH_CHAR = '\\'; 56 static constexpr uint8_t SPACE_CHAR = ' '; 57 static constexpr uint8_t COMPARE_MASK = 0xFF; 58 static constexpr size_t CHUNK_SIZE = 16; 59 60 /** 61 * origin: [ x, x,'\\', x, '"', x, x,'\t', x, x,'\\','\b', x, x, '"', x] 62 * first step: 63 * quote: [ 0, 0, 0, 0,0x41, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE1, 0] 64 * backslash: [ 0, 0,0x22, 0, 0, 0, 0, 0, 0, 0,0xA2, 0, 0, 0, 0, 0] 65 * control: [ 0, 0, 0, 0, 0, 0, 0,0x74, 0, 0, 0,0xB4, 0, 0, 0, 0] 66 * second step: 67 * combine: [ 0, 0,0x22, 0,0x41, 0, 0,0x74, 0, 0,0xA2,0xB4, 0, 0,0xE1, 0] 68 * final: [0xFF,0xFF,0x22,0xFF,0x41,0xFF,0xFF,0x74,0xFF,0xFF,0xA2,0xB4,0xFF,0xFF,0xE1,0xFF] 69 * min_index: 0x22 => 0x22 & 0x02 > 0 => backslash 70 */ ReadJsonStringRangeForUtf8(bool & isFastString,const uint8_t * current,const uint8_t * range,const uint8_t * & end)71 static bool ReadJsonStringRangeForUtf8(bool &isFastString, const uint8_t *current, 72 const uint8_t *range, const uint8_t *&end) 73 { 74 const uint8_t* cur = current; 75 for (; cur + CHUNK_SIZE <= range; cur += CHUNK_SIZE) { 76 uint8x16_t chunk = vld1q_u8(cur); 77 uint8x16_t quote_mask = vandq_u8(QUOTE_INDEX_MASK_DATA, vceqq_u8(chunk, QUOTE_VECTOR)); 78 uint8x16_t backslash_mask = vandq_u8(BACKSLASH_INDEX_MASK_DATA, vceqq_u8(chunk, BACKSLASH_VECTOR)); 79 uint8x16_t control_mask = vandq_u8(CONTROL_INDEX_MASK_DATA, vcltq_u8(chunk, SPACE_VECTOR)); 80 uint8x16_t combined_mask = vorrq_u8(quote_mask, vorrq_u8(backslash_mask, control_mask)); 81 uint8x16_t zero_mask = vceqq_u8(combined_mask, ZERO_VECTOR); 82 uint8x16_t indices = vbslq_u8(zero_mask, COMPARE_VECTOR, combined_mask); 83 uint8_t min_index = vminvq_u8(indices); 84 if (min_index != COMPARE_MASK) { // 0xFF means no special characters 85 if ((min_index & QUOTE_MASK) > 0) { 86 end = cur + ((min_index & INDEX_MASK) >> INDEX_SHIFT); 87 return true; 88 } 89 if (UNLIKELY((min_index & BACKSLASH_MASK) > 0)) { 90 isFastString = false; 91 return true; 92 } 93 if (UNLIKELY((min_index & CONTROL_MASK) > 0)) { 94 return false; 95 } 96 } 97 } 98 for (; cur != range; ++cur) { 99 if (*cur == QUOTE_CHAR) { 100 end = cur; 101 return true; 102 } 103 if (UNLIKELY(*cur == BACKSLASH_CHAR)) { 104 isFastString = false; 105 return true; 106 } 107 if (UNLIKELY(*cur < SPACE_CHAR)) { 108 return false; 109 } 110 } 111 return false; 112 } 113 }; 114 } 115 #endif //ECMASCRIPT_PLATFORM_JSON_HELPER_INTERNAL_ARM64_H 116