Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
e294410
deps: V8: cherry-pick bf0bd4868dde
targos Dec 19, 2022
7bd6a2c
wasi: fast calls
devsnek Dec 8, 2022
faee973
deps: V8: cherry-pick bc831f8ba33b
anonrig Dec 10, 2022
7e047df
doc: fix wrong output of example in util
deokjinkim Dec 12, 2022
d08a574
tls: fix re-entrancy issue with TLS close_notify
davidben Sep 6, 2022
ca9b9b9
tls: don't treat fatal TLS alerts as EOF
davidben Sep 6, 2022
99fec0b
deps: update undici to 5.14.0
nodejs-github-bot Dec 13, 2022
3c2ce56
test: remove use of --experimental-global-webcrypto flag
panva Dec 13, 2022
bdbb676
test_runner: parse yaml
MoLow Dec 13, 2022
c37a119
doc: remove last example use of require('crypto').webcrypto
panva Dec 11, 2022
fea122d
test: enable idlharness WebCryptoAPI WPTs
panva Dec 13, 2022
27cf389
tools: update eslint to 8.29.0
nodejs-github-bot Dec 14, 2022
124c2b3
tools: fix incorrect version history order
welfoz Dec 14, 2022
24cae6b
repl: improve robustness wrt to prototype pollution
aduh95 Dec 14, 2022
c86f4a1
doc: remove Juan Jose keys
RafaelGSS Dec 14, 2022
5de08ef
test: add postject to fixtures
RaisinTen Dec 15, 2022
b93a967
doc: add stream/promises pipeline and finished to doc
marco-ippolito Dec 15, 2022
dd77c05
bootstrap: support module_wrap binding in snapshot
joyeecheung Dec 13, 2022
508e830
bootstrap: include event_target into the built-in snapshot
joyeecheung Dec 13, 2022
c6ab449
modules: move modules/cjs/helpers.js to modules/helpers.js
joyeecheung Dec 13, 2022
943852a
lib: add getLazy() method to internal/util
joyeecheung Dec 13, 2022
e529ea4
lib: lazy-load deps in source_map_cache.js
joyeecheung Dec 13, 2022
f6c6673
lib: lazy-load deps in modules/run_main.js
joyeecheung Dec 13, 2022
0b3512f
modules: move callbacks and conditions into modules/esm/utils.js
joyeecheung Dec 13, 2022
d181b76
bootstrap: make CJS loader snapshotable
joyeecheung Dec 13, 2022
6e3d7f8
bootstrap: optimize modules loaded in the built-in snapshot
joyeecheung Dec 13, 2022
c980286
crypto: fix error when getRandomValues is called without arguments
panva Dec 12, 2022
6eede72
crypto: fix CryptoKey WebIDL conformance
panva Dec 12, 2022
b5e1245
test,crypto: update WebCryptoAPI WPT
panva Dec 14, 2022
dfa58c1
doc: remove release cleanup step
targos Dec 16, 2022
e229f06
doc: add backticks to webcrypto rsaOaepParams
panva Dec 16, 2022
53f02cf
test: add CryptoKey transferring tests
panva Dec 16, 2022
c9747f1
crypto: use globalThis.crypto over require('crypto').webcrypto
panva Dec 16, 2022
d500445
doc: reduce likelihood of mismerges during release
richardlau Dec 16, 2022
10367c4
test: update url wpt to latest
anonrig Dec 17, 2022
c5004d4
test_runner: run t.after() if test body throws
cjihrig Dec 17, 2022
71056da
test: update encoding wpt to latest
anonrig Dec 17, 2022
97868be
test: fix mock.method to support class instances
ErickWendel Dec 17, 2022
eff92a6
src: add undici and acorn to `process.versions`
debadree25 Dec 18, 2022
794611a
tools: enforce use of trailing commas in `tools/`
aduh95 Dec 18, 2022
353dab5
meta: update AUTHORS
nodejs-github-bot Dec 18, 2022
95ce16d
test: fix test broken under --node-builtin-modules-path
GeoffreyBooth Dec 18, 2022
cf30fca
doc: add tip for NODE_MODULE
theanarkh Dec 19, 2022
2f898f2
src: fix tls certificate root store data race
bnoordhuis Dec 19, 2022
a89f8c1
doc: fix some history entries in `deprecations.md`
aduh95 Dec 19, 2022
f3bb6a3
node-api: generalize finalizer second pass callback
legendecas Dec 19, 2022
f446af7
tools: update lint-md dependencies
nodejs-github-bot Dec 19, 2022
29f90cf
deps: update timezone to 2022g
nodejs-github-bot Dec 20, 2022
56f3ad1
crypto: fix CryptoKey prototype WPT
panva Dec 14, 2022
97a8e05
test: add all WebCryptoAPI globals to WPTRunner's loadLazyGlobals
panva Dec 14, 2022
f7dba5b
crypto: fix globalThis.crypto this check
panva Dec 16, 2022
c6c0947
test: split parallel fs-watch-recursive tests
anonrig Dec 20, 2022
27d3201
src: check size of args before using for exec_path
awilfox Dec 20, 2022
4454f5f
src: fix UB in overflow checks
bnoordhuis Dec 20, 2022
7bdad94
deps: V8: backport 8ca9f77d0f7c
addaleax Dec 21, 2022
9ed547b
doc: fix wrong output of example in `url.password`
deokjinkim Dec 21, 2022
cf2ff81
benchmark: include webstreams benchmark
RafaelGSS Dec 21, 2022
b995138
src: use CreateEnvironment instead of inlining its code where possible
addaleax Dec 21, 2022
e7b98a3
build: add option to disable shared readonly heap
addaleax Dec 21, 2022
d71883e
os: add availableParallelism()
cjihrig Dec 17, 2022
faf5c23
doc: add parallelism note to os.cpus()
cjihrig Dec 18, 2022
c2ed0cc
src: use string_view for FastStringKey implementation
addaleax Dec 21, 2022
344c5ec
deps: add simdutf dependency
anonrig Nov 30, 2022
ae842a4
util: add fast path for text-decoder fatal flag
anonrig Dec 15, 2022
98fc94a
deps: disable avx512 for simutf on benchmark ci
anonrig Dec 17, 2022
8046e0e
errors: refactor to use a method that formats a list string
daeyeon Dec 23, 2022
ded87f6
src: fix creating `Isolate`s from addons
addaleax Dec 23, 2022
e956956
meta: add `nodejs/test_runner` to CODEOWNERS
aduh95 Dec 23, 2022
1282f7f
tools: update GitHub workflow action
VoltrexKeyva Dec 23, 2022
908f4fa
doc: show output of example in http
deokjinkim Dec 24, 2022
86e30fc
meta: add `nodejs/loaders` to CODEOWNERS
GeoffreyBooth Dec 24, 2022
4457e05
doc: remove port from example in `url.hostname`
deokjinkim Dec 24, 2022
7ea72ee
http: improved timeout defaults handling
ShogunPanda Dec 24, 2022
8e6b8db
net: add autoSelectFamily global getter and setter
ShogunPanda Dec 24, 2022
d8b5b7d
doc: fix typos in packages.md
ericmutta Dec 23, 2022
eaf6b63
doc: update error message of example in repl
deokjinkim Dec 24, 2022
233a66f
build: fix arm64 cross-compile from powershell
StefanStojanovic Dec 24, 2022
05fee67
Revert "deps: disable avx512 for simutf on benchmark ci"
anonrig Dec 24, 2022
fbe399c
buffer: add buffer.isUtf8 for utf8 validation
anonrig Dec 25, 2022
4c08505
process,worker: ensure code after exit() effectless
ywave620 Dec 25, 2022
71cc3b3
doc: replace single executable champion in strategic initiatives doc
RaisinTen Dec 25, 2022
e4323f0
deps: fix updater github workflow job
anonrig Dec 25, 2022
0f5a145
test: print failed JS/parallel tests
GeoffreyBooth Dec 27, 2022
7c518cb
tools: update lint-md-dependencies to rollup@3.8.1
nodejs-github-bot Dec 27, 2022
0a70316
meta: update AUTHORS
nodejs-github-bot Dec 27, 2022
7ae24ab
test_runner: use os.availableParallelism()
cjihrig Dec 27, 2022
e73be1b
deps: update to uvwasi 0.0.14
cjihrig Dec 27, 2022
f968fdb
tools: add url to `AUTHORS` update automation
aduh95 Dec 27, 2022
952e03a
doc: make EventEmitterAsyncResource's `options` as optional
deokjinkim Dec 27, 2022
0552b13
deps: update simdutf to 2.0.9
nodejs-github-bot Dec 27, 2022
db535b6
src: define per-isolate internal bindings registration callback
legendecas Oct 25, 2022
6c5b7e6
src: add worker per-isolate binding initialization
legendecas Nov 29, 2022
bc43922
http: replace `var` with `const` on code of comment
deokjinkim Dec 28, 2022
9251dce
doc: use `os.availableParallelism()` in async_context and cluster
deokjinkim Dec 28, 2022
3d09754
debugger: refactor console in lib/internal/debugger/inspect.js
debadree25 Dec 28, 2022
261d6d0
src: fix crash on OnStreamRead on Windows
santigimeno Dec 28, 2022
0858956
stream: fix typo in JSDoc
deokjinkim Dec 28, 2022
8be1b66
doc: fix wrong output of example in `url.protocol`
deokjinkim Dec 28, 2022
af25c95
src: fix typo in `node_file.cc`
kwarabei Dec 28, 2022
2d49e0e
esm: rewrite loader hooks test
GeoffreyBooth Dec 31, 2022
ab22a8f
stream: refactor to use `validateFunction`
deokjinkim Jan 1, 2023
22a66cf
fs: refactor to use `validateInteger`
deokjinkim Jan 1, 2023
49253e1
doc: use console.error for error case in timers and tls
deokjinkim Jan 1, 2023
2807efa
test: use `process.hrtime.bigint` instead of `process.hrtime`
deokjinkim Jan 1, 2023
9e16406
doc: sort http.createServer() options alphabetically
lpinca Dec 1, 2022
71bf513
deps: patch V8 to 10.8.168.25
targos Dec 28, 2022
28f9089
lib: use `kEmptyObject` as default value for options
deokjinkim Dec 31, 2022
54b748a
async_hooks: refactor to use `validateObject`
deokjinkim Jan 1, 2023
389cc3e
vm: refactor to use `validateStringArray`
deokjinkim Jan 1, 2023
fdda2ff
deps: V8: cherry-pick 30861a39323d
AaronFriel Dec 13, 2022
47cc0e4
events: fix violation of symbol naming convention
deokjinkim Jan 1, 2023
7f1daed
lib: update JSDoc of `getOwnPropertyValueOrDefault`
deokjinkim Jan 1, 2023
54776ff
tools: add release host var to promotion script
ruyadorno Jan 1, 2023
e113d16
doc: update isUtf8 description
anonrig Jan 1, 2023
5a8d125
tools: update doc to unist-util-select@4.0.2
nodejs-github-bot Jan 1, 2023
0f0d22a
tools: update lint-md-dependencies to rollup@3.9.0
nodejs-github-bot Jan 1, 2023
25d0a94
meta: update AUTHORS
nodejs-github-bot Jan 1, 2023
777c551
crypto: ensure exported webcrypto EC keys use uncompressed point format
bnoordhuis Dec 30, 2022
4d62b09
net: handle socket.write(cb) edge case
santigimeno Jan 1, 2023
e58ed6d
2023-01-06, Version 19.4.0 (Current)
RafaelGSS Jan 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
deps: V8: cherry-pick bc831f8ba33b
Original commit message:

    [fastcall] Implement support for onebyte string arguments

    This CL adds one byte string specialization support for fast API call arguments.
    It introduces a kOneByteString variant to CTypeInfo.

    We see a ~6x improvement in Deno's TextEncoder#encode microbenchmark.
    Rendered results: https://divy-v8-patches.deno.dev/

    Bug: chromium:1052746
    Change-Id: I47c3a9e101cd18ddc6ad58f627db3a34231b60f7
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4036884
    Reviewed-by: Toon Verwaest <verwaest@chromium.org>
    Reviewed-by: Maya Lekova <mslekova@chromium.org>
    Commit-Queue: Maya Lekova <mslekova@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#84552}

