v8/src/builtins/builtins-definitions.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1241 lines
94 KiB
C
Raw Normal View History

// Copyright 2017 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.
#ifndef V8_BUILTINS_BUILTINS_DEFINITIONS_H_
#define V8_BUILTINS_BUILTINS_DEFINITIONS_H_
namespace v8 {
namespace internal {
// CPP: Builtin in C++. Entered via BUILTIN_EXIT frame.
// Args: name
// API: Builtin in C++ for API callbacks. Entered via EXIT frame.
// Args: name
// TFJ: Builtin in Turbofan, with JS linkage (callable as Javascript function).
// Args: name, arguments count, explicit argument names...
// TFS: Builtin in Turbofan, with CodeStub linkage.
// Args: name, explicit argument names...
// TFC: Builtin in Turbofan, with CodeStub linkage and custom descriptor.
// Args: name, interface descriptor, return_size
// TFH: Handlers in Turbofan, with CodeStub linkage.
// Args: name, interface descriptor
// ASM: Builtin in platform-dependent assembly.
// Args: name
#define BUILTIN_LIST_BASE(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
/* GC write barrirer */ \
TFC(RecordWrite, RecordWrite, 1) \
\
/* Adaptors for CPP/API builtin */ \
ASM(AdaptorWithExitFrame) \
ASM(AdaptorWithBuiltinExitFrame) \
\
/* Calls */ \
ASM(ArgumentsAdaptorTrampoline) \
/* ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) */ \
ASM(CallFunction_ReceiverIsNullOrUndefined) \
ASM(CallFunction_ReceiverIsNotNullOrUndefined) \
ASM(CallFunction_ReceiverIsAny) \
/* ES6 section 9.4.1.1 [[Call]] ( thisArgument, argumentsList) */ \
ASM(CallBoundFunction) \
/* ES6 section 7.3.12 Call(F, V, [argumentsList]) */ \
ASM(Call_ReceiverIsNullOrUndefined) \
ASM(Call_ReceiverIsNotNullOrUndefined) \
ASM(Call_ReceiverIsAny) \
\
/* ES6 section 9.5.12[[Call]] ( thisArgument, argumentsList ) */ \
TFC(CallProxy, CallTrampoline, 1) \
ASM(CallVarargs) \
TFC(CallWithSpread, CallWithSpread, 1) \
TFC(CallWithArrayLike, CallWithArrayLike, 1) \
ASM(CallForwardVarargs) \
ASM(CallFunctionForwardVarargs) \
\
/* Construct */ \
/* ES6 section 9.2.2 [[Construct]] ( argumentsList, newTarget) */ \
ASM(ConstructFunction) \
/* ES6 section 9.4.1.2 [[Construct]] (argumentsList, newTarget) */ \
ASM(ConstructBoundFunction) \
ASM(ConstructedNonConstructable) \
/* ES6 section 7.3.13 Construct (F, [argumentsList], [newTarget]) */ \
ASM(Construct) \
ASM(ConstructVarargs) \
TFC(ConstructWithSpread, ConstructWithSpread, 1) \
TFC(ConstructWithArrayLike, ConstructWithArrayLike, 1) \
ASM(ConstructForwardVarargs) \
ASM(ConstructFunctionForwardVarargs) \
ASM(JSConstructStubApi) \
ASM(JSConstructStubGenericRestrictedReturn) \
ASM(JSConstructStubGenericUnrestrictedReturn) \
ASM(JSBuiltinsConstructStub) \
TFC(FastNewObject, FastNewObject, 1) \
TFC(FastNewClosure, FastNewClosure, 1) \
TFC(FastNewFunctionContextEval, FastNewFunctionContext, 1) \
TFC(FastNewFunctionContextFunction, FastNewFunctionContext, 1) \
2017-09-25 12:30:25 +00:00
TFS(CreateRegExpLiteral, kFeedbackVector, kSlot, kPattern, kFlags) \
TFS(CreateEmptyArrayLiteral, kFeedbackVector, kSlot) \
TFS(CreateShallowArrayLiteral, kFeedbackVector, kSlot, kConstantElements) \
TFS(CreateShallowObjectLiteral, kFeedbackVector, kSlot, \
kBoilerplateDescription, kFlags) \
/* ES6 section 9.5.14 [[Construct]] ( argumentsList, newTarget) */ \
TFC(ConstructProxy, ConstructTrampoline, 1) \
\
/* Apply and entries */ \
ASM(JSEntryTrampoline) \
ASM(JSConstructEntryTrampoline) \
ASM(ResumeGeneratorTrampoline) \
\
/* Stack and interrupt check */ \
ASM(InterruptCheck) \
ASM(StackCheck) \
\
/* String helpers */ \
TFC(StringCharAt, StringCharAt, 1) \
TFC(StringCharCodeAt, StringCharCodeAt, 1) \
TFC(StringEqual, Compare, 1) \
TFC(StringGreaterThan, Compare, 1) \
TFC(StringGreaterThanOrEqual, Compare, 1) \
TFS(StringIndexOf, kReceiver, kSearchString, kPosition) \
TFC(StringLessThan, Compare, 1) \
TFC(StringLessThanOrEqual, Compare, 1) \
TFS(StringRepeat, kString, kCount) \
TFS(SubString, kString, kFrom, kTo) \
\
[turbofan] Inline Map and Set iterators into optimized code. This CL inlines the following builtins into TurboFan - %MapIteratorPrototype%.next - %SetIteratorPrototype%.next following the design that we are using for Array iteration already (different instance types for the different kinds of iterators). Details can be found in the relevant design document at: https://docs.google.com/document/d/13z1fvRVpe_oEroplXEEX0a3WK94fhXorHjcOMsDmR-8 The key to great performance here is to ensure that the inlined code allows escape analysis and scalar replacement of aggregates to remove the allocations for the iterator itself as well as the iterator results and potential key/value arrays in the simple case of a for-of loop (and by extension also in other constructs that reduce to for-of loops internally), i.e.: const s = new Set; // ... do something with s for (const x of s) { // ... } Here the for-of loop shouldn't perform any allocations of helper objects. Drive-by-fix: Replace the ExistsJSMapWithness in JSBuiltinReducer with a more general HasInstanceTypeWitness, similar to what's in JSCallReducer. Also migrate the {Map,Set}.prototype.size getter inlining to the JSBuiltinReducer, so that everything is in a single place. R=jgruber@chromium.org Bug: v8:6344, v8:6571, chromium:740122 Change-Id: I09cb506fe26ed3e10d7dcb2f95ec4415e639582d Reviewed-on: https://chromium-review.googlesource.com/570159 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#46655}
2017-07-14 05:35:21 +00:00
/* OrderedHashTable helpers */ \
TFS(OrderedHashTableHealIndex, kTable, kIndex) \
\
/* Interpreter */ \
ASM(InterpreterEntryTrampoline) \
ASM(InterpreterPushArgsThenCall) \
ASM(InterpreterPushUndefinedAndArgsThenCall) \
ASM(InterpreterPushArgsThenCallFunction) \
ASM(InterpreterPushUndefinedAndArgsThenCallFunction) \
ASM(InterpreterPushArgsThenCallWithFinalSpread) \
ASM(InterpreterPushArgsThenConstruct) \
ASM(InterpreterPushArgsThenConstructFunction) \
ASM(InterpreterPushArgsThenConstructWithFinalSpread) \
ASM(InterpreterEnterBytecodeAdvance) \
ASM(InterpreterEnterBytecodeDispatch) \
ASM(InterpreterOnStackReplacement) \
\
/* Code life-cycle */ \
ASM(CompileLazy) \
ASM(CompileLazyDeoptimizedCode) \
ASM(CheckOptimizationMarker) \
ASM(DeserializeLazy) \
ASM(InstantiateAsmJs) \
ASM(NotifyDeoptimized) \
\
/* Trampolines called when returning from a deoptimization that expects */ \
/* to continue in a JavaScript builtin to finish the functionality of a */ \
/* an TF-inlined version of builtin that has side-effects. */ \
/* */ \
/* The trampolines work as follows: */ \
/* 1. Trampoline restores input register values that */ \
/* the builtin expects from a BuiltinContinuationFrame. */ \
/* 2. Trampoline tears down BuiltinContinuationFrame. */ \
/* 3. Trampoline jumps to the builtin's address. */ \
/* 4. Builtin executes as if invoked by the frame above it. */ \
/* 5. When the builtin returns, execution resumes normally in the */ \
/* calling frame, processing any return result from the JavaScript */ \
/* builtin as if it had called the builtin directly. */ \
/* */ \
/* There are two variants of the stub that differ in their handling of a */ \
/* value returned by the next frame deeper on the stack. For LAZY deopts, */ \
/* the return value (e.g. rax on x64) is explicitly passed as an extra */ \
/* stack parameter to the JavaScript builtin by the "WithResult" */ \
/* trampoline variant. The plain variant is used in EAGER deopt contexts */ \
/* and has no such special handling. */ \
ASM(ContinueToCodeStubBuiltin) \
ASM(ContinueToCodeStubBuiltinWithResult) \
ASM(ContinueToJavaScriptBuiltin) \
ASM(ContinueToJavaScriptBuiltinWithResult) \
\
ASM(OnStackReplacement) \
\
/* API callback handling */ \
API(HandleApiCall) \
API(HandleApiCallAsFunction) \
API(HandleApiCallAsConstructor) \
\
/* Adapters for Turbofan into runtime */ \
ASM(AllocateInNewSpace) \
ASM(AllocateInOldSpace) \
\
/* TurboFan support builtins */ \
TFS(CopyFastSmiOrObjectElements, kObject) \
TFC(GrowFastDoubleElements, GrowArrayElements, 1) \
TFC(GrowFastSmiOrObjectElements, GrowArrayElements, 1) \
TFC(NewArgumentsElements, NewArgumentsElements, 1) \
\
/* Debugger */ \
ASM(FrameDropperTrampoline) \
ASM(HandleDebuggerStatement) \
\
/* Type conversions */ \
TFC(ToObject, TypeConversion, 1) \
TFC(ToBoolean, TypeConversion, 1) \
TFC(OrdinaryToPrimitive_Number, TypeConversion, 1) \
TFC(OrdinaryToPrimitive_String, TypeConversion, 1) \
TFC(NonPrimitiveToPrimitive_Default, TypeConversion, 1) \
TFC(NonPrimitiveToPrimitive_Number, TypeConversion, 1) \
TFC(NonPrimitiveToPrimitive_String, TypeConversion, 1) \
TFC(StringToNumber, TypeConversion, 1) \
TFC(ToName, TypeConversion, 1) \
TFC(NonNumberToNumber, TypeConversion, 1) \
TFC(NonNumberToNumeric, TypeConversion, 1) \
TFC(ToNumber, TypeConversion, 1) \
TFC(ToNumeric, TypeConversion, 1) \
TFC(NumberToString, TypeConversion, 1) \
TFC(ToString, TypeConversion, 1) \
TFC(ToInteger, TypeConversion, 1) \
TFC(ToLength, TypeConversion, 1) \
TFC(ClassOf, Typeof, 1) \
TFC(Typeof, Typeof, 1) \
TFC(GetSuperConstructor, Typeof, 1) \
\
/* Type conversions continuations */ \
TFC(ToBooleanLazyDeoptContinuation, TypeConversionStackParameter, 1) \
\
/* Handlers */ \
TFH(LoadICProtoArray, LoadICProtoArray) \
TFH(LoadICProtoArrayThrowIfNonexistent, LoadICProtoArray) \
TFH(KeyedLoadIC_Megamorphic, LoadWithVector) \
TFH(KeyedLoadIC_Miss, LoadWithVector) \
[ic] Ensure that we make progress on KeyedLoadIC polymorphic name. In the special case of KeyedLoadIC, where the key that is passed in is a Name that is always the same we only checked for identity in both the stub and the TurboFan case, which works fine for symbols and internalized strings, but doesn't really work with non-internalized strings, where the identity check will fail, the runtime will internalize the string, and the IC will then see the original internalized string again and not progress in the feedback lattice. This leads to tricky deoptimization loops in TurboFan and constantly missing ICs. This adds fixes the stub to always try to internalize strings first when the identity check fails and then doing the check again. If the name is not found in the string table we miss, since in that case the string cannot match the previously recorded feedback name (which is always a unique name). In TurboFan we represent this checks with new CheckEqualsSymbol and CheckEqualsInternalizedString operators, which validate the previously recorded feedback, and the CheckEqualsInternalizedString operator does the attempt to internalize the input. Bug: v8:6936, v8:6948, v8:6969 Change-Id: I3f3b4a587c67f00f7c4b60d239eb98a9626fe04a Reviewed-on: https://chromium-review.googlesource.com/730224 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#48784}
2017-10-20 11:36:26 +00:00
TFH(KeyedLoadIC_PolymorphicName, LoadWithVector) \
TFH(KeyedLoadIC_Slow, LoadWithVector) \
TFH(KeyedStoreIC_Megamorphic, StoreWithVector) \
TFH(KeyedStoreIC_Miss, StoreWithVector) \
TFH(KeyedStoreIC_Slow, StoreWithVector) \
TFH(LoadGlobalIC_Miss, LoadGlobalWithVector) \
TFH(LoadGlobalIC_Slow, LoadGlobalWithVector) \
TFH(LoadField, LoadField) \
TFH(LoadIC_FunctionPrototype, LoadWithVector) \
TFH(LoadIC_Miss, LoadWithVector) \
TFH(LoadIC_Slow, LoadWithVector) \
TFH(LoadIC_StringLength, LoadWithVector) \
TFH(LoadIC_StringWrapperLength, LoadWithVector) \
TFH(LoadIC_Uninitialized, LoadWithVector) \
TFH(StoreGlobalIC_Slow, StoreWithVector) \
TFH(StoreIC_Miss, StoreWithVector) \
TFH(StoreIC_Uninitialized, StoreWithVector) \
\
/* Promise helpers */ \
TFS(ResolveNativePromise, kPromise, kValue) \
TFS(RejectNativePromise, kPromise, kValue, kDebugEvent) \
TFS(PerformNativePromiseThen, kPromise, kResolveReaction, kRejectReaction, \
kResultPromise) \
\
/* Object property helpers */ \
TFS(HasProperty, kKey, kObject) \
TFS(DeleteProperty, kObject, kKey, kLanguageMode) \
\
/* Abort */ \
ASM(Abort) \
ASM(AbortJS) \
\
/* Built-in functions for Javascript */ \
/* Special internal builtins */ \
CPP(EmptyFunction) \
CPP(Illegal) \
CPP(StrictPoisonPillThrower) \
CPP(UnsupportedThrower) \
TFJ(ReturnReceiver, 0) \
\
/* Array */ \
ASM(ArrayConstructor) \
ASM(InternalArrayConstructor) \
CPP(ArrayConcat) \
/* ES6 #sec-array.isarray */ \
TFJ(ArrayIsArray, 1, kArg) \
/* ES7 #sec-array.prototype.includes */ \
TFJ(ArrayIncludes, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.indexof */ \
TFJ(ArrayIndexOf, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.pop */ \
CPP(ArrayPop) \
TFJ(FastArrayPop, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.push */ \
CPP(ArrayPush) \
TFJ(FastArrayPush, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.shift */ \
CPP(ArrayShift) \
TFJ(FastArrayShift, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.slice */ \
CPP(ArraySlice) \
Reimplement Array.prototype.slice in CSA and C++ Previously, V8's slice was implemented in a combination of C++ and a Javascript fallback. The disadvantage of this approach was that the fast-path required a call through the CEntryStub, which introduced considerable overhead for small arrays with fast elements kinds. Now the implementation primarily uses the CSA to generate both the full spec-complaint implementation as well as fast paths for argument objects and arrays with fast elements kinds. The CSA implementation uses a C++ implementation fallback in select situations where the the complexity of a CSA implementation would be too great and the CEntryStub overhead is not decisive (e.g. slices of dictionary elements arrays). Performance results on semi-random arrays with small number of elements (old vs. new): smi copy: 48.7 ms vs. 12 ms smi slice: 43.5 ms 14.8 ms object copy: 35.5 ms 7.7 ms object slice: 38.7 ms 8.8 ms dictionary slice: 2398.3 ms vs. 5.4 ms fast sloppy arguments slice: 9.6 ms vs. 7.2 ms slow sloppy arguments slice: 28.9 ms vs. 8.5 ms As a bonus, the new implementation is fully spec-compliant and fixes at least one existing bug. The design document for Array.prototype builtin rework can be found at https://goo.gl/wFHe2n Bug: v8:1956,v8:6601,v8:6710,v8:6978 Change-Id: Ia0155bedcf39b4577605ff754f416c2af938efb7 Reviewed-on: https://chromium-review.googlesource.com/574710 Commit-Queue: Daniel Clifford <danno@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#48853}
2017-10-23 18:41:42 +00:00
TFJ(FastArraySlice, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.splice */ \
CPP(ArraySplice) \
/* ES6 #sec-array.prototype.unshift */ \
CPP(ArrayUnshift) \
Reimplement Array.prototype.slice in CSA and C++ Previously, V8's slice was implemented in a combination of C++ and a Javascript fallback. The disadvantage of this approach was that the fast-path required a call through the CEntryStub, which introduced considerable overhead for small arrays with fast elements kinds. Now the implementation primarily uses the CSA to generate both the full spec-complaint implementation as well as fast paths for argument objects and arrays with fast elements kinds. The CSA implementation uses a C++ implementation fallback in select situations where the the complexity of a CSA implementation would be too great and the CEntryStub overhead is not decisive (e.g. slices of dictionary elements arrays). Performance results on semi-random arrays with small number of elements (old vs. new): smi copy: 48.7 ms vs. 12 ms smi slice: 43.5 ms 14.8 ms object copy: 35.5 ms 7.7 ms object slice: 38.7 ms 8.8 ms dictionary slice: 2398.3 ms vs. 5.4 ms fast sloppy arguments slice: 9.6 ms vs. 7.2 ms slow sloppy arguments slice: 28.9 ms vs. 8.5 ms As a bonus, the new implementation is fully spec-compliant and fixes at least one existing bug. The design document for Array.prototype builtin rework can be found at https://goo.gl/wFHe2n Bug: v8:1956,v8:6601,v8:6710,v8:6978 Change-Id: Ia0155bedcf39b4577605ff754f416c2af938efb7 Reviewed-on: https://chromium-review.googlesource.com/574710 Commit-Queue: Daniel Clifford <danno@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#48853}
2017-10-23 18:41:42 +00:00
/* Support for Array.from and other array-copying idioms */ \
TFS(CloneFastJSArray, kSource) \
TFS(ExtractFastJSArray, kSource, kBegin, kCount) \
/* ES6 #sec-array.prototype.foreach */ \
TFS(ArrayForEachLoopContinuation, kReceiver, kCallbackFn, kThisArg, kArray, \
kObject, kInitialK, kLength, kTo) \
TFJ(ArrayForEachLoopEagerDeoptContinuation, 4, kCallbackFn, kThisArg, \
kInitialK, kLength) \
TFJ(ArrayForEachLoopLazyDeoptContinuation, 5, kCallbackFn, kThisArg, \
kInitialK, kLength, kResult) \
TFJ(ArrayForEach, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.every */ \
TFS(ArrayEveryLoopContinuation, kReceiver, kCallbackFn, kThisArg, kArray, \
kObject, kInitialK, kLength, kTo) \
TFJ(ArrayEvery, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.some */ \
TFS(ArraySomeLoopContinuation, kReceiver, kCallbackFn, kThisArg, kArray, \
kObject, kInitialK, kLength, kTo) \
TFJ(ArraySome, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.filter */ \
TFS(ArrayFilterLoopContinuation, kReceiver, kCallbackFn, kThisArg, kArray, \
kObject, kInitialK, kLength, kTo) \
TFJ(ArrayFilter, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFJ(ArrayFilterLoopEagerDeoptContinuation, 6, kCallbackFn, kThisArg, kArray, \
kInitialK, kLength, kTo) \
TFJ(ArrayFilterLoopLazyDeoptContinuation, 8, kCallbackFn, kThisArg, kArray, \
kInitialK, kLength, kValueK, kTo, kResult) \
/* ES6 #sec-array.prototype.foreach */ \
TFS(ArrayMapLoopContinuation, kReceiver, kCallbackFn, kThisArg, kArray, \
kObject, kInitialK, kLength, kTo) \
TFJ(ArrayMapLoopEagerDeoptContinuation, 5, kCallbackFn, kThisArg, kArray, \
kInitialK, kLength) \
TFJ(ArrayMapLoopLazyDeoptContinuation, 6, kCallbackFn, kThisArg, kArray, \
kInitialK, kLength, kResult) \
TFJ(ArrayMap, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.reduce */ \
TFS(ArrayReduceLoopContinuation, kReceiver, kCallbackFn, kThisArg, \
kAccumulator, kObject, kInitialK, kLength, kTo) \
TFJ(ArrayReduce, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.reduceRight */ \
TFS(ArrayReduceRightLoopContinuation, kReceiver, kCallbackFn, kThisArg, \
kAccumulator, kObject, kInitialK, kLength, kTo) \
TFJ(ArrayReduceRight, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-array.prototype.entries */ \
TFJ(ArrayPrototypeEntries, 0) \
/* ES6 #sec-array.prototype.keys */ \
TFJ(ArrayPrototypeKeys, 0) \
/* ES6 #sec-array.prototype.values */ \
TFJ(ArrayPrototypeValues, 0) \
/* ES6 #sec-%arrayiteratorprototype%.next */ \
TFJ(ArrayIteratorPrototypeNext, 0) \
\
/* ArrayBuffer */ \
CPP(ArrayBufferConstructor) \
CPP(ArrayBufferConstructor_ConstructStub) \
CPP(ArrayBufferConstructor_DoNotInitialize) \
CPP(ArrayBufferPrototypeGetByteLength) \
CPP(ArrayBufferIsView) \
CPP(ArrayBufferPrototypeSlice) \
\
/* AsyncFunction */ \
TFJ(AsyncFunctionAwaitCaught, 3, kGenerator, kAwaited, kOuterPromise) \
TFJ(AsyncFunctionAwaitUncaught, 3, kGenerator, kAwaited, kOuterPromise) \
TFJ(AsyncFunctionAwaitRejectClosure, 1, kSentError) \
TFJ(AsyncFunctionAwaitResolveClosure, 1, kSentValue) \
TFJ(AsyncFunctionPromiseCreate, 0) \
TFJ(AsyncFunctionPromiseRelease, 1, kPromise) \
\
/* BigInt */ \
CPP(BigIntConstructor) \
CPP(BigIntConstructor_ConstructStub) \
CPP(BigIntParseInt) \
CPP(BigIntAsUintN) \
CPP(BigIntAsIntN) \
CPP(BigIntPrototypeToLocaleString) \
CPP(BigIntPrototypeToString) \
CPP(BigIntPrototypeValueOf) \
\
/* Boolean */ \
CPP(BooleanConstructor) \
CPP(BooleanConstructor_ConstructStub) \
/* ES6 #sec-boolean.prototype.tostring */ \
TFJ(BooleanPrototypeToString, 0) \
/* ES6 #sec-boolean.prototype.valueof */ \
TFJ(BooleanPrototypeValueOf, 0) \
\
/* CallSite */ \
CPP(CallSitePrototypeGetColumnNumber) \
CPP(CallSitePrototypeGetEvalOrigin) \
CPP(CallSitePrototypeGetFileName) \
CPP(CallSitePrototypeGetFunction) \
CPP(CallSitePrototypeGetFunctionName) \
CPP(CallSitePrototypeGetLineNumber) \
CPP(CallSitePrototypeGetMethodName) \
CPP(CallSitePrototypeGetPosition) \
CPP(CallSitePrototypeGetScriptNameOrSourceURL) \
CPP(CallSitePrototypeGetThis) \
CPP(CallSitePrototypeGetTypeName) \
CPP(CallSitePrototypeIsConstructor) \
CPP(CallSitePrototypeIsEval) \
CPP(CallSitePrototypeIsNative) \
CPP(CallSitePrototypeIsToplevel) \
CPP(CallSitePrototypeToString) \
\
/* Console */ \
CPP(ConsoleDebug) \
CPP(ConsoleError) \
CPP(ConsoleInfo) \
CPP(ConsoleLog) \
CPP(ConsoleWarn) \
CPP(ConsoleDir) \
CPP(ConsoleDirXml) \
CPP(ConsoleTable) \
CPP(ConsoleTrace) \
CPP(ConsoleGroup) \
CPP(ConsoleGroupCollapsed) \
CPP(ConsoleGroupEnd) \
CPP(ConsoleClear) \
CPP(ConsoleCount) \
CPP(ConsoleAssert) \
TFJ(FastConsoleAssert, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
CPP(ConsoleMarkTimeline) \
CPP(ConsoleProfile) \
CPP(ConsoleProfileEnd) \
CPP(ConsoleTimeline) \
CPP(ConsoleTimelineEnd) \
CPP(ConsoleTime) \
CPP(ConsoleTimeEnd) \
CPP(ConsoleTimeStamp) \
CPP(ConsoleContext) \
\
/* DataView */ \
CPP(DataViewConstructor) \
CPP(DataViewConstructor_ConstructStub) \
CPP(DataViewPrototypeGetBuffer) \
CPP(DataViewPrototypeGetByteLength) \
CPP(DataViewPrototypeGetByteOffset) \
CPP(DataViewPrototypeGetInt8) \
CPP(DataViewPrototypeSetInt8) \
CPP(DataViewPrototypeGetUint8) \
CPP(DataViewPrototypeSetUint8) \
CPP(DataViewPrototypeGetInt16) \
CPP(DataViewPrototypeSetInt16) \
CPP(DataViewPrototypeGetUint16) \
CPP(DataViewPrototypeSetUint16) \
CPP(DataViewPrototypeGetInt32) \
CPP(DataViewPrototypeSetInt32) \
CPP(DataViewPrototypeGetUint32) \
CPP(DataViewPrototypeSetUint32) \
CPP(DataViewPrototypeGetFloat32) \
CPP(DataViewPrototypeSetFloat32) \
CPP(DataViewPrototypeGetFloat64) \
CPP(DataViewPrototypeSetFloat64) \
\
/* Date */ \
CPP(DateConstructor) \
CPP(DateConstructor_ConstructStub) \
/* ES6 #sec-date.prototype.getdate */ \
TFJ(DatePrototypeGetDate, 0) \
/* ES6 #sec-date.prototype.getday */ \
TFJ(DatePrototypeGetDay, 0) \
/* ES6 #sec-date.prototype.getfullyear */ \
TFJ(DatePrototypeGetFullYear, 0) \
/* ES6 #sec-date.prototype.gethours */ \
TFJ(DatePrototypeGetHours, 0) \
/* ES6 #sec-date.prototype.getmilliseconds */ \
TFJ(DatePrototypeGetMilliseconds, 0) \
/* ES6 #sec-date.prototype.getminutes */ \
TFJ(DatePrototypeGetMinutes, 0) \
/* ES6 #sec-date.prototype.getmonth */ \
TFJ(DatePrototypeGetMonth, 0) \
/* ES6 #sec-date.prototype.getseconds */ \
TFJ(DatePrototypeGetSeconds, 0) \
/* ES6 #sec-date.prototype.gettime */ \
TFJ(DatePrototypeGetTime, 0) \
/* ES6 #sec-date.prototype.gettimezoneoffset */ \
TFJ(DatePrototypeGetTimezoneOffset, 0) \
/* ES6 #sec-date.prototype.getutcdate */ \
TFJ(DatePrototypeGetUTCDate, 0) \
/* ES6 #sec-date.prototype.getutcday */ \
TFJ(DatePrototypeGetUTCDay, 0) \
/* ES6 #sec-date.prototype.getutcfullyear */ \
TFJ(DatePrototypeGetUTCFullYear, 0) \
/* ES6 #sec-date.prototype.getutchours */ \
TFJ(DatePrototypeGetUTCHours, 0) \
/* ES6 #sec-date.prototype.getutcmilliseconds */ \
TFJ(DatePrototypeGetUTCMilliseconds, 0) \
/* ES6 #sec-date.prototype.getutcminutes */ \
TFJ(DatePrototypeGetUTCMinutes, 0) \
/* ES6 #sec-date.prototype.getutcmonth */ \
TFJ(DatePrototypeGetUTCMonth, 0) \
/* ES6 #sec-date.prototype.getutcseconds */ \
TFJ(DatePrototypeGetUTCSeconds, 0) \
/* ES6 #sec-date.prototype.valueof */ \
TFJ(DatePrototypeValueOf, 0) \
/* ES6 #sec-date.prototype-@@toprimitive */ \
TFJ(DatePrototypeToPrimitive, 1, kHint) \
CPP(DatePrototypeGetYear) \
CPP(DatePrototypeSetYear) \
CPP(DateNow) \
CPP(DateParse) \
CPP(DatePrototypeSetDate) \
CPP(DatePrototypeSetFullYear) \
CPP(DatePrototypeSetHours) \
CPP(DatePrototypeSetMilliseconds) \
CPP(DatePrototypeSetMinutes) \
CPP(DatePrototypeSetMonth) \
CPP(DatePrototypeSetSeconds) \
CPP(DatePrototypeSetTime) \
CPP(DatePrototypeSetUTCDate) \
CPP(DatePrototypeSetUTCFullYear) \
CPP(DatePrototypeSetUTCHours) \
CPP(DatePrototypeSetUTCMilliseconds) \
CPP(DatePrototypeSetUTCMinutes) \
CPP(DatePrototypeSetUTCMonth) \
CPP(DatePrototypeSetUTCSeconds) \
CPP(DatePrototypeToDateString) \
CPP(DatePrototypeToISOString) \
CPP(DatePrototypeToUTCString) \
CPP(DatePrototypeToString) \
CPP(DatePrototypeToTimeString) \
CPP(DatePrototypeToJson) \
CPP(DateUTC) \
\
/* Error */ \
CPP(ErrorConstructor) \
CPP(ErrorCaptureStackTrace) \
CPP(ErrorPrototypeToString) \
CPP(MakeError) \
CPP(MakeRangeError) \
CPP(MakeSyntaxError) \
CPP(MakeTypeError) \
CPP(MakeURIError) \
\
/* Function */ \
CPP(FunctionConstructor) \
ASM(FunctionPrototypeApply) \
CPP(FunctionPrototypeBind) \
/* ES6 #sec-function.prototype.bind */ \
TFJ(FastFunctionPrototypeBind, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
ASM(FunctionPrototypeCall) \
/* ES6 #sec-function.prototype-@@hasinstance */ \
TFJ(FunctionPrototypeHasInstance, 1, kV) \
/* ES6 #sec-function.prototype.tostring */ \
CPP(FunctionPrototypeToString) \
\
/* Belongs to Objects but is a dependency of GeneratorPrototypeResume */ \
TFS(CreateIterResultObject, kValue, kDone) \
\
/* Generator and Async */ \
TFS(CreateGeneratorObject, kClosure, kReceiver) \
CPP(GeneratorFunctionConstructor) \
/* ES6 #sec-generator.prototype.next */ \
TFJ(GeneratorPrototypeNext, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-generator.prototype.return */ \
TFJ(GeneratorPrototypeReturn, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-generator.prototype.throw */ \
TFJ(GeneratorPrototypeThrow, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
CPP(AsyncFunctionConstructor) \
\
/* Global object */ \
CPP(GlobalDecodeURI) \
CPP(GlobalDecodeURIComponent) \
CPP(GlobalEncodeURI) \
CPP(GlobalEncodeURIComponent) \
CPP(GlobalEscape) \
CPP(GlobalUnescape) \
CPP(GlobalEval) \
/* ES6 #sec-isfinite-number */ \
TFJ(GlobalIsFinite, 1, kNumber) \
/* ES6 #sec-isnan-number */ \
TFJ(GlobalIsNaN, 1, kNumber) \
\
/* JSON */ \
CPP(JsonParse) \
CPP(JsonStringify) \
\
/* ICs */ \
TFH(LoadIC, LoadWithVector) \
TFH(LoadIC_Noninlined, LoadWithVector) \
TFH(LoadICTrampoline, Load) \
TFH(KeyedLoadIC, LoadWithVector) \
TFH(KeyedLoadICTrampoline, Load) \
TFH(StoreIC, StoreWithVector) \
TFH(StoreICTrampoline, Store) \
TFH(KeyedStoreIC, StoreWithVector) \
TFH(KeyedStoreICTrampoline, Store) \
TFH(LoadGlobalIC, LoadGlobalWithVector) \
TFH(LoadGlobalICInsideTypeof, LoadGlobalWithVector) \
TFH(LoadGlobalICTrampoline, LoadGlobal) \
TFH(LoadGlobalICInsideTypeofTrampoline, LoadGlobal) \
\
/* Map */ \
TFS(FindOrderedHashMapEntry, kTable, kKey) \
TFJ(MapConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFJ(MapPrototypeSet, 2, kKey, kValue) \
TFJ(MapPrototypeDelete, 1, kKey) \
TFJ(MapPrototypeGet, 1, kKey) \
TFJ(MapPrototypeHas, 1, kKey) \
CPP(MapPrototypeClear) \
/* ES #sec-map.prototype.entries */ \
TFJ(MapPrototypeEntries, 0) \
/* ES #sec-get-map.prototype.size */ \
TFJ(MapPrototypeGetSize, 0) \
/* ES #sec-map.prototype.forEach */ \
TFJ(MapPrototypeForEach, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES #sec-map.prototype.keys */ \
TFJ(MapPrototypeKeys, 0) \
/* ES #sec-map.prototype.values */ \
TFJ(MapPrototypeValues, 0) \
/* ES #sec-%mapiteratorprototype%.next */ \
TFJ(MapIteratorPrototypeNext, 0) \
\
/* Math */ \
/* ES6 #sec-math.abs */ \
TFJ(MathAbs, 1, kX) \
/* ES6 #sec-math.acos */ \
TFJ(MathAcos, 1, kX) \
/* ES6 #sec-math.acosh */ \
TFJ(MathAcosh, 1, kX) \
/* ES6 #sec-math.asin */ \
TFJ(MathAsin, 1, kX) \
/* ES6 #sec-math.asinh */ \
TFJ(MathAsinh, 1, kX) \
/* ES6 #sec-math.atan */ \
TFJ(MathAtan, 1, kX) \
/* ES6 #sec-math.atanh */ \
TFJ(MathAtanh, 1, kX) \
/* ES6 #sec-math.atan2 */ \
TFJ(MathAtan2, 2, kY, kX) \
/* ES6 #sec-math.cbrt */ \
TFJ(MathCbrt, 1, kX) \
/* ES6 #sec-math.ceil */ \
TFJ(MathCeil, 1, kX) \
/* ES6 #sec-math.clz32 */ \
TFJ(MathClz32, 1, kX) \
/* ES6 #sec-math.cos */ \
TFJ(MathCos, 1, kX) \
/* ES6 #sec-math.cosh */ \
TFJ(MathCosh, 1, kX) \
/* ES6 #sec-math.exp */ \
TFJ(MathExp, 1, kX) \
/* ES6 #sec-math.expm1 */ \
TFJ(MathExpm1, 1, kX) \
/* ES6 #sec-math.floor */ \
TFJ(MathFloor, 1, kX) \
/* ES6 #sec-math.fround */ \
TFJ(MathFround, 1, kX) \
/* ES6 #sec-math.hypot */ \
CPP(MathHypot) \
/* ES6 #sec-math.imul */ \
TFJ(MathImul, 2, kX, kY) \
/* ES6 #sec-math.log */ \
TFJ(MathLog, 1, kX) \
/* ES6 #sec-math.log1p */ \
TFJ(MathLog1p, 1, kX) \
/* ES6 #sec-math.log10 */ \
TFJ(MathLog10, 1, kX) \
/* ES6 #sec-math.log2 */ \
TFJ(MathLog2, 1, kX) \
/* ES6 #sec-math.max */ \
TFJ(MathMax, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-math.min */ \
TFJ(MathMin, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-math.pow */ \
TFJ(MathPow, 2, kBase, kExponent) \
/* ES6 #sec-math.random */ \
TFJ(MathRandom, 0) \
/* ES6 #sec-math.round */ \
TFJ(MathRound, 1, kX) \
/* ES6 #sec-math.sign */ \
TFJ(MathSign, 1, kX) \
/* ES6 #sec-math.sin */ \
TFJ(MathSin, 1, kX) \
/* ES6 #sec-math.sinh */ \
TFJ(MathSinh, 1, kX) \
/* ES6 #sec-math.sqrt */ \
TFJ(MathTan, 1, kX) \
/* ES6 #sec-math.tan */ \
TFJ(MathTanh, 1, kX) \
/* ES6 #sec-math.tanh */ \
TFJ(MathSqrt, 1, kX) \
/* ES6 #sec-math.trunc */ \
TFJ(MathTrunc, 1, kX) \
\
/* Number */ \
TFC(AllocateHeapNumber, AllocateHeapNumber, 1) \
/* ES6 section 20.1.1.1 Number ( [ value ] ) for the [[Call]] case */ \
TFJ(NumberConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 section 20.1.1.1 Number ( [ value ] ) for the [[Construct]] case */ \
TFJ(NumberConstructor_ConstructStub, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-number.isfinite */ \
TFJ(NumberIsFinite, 1, kNumber) \
/* ES6 #sec-number.isinteger */ \
TFJ(NumberIsInteger, 1, kNumber) \
/* ES6 #sec-number.isnan */ \
TFJ(NumberIsNaN, 1, kNumber) \
/* ES6 #sec-number.issafeinteger */ \
TFJ(NumberIsSafeInteger, 1, kNumber) \
/* ES6 #sec-number.parsefloat */ \
TFJ(NumberParseFloat, 1, kString) \
/* ES6 #sec-number.parseint */ \
TFJ(NumberParseInt, 2, kString, kRadix) \
CPP(NumberPrototypeToExponential) \
CPP(NumberPrototypeToFixed) \
CPP(NumberPrototypeToLocaleString) \
CPP(NumberPrototypeToPrecision) \
CPP(NumberPrototypeToString) \
/* ES6 #sec-number.prototype.valueof */ \
TFJ(NumberPrototypeValueOf, 0) \
TFC(Add, BinaryOp, 1) \
TFC(Subtract, BinaryOp, 1) \
TFC(Multiply, BinaryOp, 1) \
TFC(Divide, BinaryOp, 1) \
TFC(Modulus, BinaryOp, 1) \
TFC(BitwiseAnd, BinaryOp, 1) \
TFC(BitwiseOr, BinaryOp, 1) \
TFC(BitwiseXor, BinaryOp, 1) \
TFC(ShiftLeft, BinaryOp, 1) \
TFC(ShiftRight, BinaryOp, 1) \
TFC(ShiftRightLogical, BinaryOp, 1) \
TFC(LessThan, Compare, 1) \
TFC(LessThanOrEqual, Compare, 1) \
TFC(GreaterThan, Compare, 1) \
TFC(GreaterThanOrEqual, Compare, 1) \
TFC(Equal, Compare, 1) \
TFC(SameValue, Compare, 1) \
TFC(StrictEqual, Compare, 1) \
TFS(BitwiseNot, kValue) \
TFS(Negate, kValue) \
\
/* Object */ \
TFJ(ObjectConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFJ(ObjectConstructor_ConstructStub, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
CPP(ObjectAssign) \
/* ES #sec-object.create */ \
TFJ(ObjectCreate, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
CPP(ObjectDefineGetter) \
CPP(ObjectDefineProperties) \
CPP(ObjectDefineProperty) \
CPP(ObjectDefineSetter) \
CPP(ObjectEntries) \
CPP(ObjectFreeze) \
TFJ(ObjectGetOwnPropertyDescriptor, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
CPP(ObjectGetOwnPropertyDescriptors) \
CPP(ObjectGetOwnPropertyNames) \
CPP(ObjectGetOwnPropertySymbols) \
CPP(ObjectGetPrototypeOf) \
CPP(ObjectSetPrototypeOf) \
[es2015] Optimize Object.is baseline and interesting cases. The Object.is builtin provides an entry point to the abstract operation SameValue, which properly distinguishes -0 and 0, and also identifies NaNs. Most of the time you don't need these, but rather just regular strict equality, but when you do, Object.is(o, -0) is the most readable way to check for minus zero. This is for example used in Node.js by formatNumber to properly print -0 for negative zero. However since the builtin thus far implemented as C++ builtin and TurboFan didn't know anything about it, Node.js considering to go with a more performant, less readable version (which also makes assumptions about the input value) in https://github.com/nodejs/node/pull/15726 until the performance of Object.is will be on par (so hopefully we can go back to Object.is in Node 9). This CL ports the baseline implementation of Object.is to CSA, which is pretty straight-forward since SameValue is already available in CodeStubAssembler, and inlines a few interesting cases into TurboFan, i.e. comparing same SSA node, and checking for -0 and NaN explicitly. On the micro-benchmarks we go from testNumberIsMinusZero: 1000 ms. testObjectIsMinusZero: 929 ms. testObjectIsNaN: 954 ms. testObjectIsSame: 793 ms. testStrictEqualSame: 104 ms. to testNumberIsMinusZero: 89 ms. testObjectIsMinusZero: 88 ms. testObjectIsNaN: 88 ms. testObjectIsSame: 86 ms. testStrictEqualSame: 105 ms. which is a nice 10x to 11x improvement and brings Object.is on par with strict equality for most cases. Drive-by-fix: Also refactor and optimize the SameValue check in the CodeStubAssembler to avoid code bloat (by not inlining StrictEqual into every user of SameValue, and also avoiding useless checks). Bug: v8:6882 Change-Id: Ibffd8c36511f219fcce0d89ed4e1073f5d6c6344 Reviewed-on: https://chromium-review.googlesource.com/700254 Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#48275}
2017-10-04 06:25:26 +00:00
TFJ(ObjectIs, 2, kLeft, kRight) \
CPP(ObjectIsExtensible) \
CPP(ObjectIsFrozen) \
CPP(ObjectIsSealed) \
TFJ(ObjectKeys, 1, kObject) \
CPP(ObjectLookupGetter) \
CPP(ObjectLookupSetter) \
CPP(ObjectPreventExtensions) \
/* ES6 #sec-object.prototype.tostring */ \
[builtins] Speed-up Object.prototype.toString. The @@toStringTag lookup in Object.prototype.toString causes quite a lot of overhead and oftentimes dominates the builtin performance. These lookups are almost always negative, especially for primitive values, and Object.prototype.toString is often used to implement predicates (like in Node core or in AngularJS), so having a way to skip the negative lookup yields big performance gains. This CL introduces a "MayHaveInterestingSymbols" bit on every map, which says whether instances with this map may have an interesting symbol. Currently only @@toStringTag is considered an interesting symbol, but we can extend that in the future. In the Object.prototype.toString we can use the interesting symbols bit to do a quick check on the prototype chain to see if there are any maps that might have the @@toStringTag, and if not, we can just immediately return the result, which is very fast because it's derived from the instance type. This also avoids the ToObject conversions for primitive values, which is important, since this causes unnecessary GC traffic and in for example AngularJS, strings are also often probed via the Object.prototype.toString based predicates. This boosts Speedometer/AngularJS by over 3% and Speedometer overall by up to 1%. On the microbenchmark from the similar SpiderMonkey bug (https://bugzilla.mozilla.org/show_bug.cgi?id=1369042), we go from roughly 450ms to 70ms, which corresponds to a 6.5x improvement. ``` function f() { var res = ""; var a = [1, 2, 3]; var toString = Object.prototype.toString; var t = new Date; for (var i = 0; i < 5000000; i++) res = toString.call(a); print(new Date - t); return res; } f(); ``` The design document at https://goo.gl/e8CruQ has some additional data points. TBR=ulan@chromium.org Bug: v8:6654 Change-Id: I31932cf41ecddad079d294e2c322a852af0ed244 Reviewed-on: https://chromium-review.googlesource.com/593620 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Cr-Commit-Position: refs/heads/master@{#47034}
2017-08-01 08:11:14 +00:00
TFJ(ObjectPrototypeToString, 0) \
/* ES6 #sec-object.prototype.valueof */ \
TFJ(ObjectPrototypeValueOf, 0) \
[turbofan] Optimize O.p.hasOwnProperty inside for-in. Optimize the common pattern for (var i in o) { if (Object.prototype.hasOwnProperty.call(o, i)) { // do something } } which is part of the guard-for-in style in ESLint (see the documentation at https://eslint.org/docs/rules/guard-for-in for details). This pattern also shows up in React and Ember applications quite a lot (and is tested by the appropriate Speedometer benchmarks, although not dominating those benchmarks, since they spent a lot of time in non-TurboFan'ed code). This improves the forInHasOwnProperty and forInHasOwnPropertySafe micro- benchmarks in v8:6702, which look like this function forInHasOwnProperty(o) { var result = 0; for (var i in o) { if (o.hasOwnProperty(i)) { result += 1; } } return result; } function forInHasOwnPropertySafe(o) { var result = 0; for (var i in o) { if (Object.prototype.hasOwnProperty.call(o, i)) { result += 1; } } return result; } by around 4x and allows for additional optimizations in the future, by also elimiating the megamorphic load when accessing the enumerated properties. This changes the interpreter ForInNext bytecode to collect more precise feedback about the for-in state, which now consists of three individual states: UNINITIALIZED, MEGAMORPHIC and GENERIC. The MEGAMORPHIC state means that the ForInNext has only seen objects with a usable enum cache thus far, whereas GENERIC means that we have seen some slow-mode for..in objects as well. R=jarin@chromium.org Bug: v8:6702 Change-Id: Ibcd75ea9b58c3b4f9219f11bc37eb04a2b985604 Reviewed-on: https://chromium-review.googlesource.com/636964 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Cr-Commit-Position: refs/heads/master@{#47632}
2017-08-28 05:26:15 +00:00
/* ES6 #sec-object.prototype.hasownproperty */ \
TFJ(ObjectPrototypeHasOwnProperty, 1, kKey) \
[builtins] Properly optimize Object.prototype.isPrototypeOf. Port the baseline implementation of Object.prototype.isPrototypeOf to the CodeStubAssembler, sharing the existing prototype chain lookup logic with the instanceof / OrdinaryHasInstance implementation. Based on that, do the same in TurboFan, introducing a new JSHasInPrototypeChain operator, which encapsulates the central prototype chain walk logic. This speeds up Object.prototype.isPrototypeOf by more than a factor of four, so that the code A.prototype.isPrototypeOf(a) is now performance-wise on par with a instanceof A for the case where A is a regular constructor function and a is an instance of A. Since instanceof does more than just the fundamental prototype chain lookup, it was discovered in Node core that O.p.isPrototypeOf would be a more appropriate alternative for certain sanity checks, since it's less vulnerable to monkey-patching. In addition, the Object builtin would also avoid the performance-cliff associated with instanceof (due to the Symbol.hasInstance hook), as for example hit by https://github.com/nodejs/node/pull/13403#issuecomment-305915874. The main blocker was the missing performance of isPrototypeOf, since it was still a JS builtin backed by a runtime call. This CL also adds more test coverage for the Object.prototype.isPrototypeOf builtin, especially when called from optimized code. CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_chromium_rel_ng BUG=v8:5269,v8:5989,v8:6483 R=jgruber@chromium.org Review-Url: https://codereview.chromium.org/2934893002 Cr-Commit-Position: refs/heads/master@{#45925}
2017-06-13 19:14:00 +00:00
TFJ(ObjectPrototypeIsPrototypeOf, 1, kValue) \
CPP(ObjectPrototypePropertyIsEnumerable) \
CPP(ObjectPrototypeGetProto) \
CPP(ObjectPrototypeSetProto) \
CPP(ObjectSeal) \
CPP(ObjectValues) \
\
/* instanceof */ \
TFC(OrdinaryHasInstance, Compare, 1) \
TFC(InstanceOf, Compare, 1) \
\
/* for-in */ \
[turbofan] Optimize fast enum cache driven for..in. This CL adds support to optimize for..in in fast enum-cache mode to the same degree that it was optimized in Crankshaft, without adding the same deoptimization loop that Crankshaft had with missing enum cache indices. That means code like for (var k in o) { var v = o[k]; // ... } and code like for (var k in o) { if (Object.prototype.hasOwnProperty.call(o, k)) { var v = o[k]; // ... } } which follows the https://eslint.org/docs/rules/guard-for-in linter rule, can now utilize the enum cache indices if o has only fast properties on the receiver, which speeds up the access o[k] significantly and reduces the pollution of the global megamorphic stub cache. For example the micro-benchmark in the tracking bug v8:6702 now runs faster than ever before: forIn: 1516 ms. forInHasOwnProperty: 1674 ms. forInHasOwnPropertySafe: 1595 ms. forInSum: 2051 ms. forInSumSafe: 2215 ms. Compared to numbers from V8 5.8 which is the last version running with Crankshaft forIn: 1641 ms. forInHasOwnProperty: 1719 ms. forInHasOwnPropertySafe: 1802 ms. forInSum: 2226 ms. forInSumSafe: 2409 ms. and V8 6.0 which is the current stable version with TurboFan: forIn: 1713 ms. forInHasOwnProperty: 5417 ms. forInHasOwnPropertySafe: 5324 ms. forInSum: 7556 ms. forInSumSafe: 11067 ms. It also improves the throughput on the string-fasta benchmark by around 7-10%, and there seems to be a ~5% improvement on the Speedometer/React benchmark locally. For this to work, the ForInPrepare bytecode was split into ForInEnumerate and ForInPrepare, which is very similar to how it was handled in Fullcodegen initially. In TurboFan we introduce a new operator LoadFieldByIndex that does the dynamic property load. This also removes the CheckMapValue operator again in favor of just using LoadField, ReferenceEqual and CheckIf, which work automatically with the EscapeAnalysis and the BranchConditionElimination. Bug: v8:6702 Change-Id: I91235413eea478ba77ace7bd14bb2f62e155dd9a Reviewed-on: https://chromium-review.googlesource.com/645949 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/master@{#47768}
2017-09-01 10:49:06 +00:00
TFS(ForInEnumerate, kReceiver) \
TFS(ForInFilter, kKey, kObject) \
\
/* Promise */ \
/* ES6 #sec-getcapabilitiesexecutor-functions */ \
TFJ(PromiseGetCapabilitiesExecutor, 2, kResolve, kReject) \
/* ES6 #sec-newpromisecapability */ \
TFJ(NewPromiseCapability, 2, kConstructor, kDebugEvent) \
/* ES6 #sec-promise-executor */ \
TFJ(PromiseConstructor, 1, kExecutor) \
TFJ(PromiseInternalConstructor, 1, kParent) \
CPP(IsPromise) \
/* ES #sec-promise-resolve-functions */ \
TFJ(PromiseResolveClosure, 1, kValue) \
/* ES #sec-promise-reject-functions */ \
TFJ(PromiseRejectClosure, 1, kValue) \
TFJ(PromiseAllResolveElementClosure, 1, kValue) \
/* ES #sec-promise.prototype.then */ \
TFJ(PromiseThen, 2, kOnFullfilled, kOnRejected) \
/* ES #sec-promise.prototype.catch */ \
TFJ(PromiseCatch, 1, kOnRejected) \
/* ES #sec-fulfillpromise */ \
TFJ(ResolvePromise, 2, kPromise, kValue) \
TFS(PromiseHandleReject, kPromise, kOnReject, kException) \
TFJ(PromiseHandle, 5, kValue, kHandler, kDeferredPromise, \
kDeferredOnResolve, kDeferredOnReject) \
/* ES #sec-promise.resolve */ \
TFJ(PromiseResolveWrapper, 1, kValue) \
TFS(PromiseResolve, kConstructor, kValue) \
/* ES #sec-promise.reject */ \
TFJ(PromiseReject, 1, kReason) \
TFJ(InternalPromiseReject, 3, kPromise, kReason, kDebugEvent) \
TFJ(PromiseFinally, 1, kOnFinally) \
TFJ(PromiseThenFinally, 1, kValue) \
TFJ(PromiseCatchFinally, 1, kReason) \
TFJ(PromiseValueThunkFinally, 0) \
TFJ(PromiseThrowerFinally, 0) \
/* ES #sec-promise.all */ \
TFJ(PromiseAll, 1, kIterable) \
/* ES #sec-promise.race */ \
TFJ(PromiseRace, 1, kIterable) \
\
/* Proxy */ \
TFJ(ProxyConstructor, 0) \
TFJ(ProxyConstructor_ConstructStub, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFS(ProxyGetProperty, kProxy, kName, kReceiverValue) \
TFS(ProxyHasProperty, kProxy, kName) \
TFS(ProxySetProperty, kProxy, kName, kValue, kReceiverValue, kLanguageMode) \
\
/* Reflect */ \
ASM(ReflectApply) \
ASM(ReflectConstruct) \
CPP(ReflectDefineProperty) \
CPP(ReflectDeleteProperty) \
CPP(ReflectGet) \
CPP(ReflectGetOwnPropertyDescriptor) \
CPP(ReflectGetPrototypeOf) \
TFJ(ReflectHas, 2, kTarget, kKey) \
CPP(ReflectIsExtensible) \
CPP(ReflectOwnKeys) \
CPP(ReflectPreventExtensions) \
CPP(ReflectSet) \
CPP(ReflectSetPrototypeOf) \
\
/* RegExp */ \
CPP(RegExpCapture1Getter) \
CPP(RegExpCapture2Getter) \
CPP(RegExpCapture3Getter) \
CPP(RegExpCapture4Getter) \
CPP(RegExpCapture5Getter) \
CPP(RegExpCapture6Getter) \
CPP(RegExpCapture7Getter) \
CPP(RegExpCapture8Getter) \
CPP(RegExpCapture9Getter) \
/* ES #sec-regexp-pattern-flags */ \
TFJ(RegExpConstructor, 2, kPattern, kFlags) \
TFJ(RegExpInternalMatch, 2, kRegExp, kString) \
CPP(RegExpInputGetter) \
CPP(RegExpInputSetter) \
CPP(RegExpLastMatchGetter) \
CPP(RegExpLastParenGetter) \
CPP(RegExpLeftContextGetter) \
/* ES #sec-regexp.prototype.compile */ \
TFJ(RegExpPrototypeCompile, 2, kPattern, kFlags) \
/* ES #sec-regexp.prototype.exec */ \
TFJ(RegExpPrototypeExec, 1, kString) \
/* ES #sec-get-regexp.prototype.dotAll */ \
TFJ(RegExpPrototypeDotAllGetter, 0) \
/* ES #sec-get-regexp.prototype.flags */ \
TFJ(RegExpPrototypeFlagsGetter, 0) \
/* ES #sec-get-regexp.prototype.global */ \
TFJ(RegExpPrototypeGlobalGetter, 0) \
/* ES #sec-get-regexp.prototype.ignorecase */ \
TFJ(RegExpPrototypeIgnoreCaseGetter, 0) \
/* ES #sec-regexp.prototype-@@match */ \
TFJ(RegExpPrototypeMatch, 1, kString) \
/* ES #sec-get-regexp.prototype.multiline */ \
TFJ(RegExpPrototypeMultilineGetter, 0) \
/* ES #sec-regexp.prototype-@@search */ \
TFJ(RegExpPrototypeSearch, 1, kString) \
/* ES #sec-get-regexp.prototype.source */ \
TFJ(RegExpPrototypeSourceGetter, 0) \
/* ES #sec-get-regexp.prototype.sticky */ \
TFJ(RegExpPrototypeStickyGetter, 0) \
/* ES #sec-regexp.prototype.test */ \
TFJ(RegExpPrototypeTest, 1, kString) \
CPP(RegExpPrototypeToString) \
/* ES #sec-get-regexp.prototype.unicode */ \
TFJ(RegExpPrototypeUnicodeGetter, 0) \
CPP(RegExpRightContextGetter) \
\
/* ES #sec-regexp.prototype-@@replace */ \
TFJ(RegExpPrototypeReplace, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES #sec-regexp.prototype-@@split */ \
TFJ(RegExpPrototypeSplit, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* RegExp helpers */ \
TFS(RegExpExecAtom, kRegExp, kString, kLastIndex, kMatchInfo) \
TFS(RegExpMatchFast, kReceiver, kPattern) \
TFS(RegExpPrototypeExecSlow, kReceiver, kString) \
TFS(RegExpReplace, kRegExp, kString, kReplaceValue) \
TFS(RegExpSearchFast, kReceiver, kPattern) \
TFS(RegExpSplit, kRegExp, kString, kLimit) \
\
/* Set */ \
TFJ(SetConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFJ(SetPrototypeHas, 1, kKey) \
TFJ(SetPrototypeAdd, 1, kKey) \
TFJ(SetPrototypeDelete, 1, kKey) \
CPP(SetPrototypeClear) \
/* ES #sec-set.prototype.entries */ \
TFJ(SetPrototypeEntries, 0) \
/* ES #sec-get-set.prototype.size */ \
TFJ(SetPrototypeGetSize, 0) \
/* ES #sec-set.prototype.foreach */ \
TFJ(SetPrototypeForEach, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES #sec-set.prototype.values */ \
TFJ(SetPrototypeValues, 0) \
/* ES #sec-%setiteratorprototype%.next */ \
TFJ(SetIteratorPrototypeNext, 0) \
\
/* SharedArrayBuffer */ \
CPP(SharedArrayBufferPrototypeGetByteLength) \
CPP(SharedArrayBufferPrototypeSlice) \
TFJ(AtomicsLoad, 2, kArray, kIndex) \
TFJ(AtomicsStore, 3, kArray, kIndex, kValue) \
TFJ(AtomicsExchange, 3, kArray, kIndex, kValue) \
TFJ(AtomicsCompareExchange, 4, kArray, kIndex, kOldValue, kNewValue) \
TFJ(AtomicsAdd, 3, kArray, kIndex, kValue) \
TFJ(AtomicsSub, 3, kArray, kIndex, kValue) \
TFJ(AtomicsAnd, 3, kArray, kIndex, kValue) \
TFJ(AtomicsOr, 3, kArray, kIndex, kValue) \
TFJ(AtomicsXor, 3, kArray, kIndex, kValue) \
CPP(AtomicsIsLockFree) \
CPP(AtomicsWait) \
CPP(AtomicsWake) \
\
/* String */ \
TFJ(StringConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFJ(StringConstructor_ConstructStub, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
CPP(StringFromCodePoint) \
/* ES6 #sec-string.fromcharcode */ \
TFJ(StringFromCharCode, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.anchor */ \
TFJ(StringPrototypeAnchor, 1, kValue) \
/* ES6 #sec-string.prototype.big */ \
TFJ(StringPrototypeBig, 0) \
/* ES6 #sec-string.prototype.blink */ \
TFJ(StringPrototypeBlink, 0) \
/* ES6 #sec-string.prototype.bold */ \
TFJ(StringPrototypeBold, 0) \
/* ES6 #sec-string.prototype.charat */ \
TFJ(StringPrototypeCharAt, 1, kPosition) \
/* ES6 #sec-string.prototype.charcodeat */ \
TFJ(StringPrototypeCharCodeAt, 1, kPosition) \
/* ES6 #sec-string.prototype.codepointat */ \
TFJ(StringPrototypeCodePointAt, 1, kPosition) \
/* ES6 #sec-string.prototype.concat */ \
TFJ(StringPrototypeConcat, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.endswith */ \
CPP(StringPrototypeEndsWith) \
/* ES6 #sec-string.prototype.fontcolor */ \
TFJ(StringPrototypeFontcolor, 1, kValue) \
/* ES6 #sec-string.prototype.fontsize */ \
TFJ(StringPrototypeFontsize, 1, kValue) \
/* ES6 #sec-string.prototype.fixed */ \
TFJ(StringPrototypeFixed, 0) \
/* ES6 #sec-string.prototype.includes */ \
TFJ(StringPrototypeIncludes, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.indexof */ \
TFJ(StringPrototypeIndexOf, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.italics */ \
TFJ(StringPrototypeItalics, 0) \
/* ES6 #sec-string.prototype.lastindexof */ \
CPP(StringPrototypeLastIndexOf) \
/* ES6 #sec-string.prototype.link */ \
TFJ(StringPrototypeLink, 1, kValue) \
/* ES6 #sec-string.prototype.match */ \
TFJ(StringPrototypeMatch, 1, kRegexp) \
/* ES6 #sec-string.prototype.localecompare */ \
CPP(StringPrototypeLocaleCompare) \
/* ES6 #sec-string.prototype.padEnd */ \
TFJ(StringPrototypePadEnd, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.padStart */ \
TFJ(StringPrototypePadStart, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.repeat */ \
TFJ(StringPrototypeRepeat, 1, kCount) \
/* ES6 #sec-string.prototype.replace */ \
TFJ(StringPrototypeReplace, 2, kSearch, kReplace) \
/* ES6 #sec-string.prototype.search */ \
TFJ(StringPrototypeSearch, 1, kRegexp) \
/* ES6 #sec-string.prototype.slice */ \
TFJ(StringPrototypeSlice, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.small */ \
TFJ(StringPrototypeSmall, 0) \
/* ES6 #sec-string.prototype.split */ \
TFJ(StringPrototypeSplit, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.strike */ \
TFJ(StringPrototypeStrike, 0) \
/* ES6 #sec-string.prototype.sub */ \
TFJ(StringPrototypeSub, 0) \
/* ES6 #sec-string.prototype.substr */ \
TFJ(StringPrototypeSubstr, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.substring */ \
TFJ(StringPrototypeSubstring, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.sup */ \
TFJ(StringPrototypeSup, 0) \
/* ES6 #sec-string.prototype.startswith */ \
CPP(StringPrototypeStartsWith) \
/* ES6 #sec-string.prototype.tostring */ \
TFJ(StringPrototypeToString, 0) \
TFJ(StringPrototypeTrim, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFJ(StringPrototypeTrimLeft, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFJ(StringPrototypeTrimRight, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.valueof */ \
TFJ(StringPrototypeValueOf, 0) \
/* ES6 #sec-string.raw */ \
CPP(StringRaw) \
/* ES6 #sec-string.prototype-@@iterator */ \
TFJ(StringPrototypeIterator, 0) \
\
/* StringIterator */ \
/* ES6 #sec-%stringiteratorprototype%.next */ \
TFJ(StringIteratorPrototypeNext, 0) \
\
/* Symbol */ \
CPP(SymbolConstructor) \
CPP(SymbolConstructor_ConstructStub) \
/* ES6 #sec-symbol.for */ \
CPP(SymbolFor) \
/* ES6 #sec-symbol.keyfor */ \
CPP(SymbolKeyFor) \
/* ES6 #sec-symbol.prototype-@@toprimitive */ \
TFJ(SymbolPrototypeToPrimitive, 1, kHint) \
/* ES6 #sec-symbol.prototype.tostring */ \
TFJ(SymbolPrototypeToString, 0) \
/* ES6 #sec-symbol.prototype.valueof */ \
TFJ(SymbolPrototypeValueOf, 0) \
\
/* TypedArray */ \
TFS(TypedArrayInitialize, kHolder, kLength, kElementSize, kInitialize) \
TFS(TypedArrayInitializeWithBuffer, kHolder, kLength, kBuffer, kElementSize, \
kByteOffset) \
/* ES6 #sec-typedarray-buffer-byteoffset-length */ \
TFJ(TypedArrayConstructByArrayBuffer, 5, kHolder, kBuffer, kByteOffset, \
kLength, kElementSize) \
TFJ(TypedArrayConstructByArrayLike, 4, kHolder, kArrayLike, kLength, \
kElementSize) \
/* ES6 #sec-typedarray-length */ \
TFJ(TypedArrayConstructByLength, 3, kHolder, kLength, kElementSize) \
CPP(TypedArrayPrototypeBuffer) \
/* ES6 #sec-get-%typedarray%.prototype.bytelength */ \
TFJ(TypedArrayPrototypeByteLength, 0) \
/* ES6 #sec-get-%typedarray%.prototype.byteoffset */ \
TFJ(TypedArrayPrototypeByteOffset, 0) \
/* ES6 #sec-get-%typedarray%.prototype.length */ \
TFJ(TypedArrayPrototypeLength, 0) \
/* ES6 #sec-%typedarray%.prototype.entries */ \
TFJ(TypedArrayPrototypeEntries, 0) \
/* ES6 #sec-%typedarray%.prototype.keys */ \
TFJ(TypedArrayPrototypeKeys, 0) \
/* ES6 #sec-%typedarray%.prototype.values */ \
TFJ(TypedArrayPrototypeValues, 0) \
/* ES6 #sec-%typedarray%.prototype.copywithin */ \
CPP(TypedArrayPrototypeCopyWithin) \
/* ES6 #sec-%typedarray%.prototype.fill */ \
CPP(TypedArrayPrototypeFill) \
/* ES7 #sec-%typedarray%.prototype.includes */ \
CPP(TypedArrayPrototypeIncludes) \
/* ES6 #sec-%typedarray%.prototype.indexof */ \
CPP(TypedArrayPrototypeIndexOf) \
/* ES6 #sec-%typedarray%.prototype.lastindexof */ \
CPP(TypedArrayPrototypeLastIndexOf) \
/* ES6 #sec-%typedarray%.prototype.reverse */ \
CPP(TypedArrayPrototypeReverse) \
/* ES6 %TypedArray%.prototype.set */ \
CPP(TypedArrayPrototypeSet) \
/* ES6 #sec-%typedarray%.prototype.slice */ \
CPP(TypedArrayPrototypeSlice) \
[es2015] Optimize TypedArray.prototype[Symbol.toStringTag]. The TypedArray.prototype[Symbol.toStringTag] getter is currently the best (and as far as I can tell only definitely side-effect free) way to check whether an arbitrary object is a TypedArray - either generally TypedArray or a specific one like Uint8Array. Using the getter is thus emerging as the general pattern to detect TypedArrays, even Node.js now adapted it starting with https://github.com/nodejs/node/pull/15663 for the isTypedArray and isUint8Array type checks in lib/internal/util/types.js now. The getter returns either the string with the TypedArray subclass name (i.e. "Uint8Array") or undefined if the receiver is not a TypedArray. This can be implemented with a simple elements kind dispatch, instead of checking the instance type and then loading the class name from the constructor, which requires a loop walking up the transition tree. This CL ports the builtin to CSA and TurboFan, and changes the logic to a simple elements kind check. On the micro-benchmark mentioned in the referenced bug, the time goes from testIsArrayBufferView: 565 ms. testIsTypedArray: 2403 ms. testIsUint8Array: 3847 ms. to testIsArrayBufferView: 566 ms. testIsTypedArray: 965 ms. testIsUint8Array: 965 ms. which presents an up to 4x improvement. Bug: v8:6874 Change-Id: I9c330b4529d9631df2f052acf023c6a4fae69611 Reviewed-on: https://chromium-review.googlesource.com/695021 Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#48254}
2017-10-02 05:28:41 +00:00
/* ES6 #sec-get-%typedarray%.prototype-@@tostringtag */ \
TFJ(TypedArrayPrototypeToStringTag, 0) \
/* ES6 %TypedArray%.prototype.every */ \
TFJ(TypedArrayPrototypeEvery, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 %TypedArray%.prototype.some */ \
TFJ(TypedArrayPrototypeSome, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 %TypedArray%.prototype.reduce */ \
TFJ(TypedArrayPrototypeReduce, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 %TypedArray%.prototype.reduceRight */ \
TFJ(TypedArrayPrototypeReduceRight, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 %TypedArray%.prototype.map */ \
TFJ(TypedArrayPrototypeMap, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 %TypedArray%.prototype.forEach */ \
TFJ(TypedArrayPrototypeForEach, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
\
/* Wasm */ \
ASM(WasmCompileLazy) \
TFC(WasmStackGuard, WasmRuntimeCall, 1) \
TFC(ThrowWasmTrapUnreachable, WasmRuntimeCall, 1) \
TFC(ThrowWasmTrapMemOutOfBounds, WasmRuntimeCall, 1) \
TFC(ThrowWasmTrapDivByZero, WasmRuntimeCall, 1) \
TFC(ThrowWasmTrapDivUnrepresentable, WasmRuntimeCall, 1) \
TFC(ThrowWasmTrapRemByZero, WasmRuntimeCall, 1) \
TFC(ThrowWasmTrapFloatUnrepresentable, WasmRuntimeCall, 1) \
TFC(ThrowWasmTrapFuncInvalid, WasmRuntimeCall, 1) \
TFC(ThrowWasmTrapFuncSigMismatch, WasmRuntimeCall, 1) \
\
/* WeakMap */ \
TFJ(WeakMapConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFS(WeakMapLookupHashIndex, kTable, kKey) \
TFJ(WeakMapGet, 1, kKey) \
TFJ(WeakMapHas, 1, kKey) \
TFJ(WeakMapPrototypeSet, 2, kKey, kValue) \
TFJ(WeakMapPrototypeDelete, 1, kKey) \
\
/* WeakSet */ \
TFJ(WeakSetConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
TFJ(WeakSetHas, 1, kKey) \
TFJ(WeakSetPrototypeAdd, 1, kValue) \
TFJ(WeakSetPrototypeDelete, 1, kValue) \
\
/* WeakSet / WeakMap Helpers */ \
TFS(WeakCollectionDelete, kCollection, kKey) \
TFS(WeakCollectionSet, kCollection, kKey, kValue) \
\
[async-iteration] implement AsyncGenerator - Introduce new struct AsyncGeneratorRequest, which holds information pertinent to resuming execution of an AsyncGenerator, such as the Promise associated with the async generator request. It is intended to be used as a singly linked list, and holds a pointer to the next item in te queue. - Introduce JSAsyncGeneratorObject (subclass of JSGeneratorObject), which includes several new internal fields (`queue` which contains a singly linked list of AsyncGeneratorRequest objects, and `await_input` which contains the sent value from an Await expression (This is necessary to prevent function.sent (used by yield*) from having the sent value observably overwritten during execution). - Modify SuspendGenerator to accept a set of Flags, which indicate whether the suspend is for a Yield or Await, and whether it takes place on an async generator or ES6 generator. - Introduce interpreter intrinsics and TF intrinsic lowering for accessing the await input of an async generator - Modify the JSGeneratorStore operator to understand whether or not it's suspending for a normal yield, or an AsyncGenerator Await. This ensures appropriate registers are stored. - Add versions of ResumeGeneratorTrampoline which store the input value in a different field depending on wether it's an AsyncGenerator Await resume, or an ordinary resume. Also modifies whether debug code will assert that the generator object is a JSGeneratorObject or a JSAsyncGeneratorObject depending on the resume type. BUG=v8:5855 R=bmeurer@chromium.org, rmcilroy@chromium.org, jgruber@chromium.org, littledan@chromium.org, neis@chromium.org TBR=marja@chromium.org Change-Id: I9d58df1d344465fc937fe7eed322424204497187 Reviewed-on: https://chromium-review.googlesource.com/446961 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#44240}
2017-03-29 13:41:45 +00:00
/* AsyncGenerator */ \
\
TFS(AsyncGeneratorResolve, kGenerator, kValue, kDone) \
TFS(AsyncGeneratorReject, kGenerator, kValue) \
TFS(AsyncGeneratorYield, kGenerator, kValue, kIsCaught) \
TFS(AsyncGeneratorReturn, kGenerator, kValue, kIsCaught) \
TFS(AsyncGeneratorResumeNext, kGenerator) \
[async-iteration] implement AsyncGenerator - Introduce new struct AsyncGeneratorRequest, which holds information pertinent to resuming execution of an AsyncGenerator, such as the Promise associated with the async generator request. It is intended to be used as a singly linked list, and holds a pointer to the next item in te queue. - Introduce JSAsyncGeneratorObject (subclass of JSGeneratorObject), which includes several new internal fields (`queue` which contains a singly linked list of AsyncGeneratorRequest objects, and `await_input` which contains the sent value from an Await expression (This is necessary to prevent function.sent (used by yield*) from having the sent value observably overwritten during execution). - Modify SuspendGenerator to accept a set of Flags, which indicate whether the suspend is for a Yield or Await, and whether it takes place on an async generator or ES6 generator. - Introduce interpreter intrinsics and TF intrinsic lowering for accessing the await input of an async generator - Modify the JSGeneratorStore operator to understand whether or not it's suspending for a normal yield, or an AsyncGenerator Await. This ensures appropriate registers are stored. - Add versions of ResumeGeneratorTrampoline which store the input value in a different field depending on wether it's an AsyncGenerator Await resume, or an ordinary resume. Also modifies whether debug code will assert that the generator object is a JSGeneratorObject or a JSAsyncGeneratorObject depending on the resume type. BUG=v8:5855 R=bmeurer@chromium.org, rmcilroy@chromium.org, jgruber@chromium.org, littledan@chromium.org, neis@chromium.org TBR=marja@chromium.org Change-Id: I9d58df1d344465fc937fe7eed322424204497187 Reviewed-on: https://chromium-review.googlesource.com/446961 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#44240}
2017-03-29 13:41:45 +00:00
\
/* AsyncGeneratorFunction( p1, p2, ... pn, body ) */ \
/* proposal-async-iteration/#sec-asyncgeneratorfunction-constructor */ \
CPP(AsyncGeneratorFunctionConstructor) \
/* AsyncGenerator.prototype.next ( value ) */ \
/* proposal-async-iteration/#sec-asyncgenerator-prototype-next */ \
TFJ(AsyncGeneratorPrototypeNext, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
[async-iteration] implement AsyncGenerator - Introduce new struct AsyncGeneratorRequest, which holds information pertinent to resuming execution of an AsyncGenerator, such as the Promise associated with the async generator request. It is intended to be used as a singly linked list, and holds a pointer to the next item in te queue. - Introduce JSAsyncGeneratorObject (subclass of JSGeneratorObject), which includes several new internal fields (`queue` which contains a singly linked list of AsyncGeneratorRequest objects, and `await_input` which contains the sent value from an Await expression (This is necessary to prevent function.sent (used by yield*) from having the sent value observably overwritten during execution). - Modify SuspendGenerator to accept a set of Flags, which indicate whether the suspend is for a Yield or Await, and whether it takes place on an async generator or ES6 generator. - Introduce interpreter intrinsics and TF intrinsic lowering for accessing the await input of an async generator - Modify the JSGeneratorStore operator to understand whether or not it's suspending for a normal yield, or an AsyncGenerator Await. This ensures appropriate registers are stored. - Add versions of ResumeGeneratorTrampoline which store the input value in a different field depending on wether it's an AsyncGenerator Await resume, or an ordinary resume. Also modifies whether debug code will assert that the generator object is a JSGeneratorObject or a JSAsyncGeneratorObject depending on the resume type. BUG=v8:5855 R=bmeurer@chromium.org, rmcilroy@chromium.org, jgruber@chromium.org, littledan@chromium.org, neis@chromium.org TBR=marja@chromium.org Change-Id: I9d58df1d344465fc937fe7eed322424204497187 Reviewed-on: https://chromium-review.googlesource.com/446961 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#44240}
2017-03-29 13:41:45 +00:00
/* AsyncGenerator.prototype.return ( value ) */ \
/* proposal-async-iteration/#sec-asyncgenerator-prototype-return */ \
TFJ(AsyncGeneratorPrototypeReturn, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
[async-iteration] implement AsyncGenerator - Introduce new struct AsyncGeneratorRequest, which holds information pertinent to resuming execution of an AsyncGenerator, such as the Promise associated with the async generator request. It is intended to be used as a singly linked list, and holds a pointer to the next item in te queue. - Introduce JSAsyncGeneratorObject (subclass of JSGeneratorObject), which includes several new internal fields (`queue` which contains a singly linked list of AsyncGeneratorRequest objects, and `await_input` which contains the sent value from an Await expression (This is necessary to prevent function.sent (used by yield*) from having the sent value observably overwritten during execution). - Modify SuspendGenerator to accept a set of Flags, which indicate whether the suspend is for a Yield or Await, and whether it takes place on an async generator or ES6 generator. - Introduce interpreter intrinsics and TF intrinsic lowering for accessing the await input of an async generator - Modify the JSGeneratorStore operator to understand whether or not it's suspending for a normal yield, or an AsyncGenerator Await. This ensures appropriate registers are stored. - Add versions of ResumeGeneratorTrampoline which store the input value in a different field depending on wether it's an AsyncGenerator Await resume, or an ordinary resume. Also modifies whether debug code will assert that the generator object is a JSGeneratorObject or a JSAsyncGeneratorObject depending on the resume type. BUG=v8:5855 R=bmeurer@chromium.org, rmcilroy@chromium.org, jgruber@chromium.org, littledan@chromium.org, neis@chromium.org TBR=marja@chromium.org Change-Id: I9d58df1d344465fc937fe7eed322424204497187 Reviewed-on: https://chromium-review.googlesource.com/446961 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#44240}
2017-03-29 13:41:45 +00:00
/* AsyncGenerator.prototype.throw ( exception ) */ \
/* proposal-async-iteration/#sec-asyncgenerator-prototype-throw */ \
TFJ(AsyncGeneratorPrototypeThrow, \
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
[async-iteration] implement AsyncGenerator - Introduce new struct AsyncGeneratorRequest, which holds information pertinent to resuming execution of an AsyncGenerator, such as the Promise associated with the async generator request. It is intended to be used as a singly linked list, and holds a pointer to the next item in te queue. - Introduce JSAsyncGeneratorObject (subclass of JSGeneratorObject), which includes several new internal fields (`queue` which contains a singly linked list of AsyncGeneratorRequest objects, and `await_input` which contains the sent value from an Await expression (This is necessary to prevent function.sent (used by yield*) from having the sent value observably overwritten during execution). - Modify SuspendGenerator to accept a set of Flags, which indicate whether the suspend is for a Yield or Await, and whether it takes place on an async generator or ES6 generator. - Introduce interpreter intrinsics and TF intrinsic lowering for accessing the await input of an async generator - Modify the JSGeneratorStore operator to understand whether or not it's suspending for a normal yield, or an AsyncGenerator Await. This ensures appropriate registers are stored. - Add versions of ResumeGeneratorTrampoline which store the input value in a different field depending on wether it's an AsyncGenerator Await resume, or an ordinary resume. Also modifies whether debug code will assert that the generator object is a JSGeneratorObject or a JSAsyncGeneratorObject depending on the resume type. BUG=v8:5855 R=bmeurer@chromium.org, rmcilroy@chromium.org, jgruber@chromium.org, littledan@chromium.org, neis@chromium.org TBR=marja@chromium.org Change-Id: I9d58df1d344465fc937fe7eed322424204497187 Reviewed-on: https://chromium-review.googlesource.com/446961 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#44240}
2017-03-29 13:41:45 +00:00
\
/* Await (proposal-async-iteration/#await), with resume behaviour */ \
/* specific to Async Generators. Internal / Not exposed to JS code. */ \
TFJ(AsyncGeneratorAwaitCaught, 2, kGenerator, kAwaited) \
TFJ(AsyncGeneratorAwaitUncaught, 2, kGenerator, kAwaited) \
[async-iteration] implement AsyncGenerator - Introduce new struct AsyncGeneratorRequest, which holds information pertinent to resuming execution of an AsyncGenerator, such as the Promise associated with the async generator request. It is intended to be used as a singly linked list, and holds a pointer to the next item in te queue. - Introduce JSAsyncGeneratorObject (subclass of JSGeneratorObject), which includes several new internal fields (`queue` which contains a singly linked list of AsyncGeneratorRequest objects, and `await_input` which contains the sent value from an Await expression (This is necessary to prevent function.sent (used by yield*) from having the sent value observably overwritten during execution). - Modify SuspendGenerator to accept a set of Flags, which indicate whether the suspend is for a Yield or Await, and whether it takes place on an async generator or ES6 generator. - Introduce interpreter intrinsics and TF intrinsic lowering for accessing the await input of an async generator - Modify the JSGeneratorStore operator to understand whether or not it's suspending for a normal yield, or an AsyncGenerator Await. This ensures appropriate registers are stored. - Add versions of ResumeGeneratorTrampoline which store the input value in a different field depending on wether it's an AsyncGenerator Await resume, or an ordinary resume. Also modifies whether debug code will assert that the generator object is a JSGeneratorObject or a JSAsyncGeneratorObject depending on the resume type. BUG=v8:5855 R=bmeurer@chromium.org, rmcilroy@chromium.org, jgruber@chromium.org, littledan@chromium.org, neis@chromium.org TBR=marja@chromium.org Change-Id: I9d58df1d344465fc937fe7eed322424204497187 Reviewed-on: https://chromium-review.googlesource.com/446961 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#44240}
2017-03-29 13:41:45 +00:00
TFJ(AsyncGeneratorAwaitResolveClosure, 1, kValue) \
TFJ(AsyncGeneratorAwaitRejectClosure, 1, kValue) \
TFJ(AsyncGeneratorYieldResolveClosure, 1, kValue) \
TFJ(AsyncGeneratorReturnClosedResolveClosure, 1, kValue) \
TFJ(AsyncGeneratorReturnClosedRejectClosure, 1, kValue) \
TFJ(AsyncGeneratorReturnResolveClosure, 1, kValue) \
[async-iteration] implement AsyncGenerator - Introduce new struct AsyncGeneratorRequest, which holds information pertinent to resuming execution of an AsyncGenerator, such as the Promise associated with the async generator request. It is intended to be used as a singly linked list, and holds a pointer to the next item in te queue. - Introduce JSAsyncGeneratorObject (subclass of JSGeneratorObject), which includes several new internal fields (`queue` which contains a singly linked list of AsyncGeneratorRequest objects, and `await_input` which contains the sent value from an Await expression (This is necessary to prevent function.sent (used by yield*) from having the sent value observably overwritten during execution). - Modify SuspendGenerator to accept a set of Flags, which indicate whether the suspend is for a Yield or Await, and whether it takes place on an async generator or ES6 generator. - Introduce interpreter intrinsics and TF intrinsic lowering for accessing the await input of an async generator - Modify the JSGeneratorStore operator to understand whether or not it's suspending for a normal yield, or an AsyncGenerator Await. This ensures appropriate registers are stored. - Add versions of ResumeGeneratorTrampoline which store the input value in a different field depending on wether it's an AsyncGenerator Await resume, or an ordinary resume. Also modifies whether debug code will assert that the generator object is a JSGeneratorObject or a JSAsyncGeneratorObject depending on the resume type. BUG=v8:5855 R=bmeurer@chromium.org, rmcilroy@chromium.org, jgruber@chromium.org, littledan@chromium.org, neis@chromium.org TBR=marja@chromium.org Change-Id: I9d58df1d344465fc937fe7eed322424204497187 Reviewed-on: https://chromium-review.googlesource.com/446961 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#44240}
2017-03-29 13:41:45 +00:00
\
/* Async-from-Sync Iterator */ \
\
/* %AsyncFromSyncIteratorPrototype% */ \
/* See tc39.github.io/proposal-async-iteration/ */ \
/* #sec-%asyncfromsynciteratorprototype%-object) */ \
TFJ(AsyncFromSyncIteratorPrototypeNext, 1, kValue) \
/* #sec-%asyncfromsynciteratorprototype%.throw */ \
TFJ(AsyncFromSyncIteratorPrototypeThrow, 1, kReason) \
/* #sec-%asyncfromsynciteratorprototype%.return */ \
TFJ(AsyncFromSyncIteratorPrototypeReturn, 1, kValue) \
/* #sec-async-iterator-value-unwrap-functions */ \
TFJ(AsyncIteratorValueUnwrap, 1, kValue)
#ifdef V8_INTL_SUPPORT
#define BUILTIN_LIST(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
BUILTIN_LIST_BASE(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
\
TFS(StringToLowerCaseIntl, kString) \
/* ES #sec-string.prototype.tolowercase */ \
TFJ(StringPrototypeToLowerCaseIntl, 0) \
/* ES #sec-string.prototype.touppercase */ \
CPP(StringPrototypeToUpperCaseIntl) \
/* ES #sec-string.prototype.normalize */ \
CPP(StringPrototypeNormalizeIntl) \
/* ecma402 #sec-intl.numberformat.prototype.formattoparts */ \
CPP(NumberFormatPrototypeFormatToParts)
#else
#define BUILTIN_LIST(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
BUILTIN_LIST_BASE(CPP, API, TFJ, TFC, TFS, TFH, ASM) \
\
/* no-op fallback version */ \
CPP(StringPrototypeNormalize) \
/* same as toLowercase; fallback version */ \
CPP(StringPrototypeToLocaleLowerCase) \
/* same as toUppercase; fallback version */ \
CPP(StringPrototypeToLocaleUpperCase) \
/* (obsolete) Unibrow version */ \
CPP(StringPrototypeToLowerCase) \
/* (obsolete) Unibrow version */ \
CPP(StringPrototypeToUpperCase)
#endif // V8_INTL_SUPPORT
// The exception thrown in the following builtins are caught
// internally and result in a promise rejection.
#define BUILTIN_PROMISE_REJECTION_PREDICTION_LIST(V) \
V(AsyncFromSyncIteratorPrototypeNext) \
V(AsyncFromSyncIteratorPrototypeReturn) \
V(AsyncFromSyncIteratorPrototypeThrow) \
V(AsyncFunctionAwaitCaught) \
V(AsyncFunctionAwaitUncaught) \
[async-iteration] implement AsyncGenerator - Introduce new struct AsyncGeneratorRequest, which holds information pertinent to resuming execution of an AsyncGenerator, such as the Promise associated with the async generator request. It is intended to be used as a singly linked list, and holds a pointer to the next item in te queue. - Introduce JSAsyncGeneratorObject (subclass of JSGeneratorObject), which includes several new internal fields (`queue` which contains a singly linked list of AsyncGeneratorRequest objects, and `await_input` which contains the sent value from an Await expression (This is necessary to prevent function.sent (used by yield*) from having the sent value observably overwritten during execution). - Modify SuspendGenerator to accept a set of Flags, which indicate whether the suspend is for a Yield or Await, and whether it takes place on an async generator or ES6 generator. - Introduce interpreter intrinsics and TF intrinsic lowering for accessing the await input of an async generator - Modify the JSGeneratorStore operator to understand whether or not it's suspending for a normal yield, or an AsyncGenerator Await. This ensures appropriate registers are stored. - Add versions of ResumeGeneratorTrampoline which store the input value in a different field depending on wether it's an AsyncGenerator Await resume, or an ordinary resume. Also modifies whether debug code will assert that the generator object is a JSGeneratorObject or a JSAsyncGeneratorObject depending on the resume type. BUG=v8:5855 R=bmeurer@chromium.org, rmcilroy@chromium.org, jgruber@chromium.org, littledan@chromium.org, neis@chromium.org TBR=marja@chromium.org Change-Id: I9d58df1d344465fc937fe7eed322424204497187 Reviewed-on: https://chromium-review.googlesource.com/446961 Commit-Queue: Caitlin Potter <caitp@igalia.com> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Hannes Payer <hpayer@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#44240}
2017-03-29 13:41:45 +00:00
V(AsyncGeneratorResolve) \
V(AsyncGeneratorAwaitCaught) \
V(AsyncGeneratorAwaitUncaught) \
V(PerformNativePromiseThen) \
V(PromiseAll) \
V(PromiseConstructor) \
V(PromiseHandle) \
V(PromiseRace) \
V(PromiseResolve) \
V(PromiseResolveClosure) \
V(RejectNativePromise) \
V(ResolveNativePromise) \
V(ResolvePromise)
// The exception thrown in the following builtins are caught internally and will
// not be propagated further or re-thrown
#define BUILTIN_EXCEPTION_CAUGHT_PREDICTION_LIST(V) V(PromiseHandleReject)
#define IGNORE_BUILTIN(...)
#define BUILTIN_LIST_ALL(V) BUILTIN_LIST(V, V, V, V, V, V, V)
#define BUILTIN_LIST_C(V) \
BUILTIN_LIST(V, V, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \
IGNORE_BUILTIN, IGNORE_BUILTIN)
#define BUILTIN_LIST_A(V) \
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \
IGNORE_BUILTIN, IGNORE_BUILTIN, V)
#define BUILTIN_LIST_TFS(V) \
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \
V, IGNORE_BUILTIN, IGNORE_BUILTIN)
#define BUILTIN_LIST_TFJ(V) \
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, V, IGNORE_BUILTIN, \
IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
#define BUILTIN_LIST_TFC(V) \
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, V, \
IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
#define BUILTINS_WITH_UNTAGGED_PARAMS(V) V(WasmCompileLazy)
} // namespace internal
} // namespace v8
#endif // V8_BUILTINS_BUILTINS_DEFINITIONS_H_