Skip to content

Commit a016775

Browse files
committed
deps: V8: backport d89d185f
Original commit message: [fastcall] expose wasm memory to cfunction Load current Memory start/size off of the wasm instance when entering fast calls, so they can use that info for whatever they need to do. Fast calls from JS set the memory to null, and the memory does not need to be piped from wasm to slow callbacks as wasm always calls the fast function. Change-Id: Ibfa33cdd7dba85300f95cbdacc9a56b3f7181663 Bug: chromium:1052746 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3719005 Reviewed-by: Maya Lekova <[email protected]> Commit-Queue: snek <[email protected]> Reviewed-by: Manos Koukoutos <[email protected]> Reviewed-by: Toon Verwaest <[email protected]> Cr-Commit-Position: refs/heads/main@{#81538}
1 parent 2dc1451 commit a016775

File tree

13 files changed

+149
-19
lines changed

13 files changed

+149
-19
lines changed

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

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

4141
##### V8 defaults for Node.js #####
4242

deps/v8/include/v8-fast-api-calls.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ struct FastApiCallbackOptions {
544544
* returned instance may be filled with mock data.
545545
*/
546546
static FastApiCallbackOptions CreateForTesting(Isolate* isolate) {
547-
return {false, {0}};
547+
return {false, {0}, nullptr};
548548
}
549549

550550
/**
@@ -568,6 +568,11 @@ struct FastApiCallbackOptions {
568568
uintptr_t data_ptr;
569569
v8::Value data;
570570
};
571+
572+
/**
573+
* When called from WebAssembly, a view of the calling module's memory.
574+
*/
575+
FastApiTypedArray<uint8_t>* const wasm_memory;
571576
};
572577

573578
namespace internal {

deps/v8/src/compiler/effect-control-linearizer.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5171,6 +5171,15 @@ Node* EffectControlLinearizer::LowerFastApiCall(Node* node) {
51715171
CheckForMinusZeroMode::kCheckForMinusZero);
51725172
}
51735173
},
5174+
// Initialize js-specific callback options.
5175+
[this](Node* options_stack_slot) {
5176+
__ Store(
5177+
StoreRepresentation(MachineType::PointerRepresentation(),
5178+
kNoWriteBarrier),
5179+
options_stack_slot,
5180+
static_cast<int>(offsetof(v8::FastApiCallbackOptions, wasm_memory)),
5181+
__ IntPtrConstant(0));
5182+
},
51745183
// Generate slow fallback if fast call fails
51755184
[this, node]() -> Node* { return GenerateSlowApiCall(node); });
51765185
}

deps/v8/src/compiler/fast-api-calls.cc

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,14 @@ class FastApiCallBuilder {
125125
GraphAssembler* graph_assembler,
126126
const GetParameter& get_parameter,
127127
const ConvertReturnValue& convert_return_value,
128+
const InitializeOptions& initialize_options,
128129
const GenerateSlowApiCall& generate_slow_api_call)
129130
: isolate_(isolate),
130131
graph_(graph),
131132
graph_assembler_(graph_assembler),
132133
get_parameter_(get_parameter),
133134
convert_return_value_(convert_return_value),
135+
initialize_options_(initialize_options),
134136
generate_slow_api_call_(generate_slow_api_call) {}
135137