Refs: v8/v8@bc831f8
PR-URL: #45788
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com>
  • Loading branch information
anonrig authored and targos committed Jan 1, 2023
commit faee973fa7aac3284028f79388704a20b49f3501
2 changes: 1 addition & 1 deletion common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
'v8_embedder_string': '-node.9',
'v8_embedder_string': '-node.10',

##### V8 defaults for Node.js #####

Expand Down
21 changes: 20 additions & 1 deletion deps/v8/include/v8-fast-api-calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ class CTypeInfo {
kFloat32,
kFloat64,
kV8Value,
kSeqOneByteString,
kApiObject, // This will be deprecated once all users have
// migrated from v8::ApiObject to v8::Local<v8::Value>.
kAny, // This is added to enable untyped representation of fast
Expand Down Expand Up @@ -379,6 +380,11 @@ struct FastApiArrayBuffer {
size_t byte_length;
};

struct FastOneByteString {
const char* data;
uint32_t length;
};

class V8_EXPORT CFunctionInfo {
public:
// Construct a struct to hold a CFunction's type information.
Expand Down Expand Up @@ -438,6 +444,7 @@ struct AnyCType {
const FastApiTypedArray<uint64_t>* uint64_ta_value;
const FastApiTypedArray<float>* float_ta_value;
const FastApiTypedArray<double>* double_ta_value;
const FastOneByteString* string_value;
FastApiCallbackOptions* options_value;
};
};
Expand Down Expand Up @@ -614,7 +621,7 @@ class CFunctionInfoImpl : public CFunctionInfo {
kReturnType == CTypeInfo::Type::kFloat32 ||
kReturnType == CTypeInfo::Type::kFloat64 ||
kReturnType == CTypeInfo::Type::kAny,
"64-bit int and api object values are not currently "
"64-bit int, string and api object values are not currently "
"supported return types.");
}

