deps: V8: backport 7857eb34db42

Original commit message:

    Reland^2 "Add ContinuationPreservedEmbedderData builtins to extras binding"

    This reverts commit cb1277e97a0ed32fd893be9f4e927f6e8b6c566c.

    > Original change's description:
    > > Add ContinuationPreservedEmbedderData builtins to extras binding
    > >
    > > Node.js and Deno wish to use CPED for AsyncLocalStorage and APM, which
    > > needs a high performance implementation. These builtins allow JavaScript
    > > to handle CPED performantly.
    > >
    > > Change-Id: I7577be80818524baa52791dfce57d442d7c0c933
    > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5638129
    > > Commit-Queue: snek <snek@chromium.org>
    > > Reviewed-by: Darius Mercadier <dmercadier@chromium.org>
    > > Reviewed-by: Leszek Swirski <leszeks@chromium.org>
    > > Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
    > > Cr-Commit-Position: refs/heads/main@{#94607}
    >
    > Change-Id: Ief390f0b99891c8de83b4c794180440f91cbaf1f
    > No-Presubmit: true
    > No-Tree-Checks: true
    > No-Try: true
    > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5649024
    > Auto-Submit: Shu-yu Guo <syg@chromium.org>
    > Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
    > Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
    > Cr-Commit-Position: refs/heads/main@{#94608}

    Change-Id: I4943071ffe192084e83bfe3113cfe9c92ef31465
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5677045
    Reviewed-by: Darius Mercadier <dmercadier@chromium.org>
    Reviewed-by: Leszek Swirski <leszeks@chromium.org>
    Commit-Queue: snek <snek@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#94866}

Refs: v8/v8@7857eb3
PR-URL: https://github.com/nodejs/node/pull/53997
Refs: 7857eb34db
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
This commit is contained in:
Stephen Belanger 2024-07-26 07:35:44 -07:00 committed by GitHub
parent 9272f02b4f
commit 5e533710c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 626 additions and 62 deletions

View File

@ -1313,7 +1313,6 @@ extern macro ChangeUint32ToWord(uint32): uintptr; // Doesn't sign-extend.
extern macro ChangeInt32ToInt64(int32): int64; // Sign-extends.
extern macro ChangeUint32ToUint64(uint32): uint64; // Doesn't sign-extend.
extern macro LoadNativeContext(Context): NativeContext;
extern macro GetContinuationPreservedEmbedderData(): Object;
extern macro TruncateFloat64ToFloat16(float64): float16;
extern macro TruncateFloat32ToFloat16(float32): float16;
extern macro TruncateFloat64ToFloat32(float64): float32;

View File

@ -30,6 +30,11 @@ extern macro PromiseBuiltinsAssembler::IsIsolatePromiseHookEnabled(uint32):
extern macro PromiseBuiltinsAssembler::PromiseHookFlags(): uint32;
namespace macros {
extern macro GetContinuationPreservedEmbedderData(): Object;
extern macro SetContinuationPreservedEmbedderData(Object): void;
}
namespace promise {
extern macro IsFunctionWithPrototypeSlotMap(Map): bool;
@ -80,7 +85,7 @@ macro NewPromiseFulfillReactionJobTask(
return new PromiseFulfillReactionJobTask{
map: PromiseFulfillReactionJobTaskMapConstant(),
continuation_preserved_embedder_data:
GetContinuationPreservedEmbedderData(),
macros::GetContinuationPreservedEmbedderData(),
argument,
context: handlerContext,
handler,
@ -108,7 +113,7 @@ macro NewPromiseRejectReactionJobTask(
return new PromiseRejectReactionJobTask{
map: PromiseRejectReactionJobTaskMapConstant(),
continuation_preserved_embedder_data:
GetContinuationPreservedEmbedderData(),
macros::GetContinuationPreservedEmbedderData(),
argument,
context: handlerContext,
handler,
@ -303,7 +308,7 @@ macro NewPromiseReaction(
return new PromiseReaction{
map: PromiseReactionMapConstant(),
continuation_preserved_embedder_data:
GetContinuationPreservedEmbedderData(),
macros::GetContinuationPreservedEmbedderData(),
next: next,
reject_handler: rejectHandler,
fulfill_handler: fulfillHandler,
@ -347,7 +352,7 @@ macro NewPromiseResolveThenableJobTask(
return new PromiseResolveThenableJobTask{
map: PromiseResolveThenableJobTaskMapConstant(),
continuation_preserved_embedder_data:
GetContinuationPreservedEmbedderData(),
macros::GetContinuationPreservedEmbedderData(),
context: nativeContext,
promise_to_resolve: promiseToResolve,
thenable,
@ -452,4 +457,18 @@ transitioning macro BranchIfAccessCheckFailed(
}
} label HasAccess {}
}
@if(V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA)
transitioning javascript builtin GetContinuationPreservedEmbedderData(
js-implicit context: Context, receiver: JSAny)(): JSAny {
return UnsafeCast<JSAny>(macros::GetContinuationPreservedEmbedderData());
}
@if(V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA)
transitioning javascript builtin SetContinuationPreservedEmbedderData(
js-implicit context: Context, receiver: JSAny)(data: Object): Undefined {
macros::SetContinuationPreservedEmbedderData(data);
return Undefined;
}
}

View File

@ -5108,6 +5108,12 @@ Reduction JSCallReducer::ReduceJSCall(Node* node,
case Builtin::kBigIntAsIntN:
case Builtin::kBigIntAsUintN:
return ReduceBigIntAsN(node, builtin);
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
case Builtin::kGetContinuationPreservedEmbedderData:
return ReduceGetContinuationPreservedEmbedderData(node);
case Builtin::kSetContinuationPreservedEmbedderData:
return ReduceSetContinuationPreservedEmbedderData(node);
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
default:
break;
}
@ -8780,6 +8786,39 @@ Reduction JSCallReducer::ReduceJSCallMathMinMaxWithArrayLike(Node* node,
return ReplaceWithSubgraph(&a, subgraph);
}
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
Reduction JSCallReducer::ReduceGetContinuationPreservedEmbedderData(
Node* node) {
JSCallNode n(node);
Effect effect = n.effect();
Control control = n.control();
Node* value = effect = graph()->NewNode(
simplified()->GetContinuationPreservedEmbedderData(), effect);
ReplaceWithValue(node, value, effect, control);
return Replace(node);
}
Reduction JSCallReducer::ReduceSetContinuationPreservedEmbedderData(
Node* node) {
JSCallNode n(node);
Effect effect = n.effect();
Control control = n.control();
if (n.ArgumentCount() == 0) return NoChange();
effect =
graph()->NewNode(simplified()->SetContinuationPreservedEmbedderData(),
n.Argument(0), effect);
Node* value = jsgraph()->UndefinedConstant();
ReplaceWithValue(node, value, effect, control);
return Replace(node);
}
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
CompilationDependencies* JSCallReducer::dependencies() const {
return broker()->dependencies();
}

View File

@ -239,6 +239,11 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
base::Optional<Reduction> TryReduceJSCallMathMinMaxWithArrayLike(Node* node);
Reduction ReduceJSCallMathMinMaxWithArrayLike(Node* node, Builtin builtin);
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
Reduction ReduceGetContinuationPreservedEmbedderData(Node* node);
Reduction ReduceSetContinuationPreservedEmbedderData(Node* node);
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
// The pendant to ReplaceWithValue when using GraphAssembler-based reductions.
Reduction ReplaceWithSubgraph(JSCallReducerAssembler* gasm, Node* subgraph);
std::pair<Node*, Node*> ReleaseEffectAndControlFromAssembler(

View File

@ -429,6 +429,14 @@
#define SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(V) V(SpeculativeToNumber)
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
#define SIMPLIFIED_CPED_OP_LIST(V) \
V(GetContinuationPreservedEmbedderData) \
V(SetContinuationPreservedEmbedderData)
#else
#define SIMPLIFIED_CPED_OP_LIST(V)
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
#define SIMPLIFIED_OTHER_OP_LIST(V) \
V(Allocate) \
V(AllocateRaw) \
@ -534,7 +542,8 @@
V(TransitionElementsKind) \
V(TypeOf) \
V(Unsigned32Divide) \
V(VerifyType)
V(VerifyType) \
SIMPLIFIED_CPED_OP_LIST(V)
#define SIMPLIFIED_SPECULATIVE_BIGINT_BINOP_LIST(V) \
V(SpeculativeBigIntAdd) \

View File

@ -4635,6 +4635,17 @@ class RepresentationSelector {
SetOutput<T>(node, LoadRepresentationOf(node->op()).representation());
return;
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
case IrOpcode::kGetContinuationPreservedEmbedderData:
SetOutput<T>(node, MachineRepresentation::kTagged);
return;
case IrOpcode::kSetContinuationPreservedEmbedderData:
ProcessInput<T>(node, 0, UseInfo::AnyTagged());
SetOutput<T>(node, MachineRepresentation::kNone);
return;
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
default:
FATAL(
"Representation inference: unsupported opcode %i (%s), node #%i\n.",

View File

@ -1339,6 +1339,26 @@ struct SimplifiedOperatorGlobalCache final {
kSpeculativeToBigIntBigInt64Operator;
SpeculativeToBigIntOperator<BigIntOperationHint::kBigInt>
kSpeculativeToBigIntBigIntOperator;
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
struct GetContinuationPreservedEmbedderDataOperator : public Operator {
GetContinuationPreservedEmbedderDataOperator()
: Operator(IrOpcode::kGetContinuationPreservedEmbedderData,
Operator::kNoThrow | Operator::kNoDeopt | Operator::kNoWrite,
"GetContinuationPreservedEmbedderData", 0, 1, 0, 1, 1, 0) {}
};
GetContinuationPreservedEmbedderDataOperator
kGetContinuationPreservedEmbedderData;
struct SetContinuationPreservedEmbedderDataOperator : public Operator {
SetContinuationPreservedEmbedderDataOperator()
: Operator(IrOpcode::kSetContinuationPreservedEmbedderData,
Operator::kNoThrow | Operator::kNoDeopt | Operator::kNoRead,
"SetContinuationPreservedEmbedderData", 1, 1, 0, 0, 1, 0) {}
};
SetContinuationPreservedEmbedderDataOperator
kSetContinuationPreservedEmbedderData;
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
};
namespace {
@ -2198,6 +2218,18 @@ const Operator* SimplifiedOperatorBuilder::StoreField(
2, 1, 1, 0, 1, 0, store_access);
}
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
const Operator*
SimplifiedOperatorBuilder::GetContinuationPreservedEmbedderData() {
return &cache_.kGetContinuationPreservedEmbedderData;
}
const Operator*
SimplifiedOperatorBuilder::SetContinuationPreservedEmbedderData() {
return &cache_.kSetContinuationPreservedEmbedderData;
}
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
const Operator* SimplifiedOperatorBuilder::LoadMessage() {
return zone()->New<Operator>(IrOpcode::kLoadMessage, Operator::kEliminatable,
"LoadMessage", 1, 1, 1, 1, 1, 0);

View File

@ -1218,6 +1218,11 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const FastApiCallFunctionVector& c_candidate_functions,
FeedbackSource const& feedback, CallDescriptor* descriptor);
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
const Operator* GetContinuationPreservedEmbedderData();
const Operator* SetContinuationPreservedEmbedderData();
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
private:
Zone* zone() const { return zone_; }

View File

@ -3855,6 +3855,16 @@ class TurboshaftAssemblerOpInterface
}
#endif // V8_ENABLE_WEBASSEMBLY
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
V<Object> GetContinuationPreservedEmbedderData() {
return ReduceIfReachableGetContinuationPreservedEmbedderData();
}
void SetContinuationPreservedEmbedderData(V<Object> data) {
ReduceIfReachableSetContinuationPreservedEmbedderData(data);
}
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
template <typename Rep>
V<Rep> resolve(const V<Rep>& v) {
return v;

View File

@ -2263,6 +2263,14 @@ OpIndex GraphBuilder::Process(
return OpIndex::Invalid();
}
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
case IrOpcode::kGetContinuationPreservedEmbedderData:
return __ GetContinuationPreservedEmbedderData();
case IrOpcode::kSetContinuationPreservedEmbedderData:
__ SetContinuationPreservedEmbedderData(Map(node->InputAt(0)));
return OpIndex::Invalid();
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
default:
std::cerr << "unsupported node type: " << *node->op() << "\n";
node->Print(std::cerr);

View File

@ -3164,6 +3164,25 @@ class MachineLoweringReducer : public Next {
}
}
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
V<Object> REDUCE(GetContinuationPreservedEmbedderData)() {
return __ Load(
__ ExternalConstant(
ExternalReference::continuation_preserved_embedder_data(isolate_)),
LoadOp::Kind::RawAligned(), MemoryRepresentation::TaggedPointer());
}
OpIndex REDUCE(SetContinuationPreservedEmbedderData)(V<Object> data) {
__ Store(
__ ExternalConstant(
ExternalReference::continuation_preserved_embedder_data(isolate_)),
data, StoreOp::Kind::RawAligned(),
MemoryRepresentation::TaggedPointer(),
WriteBarrierKind::kNoWriteBarrier);
return OpIndex::Invalid();
}
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
private:
V<Word32> BuildUint32Mod(V<Word32> left, V<Word32> right) {
Label<Word32> done(this);

View File

@ -994,6 +994,24 @@ class GraphBuilder {
return maglev::ProcessResult::kContinue;
}
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
maglev::ProcessResult Process(
maglev::GetContinuationPreservedEmbedderData* node,
const maglev::ProcessingState&) {
V<Object> data = __ GetContinuationPreservedEmbedderData();
SetMap(node, data);
return maglev::ProcessResult::kContinue;
}
maglev::ProcessResult Process(
maglev::SetContinuationPreservedEmbedderData* node,
const maglev::ProcessingState&) {
V<Object> data = Map(node->input(0));
__ SetContinuationPreservedEmbedderData(data);
return maglev::ProcessResult::kContinue;
}
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
template <typename NodeT>
maglev::ProcessResult Process(NodeT* node,
const maglev::ProcessingState& state) {

View File

@ -175,10 +175,19 @@ using Variable = SnapshotTable<OpIndex, VariableData>::Key;
V(Switch) \
V(Deoptimize)
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
#define TURBOSHAFT_CPED_OPERATION_LIST(V) \
V(GetContinuationPreservedEmbedderData) \
V(SetContinuationPreservedEmbedderData)
#else
#define TURBOSHAFT_CPED_OPERATION_LIST(V)
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
// These operations should be lowered to Machine operations during
// MachineLoweringPhase.
#define TURBOSHAFT_SIMPLIFIED_OPERATION_LIST(V) \
TURBOSHAFT_INTL_OPERATION_LIST(V) \
TURBOSHAFT_CPED_OPERATION_LIST(V) \
V(ArgumentsLength) \
V(BigIntBinop) \
V(BigIntComparison) \
@ -8115,6 +8124,47 @@ struct SetStackPointerOp : FixedArityOperationT<1, SetStackPointerOp> {
#endif // V8_ENABLE_WEBASSEMBLY
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
struct GetContinuationPreservedEmbedderDataOp
: FixedArityOperationT<0, GetContinuationPreservedEmbedderDataOp> {
static constexpr OpEffects effects = OpEffects().CanReadOffHeapMemory();
base::Vector<const RegisterRepresentation> outputs_rep() const {
return RepVector<RegisterRepresentation::Tagged()>();
}
base::Vector<const MaybeRegisterRepresentation> inputs_rep(
ZoneVector<MaybeRegisterRepresentation>& storage) const {
return {};
}
GetContinuationPreservedEmbedderDataOp() : Base() {}
void Validate(const Graph& graph) const {}
auto options() const { return std::tuple{}; }
};
struct SetContinuationPreservedEmbedderDataOp
: FixedArityOperationT<1, SetContinuationPreservedEmbedderDataOp> {
static constexpr OpEffects effects = OpEffects().CanWriteOffHeapMemory();
base::Vector<const RegisterRepresentation> outputs_rep() const { return {}; }
base::Vector<const MaybeRegisterRepresentation> inputs_rep(
ZoneVector<MaybeRegisterRepresentation>& storage) const {
return MaybeRepVector<MaybeRegisterRepresentation::Tagged()>();
}
explicit SetContinuationPreservedEmbedderDataOp(V<Object> value)
: Base(value) {}
void Validate(const Graph& graph) const {}
auto options() const { return std::tuple{}; }
};
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
#define OPERATION_EFFECTS_CASE(Name) Name##Op::EffectsIfStatic(),
static constexpr base::Optional<OpEffects>
kOperationEffectsTable[kNumberOfOpcodes] = {

View File

@ -1192,6 +1192,16 @@ Type Typer::Visitor::TypeCall(Node* node) { return Type::Any(); }
Type Typer::Visitor::TypeFastApiCall(Node* node) { return Type::Any(); }
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
Type Typer::Visitor::TypeGetContinuationPreservedEmbedderData(Node* node) {
return Type::Any();
}
Type Typer::Visitor::TypeSetContinuationPreservedEmbedderData(Node* node) {
UNREACHABLE();
}
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
#if V8_ENABLE_WEBASSEMBLY
Type Typer::Visitor::TypeJSWasmCall(Node* node) {
const JSWasmCallParameters& op_params = JSWasmCallParametersOf(node->op());

View File

@ -1707,6 +1707,19 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
CHECK_GE(value_count, 1);
CheckValueInputIs(node, 0, Type::Any()); // receiver
break;
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
case IrOpcode::kGetContinuationPreservedEmbedderData:
CHECK_EQ(value_count, 0);
CHECK_EQ(effect_count, 1);
CheckTypeIs(node, Type::Any());
break;
case IrOpcode::kSetContinuationPreservedEmbedderData:
CHECK_EQ(value_count, 1);
CHECK_EQ(effect_count, 1);
CheckValueInputIs(node, 0, Type::Any());
CheckNotTyped(node);
break;
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
case IrOpcode::kSLVerifierHint:
// SLVerifierHint is internal to SimplifiedLowering and should never be
// seen by the verifier.

21
deps/v8/src/d8/d8.cc vendored
View File

@ -2733,6 +2733,20 @@ void Shell::SetTimeout(const v8::FunctionCallbackInfo<v8::Value>& info) {
PerIsolateData::Get(isolate)->SetTimeout(callback, context);
}
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
void Shell::GetContinuationPreservedEmbedderData(
const v8::FunctionCallbackInfo<v8::Value>& info) {
info.GetReturnValue().Set(
info.GetIsolate()->GetContinuationPreservedEmbedderData());
}
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
void Shell::GetExtrasBindingObject(
const v8::FunctionCallbackInfo<v8::Value>& info) {
Local<Context> context = info.GetIsolate()->GetCurrentContext();
info.GetReturnValue().Set(context->GetExtrasBindingObject());
}
void Shell::ReadCodeTypeAndArguments(
const v8::FunctionCallbackInfo<v8::Value>& info, int index,
CodeType* code_type, Local<Value>* arguments) {
@ -3547,8 +3561,15 @@ Local<ObjectTemplate> Shell::CreateD8Template(Isolate* isolate) {
FunctionTemplate::New(isolate, ProfilerTriggerSample));
d8_template->Set(isolate, "profiler", profiler_template);
}
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
d8_template->Set(
isolate, "getContinuationPreservedEmbedderDataViaAPIForTesting",
FunctionTemplate::New(isolate, GetContinuationPreservedEmbedderData));
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
d8_template->Set(isolate, "terminate",
FunctionTemplate::New(isolate, Terminate));
d8_template->Set(isolate, "getExtrasBindingObject",
FunctionTemplate::New(isolate, GetExtrasBindingObject));
if (!options.omit_quit) {
d8_template->Set(isolate, "quit", FunctionTemplate::New(isolate, Quit));
}

9
deps/v8/src/d8/d8.h vendored
View File

@ -665,6 +665,15 @@ class Shell : public i::AllStatic {
// the "mkdir -p" command.
static void MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& info);
static void RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& info);
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
static void GetContinuationPreservedEmbedderData(
const v8::FunctionCallbackInfo<v8::Value>& info);
#endif // V8_ENABLE_CONTINUATION_PRESERVER_EMBEDDER_DATA
static void GetExtrasBindingObject(
const v8::FunctionCallbackInfo<v8::Value>& info);
static MaybeLocal<Promise> HostImportModuleDynamically(
Local<Context> context, Local<Data> host_defined_options,
Local<Value> resource_name, Local<String> specifier,

View File

@ -866,6 +866,9 @@ DebugInfo::SideEffectState BuiltinGetSideEffectState(Builtin id) {
case Builtin::kConstructWithArrayLike:
case Builtin::kGetOwnPropertyDescriptor:
case Builtin::kOrdinaryGetOwnPropertyDescriptor:
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
case Builtin::kGetContinuationPreservedEmbedderData:
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
return DebugInfo::kHasNoSideEffect;
#ifdef V8_INTL_SUPPORT

View File

@ -6383,6 +6383,18 @@ bool Genesis::InstallExtrasBindings() {
SimpleInstallFunction(isolate(), extras_binding, "trace", Builtin::kTrace, 5,
true);
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
// binding.getContinuationPreservedEmbedderData()
SimpleInstallFunction(
isolate(), extras_binding, "getContinuationPreservedEmbedderData",
Builtin::kGetContinuationPreservedEmbedderData, 0, true);
// binding.setContinuationPreservedEmbedderData(value)
SimpleInstallFunction(
isolate(), extras_binding, "setContinuationPreservedEmbedderData",
Builtin::kSetContinuationPreservedEmbedderData, 1, true);
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
InitializeConsole(extras_binding);
native_context()->set_extras_binding_object(*extras_binding);

View File

@ -6525,6 +6525,21 @@ ReduceResult MaglevGraphBuilder::TryReduceStringPrototypeLocaleCompare(
#endif
}
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
ReduceResult MaglevGraphBuilder::TryReduceGetContinuationPreservedEmbedderData(
compiler::JSFunctionRef target, CallArguments& args) {
return AddNewNode<GetContinuationPreservedEmbedderData>({});
}
ReduceResult MaglevGraphBuilder::TryReduceSetContinuationPreservedEmbedderData(
compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() == 0) return ReduceResult::Fail();
AddNewNode<SetContinuationPreservedEmbedderData>({GetTaggedValue(args[0])});
return GetRootConstant(RootIndex::kUndefinedValue);
}
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
template <typename LoadNode>
ReduceResult MaglevGraphBuilder::TryBuildLoadDataView(const CallArguments& args,
ExternalArrayType type) {

View File

@ -1690,31 +1690,40 @@ class MaglevGraphBuilder {
ExternalArrayType type,
Function&& getValue);
#define MAGLEV_REDUCED_BUILTIN(V) \
V(ArrayForEach) \
V(ArrayIsArray) \
V(DataViewPrototypeGetInt8) \
V(DataViewPrototypeSetInt8) \
V(DataViewPrototypeGetInt16) \
V(DataViewPrototypeSetInt16) \
V(DataViewPrototypeGetInt32) \
V(DataViewPrototypeSetInt32) \
V(DataViewPrototypeGetFloat64) \
V(DataViewPrototypeSetFloat64) \
V(FunctionPrototypeCall) \
V(FunctionPrototypeHasInstance) \
V(ObjectPrototypeHasOwnProperty) \
V(MathCeil) \
V(MathFloor) \
V(MathPow) \
V(ArrayPrototypePush) \
V(ArrayPrototypePop) \
V(MathRound) \
V(StringConstructor) \
V(StringFromCharCode) \
V(StringPrototypeCharCodeAt) \
V(StringPrototypeCodePointAt) \
V(StringPrototypeLocaleCompare) \
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
#define CONTINUATION_PRESERVED_EMBEDDER_DATA_LIST(V) \
V(GetContinuationPreservedEmbedderData) \
V(SetContinuationPreservedEmbedderData)
#else
#define CONTINUATION_PRESERVED_EMBEDDER_DATA_LIST(V)
#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
#define MAGLEV_REDUCED_BUILTIN(V) \
V(ArrayForEach) \
V(ArrayIsArray) \
V(DataViewPrototypeGetInt8) \
V(DataViewPrototypeSetInt8) \
V(DataViewPrototypeGetInt16) \
V(DataViewPrototypeSetInt16) \
V(DataViewPrototypeGetInt32) \
V(DataViewPrototypeSetInt32) \
V(DataViewPrototypeGetFloat64) \
V(DataViewPrototypeSetFloat64) \
V(FunctionPrototypeCall) \
V(FunctionPrototypeHasInstance) \
V(ObjectPrototypeHasOwnProperty) \
V(MathCeil) \
V(MathFloor) \
V(MathPow) \
V(ArrayPrototypePush) \
V(ArrayPrototypePop) \
V(MathRound) \
V(StringConstructor) \
V(StringFromCharCode) \
V(StringPrototypeCharCodeAt) \
V(StringPrototypeCodePointAt) \
V(StringPrototypeLocaleCompare) \
CONTINUATION_PRESERVED_EMBEDDER_DATA_LIST(V) \
IEEE_754_UNARY_LIST(V)
#define DEFINE_BUILTIN_REDUCER(Name, ...) \

View File

@ -5735,6 +5735,36 @@ void CheckTypedArrayNotDetached::GenerateCode(MaglevAssembler* masm,
__ DeoptIfBufferDetached(object, scratch, this);
}
void GetContinuationPreservedEmbedderData::SetValueLocationConstraints() {
DefineAsRegister(this);
}
void GetContinuationPreservedEmbedderData::GenerateCode(
MaglevAssembler* masm, const ProcessingState& state) {
Register result = ToRegister(this->result());
MaglevAssembler::ScratchRegisterScope temps(masm);
Register scratch = temps.GetDefaultScratchRegister();
MemOperand reference = __ ExternalReferenceAsOperand(
ExternalReference::continuation_preserved_embedder_data(masm->isolate()),
scratch);
__ Move(result, reference);
}
void SetContinuationPreservedEmbedderData::SetValueLocationConstraints() {
UseRegister(data_input());
}
void SetContinuationPreservedEmbedderData::GenerateCode(
MaglevAssembler* masm, const ProcessingState& state) {
Register data = ToRegister(data_input());
MaglevAssembler::ScratchRegisterScope temps(masm);
Register scratch = temps.GetDefaultScratchRegister();
MemOperand reference = __ ExternalReferenceAsOperand(
ExternalReference::continuation_preserved_embedder_data(masm->isolate()),
scratch);
__ Move(reference, data);
}
namespace {
template <typename ResultReg, typename NodeT>

View File

@ -261,6 +261,7 @@ class MergePointInterpreterFrameState;
V(ToString) \
V(NumberToString) \
V(UpdateJSArrayLength) \
V(GetContinuationPreservedEmbedderData) \
CONSTANT_VALUE_NODE_LIST(V) \
INT32_OPERATIONS_NODE_LIST(V) \
FLOAT64_OPERATIONS_NODE_LIST(V) \
@ -324,6 +325,7 @@ class MergePointInterpreterFrameState;
V(ThrowIfNotSuperConstructor) \
V(TransitionElementsKind) \
V(TransitionElementsKindOrCheckMap) \
V(SetContinuationPreservedEmbedderData) \
GAP_MOVE_NODE_LIST(V) \
VALUE_NODE_LIST(V)
@ -8729,6 +8731,42 @@ class TransitionElementsKindOrCheckMap
const compiler::MapRef transition_target_;
};
class GetContinuationPreservedEmbedderData
: public FixedInputValueNodeT<0, GetContinuationPreservedEmbedderData> {
using Base = FixedInputValueNodeT<0, GetContinuationPreservedEmbedderData>;
public:
explicit GetContinuationPreservedEmbedderData(uint64_t bitfield)
: Base(bitfield) {}
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
static constexpr OpProperties kProperties =
OpProperties::CanRead() | OpProperties::TaggedValue();
};
class SetContinuationPreservedEmbedderData
: public FixedInputNodeT<1, SetContinuationPreservedEmbedderData> {
using Base = FixedInputNodeT<1, SetContinuationPreservedEmbedderData>;
public:
explicit SetContinuationPreservedEmbedderData(uint64_t bitfield)
: Base(bitfield) {}
static constexpr
typename Base::InputTypes kInputTypes{ValueRepresentation::kTagged};
Input& data_input() { return input(0); }
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
static constexpr OpProperties kProperties = OpProperties::CanWrite();
};
class ControlNode : public NodeBase {
public:
// A "hole" in control flow is a control node that unconditionally interrupts

View File

@ -670,36 +670,6 @@ base::Optional<ParseResult> MakeTorqueMacroDeclaration(
return ParseResult{result};
}
base::Optional<ParseResult> MakeTorqueBuiltinDeclaration(
ParseResultIterator* child_results) {
const bool has_custom_interface_descriptor = HasAnnotation(
child_results, ANNOTATION_CUSTOM_INTERFACE_DESCRIPTOR, "builtin");
auto transitioning = child_results->NextAs<bool>();
auto javascript_linkage = child_results->NextAs<bool>();
auto name = child_results->NextAs<Identifier*>();
if (!IsUpperCamelCase(name->value)) {
NamingConventionError("Builtin", name, "UpperCamelCase");
}
auto generic_parameters = child_results->NextAs<GenericParameters>();
LintGenericParameters(generic_parameters);
auto args = child_results->NextAs<ParameterList>();
auto return_type = child_results->NextAs<TypeExpression*>();
auto body = child_results->NextAs<base::Optional<Statement*>>();
CallableDeclaration* declaration = MakeNode<TorqueBuiltinDeclaration>(
transitioning, javascript_linkage, name, args, return_type,
has_custom_interface_descriptor, body);
Declaration* result = declaration;
if (generic_parameters.empty()) {
if (!body) ReportError("A non-generic declaration needs a body.");
} else {
result =
MakeNode<GenericCallableDeclaration>(generic_parameters, declaration);
}
return ParseResult{result};
}
base::Optional<ParseResult> MakeConstDeclaration(
ParseResultIterator* child_results) {
auto name = child_results->NextAs<Identifier*>();
@ -961,6 +931,46 @@ int GetAnnotationValue(const AnnotationSet& annotations, const char* name,
return opt_value.has_value() ? *opt_value : default_value;
}
base::Optional<ParseResult> MakeTorqueBuiltinDeclaration(
ParseResultIterator* child_results) {
AnnotationSet annotations(
child_results, {ANNOTATION_CUSTOM_INTERFACE_DESCRIPTOR}, {ANNOTATION_IF});
const bool has_custom_interface_descriptor =
annotations.Contains(ANNOTATION_CUSTOM_INTERFACE_DESCRIPTOR);
auto transitioning = child_results->NextAs<bool>();
auto javascript_linkage = child_results->NextAs<bool>();
auto name = child_results->NextAs<Identifier*>();
if (!IsUpperCamelCase(name->value)) {
NamingConventionError("Builtin", name, "UpperCamelCase");
}
auto generic_parameters = child_results->NextAs<GenericParameters>();
LintGenericParameters(generic_parameters);
auto args = child_results->NextAs<ParameterList>();
auto return_type = child_results->NextAs<TypeExpression*>();
auto body = child_results->NextAs<base::Optional<Statement*>>();
CallableDeclaration* declaration = MakeNode<TorqueBuiltinDeclaration>(
transitioning, javascript_linkage, name, args, return_type,
has_custom_interface_descriptor, body);
Declaration* result = declaration;
if (generic_parameters.empty()) {
if (!body) ReportError("A non-generic declaration needs a body.");
} else {
result =
MakeNode<GenericCallableDeclaration>(generic_parameters, declaration);
}
std::vector<Declaration*> results;
if (base::Optional<std::string> condition =
annotations.GetStringParam(ANNOTATION_IF)) {
if (!BuildFlags::GetFlag(*condition, ANNOTATION_IF)) {
return ParseResult{std::move(results)};
}
}
results.push_back(result);
return ParseResult{std::move(results)};
}
InstanceTypeConstraints MakeInstanceTypeConstraints(
const AnnotationSet& annotations) {
InstanceTypeConstraints result;
@ -2863,7 +2873,7 @@ struct TorqueGrammar : Grammar {
CheckIf(Token("javascript")), Token("builtin"), &name,
TryOrDefault<GenericParameters>(&genericParameters),
&parameterListAllowVararg, &returnType, &optionalBody},
AsSingletonVector<Declaration*, MakeTorqueBuiltinDeclaration>()),
MakeTorqueBuiltinDeclaration),
Rule({CheckIf(Token("transitioning")), &name,
&genericSpecializationTypeList, &parameterListAllowVararg,
&returnType, optionalLabelList, &block},

85
deps/v8/test/mjsunit/extras-cped.js vendored Normal file
View File

@ -0,0 +1,85 @@
// Copyright 2024 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.
// Flags: --allow-natives-syntax
const {
getContinuationPreservedEmbedderData,
setContinuationPreservedEmbedderData,
} = d8.getExtrasBindingObject();
// Basic set and get
const foo = { bar: 'baz' };
setContinuationPreservedEmbedderData(foo);
assertEquals(foo, getContinuationPreservedEmbedderData());
// Captures at the point a continuation is created
{
// Resolve path
setContinuationPreservedEmbedderData('init');
let resolve;
const p = new Promise(r => {
resolve = r;
});
setContinuationPreservedEmbedderData('resolve');
resolve();
setContinuationPreservedEmbedderData('continuation-created');
p.then(deferredVerify('continuation-created'));
setContinuationPreservedEmbedderData('after');
%PerformMicrotaskCheckpoint();
}
{
// Reject path
setContinuationPreservedEmbedderData('init');
let reject;
const p = new Promise((_, r) => {
reject = r;
});
setContinuationPreservedEmbedderData('resolve');
reject();
setContinuationPreservedEmbedderData('continuation-created');
p.catch(deferredVerify('continuation-created'));
setContinuationPreservedEmbedderData('after');
%PerformMicrotaskCheckpoint();
}
// Should propagate through thenables
function thenable(expected) {
const verify = deferredVerify(expected);
return {
then(fulfill) {
verify();
fulfill();
}
}
}
async function testThenables() {
setContinuationPreservedEmbedderData('plain thenable');
await thenable('plain thenable');
setContinuationPreservedEmbedderData('resolved thenable');
await Promise.resolve(thenable('resolved thenable'));
setContinuationPreservedEmbedderData('async returned thenable');
await (async () => thenable('async returned thenable'))();
}
testThenables();
%PerformMicrotaskCheckpoint();
//
// Test helpers
//
function deferredVerify(expected) {
return () => {
assertEquals(expected, getContinuationPreservedEmbedderData());
};
}

View File

@ -0,0 +1,39 @@
// Copyright 2024 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.
// Flags: --allow-natives-syntax
const {
getExtrasBindingObject,
getContinuationPreservedEmbedderDataViaAPIForTesting,
} = d8;
const {
getContinuationPreservedEmbedderData,
setContinuationPreservedEmbedderData,
} = getExtrasBindingObject();
function testOpt(v) {
setContinuationPreservedEmbedderData(v);
return getContinuationPreservedEmbedderData();
}
const runTestOpt = (v) => {
const data = testOpt(v);
assertEquals(data, v);
assertEquals(getContinuationPreservedEmbedderDataViaAPIForTesting(), v);
};
%PrepareFunctionForOptimization(testOpt);
runTestOpt(5);
runTestOpt(5.5);
runTestOpt({});
%OptimizeMaglevOnNextCall(testOpt);
runTestOpt(5);
runTestOpt(5.5);
runTestOpt({});
assertTrue(isMaglevved(testOpt));

View File

@ -486,6 +486,9 @@
'compiler/regress-crbug-1201057': [SKIP],
'compiler/regress-crbug-1201082': [SKIP],
'maglev/extras-cped': [SKIP],
'turboshaft/extras-cped': [SKIP],
# These tests check that we can trace the compiler.
'tools/compiler-trace-flags': [SKIP],
@ -1432,6 +1435,9 @@
'regress/regress-1049982-1': [SKIP],
'regress/regress-1049982-2': [SKIP],
'maglev/extras-cped': [SKIP],
'turboshaft/extras-cped': [SKIP],
# Wasm serialization relies on TurboFan to be available, hence does not work
# in the 'nooptimization' variant.
'wasm/serialization-with-compilation-hints': [SKIP],
@ -2078,6 +2084,7 @@
# the deprecated map. Wiring this through in Maglev would be too messy to be
# worth it.
'regress/regress-map-invalidation-2': [FAIL],
'turboshaft/extras-cped': [SKIP],
}], # variant in (stress_maglev, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan)
['(variant in (stress_maglev, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan)) and (arch != arm)', {

View File

@ -0,0 +1,39 @@
// Copyright 2024 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.
// Flags: --allow-natives-syntax
const {
getExtrasBindingObject,
getContinuationPreservedEmbedderDataViaAPIForTesting,
} = d8;
const {
getContinuationPreservedEmbedderData,
setContinuationPreservedEmbedderData,
} = getExtrasBindingObject();
function testOpt(v) {
setContinuationPreservedEmbedderData(v);
return getContinuationPreservedEmbedderData();
}
const runTestOpt = (v) => {
const data = testOpt(v);
assertEquals(data, v);
assertEquals(getContinuationPreservedEmbedderDataViaAPIForTesting(), v);
};
%PrepareFunctionForOptimization(testOpt);
runTestOpt(5);
runTestOpt(5.5);
runTestOpt({});
%OptimizeFunctionOnNextCall(testOpt);
runTestOpt(5);
runTestOpt(5.5);
runTestOpt({});
assertTrue(isTurboFanned(testOpt));