|
| 1 | +// Copyright 2022 the V8 project authors. All rights reserved. |
| 2 | +// Use of this source code is governed by a BSD-style license that can be |
| 3 | +// found in the LICENSE file. |
| 4 | + |
| 5 | +// This file excercises one byte string support for fast API calls. |
| 6 | + |
| 7 | +// Flags: --turbo-fast-api-calls --expose-fast-api --allow-natives-syntax --turbofan |
| 8 | +// --always-turbofan is disabled because we rely on particular feedback for |
| 9 | +// optimizing to the fastest path. |
| 10 | +// Flags: --no-always-turbofan |
| 11 | +// The test relies on optimizing/deoptimizing at predictable moments, so |
| 12 | +// it's not suitable for deoptimization fuzzing. |
| 13 | +// Flags: --deopt-every-n-times=0 |
| 14 | + |
| 15 | +assertThrows(() => d8.test.FastCAPI()); |
| 16 | +const fast_c_api = new d8.test.FastCAPI(); |
| 17 | + |
| 18 | +function assertSlowCall(input) { |
| 19 | + assertEquals(new Uint8Array(input.length), copy_string(false, input)); |
| 20 | +} |
| 21 | + |
| 22 | +function assertFastCall(input) { |
| 23 | + const bytes = Uint8Array.from(input, c => c.charCodeAt(0)); |
| 24 | + assertEquals(bytes, copy_string(false, input)); |
| 25 | +} |
| 26 | + |
| 27 | +function copy_string(should_fallback = false, input) { |
| 28 | + const buffer = new Uint8Array(input.length); |
| 29 | + fast_c_api.copy_string(should_fallback, input, buffer); |
| 30 | + return buffer; |
| 31 | +} |
| 32 | + |
| 33 | +%PrepareFunctionForOptimization(copy_string); |
| 34 | +assertSlowCall('Hello'); |
| 35 | +%OptimizeFunctionOnNextCall(copy_string); |
| 36 | + |
| 37 | +fast_c_api.reset_counts(); |
| 38 | +assertFastCall('Hello'); |
| 39 | +assertFastCall(''); |
| 40 | +assertFastCall(['Hello', 'World'].join('')); |
| 41 | +assertOptimized(copy_string); |
| 42 | +assertEquals(3, fast_c_api.fast_call_count()); |
| 43 | +assertEquals(0, fast_c_api.slow_call_count()); |
| 44 | + |
| 45 | +// Fall back for twobyte strings. |
| 46 | +fast_c_api.reset_counts(); |
| 47 | +assertSlowCall('Hello\u{10000}'); |
| 48 | +assertSlowCall('नमस्ते'); |
| 49 | +assertSlowCall(['नमस्ते', 'World'].join('')); |
| 50 | +assertOptimized(copy_string); |
| 51 | +assertEquals(0, fast_c_api.fast_call_count()); |
| 52 | +assertEquals(3, fast_c_api.slow_call_count()); |
| 53 | + |
| 54 | +// Fall back for cons strings. |
| 55 | +function getTwoByteString() { |
| 56 | + return '\u1234t'; |
| 57 | +} |
| 58 | +function getCons() { |
| 59 | + return 'hello' + getTwoByteString() |
| 60 | +} |
| 61 | + |
| 62 | +fast_c_api.reset_counts(); |
| 63 | +assertSlowCall(getCons()); |
| 64 | +assertOptimized(copy_string); |
| 65 | +assertEquals(0, fast_c_api.fast_call_count()); |
| 66 | +assertEquals(1, fast_c_api.slow_call_count()); |
| 67 | + |
| 68 | +// Fall back for sliced strings. |
| 69 | +fast_c_api.reset_counts(); |
| 70 | +function getSliced() { |
| 71 | + return getCons().slice(1); |
| 72 | +} |
| 73 | +assertSlowCall(getSliced()); |
| 74 | +assertOptimized(copy_string); |
| 75 | +assertEquals(0, fast_c_api.fast_call_count()); |
| 76 | +assertEquals(1, fast_c_api.slow_call_count()); |
| 77 | + |
| 78 | +// Fall back for SMI and non-string inputs. |
| 79 | +fast_c_api.reset_counts(); |
| 80 | +assertSlowCall(1); |
| 81 | +assertSlowCall({}); |
| 82 | +assertSlowCall(new Uint8Array(1)); |
| 83 | +assertEquals(0, fast_c_api.fast_call_count()); |
| 84 | +assertEquals(3, fast_c_api.slow_call_count()); |
0 commit comments