Expand Down Expand Up @@ -735,6 +742,18 @@ struct TypeInfoHelper<FastApiCallbackOptions&> {
}
};

template <>
struct TypeInfoHelper<const FastOneByteString&> {
static constexpr CTypeInfo::Flags Flags() { return CTypeInfo::Flags::kNone; }

static constexpr CTypeInfo::Type Type() {
return CTypeInfo::Type::kSeqOneByteString;
}
static constexpr CTypeInfo::SequenceType SequenceType() {
return CTypeInfo::SequenceType::kScalar;
}
};

#define STATIC_ASSERT_IMPLIES(COND, ASSERTION, MSG) \
static_assert(((COND) == 0) || (ASSERTION), MSG)

Expand Down
1 change: 1 addition & 0 deletions deps/v8/src/codegen/machine-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ class MachineType {
case CTypeInfo::Type::kFloat64:
return MachineType::Float64();
case CTypeInfo::Type::kV8Value:
case CTypeInfo::Type::kSeqOneByteString:
case CTypeInfo::Type::kApiObject:
return MachineType::AnyTagged();
}
Expand Down
45 changes: 45 additions & 0 deletions deps/v8/src/compiler/effect-control-linearizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5246,6 +5246,50 @@ Node* EffectControlLinearizer::AdaptFastCallArgument(
case CTypeInfo::Type::kFloat32: {
return __ TruncateFloat64ToFloat32(node);
}
case CTypeInfo::Type::kSeqOneByteString: {
// Check that the value is a HeapObject.
Node* value_is_smi = ObjectIsSmi(node);
__ GotoIf(value_is_smi, if_error);

Node* map = __ LoadField(AccessBuilder::ForMap(), node);
Node* instance_type =
__ LoadField(AccessBuilder::ForMapInstanceType(), map);

Node* encoding = __ Word32And(
instance_type,
__ Int32Constant(kStringRepresentationAndEncodingMask));

Node* is_onebytestring = __ Word32Equal(
encoding, __ Int32Constant(kSeqOneByteStringTag));
__ GotoIfNot(is_onebytestring, if_error);

Node* length_in_bytes =
__ LoadField(AccessBuilder::ForStringLength(), node);
Node* data_ptr = __ IntPtrAdd(
node, __ IntPtrConstant(SeqOneByteString::kHeaderSize -
kHeapObjectTag));

constexpr int kAlign = alignof(FastOneByteString);
constexpr int kSize = sizeof(FastOneByteString);
static_assert(kSize == sizeof(uintptr_t) + sizeof(size_t),
"The size of "
"FastOneByteString isn't equal to the sum of its "
"expected members.");
Node* stack_slot = __ StackSlot(kSize, kAlign);

__ Store(StoreRepresentation(MachineType::PointerRepresentation(),
kNoWriteBarrier),
stack_slot, 0, data_ptr);
__ Store(StoreRepresentation(MachineRepresentation::kWord32,
kNoWriteBarrier),
stack_slot, sizeof(size_t), length_in_bytes);

static_assert(sizeof(uintptr_t) == sizeof(size_t),
"The string length can't "
"fit the PointerRepresentation used to store it.");

return stack_slot;
}
default: {
return node;
}
Expand Down Expand Up @@ -5451,6 +5495,7 @@ Node* EffectControlLinearizer::LowerFastApiCall(Node* node) {
case CTypeInfo::Type::kFloat64:
return ChangeFloat64ToTagged(
c_call_result, CheckForMinusZeroMode::kCheckForMinusZero);
case CTypeInfo::Type::kSeqOneByteString:
case CTypeInfo::Type::kV8Value:
case CTypeInfo::Type::kApiObject:
case CTypeInfo::Type::kUint8:
Expand Down
1 change: 1 addition & 0 deletions deps/v8/src/compiler/fast-api-calls.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ ElementsKind GetTypedArrayElementsKind(CTypeInfo::Type type) {
case CTypeInfo::Type::kFloat64:
return FLOAT64_ELEMENTS;
case CTypeInfo::Type::kVoid:
case CTypeInfo::Type::kSeqOneByteString:
case CTypeInfo::Type::kBool:
case CTypeInfo::Type::kV8Value:
case CTypeInfo::Type::kApiObject:
Expand Down
1 change: 1 addition & 0 deletions deps/v8/src/compiler/simplified-lowering.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1924,6 +1924,7 @@ class RepresentationSelector {
case CTypeInfo::Type::kFloat64:
return UseInfo::CheckedNumberAsFloat64(kDistinguishZeros, feedback);
case CTypeInfo::Type::kV8Value:
case CTypeInfo::Type::kSeqOneByteString:
case CTypeInfo::Type::kApiObject:
return UseInfo::AnyTagged();
}
Expand Down
47 changes: 47 additions & 0 deletions deps/v8/src/d8/d8-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,43 @@ class FastCApiObject {
public:
static FastCApiObject& instance();

#ifdef V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
static AnyCType CopyStringFastCallbackPatch(AnyCType receiver,
AnyCType should_fallback,
AnyCType source, AnyCType out,
AnyCType options) {
AnyCType ret;
CopyStringFastCallback(receiver.object_value, should_fallback.bool_value,
*source.string_value, *out.uint8_ta_value,
*options.options_value);
return ret;
}

#endif // V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
static void CopyStringFastCallback(Local<Object> receiver,
bool should_fallback,
const FastOneByteString& source,
const FastApiTypedArray<uint8_t>& out,
FastApiCallbackOptions& options) {
FastCApiObject* self = UnwrapObject(receiver);
self->fast_call_count_++;

if (should_fallback) {
options.fallback = true;
} else {
options.fallback = false;
}

uint8_t* memory = nullptr;
CHECK(out.getStorageIfAligned(&memory));
memcpy(memory, source.data, source.length);
}

static void CopyStringSlowCallback(const FunctionCallbackInfo<Value>& args) {
FastCApiObject* self = UnwrapObject(args.This());
CHECK_SELF_OR_THROW();
self->slow_call_count_++;
}
#ifdef V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
static AnyCType AddAllFastCallbackPatch(AnyCType receiver,
AnyCType should_fallback,
Expand Down Expand Up @@ -1072,6 +1109,16 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
PerIsolateData::Get(isolate)->SetTestApiObjectCtor(api_obj_ctor);
Local<Signature> signature = Signature::New(isolate, api_obj_ctor);
{
CFunction copy_str_func = CFunction::Make(
FastCApiObject::CopyStringFastCallback V8_IF_USE_SIMULATOR(
FastCApiObject::CopyStringFastCallbackPatch));
api_obj_ctor->PrototypeTemplate()->Set(
isolate, "copy_string",
FunctionTemplate::New(isolate, FastCApiObject::CopyStringSlowCallback,
Local<Value>(), signature, 1,
ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, &copy_str_func));

CFunction add_all_c_func =
CFunction::Make(FastCApiObject::AddAllFastCallback V8_IF_USE_SIMULATOR(
FastCApiObject::AddAllFastCallbackPatch));
Expand Down
84 changes: 84 additions & 0 deletions deps/v8/test/mjsunit/compiler/fast-api-calls-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file excercises one byte string support for fast API calls.

// Flags: --turbo-fast-api-calls --expose-fast-api --allow-natives-syntax --turbofan
// --always-turbofan is disabled because we rely on particular feedback for
// optimizing to the fastest path.
// Flags: --no-always-turbofan
// The test relies on optimizing/deoptimizing at predictable moments, so
// it's not suitable for deoptimization fuzzing.
// Flags: --deopt-every-n-times=0

assertThrows(() => d8.test.FastCAPI());
const fast_c_api = new d8.test.FastCAPI();

function assertSlowCall(input) {
assertEquals(new Uint8Array(input.length), copy_string(false, input));
}

function assertFastCall(input) {
const bytes = Uint8Array.from(input, c => c.charCodeAt(0));
assertEquals(bytes, copy_string(false, input));
}

function copy_string(should_fallback = false, input) {
const buffer = new Uint8Array(input.length);
fast_c_api.copy_string(should_fallback, input, buffer);
return buffer;
}

%PrepareFunctionForOptimization(copy_string);
assertSlowCall('Hello');
%OptimizeFunctionOnNextCall(copy_string);

fast_c_api.reset_counts();
assertFastCall('Hello');
assertFastCall('');
assertFastCall(['Hello', 'World'].join(''));
assertOptimized(copy_string);
assertEquals(3, fast_c_api.fast_call_count());
assertEquals(0, fast_c_api.slow_call_count());

// Fall back for twobyte strings.
fast_c_api.reset_counts();
assertSlowCall('Hello\u{10000}');
assertSlowCall('नमस्ते');
assertSlowCall(['नमस्ते', 'World'].join(''));
assertOptimized(copy_string);
assertEquals(0, fast_c_api.fast_call_count());
assertEquals(3, fast_c_api.slow_call_count());

// Fall back for cons strings.
function getTwoByteString() {
return '\u1234t';
}
function getCons() {
return 'hello' + getTwoByteString()
}

fast_c_api.reset_counts();
assertSlowCall(getCons());
assertOptimized(copy_string);
assertEquals(0, fast_c_api.fast_call_count());
assertEquals(1, fast_c_api.slow_call_count());

// Fall back for sliced strings.
fast_c_api.reset_counts();
function getSliced() {
return getCons().slice(1);
}
assertSlowCall(getSliced());
assertOptimized(copy_string);
assertEquals(0, fast_c_api.fast_call_count());
assertEquals(1, fast_c_api.slow_call_count());

// Fall back for SMI and non-string inputs.
fast_c_api.reset_counts();
assertSlowCall(1);
assertSlowCall({});
assertSlowCall(new Uint8Array(1));
assertEquals(0, fast_c_api.fast_call_count());
assertEquals(3, fast_c_api.slow_call_count());