136138
Node* Build(const FastApiCallFunctionVector& c_functions,
@@ -150,6 +152,7 @@ class FastApiCallBuilder {
150152
GraphAssembler* graph_assembler_;
151153
const GetParameter& get_parameter_;
152154
const ConvertReturnValue& convert_return_value_;
155+
const InitializeOptions& initialize_options_;
153156
const GenerateSlowApiCall& generate_slow_api_call_;
154157
};
155158

@@ -291,12 +294,12 @@ Node* FastApiCallBuilder::Build(const FastApiCallFunctionVector& c_functions,
291294

292295
Node* stack_slot = nullptr;
293296
if (c_signature->HasOptions()) {
294-
int kAlign = alignof(v8::FastApiCallbackOptions);
295-
int kSize = sizeof(v8::FastApiCallbackOptions);
297+
const int kAlign = alignof(v8::FastApiCallbackOptions);
298+
const int kSize = sizeof(v8::FastApiCallbackOptions);
296299
// If this check fails, you've probably added new fields to
297300
// v8::FastApiCallbackOptions, which means you'll need to write code
298301
// that initializes and reads from them too.
299-
CHECK_EQ(kSize, sizeof(uintptr_t) * 2);
302+
static_assert(kSize == sizeof(uintptr_t) * 3);
300303
stack_slot = __ StackSlot(kSize, kAlign);
301304

302305
__ Store(
@@ -310,6 +313,8 @@ Node* FastApiCallBuilder::Build(const FastApiCallFunctionVector& c_functions,
310313
static_cast<int>(offsetof(v8::FastApiCallbackOptions, data)),
311314
data_argument);
312315

316+
initialize_options_(stack_slot);
317+
313318
builder.AddParam(MachineType::Pointer()); // stack_slot
314319
}
315320

@@ -366,9 +371,11 @@ Node* BuildFastApiCall(Isolate* isolate, Graph* graph,
366371
const CFunctionInfo* c_signature, Node* data_argument,
367372
const GetParameter& get_parameter,
368373
const ConvertReturnValue& convert_return_value,
374+
const InitializeOptions& initialize_options,
369375
const GenerateSlowApiCall& generate_slow_api_call) {
370376
FastApiCallBuilder builder(isolate, graph, graph_assembler, get_parameter,
371-
convert_return_value, generate_slow_api_call);
377+
convert_return_value, initialize_options,
378+
generate_slow_api_call);
372379
return builder.Build(c_functions, c_signature, data_argument);
373380
}
374381

deps/v8/src/compiler/fast-api-calls.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ bool CanOptimizeFastSignature(const CFunctionInfo* c_signature);
4949
using GetParameter = std::function<Node*(int, OverloadsResolutionResult&,
5050
GraphAssemblerLabel<0>*)>;
5151
using ConvertReturnValue = std::function<Node*(const CFunctionInfo*, Node*)>;
52+
using InitializeOptions = std::function<void(Node*)>;
5253
using GenerateSlowApiCall = std::function<Node*()>;
5354

5455
Node* BuildFastApiCall(Isolate* isolate, Graph* graph,
@@ -57,6 +58,7 @@ Node* BuildFastApiCall(Isolate* isolate, Graph* graph,
5758
const CFunctionInfo* c_signature, Node* data_argument,
5859
const GetParameter& get_parameter,
5960
const ConvertReturnValue& convert_return_value,
61+
const InitializeOptions& initialize_options,
6062
const GenerateSlowApiCall& generate_slow_api_call);
6163

6264
} // namespace fast_api_call

deps/v8/src/compiler/wasm-compiler.cc

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -560,9 +560,9 @@ void WasmGraphBuilder::Start(unsigned params) {
560560
Param(Linkage::kJSCallClosureParamIndex, "%closure")));
561561
break;
562562
case kWasmApiFunctionRefMode:
563-
// We need an instance node anyway, because FromJS() needs to pass it to
564-
// the WasmIsValidRefValue runtime function.
565-
instance_node_ = UndefinedValue();
563+
instance_node_ = gasm_->Load(
564+
MachineType::TaggedPointer(), Param(0),
565+
wasm::ObjectAccess::ToTagged(WasmApiFunctionRef::kInstanceOffset));
566566
break;
567567
}
568568
graph()->SetEnd(graph()->NewNode(mcgraph()->common()->End(0)));
@@ -7454,6 +7454,38 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
74547454
[](const CFunctionInfo* signature, Node* c_return_value) {
74557455
return c_return_value;
74567456
},
7457+
// Initialize wasm-specific callback options fields
7458+
[this](Node* options_stack_slot) {
7459+
#ifdef V8_SANDBOXED_POINTERS
7460+
Node* mem_start = LOAD_INSTANCE_FIELD_NO_ELIMINATION(
7461+
MemoryStart, MachineType::SandboxedPointer());
7462+
#else
7463+
Node* mem_start = LOAD_INSTANCE_FIELD_NO_ELIMINATION(
7464+
MemoryStart, MachineType::UintPtr());
7465+
#endif
7466+
7467+
Node* mem_size = LOAD_INSTANCE_FIELD_NO_ELIMINATION(
7468+
MemorySize, MachineType::UintPtr());
7469+
7470+
constexpr int kSize = sizeof(FastApiTypedArray<uint8_t>);
7471+
constexpr int kAlign = alignof(FastApiTypedArray<uint8_t>);
7472+
7473+
Node* stack_slot = gasm_->StackSlot(kSize, kAlign);
7474+
7475+
gasm_->Store(StoreRepresentation(MachineType::PointerRepresentation(),
7476+
kNoWriteBarrier),
7477+
stack_slot, 0, mem_size);
7478+
gasm_->Store(StoreRepresentation(MachineType::PointerRepresentation(),
7479+
kNoWriteBarrier),
7480+
stack_slot, sizeof(size_t), mem_start);
7481+
7482+
gasm_->Store(StoreRepresentation(MachineType::PointerRepresentation(),
7483+
kNoWriteBarrier),
7484+
options_stack_slot,
7485+
static_cast<int>(
7486+
offsetof(v8::FastApiCallbackOptions, wasm_memory)),
7487+
stack_slot);
7488+
},
74577489
// Generate fallback slow call if fast call fails
74587490
[this, callable_node, native_context, receiver_node]() -> Node* {
74597491
int wasm_count = static_cast<int>(sig_->parameter_count());

deps/v8/src/d8/d8-test.cc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ class FastCApiObject {
186186
CHECK_SELF_OR_FALLBACK(0);
187187
self->fast_call_count_++;
188188

189+
CHECK_NULL(options.wasm_memory);
190+
189191
if (should_fallback) {
190192
options.fallback = true;
191193
return 0;
@@ -598,6 +600,30 @@ class FastCApiObject {
598600
args.GetReturnValue().Set(Boolean::New(isolate, result));
599601
}
600602

603+
static bool TestWasmMemoryFastCallback(Local<Object> receiver,
604+
uint32_t address,
605+
FastApiCallbackOptions& options) {
606+
FastCApiObject* self = UnwrapObject(receiver);
607+
CHECK_SELF_OR_FALLBACK(false);
608+
self->fast_call_count_++;
609+
610+
CHECK_NOT_NULL(options.wasm_memory);
611+
uint8_t* memory = nullptr;
612+
CHECK(options.wasm_memory->getStorageIfAligned(&memory));
613+
memory[address] = 42;
614+
615+
return true;
616+
}
617+
618+
static void TestWasmMemorySlowCallback(
619+
const FunctionCallbackInfo<Value>& args) {
620+
FastCApiObject* self = UnwrapObject(args.This());
621+
CHECK_SELF_OR_THROW();
622+
self->slow_call_count_++;
623+
624+
args.GetIsolate()->ThrowError("should be unreachable from wasm");
625+
}
626+
601627
static void FastCallCount(const FunctionCallbackInfo<Value>& args) {
602628
FastCApiObject* self = UnwrapObject(args.This());
603629
CHECK_SELF_OR_THROW();
@@ -856,6 +882,15 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
856882
Local<Value>(), signature, 1, ConstructorBehavior::kThrow,
857883
SideEffectType::kHasSideEffect, &is_valid_api_object_c_func));
858884

885+
CFunction test_wasm_memory_c_func =
886+
CFunction::Make(FastCApiObject::TestWasmMemoryFastCallback);
887+
api_obj_ctor->PrototypeTemplate()->Set(
888+
isolate, "test_wasm_memory",
889+
FunctionTemplate::New(
890+
isolate, FastCApiObject::TestWasmMemorySlowCallback, Local<Value>(),
891+
Local<Signature>(), 1, ConstructorBehavior::kThrow,
892+
SideEffectType::kHasSideEffect, &test_wasm_memory_c_func));
893+
859894
api_obj_ctor->PrototypeTemplate()->Set(
860895
isolate, "fast_call_count",
861896
FunctionTemplate::New(

deps/v8/src/heap/factory.cc

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,7 +1521,8 @@ Handle<WasmTypeInfo> Factory::NewWasmTypeInfo(
15211521
}
15221522

15231523
Handle<WasmApiFunctionRef> Factory::NewWasmApiFunctionRef(
1524-
Handle<JSReceiver> callable, Handle<HeapObject> suspender) {
1524+
Handle<JSReceiver> callable, Handle<HeapObject> suspender,
1525+
Handle<WasmInstanceObject> instance) {
15251526
Map map = *wasm_api_function_ref_map();
15261527
auto result = WasmApiFunctionRef::cast(AllocateRawWithImmortalMap(
15271528
map.instance_size(), AllocationType::kOld, map));
@@ -1538,6 +1539,11 @@ Handle<WasmApiFunctionRef> Factory::NewWasmApiFunctionRef(
15381539
} else {
15391540
result.set_suspender(*undefined_value());
15401541
}
1542+
if (!instance.is_null()) {
1543+
result.set_instance(*instance);
1544+
} else {
1545+
result.set_instance(*undefined_value());
1546+
}
15411547
return handle(result, isolate());
15421548
}
15431549

@@ -1560,7 +1566,8 @@ Handle<WasmJSFunctionData> Factory::NewWasmJSFunctionData(
15601566
Address opt_call_target, Handle<JSReceiver> callable, int return_count,
15611567
int parameter_count, Handle<PodArray<wasm::ValueType>> serialized_sig,
15621568
Handle<CodeT> wrapper_code, Handle<Map> rtt, Handle<HeapObject> suspender) {
1563-
Handle<WasmApiFunctionRef> ref = NewWasmApiFunctionRef(callable, suspender);
1569+
Handle<WasmApiFunctionRef> ref = NewWasmApiFunctionRef(
1570+
callable, suspender, Handle<WasmInstanceObject>());
15641571
Handle<WasmInternalFunction> internal =
15651572
NewWasmInternalFunction(opt_call_target, ref, rtt);
15661573
Map map = *wasm_js_function_data_map();
@@ -1621,8 +1628,8 @@ Handle<WasmCapiFunctionData> Factory::NewWasmCapiFunctionData(
16211628
Address call_target, Handle<Foreign> embedder_data,
16221629
Handle<CodeT> wrapper_code, Handle<Map> rtt,
16231630
Handle<PodArray<wasm::ValueType>> serialized_sig) {
1624-
Handle<WasmApiFunctionRef> ref =
1625-
NewWasmApiFunctionRef(Handle<JSReceiver>(), Handle<HeapObject>());
1631+
Handle<WasmApiFunctionRef> ref = NewWasmApiFunctionRef(
1632+
Handle<JSReceiver>(), Handle<HeapObject>(), Handle<WasmInstanceObject>());
16261633
Handle<WasmInternalFunction> internal =
16271634
NewWasmInternalFunction(call_target, ref, rtt);
16281635
Map map = *wasm_capi_function_data_map();

deps/v8/src/heap/factory.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,8 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
609609
Address call_target, Handle<Object> ref, int func_index,
610610
Address sig_address, int wrapper_budget, Handle<Map> rtt);
611611
Handle<WasmApiFunctionRef> NewWasmApiFunctionRef(
612-
Handle<JSReceiver> callable, Handle<HeapObject> suspender);
612+
Handle<JSReceiver> callable, Handle<HeapObject> suspender,
613+
Handle<WasmInstanceObject> instance);
613614
// {opt_call_target} is kNullAddress for JavaScript functions, and
614615
// non-null for exported Wasm functions.
615616
Handle<WasmJSFunctionData> NewWasmJSFunctionData(

deps/v8/src/wasm/wasm-objects.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,7 @@ void ImportedFunctionEntry::SetWasmToJs(
11011101
DCHECK(wasm_to_js_wrapper->kind() == wasm::WasmCode::kWasmToJsWrapper ||
11021102
wasm_to_js_wrapper->kind() == wasm::WasmCode::kWasmToCapiWrapper);
11031103
Handle<WasmApiFunctionRef> ref =
1104-
isolate->factory()->NewWasmApiFunctionRef(callable, suspender);
1104+
isolate->factory()->NewWasmApiFunctionRef(callable, suspender, instance_);
11051105
instance_->imported_function_refs().set(index_, *ref);
11061106
instance_->imported_function_targets()[index_] =
11071107
wasm_to_js_wrapper->instruction_start();
@@ -1502,7 +1502,7 @@ void WasmInstanceObject::ImportWasmJSFunctionIntoTable(
15021502
// Update the dispatch table.
15031503
Handle<HeapObject> suspender = handle(js_function->GetSuspender(), isolate);
15041504
Handle<WasmApiFunctionRef> ref =
1505-
isolate->factory()->NewWasmApiFunctionRef(callable, suspender);
1505+
isolate->factory()->NewWasmApiFunctionRef(callable, suspender, instance);
15061506
WasmIndirectFunctionTable::cast(
15071507
instance->indirect_function_tables().get(table_index))
15081508
.Set(entry_index, sig_id, call_target, *ref);

0 commit comments

Comments
 (0)