[wasm] Internal representation for function references
Design doc: bit.ly/3jEVgzz We separate the internal representation of function references in Wasm from their JSFunction-based (external) representation. This improves performance of call_ref by requiring less indirections to load the context and call target from a function reference. In the boundary between wasm and JS/the C API, we add transformations between the two representations. Detailed changes: - Introduce WasmInternalFunction, containing fields required by call_ref, as well as a reference to the corresponding WasmExternalFunction. Add a reference to the WasmInternalFunction in WasmFunctionData. The {WasmInternalFunction::FromExternal} helper extracts the internal out of an external function. - Change {WasmInstanceObject::external_functions()} to internal functions. - Change wasm function tables to contain internal functions. - Change the following code to use internal functions: - call_ref in liftoff and Turbofan - function type checks in liftoff and Turbofan - CallRefIC and GenericJSToWasmWrapper builtins - {InitExprInterface::RefFunc} - module-compiler.cc in {ProcessTypeFeedback} - In module-instantiate.cc, in function-rtt creation. - Add transformations between internal and external functions in: - WasmWrapperGraphBuilder::{ToJS, BuildUnpackObjectWrapper, FromJS, BuildJSToJSWrapper}. - debug-wasm-objects.cc in {FunctionProxy::Get}, {WasmValueObject::New} and {AddWasmTableObjectInternalProperties}. - runtime-wasm.cc in ReplaceWrapper - the C and JS APIs - module-instantiate.cc, in import and export processing, as well as {InitializeIndirectFunctionTables} - WasmTableObject::{IsValidElement, SetFunctionTableEntry} - {WasmGlobalObject::SetFuncRef} - Simplify body descriptors of WasmExternalFunction variants. - Adjust tests. Bug: v8:11510 Change-Id: I8377f46f55c3771391ae1c5c8201a83854ee7878 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3277878 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Cr-Commit-Position: refs/heads/main@{#78068}
This commit is contained in:
parent
42da0c3918
commit
f60132e96a
@ -30,10 +30,10 @@ TNode<FixedArray> WasmBuiltinsAssembler::LoadTablesFromInstance(
|
||||
WasmInstanceObject::kTablesOffset);
|
||||
}
|
||||
|
||||
TNode<FixedArray> WasmBuiltinsAssembler::LoadExternalFunctionsFromInstance(
|
||||
TNode<FixedArray> WasmBuiltinsAssembler::LoadInternalFunctionsFromInstance(
|
||||
TNode<WasmInstanceObject> instance) {
|
||||
return LoadObjectField<FixedArray>(
|
||||
instance, WasmInstanceObject::kWasmExternalFunctionsOffset);
|
||||
instance, WasmInstanceObject::kWasmInternalFunctionsOffset);
|
||||
}
|
||||
|
||||
TNode<FixedArray> WasmBuiltinsAssembler::LoadManagedObjectMapsFromInstance(
|
||||
|
@ -22,7 +22,7 @@ class WasmBuiltinsAssembler : public CodeStubAssembler {
|
||||
|
||||
TNode<FixedArray> LoadTablesFromInstance(TNode<WasmInstanceObject> instance);
|
||||
|
||||
TNode<FixedArray> LoadExternalFunctionsFromInstance(
|
||||
TNode<FixedArray> LoadInternalFunctionsFromInstance(
|
||||
TNode<WasmInstanceObject> instance);
|
||||
|
||||
TNode<FixedArray> LoadManagedObjectMapsFromInstance(
|
||||
|
@ -64,7 +64,7 @@ extern macro WasmBuiltinsAssembler::LoadContextFromInstance(WasmInstanceObject):
|
||||
NativeContext;
|
||||
extern macro WasmBuiltinsAssembler::LoadTablesFromInstance(WasmInstanceObject):
|
||||
FixedArray;
|
||||
extern macro WasmBuiltinsAssembler::LoadExternalFunctionsFromInstance(
|
||||
extern macro WasmBuiltinsAssembler::LoadInternalFunctionsFromInstance(
|
||||
WasmInstanceObject): FixedArray;
|
||||
extern macro WasmBuiltinsAssembler::LoadManagedObjectMapsFromInstance(
|
||||
WasmInstanceObject): FixedArray;
|
||||
@ -227,7 +227,7 @@ builtin WasmTableSet(tableIndex: intptr, index: int32, value: Object): Object {
|
||||
builtin WasmRefFunc(index: uint32): Object {
|
||||
const instance: WasmInstanceObject = LoadInstanceFromFrame();
|
||||
try {
|
||||
const table: FixedArray = LoadExternalFunctionsFromInstance(instance);
|
||||
const table: FixedArray = LoadInternalFunctionsFromInstance(instance);
|
||||
if (table == Undefined) goto CallRuntime;
|
||||
const functionIndex: intptr = Signed(ChangeUint32ToWord(index));
|
||||
const result: Object = LoadFixedArrayElement(table, functionIndex);
|
||||
@ -475,16 +475,11 @@ struct TargetAndInstance {
|
||||
instance: HeapObject; // WasmInstanceObject or WasmApiFunctionRef
|
||||
}
|
||||
|
||||
macro GetTargetAndInstance(funcref: JSFunction): TargetAndInstance {
|
||||
const sfi = funcref.shared_function_info;
|
||||
dcheck(Is<WasmFunctionData>(sfi.function_data));
|
||||
const funcData = UnsafeCast<WasmFunctionData>(sfi.function_data);
|
||||
const ref = funcData.ref;
|
||||
let target = funcData.foreign_address_ptr;
|
||||
macro GetTargetAndInstance(funcref: WasmInternalFunction): TargetAndInstance {
|
||||
const ref = funcref.ref;
|
||||
let target = funcref.foreign_address_ptr;
|
||||
if (Signed(target) == IntPtrConstant(0)) {
|
||||
const wrapper =
|
||||
UnsafeCast<WasmJSFunctionData>(funcData).wasm_to_js_wrapper_code;
|
||||
target = GetCodeEntry(wrapper);
|
||||
target = GetCodeEntry(funcref.code);
|
||||
}
|
||||
return TargetAndInstance{target: target, instance: ref};
|
||||
}
|
||||
@ -499,7 +494,8 @@ macro GetTargetAndInstance(funcref: JSFunction): TargetAndInstance {
|
||||
// - megamorphic: ("megamorphic" sentinel, <unused>)
|
||||
|
||||
builtin CallRefIC(
|
||||
vector: FixedArray, index: intptr, funcref: JSFunction): TargetAndInstance {
|
||||
vector: FixedArray, index: intptr,
|
||||
funcref: WasmInternalFunction): TargetAndInstance {
|
||||
const value = vector.objects[index];
|
||||
if (value == funcref) {
|
||||
// Monomorphic hit. Check for this case first to maximize its performance.
|
||||
@ -547,7 +543,7 @@ builtin CallRefIC(
|
||||
newEntries.objects[newIndex + 1] = data;
|
||||
vector.objects[index] = newEntries;
|
||||
}
|
||||
} else if (Is<JSFunction>(value)) {
|
||||
} else if (Is<WasmInternalFunction>(value)) {
|
||||
// Monomorphic miss.
|
||||
const data = new
|
||||
CallRefData{instance: result.instance, target: result.target, count: 1};
|
||||
|
@ -3385,10 +3385,12 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
|
||||
|
||||
Register function_entry = function_data;
|
||||
Register scratch = r12;
|
||||
__ LoadAnyTaggedField(
|
||||
function_entry,
|
||||
FieldOperand(function_data, WasmExportedFunctionData::kInternalOffset));
|
||||
__ LoadExternalPointerField(
|
||||
function_entry,
|
||||
FieldOperand(function_data,
|
||||
WasmExportedFunctionData::kForeignAddressOffset),
|
||||
FieldOperand(function_entry, WasmInternalFunction::kForeignAddressOffset),
|
||||
kForeignForeignAddressTag, scratch);
|
||||
function_data = no_reg;
|
||||
scratch = no_reg;
|
||||
@ -3786,10 +3788,12 @@ void Builtins::Generate_WasmReturnPromiseOnSuspend(MacroAssembler* masm) {
|
||||
MemOperand(kRootRegister, Isolate::thread_in_wasm_flag_address_offset()));
|
||||
__ movl(MemOperand(thread_in_wasm_flag_addr, 0), Immediate(1));
|
||||
Register function_entry = function_data;
|
||||
__ LoadAnyTaggedField(
|
||||
function_entry,
|
||||
FieldOperand(function_entry, WasmExportedFunctionData::kInternalOffset));
|
||||
__ LoadExternalPointerField(
|
||||
function_entry,
|
||||
FieldOperand(function_data,
|
||||
WasmExportedFunctionData::kForeignAddressOffset),
|
||||
FieldOperand(function_data, WasmInternalFunction::kForeignAddressOffset),
|
||||
kForeignForeignAddressTag, r8);
|
||||
__ Push(wasm_instance);
|
||||
__ call(function_entry);
|
||||
|
@ -3175,30 +3175,34 @@ Node* WasmGraphBuilder::BuildIndirectCall(
|
||||
}
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildLoadCallTargetFromExportedFunctionData(
|
||||
Node* function_data) {
|
||||
// TODO(saelo) move this code into a common LoadExternalPointer routine?
|
||||
Node* WasmGraphBuilder::BuildUnsandboxExternalPointer(Node* external_pointer) {
|
||||
#ifdef V8_HEAP_SANDBOX
|
||||
Node* index = gasm_->LoadFromObject(
|
||||
MachineType::Pointer(), function_data,
|
||||
wasm::ObjectAccess::ToTagged(WasmFunctionData::kForeignAddressOffset));
|
||||
|
||||
Node* isolate_root = BuildLoadIsolateRoot();
|
||||
Node* table =
|
||||
gasm_->LoadFromObject(MachineType::Pointer(), isolate_root,
|
||||
IsolateData::external_pointer_table_offset() +
|
||||
Internals::kExternalPointerTableBufferOffset);
|
||||
Node* offset = gasm_->Int32Mul(index, gasm_->Int32Constant(8));
|
||||
Node* offset = gasm_->Int32Mul(external_pointer, gasm_->Int32Constant(8));
|
||||
Node* decoded_ptr = gasm_->Load(MachineType::Pointer(), table, offset);
|
||||
Node* tag = gasm_->IntPtrConstant(~kForeignForeignAddressTag);
|
||||
return gasm_->WordAnd(decoded_ptr, tag);
|
||||
#else
|
||||
return gasm_->LoadFromObject(
|
||||
MachineType::Pointer(), function_data,
|
||||
wasm::ObjectAccess::ToTagged(WasmFunctionData::kForeignAddressOffset));
|
||||
return external_pointer;
|
||||
#endif
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildLoadCallTargetFromExportedFunctionData(
|
||||
Node* function) {
|
||||
Node* internal = gasm_->LoadFromObject(
|
||||
MachineType::TaggedPointer(), function,
|
||||
wasm::ObjectAccess::ToTagged(WasmExportedFunctionData::kInternalOffset));
|
||||
Node* external_pointer =
|
||||
gasm_->LoadFromObject(MachineType::Pointer(), internal,
|
||||
wasm::ObjectAccess::ToTagged(
|
||||
WasmInternalFunction::kForeignAddressOffset));
|
||||
return BuildUnsandboxExternalPointer(external_pointer);
|
||||
}
|
||||
|
||||
// TODO(9495): Support CAPI function refs.
|
||||
Node* WasmGraphBuilder::BuildCallRef(const wasm::FunctionSig* real_sig,
|
||||
base::Vector<Node*> args,
|
||||
@ -3211,25 +3215,29 @@ Node* WasmGraphBuilder::BuildCallRef(const wasm::FunctionSig* real_sig,
|
||||
position);
|
||||
}
|
||||
|
||||
Node* function_data = gasm_->LoadFunctionDataFromJSFunction(args[0]);
|
||||
Node* function = args[0];
|
||||
|
||||
auto load_target = gasm_->MakeLabel();
|
||||
auto end_label = gasm_->MakeLabel(MachineType::PointerRepresentation());
|
||||
|
||||
Node* instance_node = gasm_->LoadFromObject(
|
||||
MachineType::TaggedPointer(), function_data,
|
||||
wasm::ObjectAccess::ToTagged(WasmFunctionData::kRefOffset));
|
||||
Node* ref_node = gasm_->LoadFromObject(
|
||||
MachineType::TaggedPointer(), function,
|
||||
wasm::ObjectAccess::ToTagged(WasmInternalFunction::kRefOffset));
|
||||
|
||||
Node* target = BuildLoadCallTargetFromExportedFunctionData(function_data);
|
||||
Node* external_target =
|
||||
gasm_->LoadFromObject(MachineType::Pointer(), function,
|
||||
wasm::ObjectAccess::ToTagged(
|
||||
WasmInternalFunction::kForeignAddressOffset));
|
||||
|
||||
Node* target = BuildUnsandboxExternalPointer(external_target);
|
||||
Node* is_null_target = gasm_->WordEqual(target, gasm_->IntPtrConstant(0));
|
||||
gasm_->GotoIfNot(is_null_target, &end_label, target);
|
||||
{
|
||||
// Compute the call target from the (on-heap) wrapper code. The cached
|
||||
// target can only be null for WasmJSFunctions.
|
||||
Node* wrapper_code = gasm_->LoadFromObject(
|
||||
MachineType::TaggedPointer(), function_data,
|
||||
wasm::ObjectAccess::ToTagged(
|
||||
WasmJSFunctionData::kWasmToJsWrapperCodeOffset));
|
||||
MachineType::TaggedPointer(), function,
|
||||
wasm::ObjectAccess::ToTagged(WasmInternalFunction::kCodeOffset));
|
||||
Node* call_target;
|
||||
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
|
||||
CHECK(!V8_HEAP_SANDBOX_BOOL); // Not supported yet.
|
||||
@ -3250,27 +3258,26 @@ Node* WasmGraphBuilder::BuildCallRef(const wasm::FunctionSig* real_sig,
|
||||
|
||||
args[0] = end_label.PhiAt(0);
|
||||
|
||||
Node* call =
|
||||
continuation == kCallContinues
|
||||
? BuildWasmCall(real_sig, args, rets, position, instance_node)
|
||||
: BuildWasmReturnCall(real_sig, args, position, instance_node);
|
||||
Node* call = continuation == kCallContinues
|
||||
? BuildWasmCall(real_sig, args, rets, position, ref_node)
|
||||
: BuildWasmReturnCall(real_sig, args, position, ref_node);
|
||||
return call;
|
||||
}
|
||||
|
||||
void WasmGraphBuilder::CompareToExternalFunctionAtIndex(
|
||||
void WasmGraphBuilder::CompareToInternalFunctionAtIndex(
|
||||
Node* func_ref, uint32_t function_index, Node** success_control,
|
||||
Node** failure_control) {
|
||||
// Since we are comparing to a function reference, it is guaranteed that
|
||||
// instance->wasm_external_functions() has been initialized.
|
||||
Node* external_functions = gasm_->LoadFromObject(
|
||||
// instance->wasm_internal_functions() has been initialized.
|
||||
Node* internal_functions = gasm_->LoadFromObject(
|
||||
MachineType::TaggedPointer(), GetInstance(),
|
||||
wasm::ObjectAccess::ToTagged(
|
||||
WasmInstanceObject::kWasmExternalFunctionsOffset));
|
||||
Node* function_ref = gasm_->LoadFixedArrayElement(
|
||||
external_functions, gasm_->IntPtrConstant(function_index),
|
||||
WasmInstanceObject::kWasmInternalFunctionsOffset));
|
||||
Node* function_ref_at_index = gasm_->LoadFixedArrayElement(
|
||||
internal_functions, gasm_->IntPtrConstant(function_index),
|
||||
MachineType::AnyTagged());
|
||||
gasm_->Branch(gasm_->WordEqual(function_ref, func_ref), success_control,
|
||||
failure_control, BranchHint::kTrue);
|
||||
gasm_->Branch(gasm_->WordEqual(function_ref_at_index, func_ref),
|
||||
success_control, failure_control, BranchHint::kTrue);
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::CallRef(const wasm::FunctionSig* real_sig,
|
||||
@ -5843,8 +5850,9 @@ void WasmGraphBuilder::FuncCheck(Node* object, bool object_can_be_null,
|
||||
callbacks.fail_if(gasm_->WordEqual(object, RefNull()), BranchHint::kFalse);
|
||||
}
|
||||
callbacks.fail_if(gasm_->IsI31(object), BranchHint::kFalse);
|
||||
callbacks.fail_if_not(gasm_->HasInstanceType(object, JS_FUNCTION_TYPE),
|
||||
BranchHint::kTrue);
|
||||
callbacks.fail_if_not(
|
||||
gasm_->HasInstanceType(object, WASM_INTERNAL_FUNCTION_TYPE),
|
||||
BranchHint::kTrue);
|
||||
}
|
||||
|
||||
void WasmGraphBuilder::BrOnCastAbs(
|
||||
@ -6369,8 +6377,27 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
case wasm::kOptRef:
|
||||
switch (type.heap_representation()) {
|
||||
case wasm::HeapType::kExtern:
|
||||
case wasm::HeapType::kFunc:
|
||||
return node;
|
||||
case wasm::HeapType::kFunc: {
|
||||
if (type.kind() == wasm::kOptRef) {
|
||||
auto done =
|
||||
gasm_->MakeLabel(MachineRepresentation::kTaggedPointer);
|
||||
// Do not wrap {null}.
|
||||
gasm_->GotoIf(gasm_->WordEqual(node, RefNull()), &done, node);
|
||||
gasm_->Goto(&done,
|
||||
gasm_->LoadFromObject(
|
||||
MachineType::TaggedPointer(), node,
|
||||
wasm::ObjectAccess::ToTagged(
|
||||
WasmInternalFunction::kExternalOffset)));
|
||||
gasm_->Bind(&done);
|
||||
return done.PhiAt(0);
|
||||
} else {
|
||||
return gasm_->LoadFromObject(
|
||||
MachineType::TaggedPointer(), node,
|
||||
wasm::ObjectAccess::ToTagged(
|
||||
WasmInternalFunction::kExternalOffset));
|
||||
}
|
||||
}
|
||||
case wasm::HeapType::kData:
|
||||
case wasm::HeapType::kEq:
|
||||
case wasm::HeapType::kI31:
|
||||
@ -6387,23 +6414,34 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
return BuildAllocateObjectWrapper(node);
|
||||
}
|
||||
case wasm::HeapType::kAny: {
|
||||
// Only wrap {node} if it is an array/struct/i31, i.e., do not wrap
|
||||
// functions and null.
|
||||
// Wrap {node} in object wrapper if it is an array/struct/i31.
|
||||
// Extract external function if this is a WasmInternalFunction.
|
||||
// Otherwise (i.e. null and external refs), return input.
|
||||
// TODO(7748): Update this when JS interop is settled.
|
||||
auto done = gasm_->MakeLabel(MachineRepresentation::kTaggedPointer);
|
||||
gasm_->GotoIf(IsSmi(node), &done, BuildAllocateObjectWrapper(node));
|
||||
// This includes the case where {node == null}.
|
||||
gasm_->GotoIfNot(gasm_->IsDataRefMap(gasm_->LoadMap(node)), &done,
|
||||
node);
|
||||
gasm_->Goto(&done, BuildAllocateObjectWrapper(node));
|
||||
gasm_->GotoIf(gasm_->IsDataRefMap(gasm_->LoadMap(node)), &done,
|
||||
BuildAllocateObjectWrapper(node));
|
||||
gasm_->GotoIf(
|
||||
gasm_->HasInstanceType(node, WASM_INTERNAL_FUNCTION_TYPE),
|
||||
&done,
|
||||
gasm_->LoadFromObject(
|
||||
MachineType::TaggedPointer(), node,
|
||||
wasm::ObjectAccess::ToTagged(
|
||||
WasmInternalFunction::kExternalOffset)));
|
||||
gasm_->Goto(&done, node);
|
||||
gasm_->Bind(&done);
|
||||
return done.PhiAt(0);
|
||||
}
|
||||
default:
|
||||
DCHECK(type.has_index());
|
||||
if (module_->has_signature(type.ref_index())) {
|
||||
// Typed function
|
||||
return node;
|
||||
// Typed function. Extract the external function.
|
||||
return gasm_->LoadFromObject(
|
||||
MachineType::TaggedPointer(), node,
|
||||
wasm::ObjectAccess::ToTagged(
|
||||
WasmInternalFunction::kExternalOffset));
|
||||
}
|
||||
// If this is reached, then IsJSCompatibleSignature() is too
|
||||
// permissive.
|
||||
@ -6434,24 +6472,43 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
}
|
||||
|
||||
// Assumes {input} has been checked for validity against the target wasm type.
|
||||
// Returns the value of the property associated with
|
||||
// {wasm_wrapped_object_symbol} in {input}, or {input} itself if the property
|
||||
// is not found.
|
||||
// If {input} is a function, returns the WasmInternalFunction associated with
|
||||
// it. If {input} has the {wasm_wrapped_object_symbol} property, returns the
|
||||
// value of that property. Otherwise, returns {input}.
|
||||
Node* BuildUnpackObjectWrapper(Node* input) {
|
||||
if (FLAG_wasm_gc_js_interop) return input;
|
||||
Node* obj = gasm_->CallBuiltin(
|
||||
Builtin::kWasmGetOwnProperty, Operator::kEliminatable, input,
|
||||
LOAD_ROOT(wasm_wrapped_object_symbol, wasm_wrapped_object_symbol),
|
||||
LOAD_INSTANCE_FIELD(NativeContext, MachineType::TaggedPointer()));
|
||||
// Invalid object wrappers (i.e. any other JS object that doesn't have the
|
||||
// magic hidden property) will return {undefined}. Map that to {null} or
|
||||
// {input}, depending on the value of {failure}.
|
||||
Node* undefined = UndefinedValue();
|
||||
Node* is_undefined = gasm_->WordEqual(obj, undefined);
|
||||
Diamond check(graph(), mcgraph()->common(), is_undefined,
|
||||
BranchHint::kFalse);
|
||||
check.Chain(control());
|
||||
return check.Phi(MachineRepresentation::kTagged, input, obj);
|
||||
auto not_a_function = gasm_->MakeLabel();
|
||||
auto end = gasm_->MakeLabel(MachineRepresentation::kTaggedPointer);
|
||||
|
||||
gasm_->GotoIfNot(gasm_->HasInstanceType(input, JS_FUNCTION_TYPE),
|
||||
¬_a_function);
|
||||
|
||||
Node* function_data = gasm_->LoadFunctionDataFromJSFunction(input);
|
||||
|
||||
// Due to type checking, {function_data} will be a WasmFunctionData.
|
||||
Node* internal = gasm_->LoadFromObject(
|
||||
MachineType::TaggedPointer(), function_data,
|
||||
wasm::ObjectAccess::ToTagged(WasmFunctionData::kInternalOffset));
|
||||
gasm_->Goto(&end, internal);
|
||||
|
||||
gasm_->Bind(¬_a_function);
|
||||
if (!FLAG_wasm_gc_js_interop) {
|
||||
Node* obj = gasm_->CallBuiltin(
|
||||
Builtin::kWasmGetOwnProperty, Operator::kEliminatable, input,
|
||||
LOAD_ROOT(wasm_wrapped_object_symbol, wasm_wrapped_object_symbol),
|
||||
LOAD_INSTANCE_FIELD(NativeContext, MachineType::TaggedPointer()));
|
||||
// Invalid object wrappers (i.e. any other JS object that doesn't have the
|
||||
// magic hidden property) will return {undefined}. Map that to {input}.
|
||||
Node* is_undefined = gasm_->WordEqual(obj, UndefinedValue());
|
||||
gasm_->GotoIf(is_undefined, &end, input);
|
||||
|
||||
gasm_->Goto(&end, obj);
|
||||
} else {
|
||||
gasm_->Goto(&end, input);
|
||||
}
|
||||
|
||||
gasm_->Bind(&end);
|
||||
|
||||
return end.PhiAt(0);
|
||||
}
|
||||
|
||||
Node* BuildChangeInt64ToBigInt(Node* input) {
|
||||
@ -6530,7 +6587,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
return BuildUnpackObjectWrapper(input);
|
||||
case wasm::HeapType::kFunc:
|
||||
BuildCheckValidRefValue(input, js_context, type);
|
||||
return input;
|
||||
return BuildUnpackObjectWrapper(input);
|
||||
case wasm::HeapType::kData:
|
||||
case wasm::HeapType::kEq:
|
||||
case wasm::HeapType::kI31:
|
||||
@ -6542,7 +6599,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
default:
|
||||
if (module_->has_signature(type.ref_index())) {
|
||||
BuildCheckValidRefValue(input, js_context, type);
|
||||
return input;
|
||||
return BuildUnpackObjectWrapper(input);
|
||||
}
|
||||
// If this is reached, then IsJSCompatibleSignature() is too
|
||||
// permissive.
|
||||
@ -6741,10 +6798,17 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
} else {
|
||||
// Call to a wasm function defined in this module.
|
||||
// The (cached) call target is the jump table slot for that function.
|
||||
args[0] = BuildLoadCallTargetFromExportedFunctionData(function_data);
|
||||
Node* instance_node = gasm_->LoadFromObject(
|
||||
Node* internal = gasm_->LoadFromObject(
|
||||
MachineType::TaggedPointer(), function_data,
|
||||
wasm::ObjectAccess::ToTagged(WasmFunctionData::kRefOffset));
|
||||
wasm::ObjectAccess::ToTagged(WasmFunctionData::kInternalOffset));
|
||||
Node* sandboxed_pointer = gasm_->LoadFromObject(
|
||||
MachineType::Pointer(), internal,
|
||||
wasm::ObjectAccess::ToTagged(
|
||||
WasmInternalFunction::kForeignAddressOffset));
|
||||
args[0] = BuildUnsandboxExternalPointer(sandboxed_pointer);
|
||||
Node* instance_node = gasm_->LoadFromObject(
|
||||
MachineType::TaggedPointer(), internal,
|
||||
wasm::ObjectAccess::ToTagged(WasmInternalFunction::kRefOffset));
|
||||
BuildWasmCall(sig_, base::VectorOf(args), base::VectorOf(rets),
|
||||
wasm::kNoCodePosition, instance_node, frame_state);
|
||||
}
|
||||
@ -7246,9 +7310,12 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
|
||||
// Load the original callable from the closure.
|
||||
Node* func_data = gasm_->LoadFunctionDataFromJSFunction(closure);
|
||||
Node* ref = gasm_->LoadFromObject(
|
||||
Node* internal = gasm_->LoadFromObject(
|
||||
MachineType::AnyTagged(), func_data,
|
||||
wasm::ObjectAccess::ToTagged(WasmJSFunctionData::kRefOffset));
|
||||
wasm::ObjectAccess::ToTagged(WasmFunctionData::kInternalOffset));
|
||||
Node* ref = gasm_->LoadFromObject(
|
||||
MachineType::AnyTagged(), internal,
|
||||
wasm::ObjectAccess::ToTagged(WasmInternalFunction::kRefOffset));
|
||||
Node* callable = gasm_->LoadFromObject(
|
||||
MachineType::AnyTagged(), ref,
|
||||
wasm::ObjectAccess::ToTagged(WasmApiFunctionRef::kCallableOffset));
|
||||
|
@ -356,7 +356,7 @@ class WasmGraphBuilder {
|
||||
base::Vector<Node*> args, CheckForNull null_check,
|
||||
wasm::WasmCodePosition position);
|
||||
|
||||
void CompareToExternalFunctionAtIndex(Node* func_ref, uint32_t function_index,
|
||||
void CompareToInternalFunctionAtIndex(Node* func_ref, uint32_t function_index,
|
||||
Node** success_control,
|
||||
Node** failure_control);
|
||||
|
||||
@ -755,6 +755,8 @@ class WasmGraphBuilder {
|
||||
Node* BuildMultiReturnFixedArrayFromIterable(const wasm::FunctionSig* sig,
|
||||
Node* iterable, Node* context);
|
||||
|
||||
Node* BuildUnsandboxExternalPointer(Node* external_pointer);
|
||||
|
||||
Node* BuildLoadCallTargetFromExportedFunctionData(Node* function_data);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
@ -127,8 +127,8 @@ class WasmInliner final : public AdvancedReducer {
|
||||
}
|
||||
|
||||
// The smallest size in TF nodes any meaningful wasm function can have
|
||||
// (start, instance parameter, end).
|
||||
static constexpr size_t kMinimumFunctionNodeCount = 3;
|
||||
// (start, return, IntConstant(0), end).
|
||||
static constexpr size_t kMinimumFunctionNodeCount = 4;
|
||||
|
||||
Reduction ReduceCall(Node* call);
|
||||
void InlineCall(Node* call, Node* callee_start, Node* callee_end,
|
||||
|
@ -317,8 +317,10 @@ struct FunctionsProxy : NamedDebugProxy<FunctionsProxy, kFunctionsProxy> {
|
||||
static Handle<Object> Get(Isolate* isolate,
|
||||
Handle<WasmInstanceObject> instance,
|
||||
uint32_t index) {
|
||||
return WasmInstanceObject::GetOrCreateWasmExternalFunction(isolate,
|
||||
instance, index);
|
||||
return handle(WasmInstanceObject::GetOrCreateWasmInternalFunction(
|
||||
isolate, instance, index)
|
||||
->external(),
|
||||
isolate);
|
||||
}
|
||||
|
||||
static Handle<String> GetName(Isolate* isolate,
|
||||
@ -1027,6 +1029,9 @@ Handle<WasmValueObject> WasmValueObject::New(
|
||||
v = ArrayProxy::Create(isolate, value, module_object);
|
||||
} else if (ref->IsJSFunction() || ref->IsSmi() || ref->IsNull()) {
|
||||
v = ref;
|
||||
} else if (ref->IsWasmInternalFunction()) {
|
||||
v = handle(Handle<WasmInternalFunction>::cast(ref)->external(),
|
||||
isolate);
|
||||
} else {
|
||||
// Fail gracefully.
|
||||
base::EmbeddedVector<char, 64> error;
|
||||
@ -1135,7 +1140,11 @@ Handle<ArrayList> AddWasmTableObjectInternalProperties(
|
||||
int length = table->current_length();
|
||||
Handle<FixedArray> entries = isolate->factory()->NewFixedArray(length);
|
||||
for (int i = 0; i < length; ++i) {
|
||||
auto entry = WasmTableObject::Get(isolate, table, i);
|
||||
Handle<Object> entry = WasmTableObject::Get(isolate, table, i);
|
||||
if (entry->IsWasmInternalFunction()) {
|
||||
entry = handle(Handle<WasmInternalFunction>::cast(entry)->external(),
|
||||
isolate);
|
||||
}
|
||||
entries->set(i, *entry);
|
||||
}
|
||||
Handle<JSArray> final_entries = isolate->factory()->NewJSArrayWithElements(
|
||||
|
@ -1913,8 +1913,7 @@ void WasmInstanceObject::WasmInstanceObjectPrint(std::ostream& os) {
|
||||
|
||||
// Never called directly, as WasmFunctionData is an "abstract" class.
|
||||
void WasmFunctionData::WasmFunctionDataPrint(std::ostream& os) {
|
||||
os << "\n - target: " << reinterpret_cast<void*>(foreign_address());
|
||||
os << "\n - ref: " << Brief(ref());
|
||||
os << "\n - internal: " << Brief(internal());
|
||||
os << "\n - wrapper_code: " << Brief(TorqueGeneratedClass::wrapper_code());
|
||||
}
|
||||
|
||||
@ -1931,8 +1930,6 @@ void WasmExportedFunctionData::WasmExportedFunctionDataPrint(std::ostream& os) {
|
||||
void WasmJSFunctionData::WasmJSFunctionDataPrint(std::ostream& os) {
|
||||
PrintHeader(os, "WasmJSFunctionData");
|
||||
WasmFunctionDataPrint(os);
|
||||
os << "\n - wasm_to_js_wrapper_code: "
|
||||
<< Brief(raw_wasm_to_js_wrapper_code());
|
||||
os << "\n - serialized_return_count: " << serialized_return_count();
|
||||
os << "\n - serialized_parameter_count: " << serialized_parameter_count();
|
||||
os << "\n - serialized_signature: " << Brief(serialized_signature());
|
||||
@ -1947,6 +1944,15 @@ void WasmApiFunctionRef::WasmApiFunctionRefPrint(std::ostream& os) {
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
void WasmInternalFunction::WasmInternalFunctionPrint(std::ostream& os) {
|
||||
PrintHeader(os, "WasmInternalFunction");
|
||||
os << "\n - call target: " << reinterpret_cast<void*>(foreign_address());
|
||||
os << "\n - ref: " << Brief(ref());
|
||||
os << "\n - external: " << Brief(external());
|
||||
os << "\n - code: " << Brief(code());
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
void WasmCapiFunctionData::WasmCapiFunctionDataPrint(std::ostream& os) {
|
||||
PrintHeader(os, "WasmCapiFunctionData");
|
||||
WasmFunctionDataPrint(os);
|
||||
|
@ -1518,43 +1518,55 @@ Handle<WasmApiFunctionRef> Factory::NewWasmApiFunctionRef(
|
||||
return handle(result, isolate());
|
||||
}
|
||||
|
||||
Handle<WasmInternalFunction> Factory::NewWasmInternalFunction(
|
||||
Address opt_call_target, Handle<HeapObject> ref, Handle<Map> rtt) {
|
||||
HeapObject raw = AllocateRaw(rtt->instance_size(), AllocationType::kOld);
|
||||
raw.set_map_after_allocation(*rtt);
|
||||
WasmInternalFunction result = WasmInternalFunction::cast(raw);
|
||||
DisallowGarbageCollection no_gc;
|
||||
result.AllocateExternalPointerEntries(isolate());
|
||||
result.set_foreign_address(isolate(), opt_call_target);
|
||||
result.set_ref(*ref);
|
||||
// Default values, will be overwritten by the caller.
|
||||
result.set_code(isolate()->builtins()->code(Builtin::kAbort));
|
||||
result.set_external(*undefined_value());
|
||||
return handle(result, isolate());
|
||||
}
|
||||
|
||||
Handle<WasmJSFunctionData> Factory::NewWasmJSFunctionData(
|
||||
Address opt_call_target, Handle<JSReceiver> callable, int return_count,
|
||||
int parameter_count, Handle<PodArray<wasm::ValueType>> serialized_sig,
|
||||
Handle<Code> wrapper_code) {
|
||||
Handle<Code> wrapper_code, Handle<Map> rtt) {
|
||||
Handle<WasmApiFunctionRef> ref = NewWasmApiFunctionRef(callable);
|
||||
Handle<WasmInternalFunction> internal =
|
||||
NewWasmInternalFunction(opt_call_target, ref, rtt);
|
||||
Map map = *wasm_js_function_data_map();
|
||||
WasmJSFunctionData result =
|
||||
WasmJSFunctionData::cast(AllocateRawWithImmortalMap(
|
||||
map.instance_size(), AllocationType::kOld, map));
|
||||
DisallowGarbageCollection no_gc;
|
||||
result.AllocateExternalPointerEntries(isolate());
|
||||
result.set_foreign_address(isolate(), opt_call_target);
|
||||
result.set_ref(*ref);
|
||||
result.set_internal(*internal);
|
||||
result.set_wrapper_code(*wrapper_code);
|
||||
result.set_serialized_return_count(return_count);
|
||||
result.set_serialized_parameter_count(parameter_count);
|
||||
result.set_serialized_signature(*serialized_sig);
|
||||
// Default value, will be overwritten by the caller.
|
||||
result.set_wasm_to_js_wrapper_code(
|
||||
isolate()->builtins()->code(Builtin::kAbort));
|
||||
return handle(result, isolate());
|
||||
}
|
||||
|
||||
Handle<WasmExportedFunctionData> Factory::NewWasmExportedFunctionData(
|
||||
Handle<Code> export_wrapper, Handle<WasmInstanceObject> instance,
|
||||
Address call_target, Handle<Object> ref, int func_index,
|
||||
Address sig_address, int wrapper_budget) {
|
||||
Address sig_address, int wrapper_budget, Handle<Map> rtt) {
|
||||
Handle<Foreign> sig_foreign = NewForeign(sig_address);
|
||||
Handle<WasmInternalFunction> internal =
|
||||
NewWasmInternalFunction(call_target, Handle<HeapObject>::cast(ref), rtt);
|
||||
Map map = *wasm_exported_function_data_map();
|
||||
WasmExportedFunctionData result =
|
||||
WasmExportedFunctionData::cast(AllocateRawWithImmortalMap(
|
||||
map.instance_size(), AllocationType::kOld, map));
|
||||
DisallowGarbageCollection no_gc;
|
||||
result.AllocateExternalPointerEntries(isolate());
|
||||
result.set_foreign_address(isolate(), call_target);
|
||||
DCHECK(ref->IsWasmInstanceObject() || ref->IsWasmApiFunctionRef());
|
||||
result.set_ref(*ref);
|
||||
result.set_internal(*internal);
|
||||
result.set_wrapper_code(*export_wrapper);
|
||||
result.set_instance(*instance);
|
||||
result.set_function_index(func_index);
|
||||
@ -1568,17 +1580,17 @@ Handle<WasmExportedFunctionData> Factory::NewWasmExportedFunctionData(
|
||||
|
||||
Handle<WasmCapiFunctionData> Factory::NewWasmCapiFunctionData(
|
||||
Address call_target, Handle<Foreign> embedder_data,
|
||||
Handle<Code> wrapper_code,
|
||||
Handle<Code> wrapper_code, Handle<Map> rtt,
|
||||
Handle<PodArray<wasm::ValueType>> serialized_sig) {
|
||||
Handle<WasmApiFunctionRef> ref = NewWasmApiFunctionRef(Handle<JSReceiver>());
|
||||
Handle<WasmInternalFunction> internal =
|
||||
NewWasmInternalFunction(call_target, ref, rtt);
|
||||
Map map = *wasm_capi_function_data_map();
|
||||
WasmCapiFunctionData result =
|
||||
WasmCapiFunctionData::cast(AllocateRawWithImmortalMap(
|
||||
map.instance_size(), AllocationType::kOld, map));
|
||||
DisallowGarbageCollection no_gc;
|
||||
result.AllocateExternalPointerEntries(isolate());
|
||||
result.set_foreign_address(isolate(), call_target);
|
||||
result.set_ref(*ref);
|
||||
result.set_internal(*internal);
|
||||
result.set_wrapper_code(*wrapper_code);
|
||||
result.set_embedder_data(*embedder_data);
|
||||
result.set_serialized_signature(*serialized_sig);
|
||||
|
@ -584,21 +584,24 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
|
||||
Handle<Map> opt_parent,
|
||||
int instance_size_bytes,
|
||||
Handle<WasmInstanceObject> instance);
|
||||
Handle<WasmInternalFunction> NewWasmInternalFunction(Address opt_call_target,
|
||||
Handle<HeapObject> ref,
|
||||
Handle<Map> rtt);
|
||||
Handle<WasmCapiFunctionData> NewWasmCapiFunctionData(
|
||||
Address call_target, Handle<Foreign> embedder_data,
|
||||
Handle<Code> wrapper_code,
|
||||
Handle<Code> wrapper_code, Handle<Map> rtt,
|
||||
Handle<PodArray<wasm::ValueType>> serialized_sig);
|
||||
Handle<WasmExportedFunctionData> NewWasmExportedFunctionData(
|
||||
Handle<Code> export_wrapper, Handle<WasmInstanceObject> instance,
|
||||
Address call_target, Handle<Object> ref, int func_index,
|
||||
Address sig_address, int wrapper_budget);
|
||||
Address sig_address, int wrapper_budget, Handle<Map> rtt);
|
||||
Handle<WasmApiFunctionRef> NewWasmApiFunctionRef(Handle<JSReceiver> callable);
|
||||
// {opt_call_target} is kNullAddress for JavaScript functions, and
|
||||
// non-null for exported Wasm functions.
|
||||
Handle<WasmJSFunctionData> NewWasmJSFunctionData(
|
||||
Address opt_call_target, Handle<JSReceiver> callable, int return_count,
|
||||
int parameter_count, Handle<PodArray<wasm::ValueType>> serialized_sig,
|
||||
Handle<Code> wrapper_code);
|
||||
Handle<Code> wrapper_code, Handle<Map> rtt);
|
||||
Handle<WasmStruct> NewWasmStruct(const wasm::StructType* type,
|
||||
wasm::WasmValue* args, Handle<Map> map);
|
||||
Handle<WasmArray> NewWasmArray(const wasm::ArrayType* type,
|
||||
|
@ -50,14 +50,15 @@ namespace internal {
|
||||
V(Symbol) \
|
||||
V(SyntheticModule) \
|
||||
V(TransitionArray) \
|
||||
IF_WASM(V, WasmApiFunctionRef) \
|
||||
IF_WASM(V, WasmArray) \
|
||||
IF_WASM(V, WasmCapiFunctionData) \
|
||||
IF_WASM(V, WasmExportedFunctionData) \
|
||||
IF_WASM(V, WasmFunctionData) \
|
||||
IF_WASM(V, WasmIndirectFunctionTable) \
|
||||
IF_WASM(V, WasmInstanceObject) \
|
||||
IF_WASM(V, WasmInternalFunction) \
|
||||
IF_WASM(V, WasmJSFunctionData) \
|
||||
IF_WASM(V, WasmApiFunctionRef) \
|
||||
IF_WASM(V, WasmStruct) \
|
||||
IF_WASM(V, WasmSuspenderObject) \
|
||||
IF_WASM(V, WasmTypeInfo)
|
||||
|
@ -503,12 +503,14 @@ bool Heap::CreateInitialMaps() {
|
||||
ALLOCATE_MAP(CODE_DATA_CONTAINER_TYPE, CodeDataContainer::kSize,
|
||||
code_data_container)
|
||||
|
||||
IF_WASM(ALLOCATE_MAP, WASM_API_FUNCTION_REF_TYPE, WasmApiFunctionRef::kSize,
|
||||
wasm_api_function_ref)
|
||||
IF_WASM(ALLOCATE_MAP, WASM_CAPI_FUNCTION_DATA_TYPE,
|
||||
WasmCapiFunctionData::kSize, wasm_capi_function_data)
|
||||
IF_WASM(ALLOCATE_MAP, WASM_EXPORTED_FUNCTION_DATA_TYPE,
|
||||
WasmExportedFunctionData::kSize, wasm_exported_function_data)
|
||||
IF_WASM(ALLOCATE_MAP, WASM_API_FUNCTION_REF_TYPE, WasmApiFunctionRef::kSize,
|
||||
wasm_api_function_ref)
|
||||
IF_WASM(ALLOCATE_MAP, WASM_INTERNAL_FUNCTION_TYPE,
|
||||
WasmInternalFunction::kSize, wasm_internal_function)
|
||||
IF_WASM(ALLOCATE_MAP, WASM_JS_FUNCTION_DATA_TYPE, WasmJSFunctionData::kSize,
|
||||
wasm_js_function_data)
|
||||
IF_WASM(ALLOCATE_MAP, WASM_TYPE_INFO_TYPE, WasmTypeInfo::kSize,
|
||||
|
@ -790,7 +790,8 @@ ACCESSORS_CHECKED(Map, native_context_or_null, Object,
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
ACCESSORS_CHECKED(Map, wasm_type_info, WasmTypeInfo,
|
||||
kConstructorOrBackPointerOrNativeContextOffset,
|
||||
IsWasmStructMap() || IsWasmArrayMap())
|
||||
IsWasmStructMap() || IsWasmArrayMap() ||
|
||||
IsWasmInternalFunctionMap())
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
|
||||
bool Map::IsPrototypeValidityCellValid() const {
|
||||
|
@ -366,6 +366,8 @@ VisitorId Map::GetVisitorId(Map map) {
|
||||
return kVisitWasmStruct;
|
||||
case WASM_TYPE_INFO_TYPE:
|
||||
return kVisitWasmTypeInfo;
|
||||
case WASM_INTERNAL_FUNCTION_TYPE:
|
||||
return kVisitWasmInternalFunction;
|
||||
case WASM_JS_FUNCTION_DATA_TYPE:
|
||||
return kVisitWasmJSFunctionData;
|
||||
case WASM_API_FUNCTION_REF_TYPE:
|
||||
|
@ -68,14 +68,15 @@ enum InstanceType : uint16_t;
|
||||
V(Symbol) \
|
||||
V(SyntheticModule) \
|
||||
V(TransitionArray) \
|
||||
IF_WASM(V, WasmApiFunctionRef) \
|
||||
IF_WASM(V, WasmArray) \
|
||||
IF_WASM(V, WasmCapiFunctionData) \
|
||||
IF_WASM(V, WasmExportedFunctionData) \
|
||||
IF_WASM(V, WasmFunctionData) \
|
||||
IF_WASM(V, WasmIndirectFunctionTable) \
|
||||
IF_WASM(V, WasmInstanceObject) \
|
||||
IF_WASM(V, WasmInternalFunction) \
|
||||
IF_WASM(V, WasmJSFunctionData) \
|
||||
IF_WASM(V, WasmApiFunctionRef) \
|
||||
IF_WASM(V, WasmStruct) \
|
||||
IF_WASM(V, WasmSuspenderObject) \
|
||||
IF_WASM(V, WasmTypeInfo) \
|
||||
|
@ -232,6 +232,7 @@ class ZoneForwardList;
|
||||
V(UncompiledDataWithoutPreparseData) \
|
||||
V(Undetectable) \
|
||||
V(UniqueName) \
|
||||
IF_WASM(V, WasmApiFunctionRef) \
|
||||
IF_WASM(V, WasmArray) \
|
||||
IF_WASM(V, WasmCapiFunctionData) \
|
||||
IF_WASM(V, WasmTagObject) \
|
||||
@ -239,9 +240,9 @@ class ZoneForwardList;
|
||||
IF_WASM(V, WasmExportedFunctionData) \
|
||||
IF_WASM(V, WasmFunctionData) \
|
||||
IF_WASM(V, WasmGlobalObject) \
|
||||
IF_WASM(V, WasmInternalFunction) \
|
||||
IF_WASM(V, WasmInstanceObject) \
|
||||
IF_WASM(V, WasmJSFunctionData) \
|
||||
IF_WASM(V, WasmApiFunctionRef) \
|
||||
IF_WASM(V, WasmMemoryObject) \
|
||||
IF_WASM(V, WasmModuleObject) \
|
||||
IF_WASM(V, WasmObject) \
|
||||
|
@ -624,24 +624,6 @@ class WasmTypeInfo::BodyDescriptor final : public BodyDescriptorBase {
|
||||
static inline int SizeOf(Map map, HeapObject object) { return kSize; }
|
||||
};
|
||||
|
||||
class WasmJSFunctionData::BodyDescriptor final : public BodyDescriptorBase {
|
||||
public:
|
||||
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template <typename ObjectVisitor>
|
||||
static inline void IterateBody(Map map, HeapObject obj, int object_size,
|
||||
ObjectVisitor* v) {
|
||||
Foreign::BodyDescriptor::IterateBody<ObjectVisitor>(map, obj, object_size,
|
||||
v);
|
||||
IteratePointers(obj, WasmFunctionData::kStartOfStrongFieldsOffset,
|
||||
kEndOfStrongFieldsOffset, v);
|
||||
}
|
||||
|
||||
static inline int SizeOf(Map map, HeapObject object) { return kSize; }
|
||||
};
|
||||
|
||||
class WasmApiFunctionRef::BodyDescriptor final : public BodyDescriptorBase {
|
||||
public:
|
||||
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
|
||||
@ -658,8 +640,7 @@ class WasmApiFunctionRef::BodyDescriptor final : public BodyDescriptorBase {
|
||||
static inline int SizeOf(Map map, HeapObject object) { return kSize; }
|
||||
};
|
||||
|
||||
class WasmExportedFunctionData::BodyDescriptor final
|
||||
: public BodyDescriptorBase {
|
||||
class WasmInternalFunction::BodyDescriptor final : public BodyDescriptorBase {
|
||||
public:
|
||||
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
|
||||
UNREACHABLE();
|
||||
@ -670,26 +651,8 @@ class WasmExportedFunctionData::BodyDescriptor final
|
||||
ObjectVisitor* v) {
|
||||
Foreign::BodyDescriptor::IterateBody<ObjectVisitor>(map, obj, object_size,
|
||||
v);
|
||||
IteratePointers(obj, WasmFunctionData::kStartOfStrongFieldsOffset,
|
||||
kEndOfStrongFieldsOffset, v);
|
||||
}
|
||||
|
||||
static inline int SizeOf(Map map, HeapObject object) { return kSize; }
|
||||
};
|
||||
|
||||
class WasmCapiFunctionData::BodyDescriptor final : public BodyDescriptorBase {
|
||||
public:
|
||||
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template <typename ObjectVisitor>
|
||||
static inline void IterateBody(Map map, HeapObject obj, int object_size,
|
||||
ObjectVisitor* v) {
|
||||
Foreign::BodyDescriptor::IterateBody<ObjectVisitor>(map, obj, object_size,
|
||||
v);
|
||||
IteratePointers(obj, WasmFunctionData::kStartOfStrongFieldsOffset,
|
||||
kEndOfStrongFieldsOffset, v);
|
||||
IteratePointers(obj, kStartOfStrongFieldsOffset, kEndOfStrongFieldsOffset,
|
||||
v);
|
||||
}
|
||||
|
||||
static inline int SizeOf(Map map, HeapObject object) { return kSize; }
|
||||
@ -1066,6 +1029,9 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
|
||||
case COVERAGE_INFO_TYPE:
|
||||
return Op::template apply<CoverageInfo::BodyDescriptor>(p1, p2, p3, p4);
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
case WASM_API_FUNCTION_REF_TYPE:
|
||||
return Op::template apply<WasmApiFunctionRef::BodyDescriptor>(p1, p2, p3,
|
||||
p4);
|
||||
case WASM_ARRAY_TYPE:
|
||||
return Op::template apply<WasmArray::BodyDescriptor>(p1, p2, p3, p4);
|
||||
case WASM_CAPI_FUNCTION_DATA_TYPE:
|
||||
@ -1074,12 +1040,12 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
|
||||
case WASM_EXPORTED_FUNCTION_DATA_TYPE:
|
||||
return Op::template apply<WasmExportedFunctionData::BodyDescriptor>(
|
||||
p1, p2, p3, p4);
|
||||
case WASM_INTERNAL_FUNCTION_TYPE:
|
||||
return Op::template apply<WasmInternalFunction::BodyDescriptor>(p1, p2,
|
||||
p3, p4);
|
||||
case WASM_JS_FUNCTION_DATA_TYPE:
|
||||
return Op::template apply<WasmJSFunctionData::BodyDescriptor>(p1, p2, p3,
|
||||
p4);
|
||||
case WASM_API_FUNCTION_REF_TYPE:
|
||||
return Op::template apply<WasmApiFunctionRef::BodyDescriptor>(p1, p2, p3,
|
||||
p4);
|
||||
case WASM_STRUCT_TYPE:
|
||||
return Op::template apply<WasmStruct::BodyDescriptor>(p1, p2, p3, p4);
|
||||
case WASM_TYPE_INFO_TYPE:
|
||||
|
@ -111,11 +111,12 @@ class Symbol;
|
||||
V(Map, source_text_module_map, SourceTextModuleMap) \
|
||||
V(Map, swiss_name_dictionary_map, SwissNameDictionaryMap) \
|
||||
V(Map, synthetic_module_map, SyntheticModuleMap) \
|
||||
IF_WASM(V, Map, wasm_api_function_ref_map, WasmApiFunctionRefMap) \
|
||||
IF_WASM(V, Map, wasm_capi_function_data_map, WasmCapiFunctionDataMap) \
|
||||
IF_WASM(V, Map, wasm_exported_function_data_map, \
|
||||
WasmExportedFunctionDataMap) \
|
||||
IF_WASM(V, Map, wasm_internal_function_map, WasmInternalFunctionMap) \
|
||||
IF_WASM(V, Map, wasm_js_function_data_map, WasmJSFunctionDataMap) \
|
||||
IF_WASM(V, Map, wasm_api_function_ref_map, WasmApiFunctionRefMap) \
|
||||
IF_WASM(V, Map, wasm_type_info_map, WasmTypeInfoMap) \
|
||||
V(Map, weak_fixed_array_map, WeakFixedArrayMap) \
|
||||
V(Map, weak_array_list_map, WeakArrayListMap) \
|
||||
|
@ -232,10 +232,12 @@ RUNTIME_FUNCTION(Runtime_WasmCompileLazy) {
|
||||
namespace {
|
||||
void ReplaceWrapper(Isolate* isolate, Handle<WasmInstanceObject> instance,
|
||||
int function_index, Handle<Code> wrapper_code) {
|
||||
Handle<WasmExternalFunction> exported_function =
|
||||
WasmInstanceObject::GetWasmExternalFunction(isolate, instance,
|
||||
Handle<WasmInternalFunction> internal =
|
||||
WasmInstanceObject::GetWasmInternalFunction(isolate, instance,
|
||||
function_index)
|
||||
.ToHandleChecked();
|
||||
Handle<WasmExternalFunction> exported_function =
|
||||
handle(WasmExternalFunction::cast(internal->external()), isolate);
|
||||
exported_function->set_code(*wrapper_code, kReleaseStore);
|
||||
WasmExportedFunctionData function_data =
|
||||
exported_function->shared().wasm_exported_function_data();
|
||||
@ -260,11 +262,9 @@ RUNTIME_FUNCTION(Runtime_WasmCompileWrapper) {
|
||||
// an exported function (although it is called as one).
|
||||
// If there is no entry for the start function,
|
||||
// the tier-up is abandoned.
|
||||
MaybeHandle<WasmExternalFunction> maybe_exported_function =
|
||||
WasmInstanceObject::GetWasmExternalFunction(isolate, instance,
|
||||
function_index);
|
||||
Handle<WasmExternalFunction> exported_function;
|
||||
if (!maybe_exported_function.ToHandle(&exported_function)) {
|
||||
if (WasmInstanceObject::GetWasmInternalFunction(isolate, instance,
|
||||
function_index)
|
||||
.is_null()) {
|
||||
DCHECK_EQ(function_index, module->start_function_index);
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
@ -398,11 +398,8 @@ RUNTIME_FUNCTION(Runtime_WasmRefFunc) {
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
|
||||
CONVERT_UINT32_ARG_CHECKED(function_index, 1);
|
||||
|
||||
Handle<WasmExternalFunction> function =
|
||||
WasmInstanceObject::GetOrCreateWasmExternalFunction(isolate, instance,
|
||||
function_index);
|
||||
|
||||
return *function;
|
||||
return *WasmInstanceObject::GetOrCreateWasmInternalFunction(isolate, instance,
|
||||
function_index);
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_WasmFunctionTableGet) {
|
||||
|
@ -5435,13 +5435,12 @@ class LiftoffCompiler {
|
||||
obj.type.kind(), obj_reg.gp(), tmp1.gp());
|
||||
}
|
||||
|
||||
// Perform a regular type check. Check for exact match first.
|
||||
__ LoadMap(tmp1.gp(), obj_reg.gp());
|
||||
// {tmp1} now holds the object's map.
|
||||
|
||||
if (decoder->module_->has_signature(rtt.type.ref_index())) {
|
||||
// Function case: currently, the only way for a function to match an rtt
|
||||
// is if its map is equal to that rtt.
|
||||
// Function case: currently, the only way for the type check to succeed is
|
||||
// that the function's map equals the rtt.
|
||||
__ emit_cond_jump(kUnequal, no_match, rtt.type.kind(), tmp1.gp(),
|
||||
rtt_reg.gp());
|
||||
__ bind(&match);
|
||||
@ -5625,7 +5624,8 @@ class LiftoffCompiler {
|
||||
__ Load(tmp1, tmp1.gp(), no_reg,
|
||||
wasm::ObjectAccess::ToTagged(Map::kInstanceTypeOffset),
|
||||
LoadType::kI32Load16U, pinned);
|
||||
__ emit_i32_cond_jumpi(kUnequal, no_match, tmp1.gp(), JS_FUNCTION_TYPE);
|
||||
__ emit_i32_cond_jumpi(kUnequal, no_match, tmp1.gp(),
|
||||
WASM_INTERNAL_FUNCTION_TYPE);
|
||||
|
||||
return obj_reg;
|
||||
}
|
||||
@ -6033,7 +6033,8 @@ class LiftoffCompiler {
|
||||
__ LoadConstant(index, WasmValue::ForUintPtr(vector_slot));
|
||||
LiftoffAssembler::VarState index_var(kIntPtrKind, index, 0);
|
||||
|
||||
// CallRefIC(vector: FixedArray, index: intptr, funcref: JSFunction)
|
||||
// CallRefIC(vector: FixedArray, index: intptr,
|
||||
// funcref: WasmInternalFunction)
|
||||
CallRuntimeStub(WasmCode::kCallRefIC,
|
||||
MakeSig::Returns(kPointerKind, kPointerKind)
|
||||
.Params(kPointerKind, kIntPtrKind, kPointerKind),
|
||||
@ -6063,32 +6064,22 @@ class LiftoffCompiler {
|
||||
LiftoffRegister target = pinned.set(__ GetUnusedRegister(kGpReg, pinned));
|
||||
LiftoffRegister temp = pinned.set(__ GetUnusedRegister(kGpReg, pinned));
|
||||
|
||||
// Load the WasmFunctionData.
|
||||
LiftoffRegister func_data = func_ref;
|
||||
__ LoadTaggedPointer(
|
||||
func_data.gp(), func_ref.gp(), no_reg,
|
||||
wasm::ObjectAccess::ToTagged(JSFunction::kSharedFunctionInfoOffset),
|
||||
pinned);
|
||||
__ LoadTaggedPointer(
|
||||
func_data.gp(), func_data.gp(), no_reg,
|
||||
wasm::ObjectAccess::ToTagged(SharedFunctionInfo::kFunctionDataOffset),
|
||||
pinned);
|
||||
|
||||
// Load "ref" (instance or WasmApiFunctionRef) and target.
|
||||
__ LoadTaggedPointer(
|
||||
instance.gp(), func_data.gp(), no_reg,
|
||||
wasm::ObjectAccess::ToTagged(WasmFunctionData::kRefOffset), pinned);
|
||||
instance.gp(), func_ref.gp(), no_reg,
|
||||
wasm::ObjectAccess::ToTagged(WasmInternalFunction::kRefOffset),
|
||||
pinned);
|
||||
|
||||
#ifdef V8_HEAP_SANDBOX
|
||||
LOAD_INSTANCE_FIELD(temp.gp(), IsolateRoot, kSystemPointerSize, pinned);
|
||||
__ LoadExternalPointer(target.gp(), func_data.gp(),
|
||||
WasmFunctionData::kForeignAddressOffset,
|
||||
WasmInternalFunction::kForeignAddressOffset,
|
||||
kForeignForeignAddressTag, temp.gp());
|
||||
#else
|
||||
__ Load(
|
||||
target, func_data.gp(), no_reg,
|
||||
wasm::ObjectAccess::ToTagged(WasmFunctionData::kForeignAddressOffset),
|
||||
kPointerLoadType, pinned);
|
||||
__ Load(target, func_ref.gp(), no_reg,
|
||||
wasm::ObjectAccess::ToTagged(
|
||||
WasmInternalFunction::kForeignAddressOffset),
|
||||
kPointerLoadType, pinned);
|
||||
#endif
|
||||
|
||||
Label perform_call;
|
||||
@ -6098,10 +6089,10 @@ class LiftoffCompiler {
|
||||
__ emit_cond_jump(kUnequal, &perform_call, kRef, target.gp(),
|
||||
null_address.gp());
|
||||
// The cached target can only be null for WasmJSFunctions.
|
||||
__ LoadTaggedPointer(target.gp(), func_data.gp(), no_reg,
|
||||
wasm::ObjectAccess::ToTagged(
|
||||
WasmJSFunctionData::kWasmToJsWrapperCodeOffset),
|
||||
pinned);
|
||||
__ LoadTaggedPointer(
|
||||
target.gp(), func_ref.gp(), no_reg,
|
||||
wasm::ObjectAccess::ToTagged(WasmInternalFunction::kCodeOffset),
|
||||
pinned);
|
||||
#ifdef V8_EXTERNAL_CODE_SPACE
|
||||
__ LoadCodeDataContainerEntry(target.gp(), target.gp());
|
||||
#else
|
||||
|
@ -1443,7 +1443,7 @@ auto make_func(Store* store_abs, FuncData* data) -> own<Func> {
|
||||
isolate, reinterpret_cast<i::Address>(&FuncData::v8_callback),
|
||||
embedder_data, SignatureHelper::Serialize(isolate, data->type.get()));
|
||||
i::WasmApiFunctionRef::cast(
|
||||
function->shared().wasm_capi_function_data().ref())
|
||||
function->shared().wasm_capi_function_data().internal().ref())
|
||||
.set_callable(*function);
|
||||
auto func = implement<Func>::type::make(store, function);
|
||||
return func;
|
||||
@ -1670,7 +1670,7 @@ auto Func::call(const Val args[], Val results[]) const -> own<Trap> {
|
||||
// TODO(v8:11880): avoid roundtrips between cdc and code.
|
||||
i::Handle<i::CodeT> wrapper_code = i::Handle<i::CodeT>(
|
||||
i::CodeT::cast(function_data->c_wrapper_code()), isolate);
|
||||
i::Address call_target = function_data->foreign_address();
|
||||
i::Address call_target = function_data->internal().foreign_address();
|
||||
|
||||
i::wasm::CWasmArgumentsPacker packer(function_data->packed_args_size());
|
||||
PushArgs(sig, args, &packer, store);
|
||||
@ -1996,6 +1996,10 @@ auto Table::get(size_t index) const -> own<Ref> {
|
||||
i::WasmTableObject::Get(isolate, table, static_cast<uint32_t>(index));
|
||||
// TODO(jkummerow): If we support both JavaScript and the C-API at the same
|
||||
// time, we need to handle Smis and other JS primitives here.
|
||||
if (result->IsWasmInternalFunction()) {
|
||||
result = handle(
|
||||
i::Handle<i::WasmInternalFunction>::cast(result)->external(), isolate);
|
||||
}
|
||||
DCHECK(result->IsNull(isolate) || result->IsJSReceiver());
|
||||
return V8RefValueToWasm(impl(this)->store(), result);
|
||||
}
|
||||
@ -2006,7 +2010,11 @@ auto Table::set(size_t index, const Ref* ref) -> bool {
|
||||
i::Isolate* isolate = table->GetIsolate();
|
||||
i::HandleScope handle_scope(isolate);
|
||||
i::Handle<i::Object> obj = WasmRefToV8(isolate, ref);
|
||||
i::WasmTableObject::Set(isolate, table, static_cast<uint32_t>(index), obj);
|
||||
i::Handle<i::Object> entry;
|
||||
if (!i::WasmInternalFunction::FromExternal(obj, isolate).ToHandle(&entry)) {
|
||||
entry = obj;
|
||||
}
|
||||
i::WasmTableObject::Set(isolate, table, static_cast<uint32_t>(index), entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2019,7 +2027,12 @@ auto Table::grow(size_t delta, const Ref* ref) -> bool {
|
||||
i::Handle<i::WasmTableObject> table = impl(this)->v8_object();
|
||||
i::Isolate* isolate = table->GetIsolate();
|
||||
i::HandleScope scope(isolate);
|
||||
i::Handle<i::Object> init_value = WasmRefToV8(isolate, ref);
|
||||
i::Handle<i::Object> obj = WasmRefToV8(isolate, ref);
|
||||
i::Handle<i::Object> init_value;
|
||||
if (!i::WasmInternalFunction::FromExternal(obj, isolate)
|
||||
.ToHandle(&init_value)) {
|
||||
init_value = obj;
|
||||
}
|
||||
int result = i::WasmTableObject::Grow(
|
||||
isolate, table, static_cast<uint32_t>(delta), init_value);
|
||||
return result >= 0;
|
||||
|
@ -695,7 +695,7 @@ class WasmGraphBuildingInterface {
|
||||
|
||||
TFNode* success_control;
|
||||
TFNode* failure_control;
|
||||
builder_->CompareToExternalFunctionAtIndex(
|
||||
builder_->CompareToInternalFunctionAtIndex(
|
||||
func_ref.node, expected_function_index, &success_control,
|
||||
&failure_control);
|
||||
TFNode* initial_effect = effect();
|
||||
@ -766,7 +766,7 @@ class WasmGraphBuildingInterface {
|
||||
|
||||
TFNode* success_control;
|
||||
TFNode* failure_control;
|
||||
builder_->CompareToExternalFunctionAtIndex(
|
||||
builder_->CompareToInternalFunctionAtIndex(
|
||||
func_ref.node, expected_function_index, &success_control,
|
||||
&failure_control);
|
||||
TFNode* initial_effect = effect();
|
||||
|
@ -53,10 +53,10 @@ void InitExprInterface::RefNull(FullDecoder* decoder, ValueType type,
|
||||
void InitExprInterface::RefFunc(FullDecoder* decoder, uint32_t function_index,
|
||||
Value* result) {
|
||||
if (isolate_ != nullptr) {
|
||||
auto function = WasmInstanceObject::GetOrCreateWasmExternalFunction(
|
||||
auto internal = WasmInstanceObject::GetOrCreateWasmInternalFunction(
|
||||
isolate_, instance_, function_index);
|
||||
result->runtime_value = WasmValue(
|
||||
function, ValueType::Ref(module_->functions[function_index].sig_index,
|
||||
internal, ValueType::Ref(module_->functions[function_index].sig_index,
|
||||
kNonNullable));
|
||||
} else {
|
||||
outer_module_->functions[function_index].declared = true;
|
||||
|
@ -1253,10 +1253,11 @@ std::vector<CallSiteFeedback> ProcessTypeFeedback(
|
||||
static_cast<int>(instance->module()->num_imported_functions);
|
||||
for (int i = 0; i < feedback.length(); i += 2) {
|
||||
Object value = feedback.get(i);
|
||||
if (WasmExportedFunction::IsWasmExportedFunction(value)) {
|
||||
if (value.IsWasmInternalFunction()) {
|
||||
// Monomorphic. Mark the target for inlining if it's defined in the
|
||||
// same module.
|
||||
WasmExportedFunction target = WasmExportedFunction::cast(value);
|
||||
WasmExportedFunction target = WasmExportedFunction::cast(
|
||||
WasmInternalFunction::cast(value).external());
|
||||
if (target.instance() == *instance &&
|
||||
target.function_index() >= imported_functions) {
|
||||
if (FLAG_trace_wasm_speculative_inlining) {
|
||||
@ -1286,11 +1287,11 @@ std::vector<CallSiteFeedback> ProcessTypeFeedback(
|
||||
if (frequency > best_frequency) best_frequency = frequency;
|
||||
if (frequency < 0.8) continue;
|
||||
Object maybe_target = polymorphic.get(j);
|
||||
if (!WasmExportedFunction::IsWasmExportedFunction(maybe_target)) {
|
||||
if (!maybe_target.IsWasmInternalFunction()) {
|
||||
continue;
|
||||
}
|
||||
WasmExportedFunction target =
|
||||
WasmExportedFunction::cast(polymorphic.get(j));
|
||||
WasmExportedFunction target = WasmExportedFunction::cast(
|
||||
WasmInternalFunction::cast(polymorphic.get(j)).external());
|
||||
if (target.instance() != *instance ||
|
||||
target.function_index() < imported_functions) {
|
||||
continue;
|
||||
|
@ -196,6 +196,23 @@ Handle<Map> CreateArrayMap(Isolate* isolate, const WasmModule* module,
|
||||
return map;
|
||||
}
|
||||
|
||||
Handle<Map> CreateFuncRefMap(Isolate* isolate, const WasmModule* module,
|
||||
Handle<Map> opt_rtt_parent,
|
||||
Handle<WasmInstanceObject> instance) {
|
||||
const int inobject_properties = 0;
|
||||
const int instance_size =
|
||||
Map::cast(isolate->root(RootIndex::kWasmInternalFunctionMap))
|
||||
.instance_size();
|
||||
const InstanceType instance_type = WASM_INTERNAL_FUNCTION_TYPE;
|
||||
const ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND;
|
||||
Handle<WasmTypeInfo> type_info = isolate->factory()->NewWasmTypeInfo(
|
||||
kNullAddress, opt_rtt_parent, instance_size, instance);
|
||||
Handle<Map> map = isolate->factory()->NewMap(
|
||||
instance_type, instance_size, elements_kind, inobject_properties);
|
||||
map->set_wasm_type_info(*type_info);
|
||||
return map;
|
||||
}
|
||||
|
||||
void CreateMapForType(Isolate* isolate, const WasmModule* module,
|
||||
int type_index, Handle<WasmInstanceObject> instance,
|
||||
Handle<FixedArray> maps) {
|
||||
@ -221,11 +238,9 @@ void CreateMapForType(Isolate* isolate, const WasmModule* module,
|
||||
map = CreateArrayMap(isolate, module, type_index, rtt_parent, instance);
|
||||
break;
|
||||
case kWasmFunctionTypeCode:
|
||||
// TODO(7748): Think about canonicalizing rtts to make them work for
|
||||
// identical function types.
|
||||
map = Map::Copy(isolate, isolate->wasm_exported_function_map(),
|
||||
"fresh function map for function type canonical rtt "
|
||||
"initialization");
|
||||
// TODO(7748): Create funcref RTTs lazily?
|
||||
// TODO(7748): Canonicalize function maps (cross-module)?
|
||||
map = CreateFuncRefMap(isolate, module, rtt_parent, instance);
|
||||
break;
|
||||
}
|
||||
maps->set(type_index, *map);
|
||||
@ -265,17 +280,14 @@ Handle<Map> AllocateSubRtt(Isolate* isolate,
|
||||
Handle<WasmInstanceObject> instance, uint32_t type,
|
||||
Handle<Map> parent, WasmRttSubMode mode) {
|
||||
DCHECK(parent->IsWasmStructMap() || parent->IsWasmArrayMap() ||
|
||||
parent->IsJSFunctionMap());
|
||||
parent->IsWasmInternalFunctionMap());
|
||||
|
||||
const wasm::WasmModule* module = instance->module();
|
||||
if (module->has_signature(type)) {
|
||||
// Currently, parent rtts for functions are meaningless,
|
||||
// since (rtt.test func rtt) iff (func.map == rtt).
|
||||
// Therefore, we simply create a fresh function map here.
|
||||
// TODO(7748): Canonicalize rtts to make them work for identical function
|
||||
// types.
|
||||
return Map::Copy(isolate, isolate->wasm_exported_function_map(),
|
||||
"fresh function map for AllocateSubRtt");
|
||||
// Function references are implicitly allocated with their canonical rtt,
|
||||
// and type checks against sub-rtts will always fail. Therefore, we simply
|
||||
// create a fresh function map here.
|
||||
return CreateFuncRefMap(isolate, module, Handle<Map>(), instance);
|
||||
}
|
||||
// If canonicalization is requested, check for an existing RTT first.
|
||||
Handle<ArrayList> cache;
|
||||
@ -1059,9 +1071,11 @@ bool InstanceBuilder::ProcessImportedFunction(
|
||||
// is resolved to preserve its identity. This handles exported functions as
|
||||
// well as functions constructed via other means (e.g. WebAssembly.Function).
|
||||
if (WasmExternalFunction::IsWasmExternalFunction(*value)) {
|
||||
WasmInstanceObject::SetWasmExternalFunction(
|
||||
WasmInstanceObject::SetWasmInternalFunction(
|
||||
isolate_, instance, func_index,
|
||||
Handle<WasmExternalFunction>::cast(value));
|
||||
WasmInternalFunction::FromExternal(
|
||||
Handle<WasmExternalFunction>::cast(value), isolate_)
|
||||
.ToHandleChecked());
|
||||
}
|
||||
auto js_receiver = Handle<JSReceiver>::cast(value);
|
||||
const FunctionSig* expected_sig = module_->functions[func_index].sig;
|
||||
@ -1460,7 +1474,12 @@ bool InstanceBuilder::ProcessImportedGlobal(Handle<WasmInstanceObject> instance,
|
||||
ReportLinkError(error_message, global_index, module_name, import_name);
|
||||
return false;
|
||||
}
|
||||
WriteGlobalValue(global, WasmValue(value, global.type));
|
||||
auto stored_value =
|
||||
WasmExternalFunction::IsWasmExternalFunction(*value)
|
||||
? WasmInternalFunction::FromExternal(value, isolate_)
|
||||
.ToHandleChecked()
|
||||
: value;
|
||||
WriteGlobalValue(global, WasmValue(stored_value, global.type));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1705,9 +1724,11 @@ void InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) {
|
||||
if (import.kind == kExternalFunction) {
|
||||
Handle<Object> value = sanitized_imports_[index].value;
|
||||
if (WasmExternalFunction::IsWasmExternalFunction(*value)) {
|
||||
WasmInstanceObject::SetWasmExternalFunction(
|
||||
WasmInstanceObject::SetWasmInternalFunction(
|
||||
isolate_, instance, import.index,
|
||||
Handle<WasmExternalFunction>::cast(value));
|
||||
WasmInternalFunction::FromExternal(
|
||||
Handle<WasmExternalFunction>::cast(value), isolate_)
|
||||
.ToHandleChecked());
|
||||
}
|
||||
} else if (import.kind == kExternalGlobal) {
|
||||
Handle<Object> value = sanitized_imports_[index].value;
|
||||
@ -1745,9 +1766,11 @@ void InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) {
|
||||
case kExternalFunction: {
|
||||
// Wrap and export the code as a JSFunction.
|
||||
// TODO(wasm): reduce duplication with LoadElemSegment() further below
|
||||
Handle<WasmExternalFunction> wasm_external_function =
|
||||
WasmInstanceObject::GetOrCreateWasmExternalFunction(
|
||||
Handle<WasmInternalFunction> internal =
|
||||
WasmInstanceObject::GetOrCreateWasmInternalFunction(
|
||||
isolate_, instance, exp.index);
|
||||
Handle<WasmExternalFunction> wasm_external_function =
|
||||
handle(WasmExternalFunction::cast(internal->external()), isolate_);
|
||||
desc.set_value(wasm_external_function);
|
||||
|
||||
if (is_asm_js &&
|
||||
@ -1888,11 +1911,11 @@ void SetFunctionTableEntry(Isolate* isolate,
|
||||
// For externref tables, we have to generate the WasmExternalFunction eagerly.
|
||||
// Later we cannot know if an entry is a placeholder or not.
|
||||
if (table_object->type().is_reference_to(HeapType::kExtern)) {
|
||||
Handle<WasmExternalFunction> wasm_external_function =
|
||||
WasmInstanceObject::GetOrCreateWasmExternalFunction(isolate, instance,
|
||||
Handle<WasmInternalFunction> wasm_internal_function =
|
||||
WasmInstanceObject::GetOrCreateWasmInternalFunction(isolate, instance,
|
||||
func_index);
|
||||
WasmTableObject::Set(isolate, table_object, entry_index,
|
||||
wasm_external_function);
|
||||
wasm_internal_function);
|
||||
} else {
|
||||
DCHECK(IsSubtypeOf(table_object->type(), kWasmFuncRef, module));
|
||||
|
||||
@ -1903,17 +1926,17 @@ void SetFunctionTableEntry(Isolate* isolate,
|
||||
->Set(entry_index, sig_id, entry.call_target(), *entry.ref());
|
||||
|
||||
// Update the table object's other dispatch tables.
|
||||
MaybeHandle<WasmExternalFunction> wasm_external_function =
|
||||
WasmInstanceObject::GetWasmExternalFunction(isolate, instance,
|
||||
MaybeHandle<WasmInternalFunction> wasm_internal_function =
|
||||
WasmInstanceObject::GetWasmInternalFunction(isolate, instance,
|
||||
func_index);
|
||||
if (wasm_external_function.is_null()) {
|
||||
if (wasm_internal_function.is_null()) {
|
||||
// No JSFunction entry yet exists for this function. Create a
|
||||
// {Tuple2} holding the information to lazily allocate one.
|
||||
WasmTableObject::SetFunctionTablePlaceholder(
|
||||
isolate, table_object, entry_index, instance, func_index);
|
||||
} else {
|
||||
table_object->entries().set(entry_index,
|
||||
*wasm_external_function.ToHandleChecked());
|
||||
*wasm_internal_function.ToHandleChecked());
|
||||
}
|
||||
// UpdateDispatchTables() updates all other dispatch tables, since
|
||||
// we have not yet added the dispatch table we are currently building.
|
||||
@ -1945,19 +1968,22 @@ void InstanceBuilder::InitializeIndirectFunctionTables(
|
||||
SetNullTableEntry(isolate_, instance, table_object, table_index,
|
||||
entry_index);
|
||||
}
|
||||
} else if (WasmExportedFunction::IsWasmExportedFunction(*value)) {
|
||||
} else if (value->IsWasmInternalFunction()) {
|
||||
Handle<Object> external = handle(
|
||||
Handle<WasmInternalFunction>::cast(value)->external(), isolate_);
|
||||
// TODO(manoskouk): Support WasmJSFunction/WasmCapiFunction.
|
||||
if (!WasmExportedFunction::IsWasmExportedFunction(*external)) {
|
||||
thrower_->TypeError(
|
||||
"Initializing a table with a Webassembly.Function object is not "
|
||||
"supported yet");
|
||||
}
|
||||
uint32_t function_index =
|
||||
Handle<WasmExportedFunction>::cast(value)->function_index();
|
||||
Handle<WasmExportedFunction>::cast(external)->function_index();
|
||||
for (uint32_t entry_index = 0; entry_index < table.initial_size;
|
||||
entry_index++) {
|
||||
SetFunctionTableEntry(isolate_, instance, table_object, table_index,
|
||||
entry_index, function_index);
|
||||
}
|
||||
} else if (WasmJSFunction::IsWasmJSFunction(*value)) {
|
||||
// TODO(manoskouk): Support WasmJSFunction.
|
||||
thrower_->TypeError(
|
||||
"Initializing a table with a Webassembly.Function object is not "
|
||||
"supported yet");
|
||||
} else {
|
||||
for (uint32_t entry_index = 0; entry_index < table.initial_size;
|
||||
entry_index++) {
|
||||
|
@ -1206,6 +1206,10 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
"with the type of the new table.");
|
||||
return;
|
||||
}
|
||||
if (element->IsJSFunction()) {
|
||||
element = i::WasmInternalFunction::FromExternal(element, i_isolate)
|
||||
.ToHandleChecked();
|
||||
}
|
||||
for (uint32_t index = 0; index < static_cast<uint32_t>(initial); ++index) {
|
||||
i::WasmTableObject::Set(i_isolate, table_obj, index, element);
|
||||
}
|
||||
@ -1976,8 +1980,14 @@ void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
init_value = DefaultReferenceValue(i_isolate, receiver->type());
|
||||
}
|
||||
|
||||
int old_size =
|
||||
i::WasmTableObject::Grow(i_isolate, receiver, grow_by, init_value);
|
||||
i::Handle<i::Object> internal_init_value;
|
||||
if (!i::WasmInternalFunction::FromExternal(init_value, i_isolate)
|
||||
.ToHandle(&internal_init_value)) {
|
||||
internal_init_value = init_value;
|
||||
}
|
||||
|
||||
int old_size = i::WasmTableObject::Grow(i_isolate, receiver, grow_by,
|
||||
internal_init_value);
|
||||
|
||||
if (old_size < 0) {
|
||||
thrower.RangeError("failed to grow table by %u", grow_by);
|
||||
@ -2007,6 +2017,11 @@ void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
|
||||
i::Handle<i::Object> result =
|
||||
i::WasmTableObject::Get(i_isolate, receiver, index);
|
||||
if (result->IsWasmInternalFunction()) {
|
||||
result =
|
||||
handle(i::Handle<i::WasmInternalFunction>::cast(result)->external(),
|
||||
i_isolate);
|
||||
}
|
||||
|
||||
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
||||
return_value.Set(Utils::ToLocal(result));
|
||||
@ -2043,7 +2058,14 @@ void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
"to 'this'");
|
||||
return;
|
||||
}
|
||||
i::WasmTableObject::Set(i_isolate, table_object, index, element);
|
||||
|
||||
i::Handle<i::Object> value;
|
||||
if (!i::WasmInternalFunction::FromExternal(element, i_isolate)
|
||||
.ToHandle(&value)) {
|
||||
value = element;
|
||||
}
|
||||
|
||||
i::WasmTableObject::Set(i_isolate, table_object, index, value);
|
||||
}
|
||||
|
||||
// WebAssembly.Table.type() -> TableType
|
||||
@ -2371,10 +2393,19 @@ void WebAssemblyGlobalGetValueCommon(
|
||||
case i::wasm::kOptRef:
|
||||
switch (receiver->type().heap_representation()) {
|
||||
case i::wasm::HeapType::kExtern:
|
||||
case i::wasm::HeapType::kFunc:
|
||||
case i::wasm::HeapType::kAny:
|
||||
return_value.Set(Utils::ToLocal(receiver->GetRef()));
|
||||
break;
|
||||
case i::wasm::HeapType::kFunc:
|
||||
case i::wasm::HeapType::kAny: {
|
||||
i::Handle<i::Object> result = receiver->GetRef();
|
||||
if (result->IsWasmInternalFunction()) {
|
||||
result = handle(
|
||||
i::Handle<i::WasmInternalFunction>::cast(result)->external(),
|
||||
i_isolate);
|
||||
}
|
||||
return_value.Set(Utils::ToLocal(result));
|
||||
break;
|
||||
}
|
||||
case internal::wasm::HeapType::kBottom:
|
||||
UNREACHABLE();
|
||||
case internal::wasm::HeapType::kI31:
|
||||
@ -2527,7 +2558,7 @@ void WebAssemblySuspenderReturnPromiseOnSuspend(
|
||||
i::WasmExportedFunctionData data = sfi.wasm_exported_function_data();
|
||||
int index = data.function_index();
|
||||
i::Handle<i::WasmInstanceObject> instance(
|
||||
i::WasmInstanceObject::cast(data.ref()), i_isolate);
|
||||
i::WasmInstanceObject::cast(data.internal().ref()), i_isolate);
|
||||
i::Handle<i::Code> wrapper = i_isolate->builtins()->code_handle(
|
||||
i::Builtin::kWasmReturnPromiseOnSuspend);
|
||||
i::Handle<i::JSObject> result =
|
||||
|
@ -314,9 +314,10 @@ struct V8_EXPORT_PRIVATE WasmModule {
|
||||
std::vector<TypeDefinition> types; // by type index
|
||||
std::vector<uint8_t> type_kinds; // by type index
|
||||
std::vector<uint32_t> supertypes; // by type index
|
||||
// Map from each type index to the index of its corresponding canonical type.
|
||||
// Map from each type index to the index of its corresponding canonical index.
|
||||
// Canonical indices do not correspond to types.
|
||||
// Note: right now, only functions are canonicalized, and arrays and structs
|
||||
// map to themselves.
|
||||
// map to 0.
|
||||
std::vector<uint32_t> canonicalized_type_ids;
|
||||
|
||||
bool has_type(uint32_t index) const { return index < types.size(); }
|
||||
|
@ -48,6 +48,7 @@ TQ_OBJECT_CONSTRUCTORS_IMPL(WasmTableObject)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(AsmWasmData)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmFunctionData)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmApiFunctionRef)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmInternalFunction)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmTypeInfo)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmStruct)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmArray)
|
||||
@ -177,13 +178,12 @@ void WasmGlobalObject::SetExternRef(Handle<Object> value) {
|
||||
|
||||
bool WasmGlobalObject::SetFuncRef(Isolate* isolate, Handle<Object> value) {
|
||||
DCHECK_EQ(type(), wasm::kWasmFuncRef);
|
||||
if (!value->IsNull(isolate) &&
|
||||
!WasmExternalFunction::IsWasmExternalFunction(*value) &&
|
||||
!WasmCapiFunction::IsWasmCapiFunction(*value)) {
|
||||
return false;
|
||||
if (value->IsNull() ||
|
||||
WasmInternalFunction::FromExternal(value, isolate).ToHandle(&value)) {
|
||||
tagged_buffer().set(offset(), *value);
|
||||
return true;
|
||||
}
|
||||
tagged_buffer().set(offset(), *value);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// WasmInstanceObject
|
||||
@ -252,8 +252,8 @@ OPTIONAL_ACCESSORS(WasmInstanceObject, indirect_function_table_refs, FixedArray,
|
||||
OPTIONAL_ACCESSORS(WasmInstanceObject, managed_native_allocations, Foreign,
|
||||
kManagedNativeAllocationsOffset)
|
||||
OPTIONAL_ACCESSORS(WasmInstanceObject, tags_table, FixedArray, kTagsTableOffset)
|
||||
OPTIONAL_ACCESSORS(WasmInstanceObject, wasm_external_functions, FixedArray,
|
||||
kWasmExternalFunctionsOffset)
|
||||
OPTIONAL_ACCESSORS(WasmInstanceObject, wasm_internal_functions, FixedArray,
|
||||
kWasmInternalFunctionsOffset)
|
||||
ACCESSORS(WasmInstanceObject, managed_object_maps, FixedArray,
|
||||
kManagedObjectMapsOffset)
|
||||
ACCESSORS(WasmInstanceObject, feedback_vectors, FixedArray,
|
||||
@ -285,7 +285,7 @@ WasmExportedFunction::WasmExportedFunction(Address ptr) : JSFunction(ptr) {
|
||||
CAST_ACCESSOR(WasmExportedFunction)
|
||||
|
||||
// WasmFunctionData
|
||||
ACCESSORS(WasmFunctionData, ref, Object, kRefOffset)
|
||||
ACCESSORS(WasmFunctionData, internal, WasmInternalFunction, kInternalOffset)
|
||||
|
||||
DEF_GETTER(WasmFunctionData, wrapper_code, Code) {
|
||||
return FromCodeT(TorqueGeneratedClass::wrapper_code(cage_base));
|
||||
@ -306,15 +306,15 @@ CAST_ACCESSOR(WasmJSFunction)
|
||||
|
||||
// WasmJSFunctionData
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmJSFunctionData)
|
||||
ACCESSORS(WasmJSFunctionData, raw_wasm_to_js_wrapper_code, CodeT,
|
||||
kWasmToJsWrapperCodeOffset)
|
||||
|
||||
DEF_GETTER(WasmJSFunctionData, wasm_to_js_wrapper_code, Code) {
|
||||
return FromCodeT(raw_wasm_to_js_wrapper_code(cage_base));
|
||||
// WasmInternalFunction
|
||||
ACCESSORS(WasmInternalFunction, raw_code, CodeT, kCodeOffset)
|
||||
|
||||
DEF_GETTER(WasmInternalFunction, code, Code) {
|
||||
return FromCodeT(raw_code(cage_base));
|
||||
}
|
||||
void WasmJSFunctionData::set_wasm_to_js_wrapper_code(Code code,
|
||||
WriteBarrierMode mode) {
|
||||
set_raw_wasm_to_js_wrapper_code(ToCodeT(code), mode);
|
||||
void WasmInternalFunction::set_code(Code code, WriteBarrierMode mode) {
|
||||
set_raw_code(ToCodeT(code), mode);
|
||||
}
|
||||
|
||||
// WasmCapiFunction
|
||||
|
@ -345,6 +345,10 @@ bool WasmTableObject::IsValidElement(Isolate* isolate,
|
||||
!table->instance().IsUndefined()
|
||||
? WasmInstanceObject::cast(table->instance()).module()
|
||||
: nullptr;
|
||||
if (entry->IsWasmInternalFunction()) {
|
||||
entry =
|
||||
handle(Handle<WasmInternalFunction>::cast(entry)->external(), isolate);
|
||||
}
|
||||
return wasm::TypecheckJSObject(isolate, module, entry, table->type(),
|
||||
&error_message);
|
||||
}
|
||||
@ -360,8 +364,11 @@ void WasmTableObject::SetFunctionTableEntry(Isolate* isolate,
|
||||
return;
|
||||
}
|
||||
|
||||
if (WasmExportedFunction::IsWasmExportedFunction(*entry)) {
|
||||
auto exported_function = Handle<WasmExportedFunction>::cast(entry);
|
||||
Handle<Object> external =
|
||||
handle(Handle<WasmInternalFunction>::cast(entry)->external(), isolate);
|
||||
|
||||
if (WasmExportedFunction::IsWasmExportedFunction(*external)) {
|
||||
auto exported_function = Handle<WasmExportedFunction>::cast(external);
|
||||
Handle<WasmInstanceObject> target_instance(exported_function->instance(),
|
||||
isolate);
|
||||
int func_index = exported_function->function_index();
|
||||
@ -370,13 +377,13 @@ void WasmTableObject::SetFunctionTableEntry(Isolate* isolate,
|
||||
DCHECK_NOT_NULL(wasm_function->sig);
|
||||
UpdateDispatchTables(isolate, table, entry_index, wasm_function->sig,
|
||||
target_instance, func_index);
|
||||
} else if (WasmJSFunction::IsWasmJSFunction(*entry)) {
|
||||
} else if (WasmJSFunction::IsWasmJSFunction(*external)) {
|
||||
UpdateDispatchTables(isolate, table, entry_index,
|
||||
Handle<WasmJSFunction>::cast(entry));
|
||||
Handle<WasmJSFunction>::cast(external));
|
||||
} else {
|
||||
DCHECK(WasmCapiFunction::IsWasmCapiFunction(*entry));
|
||||
DCHECK(WasmCapiFunction::IsWasmCapiFunction(*external));
|
||||
UpdateDispatchTables(isolate, table, entry_index,
|
||||
Handle<WasmCapiFunction>::cast(entry));
|
||||
Handle<WasmCapiFunction>::cast(external));
|
||||
}
|
||||
entries->set(entry_index, *entry);
|
||||
}
|
||||
@ -437,11 +444,7 @@ Handle<Object> WasmTableObject::Get(Isolate* isolate,
|
||||
case wasm::HeapType::kExtern:
|
||||
return entry;
|
||||
case wasm::HeapType::kFunc:
|
||||
if (WasmExportedFunction::IsWasmExportedFunction(*entry) ||
|
||||
WasmJSFunction::IsWasmJSFunction(*entry) ||
|
||||
WasmCapiFunction::IsWasmCapiFunction(*entry)) {
|
||||
return entry;
|
||||
}
|
||||
if (entry->IsWasmInternalFunction()) return entry;
|
||||
break;
|
||||
case wasm::HeapType::kEq:
|
||||
case wasm::HeapType::kI31:
|
||||
@ -458,11 +461,7 @@ Handle<Object> WasmTableObject::Get(Isolate* isolate,
|
||||
DCHECK(WasmInstanceObject::cast(table->instance())
|
||||
.module()
|
||||
->has_signature(table->type().ref_index()));
|
||||
if (WasmExportedFunction::IsWasmExportedFunction(*entry) ||
|
||||
WasmJSFunction::IsWasmJSFunction(*entry) ||
|
||||
WasmCapiFunction::IsWasmCapiFunction(*entry)) {
|
||||
return entry;
|
||||
}
|
||||
if (entry->IsWasmInternalFunction()) return entry;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -474,10 +473,11 @@ Handle<Object> WasmTableObject::Get(Isolate* isolate,
|
||||
|
||||
// Check if we already compiled a wrapper for the function but did not store
|
||||
// it in the table slot yet.
|
||||
entry = WasmInstanceObject::GetOrCreateWasmExternalFunction(isolate, instance,
|
||||
function_index);
|
||||
entries->set(entry_index, *entry);
|
||||
return entry;
|
||||
Handle<WasmInternalFunction> internal =
|
||||
WasmInstanceObject::GetOrCreateWasmInternalFunction(isolate, instance,
|
||||
function_index);
|
||||
entries->set(entry_index, *internal);
|
||||
return internal;
|
||||
}
|
||||
|
||||
void WasmTableObject::Fill(Isolate* isolate, Handle<WasmTableObject> table,
|
||||
@ -599,6 +599,7 @@ void WasmTableObject::UpdateDispatchTables(
|
||||
->Set(entry_index, sig_id, wasm_code->instruction_start(),
|
||||
WasmCapiFunctionData::cast(
|
||||
capi_function->shared().function_data(kAcquireLoad))
|
||||
.internal()
|
||||
.ref());
|
||||
}
|
||||
}
|
||||
@ -648,6 +649,10 @@ void WasmTableObject::GetFunctionTableEntry(
|
||||
*is_null = element->IsNull(isolate);
|
||||
if (*is_null) return;
|
||||
|
||||
if (element->IsWasmInternalFunction()) {
|
||||
element = handle(Handle<WasmInternalFunction>::cast(element)->external(),
|
||||
isolate);
|
||||
}
|
||||
if (WasmExportedFunction::IsWasmExportedFunction(*element)) {
|
||||
auto target_func = Handle<WasmExportedFunction>::cast(element);
|
||||
*instance = handle(target_func->instance(), isolate);
|
||||
@ -1344,27 +1349,27 @@ bool WasmInstanceObject::InitTableEntries(Isolate* isolate,
|
||||
dst, src, count);
|
||||
}
|
||||
|
||||
MaybeHandle<WasmExternalFunction> WasmInstanceObject::GetWasmExternalFunction(
|
||||
MaybeHandle<WasmInternalFunction> WasmInstanceObject::GetWasmInternalFunction(
|
||||
Isolate* isolate, Handle<WasmInstanceObject> instance, int index) {
|
||||
MaybeHandle<WasmExternalFunction> result;
|
||||
if (instance->has_wasm_external_functions()) {
|
||||
Object val = instance->wasm_external_functions().get(index);
|
||||
MaybeHandle<WasmInternalFunction> result;
|
||||
if (instance->has_wasm_internal_functions()) {
|
||||
Object val = instance->wasm_internal_functions().get(index);
|
||||
if (!val.IsUndefined(isolate)) {
|
||||
result = Handle<WasmExternalFunction>(WasmExternalFunction::cast(val),
|
||||
result = Handle<WasmInternalFunction>(WasmInternalFunction::cast(val),
|
||||
isolate);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Handle<WasmExternalFunction>
|
||||
WasmInstanceObject::GetOrCreateWasmExternalFunction(
|
||||
Handle<WasmInternalFunction>
|
||||
WasmInstanceObject::GetOrCreateWasmInternalFunction(
|
||||
Isolate* isolate, Handle<WasmInstanceObject> instance, int function_index) {
|
||||
MaybeHandle<WasmExternalFunction> maybe_result =
|
||||
WasmInstanceObject::GetWasmExternalFunction(isolate, instance,
|
||||
MaybeHandle<WasmInternalFunction> maybe_result =
|
||||
WasmInstanceObject::GetWasmInternalFunction(isolate, instance,
|
||||
function_index);
|
||||
|
||||
Handle<WasmExternalFunction> result;
|
||||
Handle<WasmInternalFunction> result;
|
||||
if (maybe_result.ToHandle(&result)) {
|
||||
return result;
|
||||
}
|
||||
@ -1391,27 +1396,29 @@ WasmInstanceObject::GetOrCreateWasmExternalFunction(
|
||||
isolate, function.sig, instance->module(), function.imported);
|
||||
module_object->export_wrappers().set(wrapper_index, ToCodeT(*wrapper));
|
||||
}
|
||||
result = Handle<WasmExternalFunction>::cast(WasmExportedFunction::New(
|
||||
auto external = Handle<WasmExternalFunction>::cast(WasmExportedFunction::New(
|
||||
isolate, instance, function_index,
|
||||
static_cast<int>(function.sig->parameter_count()), wrapper));
|
||||
result =
|
||||
WasmInternalFunction::FromExternal(external, isolate).ToHandleChecked();
|
||||
|
||||
WasmInstanceObject::SetWasmExternalFunction(isolate, instance, function_index,
|
||||
WasmInstanceObject::SetWasmInternalFunction(isolate, instance, function_index,
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void WasmInstanceObject::SetWasmExternalFunction(
|
||||
void WasmInstanceObject::SetWasmInternalFunction(
|
||||
Isolate* isolate, Handle<WasmInstanceObject> instance, int index,
|
||||
Handle<WasmExternalFunction> val) {
|
||||
Handle<WasmInternalFunction> val) {
|
||||
Handle<FixedArray> functions;
|
||||
if (!instance->has_wasm_external_functions()) {
|
||||
if (!instance->has_wasm_internal_functions()) {
|
||||
// Lazily allocate the wasm external functions array.
|
||||
functions = isolate->factory()->NewFixedArray(
|
||||
static_cast<int>(instance->module()->functions.size()));
|
||||
instance->set_wasm_external_functions(*functions);
|
||||
instance->set_wasm_internal_functions(*functions);
|
||||
} else {
|
||||
functions =
|
||||
Handle<FixedArray>(instance->wasm_external_functions(), isolate);
|
||||
Handle<FixedArray>(instance->wasm_internal_functions(), isolate);
|
||||
}
|
||||
functions->set(index, *val);
|
||||
}
|
||||
@ -1450,6 +1457,7 @@ void WasmInstanceObject::ImportWasmJSFunctionIntoTable(
|
||||
->shared()
|
||||
.internal_formal_parameter_count_without_receiver();
|
||||
}
|
||||
// TODO(manoskouk): Reuse js_function->wasm_to_js_wrapper_code().
|
||||
wasm::WasmCompilationResult result = compiler::CompileWasmImportCallWrapper(
|
||||
&env, kind, sig, false, expected_arity);
|
||||
wasm::CodeSpaceWriteScope write_scope(native_module);
|
||||
@ -1871,16 +1879,21 @@ Handle<WasmCapiFunction> WasmCapiFunction::New(
|
||||
// call target (which is an address pointing into the C++ binary).
|
||||
call_target = ExternalReference::Create(call_target).address();
|
||||
|
||||
// TODO(7748): Support proper typing for external functions. That requires
|
||||
// global (cross-module) canonicalization of signatures/RTTs.
|
||||
Handle<Map> rtt = isolate->factory()->wasm_internal_function_map();
|
||||
Handle<WasmCapiFunctionData> fun_data =
|
||||
isolate->factory()->NewWasmCapiFunctionData(
|
||||
call_target, embedder_data,
|
||||
isolate->builtins()->code_handle(Builtin::kIllegal),
|
||||
isolate->builtins()->code_handle(Builtin::kIllegal), rtt,
|
||||
serialized_signature);
|
||||
Handle<SharedFunctionInfo> shared =
|
||||
isolate->factory()->NewSharedFunctionInfoForWasmCapiFunction(fun_data);
|
||||
return Handle<WasmCapiFunction>::cast(
|
||||
Handle<JSFunction> result =
|
||||
Factory::JSFunctionBuilder{isolate, shared, isolate->native_context()}
|
||||
.Build());
|
||||
.Build();
|
||||
fun_data->internal().set_external(*result);
|
||||
return Handle<WasmCapiFunction>::cast(result);
|
||||
}
|
||||
|
||||
WasmInstanceObject WasmExportedFunction::instance() {
|
||||
@ -1908,10 +1921,19 @@ Handle<WasmExportedFunction> WasmExportedFunction::New(
|
||||
Factory* factory = isolate->factory();
|
||||
const wasm::FunctionSig* sig = instance->module()->functions[func_index].sig;
|
||||
Address call_target = instance->GetCallTarget(func_index);
|
||||
Handle<Map> rtt;
|
||||
if (FLAG_experimental_wasm_gc) {
|
||||
int sig_index = instance->module()->functions[func_index].sig_index;
|
||||
// TODO(7748): Create funcref RTTs lazily?
|
||||
rtt = handle(Map::cast(instance->managed_object_maps().get(sig_index)),
|
||||
isolate);
|
||||
} else {
|
||||
rtt = factory->wasm_internal_function_map();
|
||||
}
|
||||
Handle<WasmExportedFunctionData> function_data =
|
||||
factory->NewWasmExportedFunctionData(
|
||||
export_wrapper, instance, call_target, ref, func_index,
|
||||
reinterpret_cast<Address>(sig), wasm::kGenericWrapperBudget);
|
||||
reinterpret_cast<Address>(sig), wasm::kGenericWrapperBudget, rtt);
|
||||
|
||||
MaybeHandle<String> maybe_name;
|
||||
bool is_asm_js_module = instance->module_object().is_asm_js();
|
||||
@ -1933,17 +1955,7 @@ Handle<WasmExportedFunction> WasmExportedFunction::New(
|
||||
Handle<Map> function_map;
|
||||
switch (instance->module()->origin) {
|
||||
case wasm::kWasmOrigin:
|
||||
if (instance->module_object()
|
||||
.native_module()
|
||||
->enabled_features()
|
||||
.has_gc()) {
|
||||
uint32_t sig_index =
|
||||
instance->module()->functions[func_index].sig_index;
|
||||
function_map = handle(
|
||||
Map::cast(instance->managed_object_maps().get(sig_index)), isolate);
|
||||
} else {
|
||||
function_map = isolate->wasm_exported_function_map();
|
||||
}
|
||||
function_map = isolate->wasm_exported_function_map();
|
||||
break;
|
||||
case wasm::kAsmJsSloppyOrigin:
|
||||
function_map = isolate->sloppy_function_map();
|
||||
@ -1968,6 +1980,7 @@ Handle<WasmExportedFunction> WasmExportedFunction::New(
|
||||
shared->set_length(arity);
|
||||
shared->set_internal_formal_parameter_count(JSParameterCount(arity));
|
||||
shared->set_script(instance->module_object().script());
|
||||
function_data->internal().set_external(*js_function);
|
||||
return Handle<WasmExportedFunction>::cast(js_function);
|
||||
}
|
||||
|
||||
@ -2041,9 +2054,12 @@ Handle<WasmJSFunction> WasmJSFunction::New(Isolate* isolate,
|
||||
}
|
||||
|
||||
Factory* factory = isolate->factory();
|
||||
// TODO(7748): Support proper typing for external functions. That requires
|
||||
// global (cross-module) canonicalization of signatures/RTTs.
|
||||
Handle<Map> rtt = factory->wasm_internal_function_map();
|
||||
Handle<WasmJSFunctionData> function_data = factory->NewWasmJSFunctionData(
|
||||
call_target, callable, return_count, parameter_count, serialized_sig,
|
||||
wrapper_code);
|
||||
wrapper_code, rtt);
|
||||
|
||||
if (wasm::WasmFeatures::FromIsolate(isolate).has_typed_funcref()) {
|
||||
using CK = compiler::WasmImportCallKind;
|
||||
@ -2062,7 +2078,7 @@ Handle<WasmJSFunction> WasmJSFunction::New(Isolate* isolate,
|
||||
Handle<Code> wasm_to_js_wrapper_code =
|
||||
compiler::CompileWasmToJSWrapper(isolate, sig, kind, expected_arity)
|
||||
.ToHandleChecked();
|
||||
function_data->set_wasm_to_js_wrapper_code(*wasm_to_js_wrapper_code);
|
||||
function_data->internal().set_code(*wasm_to_js_wrapper_code);
|
||||
}
|
||||
|
||||
Handle<String> name = factory->Function_string();
|
||||
@ -2070,25 +2086,23 @@ Handle<WasmJSFunction> WasmJSFunction::New(Isolate* isolate,
|
||||
name = JSFunction::GetDebugName(Handle<JSFunction>::cast(callable));
|
||||
name = String::Flatten(isolate, name);
|
||||
}
|
||||
Handle<Map> function_map =
|
||||
Map::Copy(isolate, isolate->wasm_exported_function_map(),
|
||||
"fresh function map for WasmJSFunction::New");
|
||||
Handle<NativeContext> context(isolate->native_context());
|
||||
Handle<SharedFunctionInfo> shared =
|
||||
factory->NewSharedFunctionInfoForWasmJSFunction(name, function_data);
|
||||
Handle<JSFunction> js_function =
|
||||
Factory::JSFunctionBuilder{isolate, shared, context}
|
||||
.set_map(function_map)
|
||||
.set_map(isolate->wasm_exported_function_map())
|
||||
.Build();
|
||||
js_function->shared().set_internal_formal_parameter_count(
|
||||
JSParameterCount(parameter_count));
|
||||
function_data->internal().set_external(*js_function);
|
||||
return Handle<WasmJSFunction>::cast(js_function);
|
||||
}
|
||||
|
||||
JSReceiver WasmJSFunction::GetCallable() const {
|
||||
return JSReceiver::cast(
|
||||
WasmApiFunctionRef::cast(shared().wasm_js_function_data().ref())
|
||||
.callable());
|
||||
return JSReceiver::cast(WasmApiFunctionRef::cast(
|
||||
shared().wasm_js_function_data().internal().ref())
|
||||
.callable());
|
||||
}
|
||||
|
||||
const wasm::FunctionSig* WasmJSFunction::GetSignature(Zone* zone) {
|
||||
@ -2128,6 +2142,24 @@ bool WasmExternalFunction::IsWasmExternalFunction(Object object) {
|
||||
WasmJSFunction::IsWasmJSFunction(object);
|
||||
}
|
||||
|
||||
// static
|
||||
MaybeHandle<WasmInternalFunction> WasmInternalFunction::FromExternal(
|
||||
Handle<Object> external, Isolate* isolate) {
|
||||
if (external->IsNull(isolate)) {
|
||||
return MaybeHandle<WasmInternalFunction>();
|
||||
}
|
||||
if (WasmExportedFunction::IsWasmExportedFunction(*external) ||
|
||||
WasmJSFunction::IsWasmJSFunction(*external) ||
|
||||
WasmCapiFunction::IsWasmCapiFunction(*external)) {
|
||||
WasmFunctionData data = WasmFunctionData::cast(
|
||||
Handle<JSFunction>::cast(external)->shared().function_data(
|
||||
kAcquireLoad));
|
||||
return handle(data.internal(), isolate);
|
||||
}
|
||||
// {external} is not null or a wasm external function.
|
||||
return MaybeHandle<WasmInternalFunction>();
|
||||
}
|
||||
|
||||
Handle<WasmExceptionTag> WasmExceptionTag::New(Isolate* isolate, int index) {
|
||||
Handle<WasmExceptionTag> result =
|
||||
Handle<WasmExceptionTag>::cast(isolate->factory()->NewStruct(
|
||||
|
@ -232,6 +232,7 @@ class WasmTableObject
|
||||
int* function_index, MaybeHandle<WasmJSFunction>* maybe_js_function);
|
||||
|
||||
private:
|
||||
// {entry} is either {Null} or a {WasmInternalFunction}.
|
||||
static void SetFunctionTableEntry(Isolate* isolate,
|
||||
Handle<WasmTableObject> table,
|
||||
Handle<FixedArray> entries, int entry_index,
|
||||
@ -329,7 +330,7 @@ class V8_EXPORT_PRIVATE WasmInstanceObject : public JSObject {
|
||||
DECL_OPTIONAL_ACCESSORS(indirect_function_table_refs, FixedArray)
|
||||
DECL_OPTIONAL_ACCESSORS(managed_native_allocations, Foreign)
|
||||
DECL_OPTIONAL_ACCESSORS(tags_table, FixedArray)
|
||||
DECL_OPTIONAL_ACCESSORS(wasm_external_functions, FixedArray)
|
||||
DECL_OPTIONAL_ACCESSORS(wasm_internal_functions, FixedArray)
|
||||
DECL_ACCESSORS(managed_object_maps, FixedArray)
|
||||
DECL_ACCESSORS(feedback_vectors, FixedArray)
|
||||
DECL_PRIMITIVE_ACCESSORS(memory_start, byte*)
|
||||
@ -406,7 +407,7 @@ class V8_EXPORT_PRIVATE WasmInstanceObject : public JSObject {
|
||||
V(kIndirectFunctionTablesOffset, kTaggedSize) \
|
||||
V(kManagedNativeAllocationsOffset, kTaggedSize) \
|
||||
V(kTagsTableOffset, kTaggedSize) \
|
||||
V(kWasmExternalFunctionsOffset, kTaggedSize) \
|
||||
V(kWasmInternalFunctionsOffset, kTaggedSize) \
|
||||
V(kManagedObjectMapsOffset, kTaggedSize) \
|
||||
V(kFeedbackVectorsOffset, kTaggedSize) \
|
||||
V(kBreakOnEntryOffset, kUInt8Size) \
|
||||
@ -443,7 +444,7 @@ class V8_EXPORT_PRIVATE WasmInstanceObject : public JSObject {
|
||||
kIndirectFunctionTablesOffset,
|
||||
kManagedNativeAllocationsOffset,
|
||||
kTagsTableOffset,
|
||||
kWasmExternalFunctionsOffset,
|
||||
kWasmInternalFunctionsOffset,
|
||||
kManagedObjectMapsOffset,
|
||||
kFeedbackVectorsOffset};
|
||||
|
||||
@ -483,21 +484,21 @@ class V8_EXPORT_PRIVATE WasmInstanceObject : public JSObject {
|
||||
// Iterates all fields in the object except the untagged fields.
|
||||
class BodyDescriptor;
|
||||
|
||||
static MaybeHandle<WasmExternalFunction> GetWasmExternalFunction(
|
||||
static MaybeHandle<WasmInternalFunction> GetWasmInternalFunction(
|
||||
Isolate* isolate, Handle<WasmInstanceObject> instance, int index);
|
||||
|
||||
// Acquires the {WasmExternalFunction} for a given {function_index} from the
|
||||
// cache of the given {instance}, or creates a new {WasmExportedFunction} if
|
||||
// it does not exist yet. The new {WasmExportedFunction} is added to the
|
||||
// Acquires the {WasmInternalFunction} for a given {function_index} from the
|
||||
// cache of the given {instance}, or creates a new {WasmInternalFunction} if
|
||||
// it does not exist yet. The new {WasmInternalFunction} is added to the
|
||||
// cache of the {instance} immediately.
|
||||
static Handle<WasmExternalFunction> GetOrCreateWasmExternalFunction(
|
||||
static Handle<WasmInternalFunction> GetOrCreateWasmInternalFunction(
|
||||
Isolate* isolate, Handle<WasmInstanceObject> instance,
|
||||
int function_index);
|
||||
|
||||
static void SetWasmExternalFunction(Isolate* isolate,
|
||||
static void SetWasmInternalFunction(Isolate* isolate,
|
||||
Handle<WasmInstanceObject> instance,
|
||||
int index,
|
||||
Handle<WasmExternalFunction> val);
|
||||
Handle<WasmInternalFunction> val);
|
||||
|
||||
// Imports a constructed {WasmJSFunction} into the indirect function table of
|
||||
// this instance. Note that this might trigger wrapper compilation, since a
|
||||
@ -688,13 +689,15 @@ class WasmIndirectFunctionTable
|
||||
};
|
||||
|
||||
class WasmFunctionData
|
||||
: public TorqueGeneratedWasmFunctionData<WasmFunctionData, Foreign> {
|
||||
: public TorqueGeneratedWasmFunctionData<WasmFunctionData, HeapObject> {
|
||||
public:
|
||||
DECL_ACCESSORS(ref, Object)
|
||||
DECL_ACCESSORS(internal, WasmInternalFunction)
|
||||
DECL_ACCESSORS(wrapper_code, Code)
|
||||
|
||||
DECL_PRINTER(WasmFunctionData)
|
||||
|
||||
using BodyDescriptor = FlexibleBodyDescriptor<kStartOfStrongFieldsOffset>;
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS(WasmFunctionData)
|
||||
};
|
||||
|
||||
@ -711,7 +714,8 @@ class WasmExportedFunctionData
|
||||
DECL_PRINTER(WasmExportedFunctionData)
|
||||
DECL_VERIFIER(WasmExportedFunctionData)
|
||||
|
||||
class BodyDescriptor;
|
||||
using BodyDescriptor =
|
||||
FlexibleBodyDescriptor<WasmFunctionData::kStartOfStrongFieldsOffset>;
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS(WasmExportedFunctionData)
|
||||
};
|
||||
@ -727,6 +731,28 @@ class WasmApiFunctionRef
|
||||
TQ_OBJECT_CONSTRUCTORS(WasmApiFunctionRef)
|
||||
};
|
||||
|
||||
class WasmInternalFunction
|
||||
: public TorqueGeneratedWasmInternalFunction<WasmInternalFunction,
|
||||
Foreign> {
|
||||
public:
|
||||
DECL_ACCESSORS(code, Code)
|
||||
|
||||
// Returns a handle to the corresponding WasmInternalFunction if {external} is
|
||||
// a WasmExternalFunction, or an empty handle otherwise.
|
||||
static MaybeHandle<WasmInternalFunction> FromExternal(Handle<Object> external,
|
||||
Isolate* isolate);
|
||||
|
||||
// Dispatched behavior.
|
||||
DECL_PRINTER(WasmInternalFunction)
|
||||
|
||||
class BodyDescriptor;
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS(WasmInternalFunction)
|
||||
|
||||
private:
|
||||
DECL_ACCESSORS(raw_code, CodeT)
|
||||
};
|
||||
|
||||
// Information for a WasmJSFunction which is referenced as the function data of
|
||||
// the SharedFunctionInfo underlying the function. For details please see the
|
||||
// {SharedFunctionInfo::HasWasmJSFunctionData} predicate.
|
||||
@ -739,11 +765,10 @@ class WasmJSFunctionData
|
||||
// Dispatched behavior.
|
||||
DECL_PRINTER(WasmJSFunctionData)
|
||||
|
||||
class BodyDescriptor;
|
||||
using BodyDescriptor =
|
||||
FlexibleBodyDescriptor<WasmFunctionData::kStartOfStrongFieldsOffset>;
|
||||
|
||||
private:
|
||||
DECL_ACCESSORS(raw_wasm_to_js_wrapper_code, CodeT)
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS(WasmJSFunctionData)
|
||||
};
|
||||
|
||||
@ -753,7 +778,8 @@ class WasmCapiFunctionData
|
||||
public:
|
||||
DECL_PRINTER(WasmCapiFunctionData)
|
||||
|
||||
class BodyDescriptor;
|
||||
using BodyDescriptor =
|
||||
FlexibleBodyDescriptor<WasmFunctionData::kStartOfStrongFieldsOffset>;
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS(WasmCapiFunctionData)
|
||||
};
|
||||
|
@ -23,7 +23,11 @@ extern class WasmApiFunctionRef extends HeapObject {
|
||||
callable: JSReceiver|Undefined;
|
||||
}
|
||||
|
||||
extern class WasmFunctionData extends Foreign {
|
||||
// This is the representation that is used internally by wasm to represent
|
||||
// function references.
|
||||
// The {foreign_address} field inherited from {Foreign} points to the call
|
||||
// target.
|
||||
extern class WasmInternalFunction extends Foreign {
|
||||
// This is the "reference" value that must be passed along in the "instance"
|
||||
// register when calling the given function. It is either the target instance
|
||||
// (for wasm functions), or a WasmApiFunctionRef object (for functions defined
|
||||
@ -31,6 +35,19 @@ extern class WasmFunctionData extends Foreign {
|
||||
// For imported functions, this value equals the respective entry in
|
||||
// the module's imported_function_refs array.
|
||||
ref: WasmInstanceObject|WasmApiFunctionRef;
|
||||
// The external (JS) representation of this function reference.
|
||||
external: JSFunction|Undefined;
|
||||
// This field is used when the call target is null.
|
||||
@if(V8_EXTERNAL_CODE_SPACE) code: CodeDataContainer;
|
||||
@ifnot(V8_EXTERNAL_CODE_SPACE) code: Code;
|
||||
}
|
||||
// WasmInternalFunction is safely comparable for pointer equality.
|
||||
extern operator '==' macro TaggedEqual(WasmInternalFunction, Object): bool;
|
||||
extern operator '==' macro TaggedEqual(Object, WasmInternalFunction): bool;
|
||||
|
||||
extern class WasmFunctionData extends HeapObject {
|
||||
// The wasm-internal representation of this function object.
|
||||
internal: WasmInternalFunction;
|
||||
// Used for calling this function from JavaScript.
|
||||
@if(V8_EXTERNAL_CODE_SPACE) wrapper_code: CodeDataContainer;
|
||||
@ifnot(V8_EXTERNAL_CODE_SPACE) wrapper_code: Code;
|
||||
@ -52,8 +69,6 @@ extern class WasmExportedFunctionData extends WasmFunctionData {
|
||||
}
|
||||
|
||||
extern class WasmJSFunctionData extends WasmFunctionData {
|
||||
@if(V8_EXTERNAL_CODE_SPACE) wasm_to_js_wrapper_code: CodeDataContainer;
|
||||
@ifnot(V8_EXTERNAL_CODE_SPACE) wasm_to_js_wrapper_code: Code;
|
||||
serialized_return_count: Smi;
|
||||
serialized_parameter_count: Smi;
|
||||
serialized_signature: PodArrayOfWasmValueType;
|
||||
|
@ -1797,17 +1797,20 @@ WASM_COMPILED_EXEC_TEST(FunctionRefs) {
|
||||
tester.GetResultObject(rtt_canon).ToHandleChecked();
|
||||
CHECK(result_canon->IsMap());
|
||||
Handle<Map> map_canon = Handle<Map>::cast(result_canon);
|
||||
CHECK(map_canon->IsJSFunctionMap());
|
||||
CHECK(map_canon->IsWasmInternalFunctionMap());
|
||||
|
||||
Handle<Object> result_cast = tester.GetResultObject(cast).ToHandleChecked();
|
||||
CHECK(result_cast->IsJSFunction());
|
||||
Handle<JSFunction> cast_function = Handle<JSFunction>::cast(result_cast);
|
||||
CHECK(result_cast->IsWasmInternalFunction());
|
||||
Handle<JSFunction> cast_function = Handle<JSFunction>::cast(
|
||||
handle(Handle<WasmInternalFunction>::cast(result_cast)->external(),
|
||||
tester.isolate()));
|
||||
|
||||
Handle<Object> result_cast_reference =
|
||||
tester.GetResultObject(cast_reference).ToHandleChecked();
|
||||
CHECK(result_cast_reference->IsJSFunction());
|
||||
Handle<JSFunction> cast_function_reference =
|
||||
Handle<JSFunction>::cast(result_cast_reference);
|
||||
CHECK(result_cast_reference->IsWasmInternalFunction());
|
||||
Handle<JSFunction> cast_function_reference = Handle<JSFunction>::cast(handle(
|
||||
Handle<WasmInternalFunction>::cast(result_cast_reference)->external(),
|
||||
tester.isolate()));
|
||||
|
||||
CHECK_EQ(cast_function->code().raw_instruction_start(),
|
||||
cast_function_reference->code().raw_instruction_start());
|
||||
|
@ -318,15 +318,17 @@ TEST(WrapperReplacement_IndirectExport) {
|
||||
CompileModule(&zone, isolate, builder);
|
||||
|
||||
// Get the exported table.
|
||||
Handle<WasmTableObject> table = handle(
|
||||
Handle<WasmTableObject> table(
|
||||
WasmTableObject::cast(instance->tables().get(table_index)), isolate);
|
||||
// Get the Wasm function through the exported table.
|
||||
Handle<Object> function =
|
||||
WasmTableObject::Get(isolate, table, function_index);
|
||||
Handle<WasmExportedFunction> indirect_function =
|
||||
handle(WasmExportedFunction::cast(*function), isolate);
|
||||
Handle<WasmExportedFunction> indirect_function(
|
||||
WasmExportedFunction::cast(
|
||||
WasmInternalFunction::cast(*function).external()),
|
||||
isolate);
|
||||
// Get the function data.
|
||||
Handle<WasmExportedFunctionData> indirect_function_data = handle(
|
||||
Handle<WasmExportedFunctionData> indirect_function_data(
|
||||
indirect_function->shared().wasm_exported_function_data(), isolate);
|
||||
|
||||
// Verify that the generic-wrapper budget has initially a value of
|
||||
|
@ -187,8 +187,11 @@ void TestingModuleBuilder::FreezeSignatureMapAndInitializeWrapperCache() {
|
||||
Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) {
|
||||
CHECK(!interpreter_);
|
||||
FreezeSignatureMapAndInitializeWrapperCache();
|
||||
return WasmInstanceObject::GetOrCreateWasmExternalFunction(
|
||||
isolate_, instance_object(), index);
|
||||
return handle(
|
||||
JSFunction::cast(WasmInstanceObject::GetOrCreateWasmInternalFunction(
|
||||
isolate_, instance_object(), index)
|
||||
->external()),
|
||||
isolate_);
|
||||
}
|
||||
|
||||
void TestingModuleBuilder::AddIndirectFunctionTable(
|
||||
|
@ -3520,8 +3520,8 @@ class WasmInterpreterInternals {
|
||||
"function index");
|
||||
HandleScope handle_scope(isolate_); // Avoid leaking handles.
|
||||
|
||||
Handle<WasmExternalFunction> function =
|
||||
WasmInstanceObject::GetOrCreateWasmExternalFunction(
|
||||
Handle<WasmInternalFunction> function =
|
||||
WasmInstanceObject::GetOrCreateWasmInternalFunction(
|
||||
isolate_, instance_object_, imm.index);
|
||||
Push(WasmValue(function, kWasmFuncRef));
|
||||
len = 1 + imm.length;
|
||||
|
@ -7,6 +7,7 @@
|
||||
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
|
||||
(function TestTables() {
|
||||
print(arguments.callee.name);
|
||||
var exporting_instance = (function() {
|
||||
var builder = new WasmModuleBuilder();
|
||||
var binary_type = builder.addType(kSig_i_ii);
|
||||
@ -103,6 +104,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
})();
|
||||
|
||||
(function TestNonNullableTables() {
|
||||
print(arguments.callee.name);
|
||||
var builder = new WasmModuleBuilder();
|
||||
|
||||
var binary_type = builder.addType(kSig_i_ii);
|
||||
|
@ -123,8 +123,8 @@ with open(sys.argv[1], "r") as f:
|
||||
funcs_list.sort(key=lambda fun: fun.time_tf)
|
||||
for f in funcs_list:
|
||||
print(f)
|
||||
total_tf_time += f.time_tf
|
||||
total_tf_size += f.size_tf
|
||||
if f.time_tf > 0: total_tf_time += f.time_tf
|
||||
if f.size_tf > 0: total_tf_size += f.size_tf
|
||||
|
||||
print("Total TF time: %d" % total_tf_time)
|
||||
print("Total TF size: %d" % total_tf_size)
|
||||
|
@ -104,66 +104,67 @@ INSTANCE_TYPES = {
|
||||
202: "SCRIPT_CONTEXT_TYPE",
|
||||
203: "WITH_CONTEXT_TYPE",
|
||||
204: "FOREIGN_TYPE",
|
||||
205: "WASM_FUNCTION_DATA_TYPE",
|
||||
206: "WASM_CAPI_FUNCTION_DATA_TYPE",
|
||||
207: "WASM_EXPORTED_FUNCTION_DATA_TYPE",
|
||||
208: "WASM_JS_FUNCTION_DATA_TYPE",
|
||||
209: "WASM_TYPE_INFO_TYPE",
|
||||
210: "TURBOFAN_BITSET_TYPE_TYPE",
|
||||
211: "TURBOFAN_HEAP_CONSTANT_TYPE_TYPE",
|
||||
212: "TURBOFAN_OTHER_NUMBER_CONSTANT_TYPE_TYPE",
|
||||
213: "TURBOFAN_RANGE_TYPE_TYPE",
|
||||
214: "TURBOFAN_UNION_TYPE_TYPE",
|
||||
215: "EXPORTED_SUB_CLASS_BASE_TYPE",
|
||||
216: "EXPORTED_SUB_CLASS_TYPE",
|
||||
217: "EXPORTED_SUB_CLASS2_TYPE",
|
||||
218: "SMALL_ORDERED_HASH_MAP_TYPE",
|
||||
219: "SMALL_ORDERED_HASH_SET_TYPE",
|
||||
220: "SMALL_ORDERED_NAME_DICTIONARY_TYPE",
|
||||
221: "ABSTRACT_INTERNAL_CLASS_SUBCLASS1_TYPE",
|
||||
222: "ABSTRACT_INTERNAL_CLASS_SUBCLASS2_TYPE",
|
||||
223: "DESCRIPTOR_ARRAY_TYPE",
|
||||
224: "STRONG_DESCRIPTOR_ARRAY_TYPE",
|
||||
225: "SOURCE_TEXT_MODULE_TYPE",
|
||||
226: "SYNTHETIC_MODULE_TYPE",
|
||||
227: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE",
|
||||
228: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE",
|
||||
229: "WEAK_FIXED_ARRAY_TYPE",
|
||||
230: "TRANSITION_ARRAY_TYPE",
|
||||
231: "CALL_REF_DATA_TYPE",
|
||||
232: "CELL_TYPE",
|
||||
233: "CODE_TYPE",
|
||||
234: "CODE_DATA_CONTAINER_TYPE",
|
||||
235: "COVERAGE_INFO_TYPE",
|
||||
236: "EMBEDDER_DATA_ARRAY_TYPE",
|
||||
237: "FEEDBACK_METADATA_TYPE",
|
||||
238: "FEEDBACK_VECTOR_TYPE",
|
||||
239: "FILLER_TYPE",
|
||||
240: "FREE_SPACE_TYPE",
|
||||
241: "INTERNAL_CLASS_TYPE",
|
||||
242: "INTERNAL_CLASS_WITH_STRUCT_ELEMENTS_TYPE",
|
||||
243: "MAP_TYPE",
|
||||
244: "MEGA_DOM_HANDLER_TYPE",
|
||||
245: "ON_HEAP_BASIC_BLOCK_PROFILER_DATA_TYPE",
|
||||
246: "PREPARSE_DATA_TYPE",
|
||||
247: "PROPERTY_ARRAY_TYPE",
|
||||
248: "PROPERTY_CELL_TYPE",
|
||||
249: "SCOPE_INFO_TYPE",
|
||||
250: "SHARED_FUNCTION_INFO_TYPE",
|
||||
251: "SMI_BOX_TYPE",
|
||||
252: "SMI_PAIR_TYPE",
|
||||
253: "SORT_STATE_TYPE",
|
||||
254: "SWISS_NAME_DICTIONARY_TYPE",
|
||||
255: "WASM_API_FUNCTION_REF_TYPE",
|
||||
256: "WEAK_ARRAY_LIST_TYPE",
|
||||
257: "WEAK_CELL_TYPE",
|
||||
258: "WASM_ARRAY_TYPE",
|
||||
259: "WASM_STRUCT_TYPE",
|
||||
260: "JS_PROXY_TYPE",
|
||||
205: "WASM_INTERNAL_FUNCTION_TYPE",
|
||||
206: "WASM_TYPE_INFO_TYPE",
|
||||
207: "TURBOFAN_BITSET_TYPE_TYPE",
|
||||
208: "TURBOFAN_HEAP_CONSTANT_TYPE_TYPE",
|
||||
209: "TURBOFAN_OTHER_NUMBER_CONSTANT_TYPE_TYPE",
|
||||
210: "TURBOFAN_RANGE_TYPE_TYPE",
|
||||
211: "TURBOFAN_UNION_TYPE_TYPE",
|
||||
212: "WASM_FUNCTION_DATA_TYPE",
|
||||
213: "WASM_CAPI_FUNCTION_DATA_TYPE",
|
||||
214: "WASM_EXPORTED_FUNCTION_DATA_TYPE",
|
||||
215: "WASM_JS_FUNCTION_DATA_TYPE",
|
||||
216: "EXPORTED_SUB_CLASS_BASE_TYPE",
|
||||
217: "EXPORTED_SUB_CLASS_TYPE",
|
||||
218: "EXPORTED_SUB_CLASS2_TYPE",
|
||||
219: "SMALL_ORDERED_HASH_MAP_TYPE",
|
||||
220: "SMALL_ORDERED_HASH_SET_TYPE",
|
||||
221: "SMALL_ORDERED_NAME_DICTIONARY_TYPE",
|
||||
222: "ABSTRACT_INTERNAL_CLASS_SUBCLASS1_TYPE",
|
||||
223: "ABSTRACT_INTERNAL_CLASS_SUBCLASS2_TYPE",
|
||||
224: "DESCRIPTOR_ARRAY_TYPE",
|
||||
225: "STRONG_DESCRIPTOR_ARRAY_TYPE",
|
||||
226: "SOURCE_TEXT_MODULE_TYPE",
|
||||
227: "SYNTHETIC_MODULE_TYPE",
|
||||
228: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE",
|
||||
229: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE",
|
||||
230: "WEAK_FIXED_ARRAY_TYPE",
|
||||
231: "TRANSITION_ARRAY_TYPE",
|
||||
232: "CALL_REF_DATA_TYPE",
|
||||
233: "CELL_TYPE",
|
||||
234: "CODE_TYPE",
|
||||
235: "CODE_DATA_CONTAINER_TYPE",
|
||||
236: "COVERAGE_INFO_TYPE",
|
||||
237: "EMBEDDER_DATA_ARRAY_TYPE",
|
||||
238: "FEEDBACK_METADATA_TYPE",
|
||||
239: "FEEDBACK_VECTOR_TYPE",
|
||||
240: "FILLER_TYPE",
|
||||
241: "FREE_SPACE_TYPE",
|
||||
242: "INTERNAL_CLASS_TYPE",
|
||||
243: "INTERNAL_CLASS_WITH_STRUCT_ELEMENTS_TYPE",
|
||||
244: "MAP_TYPE",
|
||||
245: "MEGA_DOM_HANDLER_TYPE",
|
||||
246: "ON_HEAP_BASIC_BLOCK_PROFILER_DATA_TYPE",
|
||||
247: "PREPARSE_DATA_TYPE",
|
||||
248: "PROPERTY_ARRAY_TYPE",
|
||||
249: "PROPERTY_CELL_TYPE",
|
||||
250: "SCOPE_INFO_TYPE",
|
||||
251: "SHARED_FUNCTION_INFO_TYPE",
|
||||
252: "SMI_BOX_TYPE",
|
||||
253: "SMI_PAIR_TYPE",
|
||||
254: "SORT_STATE_TYPE",
|
||||
255: "SWISS_NAME_DICTIONARY_TYPE",
|
||||
256: "WASM_API_FUNCTION_REF_TYPE",
|
||||
257: "WEAK_ARRAY_LIST_TYPE",
|
||||
258: "WEAK_CELL_TYPE",
|
||||
259: "WASM_ARRAY_TYPE",
|
||||
260: "WASM_STRUCT_TYPE",
|
||||
261: "JS_PROXY_TYPE",
|
||||
1057: "JS_OBJECT_TYPE",
|
||||
261: "JS_GLOBAL_OBJECT_TYPE",
|
||||
262: "JS_GLOBAL_PROXY_TYPE",
|
||||
263: "JS_MODULE_NAMESPACE_TYPE",
|
||||
262: "JS_GLOBAL_OBJECT_TYPE",
|
||||
263: "JS_GLOBAL_PROXY_TYPE",
|
||||
264: "JS_MODULE_NAMESPACE_TYPE",
|
||||
1040: "JS_SPECIAL_API_OBJECT_TYPE",
|
||||
1041: "JS_PRIMITIVE_WRAPPER_TYPE",
|
||||
1058: "JS_API_OBJECT_TYPE",
|
||||
@ -258,16 +259,16 @@ INSTANCE_TYPES = {
|
||||
|
||||
# List of known V8 maps.
|
||||
KNOWN_MAPS = {
|
||||
("read_only_space", 0x02119): (243, "MetaMap"),
|
||||
("read_only_space", 0x02119): (244, "MetaMap"),
|
||||
("read_only_space", 0x02141): (131, "NullMap"),
|
||||
("read_only_space", 0x02169): (224, "StrongDescriptorArrayMap"),
|
||||
("read_only_space", 0x02191): (256, "WeakArrayListMap"),
|
||||
("read_only_space", 0x02169): (225, "StrongDescriptorArrayMap"),
|
||||
("read_only_space", 0x02191): (257, "WeakArrayListMap"),
|
||||
("read_only_space", 0x021d5): (156, "EnumCacheMap"),
|
||||
("read_only_space", 0x02209): (176, "FixedArrayMap"),
|
||||
("read_only_space", 0x02255): (8, "OneByteInternalizedStringMap"),
|
||||
("read_only_space", 0x022a1): (240, "FreeSpaceMap"),
|
||||
("read_only_space", 0x022c9): (239, "OnePointerFillerMap"),
|
||||
("read_only_space", 0x022f1): (239, "TwoPointerFillerMap"),
|
||||
("read_only_space", 0x022a1): (241, "FreeSpaceMap"),
|
||||
("read_only_space", 0x022c9): (240, "OnePointerFillerMap"),
|
||||
("read_only_space", 0x022f1): (240, "TwoPointerFillerMap"),
|
||||
("read_only_space", 0x02319): (131, "UninitializedMap"),
|
||||
("read_only_space", 0x02391): (131, "UndefinedMap"),
|
||||
("read_only_space", 0x023d5): (130, "HeapNumberMap"),
|
||||
@ -278,15 +279,15 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x0255d): (177, "HashTableMap"),
|
||||
("read_only_space", 0x02585): (128, "SymbolMap"),
|
||||
("read_only_space", 0x025ad): (40, "OneByteStringMap"),
|
||||
("read_only_space", 0x025d5): (249, "ScopeInfoMap"),
|
||||
("read_only_space", 0x025fd): (250, "SharedFunctionInfoMap"),
|
||||
("read_only_space", 0x02625): (233, "CodeMap"),
|
||||
("read_only_space", 0x0264d): (232, "CellMap"),
|
||||
("read_only_space", 0x02675): (248, "GlobalPropertyCellMap"),
|
||||
("read_only_space", 0x025d5): (250, "ScopeInfoMap"),
|
||||
("read_only_space", 0x025fd): (251, "SharedFunctionInfoMap"),
|
||||
("read_only_space", 0x02625): (234, "CodeMap"),
|
||||
("read_only_space", 0x0264d): (233, "CellMap"),
|
||||
("read_only_space", 0x02675): (249, "GlobalPropertyCellMap"),
|
||||
("read_only_space", 0x0269d): (204, "ForeignMap"),
|
||||
("read_only_space", 0x026c5): (230, "TransitionArrayMap"),
|
||||
("read_only_space", 0x026c5): (231, "TransitionArrayMap"),
|
||||
("read_only_space", 0x026ed): (45, "ThinOneByteStringMap"),
|
||||
("read_only_space", 0x02715): (238, "FeedbackVectorMap"),
|
||||
("read_only_space", 0x02715): (239, "FeedbackVectorMap"),
|
||||
("read_only_space", 0x0274d): (131, "ArgumentsMarkerMap"),
|
||||
("read_only_space", 0x027ad): (131, "ExceptionMap"),
|
||||
("read_only_space", 0x02809): (131, "TerminationExceptionMap"),
|
||||
@ -294,17 +295,17 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x028d1): (131, "StaleRegisterMap"),
|
||||
("read_only_space", 0x02931): (188, "ScriptContextTableMap"),
|
||||
("read_only_space", 0x02959): (186, "ClosureFeedbackCellArrayMap"),
|
||||
("read_only_space", 0x02981): (237, "FeedbackMetadataArrayMap"),
|
||||
("read_only_space", 0x02981): (238, "FeedbackMetadataArrayMap"),
|
||||
("read_only_space", 0x029a9): (176, "ArrayListMap"),
|
||||
("read_only_space", 0x029d1): (129, "BigIntMap"),
|
||||
("read_only_space", 0x029f9): (187, "ObjectBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x02a21): (190, "BytecodeArrayMap"),
|
||||
("read_only_space", 0x02a49): (234, "CodeDataContainerMap"),
|
||||
("read_only_space", 0x02a71): (235, "CoverageInfoMap"),
|
||||
("read_only_space", 0x02a49): (235, "CodeDataContainerMap"),
|
||||
("read_only_space", 0x02a71): (236, "CoverageInfoMap"),
|
||||
("read_only_space", 0x02a99): (191, "FixedDoubleArrayMap"),
|
||||
("read_only_space", 0x02ac1): (179, "GlobalDictionaryMap"),
|
||||
("read_only_space", 0x02ae9): (157, "ManyClosuresCellMap"),
|
||||
("read_only_space", 0x02b11): (244, "MegaDomHandlerMap"),
|
||||
("read_only_space", 0x02b11): (245, "MegaDomHandlerMap"),
|
||||
("read_only_space", 0x02b39): (176, "ModuleInfoMap"),
|
||||
("read_only_space", 0x02b61): (180, "NameDictionaryMap"),
|
||||
("read_only_space", 0x02b89): (157, "NoClosuresCellMap"),
|
||||
@ -313,115 +314,116 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x02c01): (182, "OrderedHashMapMap"),
|
||||
("read_only_space", 0x02c29): (183, "OrderedHashSetMap"),
|
||||
("read_only_space", 0x02c51): (184, "OrderedNameDictionaryMap"),
|
||||
("read_only_space", 0x02c79): (246, "PreparseDataMap"),
|
||||
("read_only_space", 0x02ca1): (247, "PropertyArrayMap"),
|
||||
("read_only_space", 0x02c79): (247, "PreparseDataMap"),
|
||||
("read_only_space", 0x02ca1): (248, "PropertyArrayMap"),
|
||||
("read_only_space", 0x02cc9): (153, "SideEffectCallHandlerInfoMap"),
|
||||
("read_only_space", 0x02cf1): (153, "SideEffectFreeCallHandlerInfoMap"),
|
||||
("read_only_space", 0x02d19): (153, "NextCallSideEffectFreeCallHandlerInfoMap"),
|
||||
("read_only_space", 0x02d41): (185, "SimpleNumberDictionaryMap"),
|
||||
("read_only_space", 0x02d69): (218, "SmallOrderedHashMapMap"),
|
||||
("read_only_space", 0x02d91): (219, "SmallOrderedHashSetMap"),
|
||||
("read_only_space", 0x02db9): (220, "SmallOrderedNameDictionaryMap"),
|
||||
("read_only_space", 0x02de1): (225, "SourceTextModuleMap"),
|
||||
("read_only_space", 0x02e09): (254, "SwissNameDictionaryMap"),
|
||||
("read_only_space", 0x02e31): (226, "SyntheticModuleMap"),
|
||||
("read_only_space", 0x02e59): (206, "WasmCapiFunctionDataMap"),
|
||||
("read_only_space", 0x02e81): (207, "WasmExportedFunctionDataMap"),
|
||||
("read_only_space", 0x02ea9): (208, "WasmJSFunctionDataMap"),
|
||||
("read_only_space", 0x02ed1): (255, "WasmApiFunctionRefMap"),
|
||||
("read_only_space", 0x02ef9): (209, "WasmTypeInfoMap"),
|
||||
("read_only_space", 0x02f21): (229, "WeakFixedArrayMap"),
|
||||
("read_only_space", 0x02f49): (178, "EphemeronHashTableMap"),
|
||||
("read_only_space", 0x02f71): (236, "EmbedderDataArrayMap"),
|
||||
("read_only_space", 0x02f99): (257, "WeakCellMap"),
|
||||
("read_only_space", 0x02fc1): (32, "StringMap"),
|
||||
("read_only_space", 0x02fe9): (41, "ConsOneByteStringMap"),
|
||||
("read_only_space", 0x03011): (33, "ConsStringMap"),
|
||||
("read_only_space", 0x03039): (37, "ThinStringMap"),
|
||||
("read_only_space", 0x03061): (35, "SlicedStringMap"),
|
||||
("read_only_space", 0x03089): (43, "SlicedOneByteStringMap"),
|
||||
("read_only_space", 0x030b1): (34, "ExternalStringMap"),
|
||||
("read_only_space", 0x030d9): (42, "ExternalOneByteStringMap"),
|
||||
("read_only_space", 0x03101): (50, "UncachedExternalStringMap"),
|
||||
("read_only_space", 0x03129): (0, "InternalizedStringMap"),
|
||||
("read_only_space", 0x03151): (2, "ExternalInternalizedStringMap"),
|
||||
("read_only_space", 0x03179): (10, "ExternalOneByteInternalizedStringMap"),
|
||||
("read_only_space", 0x031a1): (18, "UncachedExternalInternalizedStringMap"),
|
||||
("read_only_space", 0x031c9): (26, "UncachedExternalOneByteInternalizedStringMap"),
|
||||
("read_only_space", 0x031f1): (58, "UncachedExternalOneByteStringMap"),
|
||||
("read_only_space", 0x03219): (104, "SharedOneByteStringMap"),
|
||||
("read_only_space", 0x03241): (96, "SharedStringMap"),
|
||||
("read_only_space", 0x03269): (131, "SelfReferenceMarkerMap"),
|
||||
("read_only_space", 0x03291): (131, "BasicBlockCountersMarkerMap"),
|
||||
("read_only_space", 0x032d5): (147, "ArrayBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x033d5): (159, "InterceptorInfoMap"),
|
||||
("read_only_space", 0x05c65): (132, "PromiseFulfillReactionJobTaskMap"),
|
||||
("read_only_space", 0x05c8d): (133, "PromiseRejectReactionJobTaskMap"),
|
||||
("read_only_space", 0x05cb5): (134, "CallableTaskMap"),
|
||||
("read_only_space", 0x05cdd): (135, "CallbackTaskMap"),
|
||||
("read_only_space", 0x05d05): (136, "PromiseResolveThenableJobTaskMap"),
|
||||
("read_only_space", 0x05d2d): (139, "FunctionTemplateInfoMap"),
|
||||
("read_only_space", 0x05d55): (140, "ObjectTemplateInfoMap"),
|
||||
("read_only_space", 0x05d7d): (141, "AccessCheckInfoMap"),
|
||||
("read_only_space", 0x05da5): (142, "AccessorInfoMap"),
|
||||
("read_only_space", 0x05dcd): (143, "AccessorPairMap"),
|
||||
("read_only_space", 0x05df5): (144, "AliasedArgumentsEntryMap"),
|
||||
("read_only_space", 0x05e1d): (145, "AllocationMementoMap"),
|
||||
("read_only_space", 0x05e45): (148, "AsmWasmDataMap"),
|
||||
("read_only_space", 0x05e6d): (149, "AsyncGeneratorRequestMap"),
|
||||
("read_only_space", 0x05e95): (150, "BreakPointMap"),
|
||||
("read_only_space", 0x05ebd): (151, "BreakPointInfoMap"),
|
||||
("read_only_space", 0x05ee5): (152, "CachedTemplateObjectMap"),
|
||||
("read_only_space", 0x05f0d): (154, "ClassPositionsMap"),
|
||||
("read_only_space", 0x05f35): (155, "DebugInfoMap"),
|
||||
("read_only_space", 0x05f5d): (158, "FunctionTemplateRareDataMap"),
|
||||
("read_only_space", 0x05f85): (160, "InterpreterDataMap"),
|
||||
("read_only_space", 0x05fad): (161, "ModuleRequestMap"),
|
||||
("read_only_space", 0x05fd5): (162, "PromiseCapabilityMap"),
|
||||
("read_only_space", 0x05ffd): (163, "PromiseReactionMap"),
|
||||
("read_only_space", 0x06025): (164, "PropertyDescriptorObjectMap"),
|
||||
("read_only_space", 0x0604d): (165, "PrototypeInfoMap"),
|
||||
("read_only_space", 0x06075): (166, "RegExpBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x0609d): (167, "ScriptMap"),
|
||||
("read_only_space", 0x060c5): (168, "ScriptOrModuleMap"),
|
||||
("read_only_space", 0x060ed): (169, "SourceTextModuleInfoEntryMap"),
|
||||
("read_only_space", 0x06115): (170, "StackFrameInfoMap"),
|
||||
("read_only_space", 0x0613d): (171, "TemplateObjectDescriptionMap"),
|
||||
("read_only_space", 0x06165): (172, "Tuple2Map"),
|
||||
("read_only_space", 0x0618d): (173, "WasmContinuationObjectMap"),
|
||||
("read_only_space", 0x061b5): (174, "WasmExceptionTagMap"),
|
||||
("read_only_space", 0x061dd): (175, "WasmIndirectFunctionTableMap"),
|
||||
("read_only_space", 0x06205): (193, "SloppyArgumentsElementsMap"),
|
||||
("read_only_space", 0x0622d): (223, "DescriptorArrayMap"),
|
||||
("read_only_space", 0x06255): (228, "UncompiledDataWithoutPreparseDataMap"),
|
||||
("read_only_space", 0x0627d): (227, "UncompiledDataWithPreparseDataMap"),
|
||||
("read_only_space", 0x062a5): (245, "OnHeapBasicBlockProfilerDataMap"),
|
||||
("read_only_space", 0x062cd): (210, "TurbofanBitsetTypeMap"),
|
||||
("read_only_space", 0x062f5): (214, "TurbofanUnionTypeMap"),
|
||||
("read_only_space", 0x0631d): (213, "TurbofanRangeTypeMap"),
|
||||
("read_only_space", 0x06345): (211, "TurbofanHeapConstantTypeMap"),
|
||||
("read_only_space", 0x0636d): (212, "TurbofanOtherNumberConstantTypeMap"),
|
||||
("read_only_space", 0x06395): (241, "InternalClassMap"),
|
||||
("read_only_space", 0x063bd): (252, "SmiPairMap"),
|
||||
("read_only_space", 0x063e5): (251, "SmiBoxMap"),
|
||||
("read_only_space", 0x0640d): (215, "ExportedSubClassBaseMap"),
|
||||
("read_only_space", 0x06435): (216, "ExportedSubClassMap"),
|
||||
("read_only_space", 0x0645d): (221, "AbstractInternalClassSubclass1Map"),
|
||||
("read_only_space", 0x06485): (222, "AbstractInternalClassSubclass2Map"),
|
||||
("read_only_space", 0x064ad): (192, "InternalClassWithSmiElementsMap"),
|
||||
("read_only_space", 0x064d5): (242, "InternalClassWithStructElementsMap"),
|
||||
("read_only_space", 0x064fd): (217, "ExportedSubClass2Map"),
|
||||
("read_only_space", 0x06525): (253, "SortStateMap"),
|
||||
("read_only_space", 0x0654d): (231, "CallRefDataMap"),
|
||||
("read_only_space", 0x06575): (146, "AllocationSiteWithWeakNextMap"),
|
||||
("read_only_space", 0x0659d): (146, "AllocationSiteWithoutWeakNextMap"),
|
||||
("read_only_space", 0x065c5): (137, "LoadHandler1Map"),
|
||||
("read_only_space", 0x065ed): (137, "LoadHandler2Map"),
|
||||
("read_only_space", 0x06615): (137, "LoadHandler3Map"),
|
||||
("read_only_space", 0x0663d): (138, "StoreHandler0Map"),
|
||||
("read_only_space", 0x06665): (138, "StoreHandler1Map"),
|
||||
("read_only_space", 0x0668d): (138, "StoreHandler2Map"),
|
||||
("read_only_space", 0x066b5): (138, "StoreHandler3Map"),
|
||||
("read_only_space", 0x02d69): (219, "SmallOrderedHashMapMap"),
|
||||
("read_only_space", 0x02d91): (220, "SmallOrderedHashSetMap"),
|
||||
("read_only_space", 0x02db9): (221, "SmallOrderedNameDictionaryMap"),
|
||||
("read_only_space", 0x02de1): (226, "SourceTextModuleMap"),
|
||||
("read_only_space", 0x02e09): (255, "SwissNameDictionaryMap"),
|
||||
("read_only_space", 0x02e31): (227, "SyntheticModuleMap"),
|
||||
("read_only_space", 0x02e59): (256, "WasmApiFunctionRefMap"),
|
||||
("read_only_space", 0x02e81): (213, "WasmCapiFunctionDataMap"),
|
||||
("read_only_space", 0x02ea9): (214, "WasmExportedFunctionDataMap"),
|
||||
("read_only_space", 0x02ed1): (205, "WasmInternalFunctionMap"),
|
||||
("read_only_space", 0x02ef9): (215, "WasmJSFunctionDataMap"),
|
||||
("read_only_space", 0x02f21): (206, "WasmTypeInfoMap"),
|
||||
("read_only_space", 0x02f49): (230, "WeakFixedArrayMap"),
|
||||
("read_only_space", 0x02f71): (178, "EphemeronHashTableMap"),
|
||||
("read_only_space", 0x02f99): (237, "EmbedderDataArrayMap"),
|
||||
("read_only_space", 0x02fc1): (258, "WeakCellMap"),
|
||||
("read_only_space", 0x02fe9): (32, "StringMap"),
|
||||
("read_only_space", 0x03011): (41, "ConsOneByteStringMap"),
|
||||
("read_only_space", 0x03039): (33, "ConsStringMap"),
|
||||
("read_only_space", 0x03061): (37, "ThinStringMap"),
|
||||
("read_only_space", 0x03089): (35, "SlicedStringMap"),
|
||||
("read_only_space", 0x030b1): (43, "SlicedOneByteStringMap"),
|
||||
("read_only_space", 0x030d9): (34, "ExternalStringMap"),
|
||||
("read_only_space", 0x03101): (42, "ExternalOneByteStringMap"),
|
||||
("read_only_space", 0x03129): (50, "UncachedExternalStringMap"),
|
||||
("read_only_space", 0x03151): (0, "InternalizedStringMap"),
|
||||
("read_only_space", 0x03179): (2, "ExternalInternalizedStringMap"),
|
||||
("read_only_space", 0x031a1): (10, "ExternalOneByteInternalizedStringMap"),
|
||||
("read_only_space", 0x031c9): (18, "UncachedExternalInternalizedStringMap"),
|
||||
("read_only_space", 0x031f1): (26, "UncachedExternalOneByteInternalizedStringMap"),
|
||||
("read_only_space", 0x03219): (58, "UncachedExternalOneByteStringMap"),
|
||||
("read_only_space", 0x03241): (104, "SharedOneByteStringMap"),
|
||||
("read_only_space", 0x03269): (96, "SharedStringMap"),
|
||||
("read_only_space", 0x03291): (131, "SelfReferenceMarkerMap"),
|
||||
("read_only_space", 0x032b9): (131, "BasicBlockCountersMarkerMap"),
|
||||
("read_only_space", 0x032fd): (147, "ArrayBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x033fd): (159, "InterceptorInfoMap"),
|
||||
("read_only_space", 0x05c8d): (132, "PromiseFulfillReactionJobTaskMap"),
|
||||
("read_only_space", 0x05cb5): (133, "PromiseRejectReactionJobTaskMap"),
|
||||
("read_only_space", 0x05cdd): (134, "CallableTaskMap"),
|
||||
("read_only_space", 0x05d05): (135, "CallbackTaskMap"),
|
||||
("read_only_space", 0x05d2d): (136, "PromiseResolveThenableJobTaskMap"),
|
||||
("read_only_space", 0x05d55): (139, "FunctionTemplateInfoMap"),
|
||||
("read_only_space", 0x05d7d): (140, "ObjectTemplateInfoMap"),
|
||||
("read_only_space", 0x05da5): (141, "AccessCheckInfoMap"),
|
||||
("read_only_space", 0x05dcd): (142, "AccessorInfoMap"),
|
||||
("read_only_space", 0x05df5): (143, "AccessorPairMap"),
|
||||
("read_only_space", 0x05e1d): (144, "AliasedArgumentsEntryMap"),
|
||||
("read_only_space", 0x05e45): (145, "AllocationMementoMap"),
|
||||
("read_only_space", 0x05e6d): (148, "AsmWasmDataMap"),
|
||||
("read_only_space", 0x05e95): (149, "AsyncGeneratorRequestMap"),
|
||||
("read_only_space", 0x05ebd): (150, "BreakPointMap"),
|
||||
("read_only_space", 0x05ee5): (151, "BreakPointInfoMap"),
|
||||
("read_only_space", 0x05f0d): (152, "CachedTemplateObjectMap"),
|
||||
("read_only_space", 0x05f35): (154, "ClassPositionsMap"),
|
||||
("read_only_space", 0x05f5d): (155, "DebugInfoMap"),
|
||||
("read_only_space", 0x05f85): (158, "FunctionTemplateRareDataMap"),
|
||||
("read_only_space", 0x05fad): (160, "InterpreterDataMap"),
|
||||
("read_only_space", 0x05fd5): (161, "ModuleRequestMap"),
|
||||
("read_only_space", 0x05ffd): (162, "PromiseCapabilityMap"),
|
||||
("read_only_space", 0x06025): (163, "PromiseReactionMap"),
|
||||
("read_only_space", 0x0604d): (164, "PropertyDescriptorObjectMap"),
|
||||
("read_only_space", 0x06075): (165, "PrototypeInfoMap"),
|
||||
("read_only_space", 0x0609d): (166, "RegExpBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x060c5): (167, "ScriptMap"),
|
||||
("read_only_space", 0x060ed): (168, "ScriptOrModuleMap"),
|
||||
("read_only_space", 0x06115): (169, "SourceTextModuleInfoEntryMap"),
|
||||
("read_only_space", 0x0613d): (170, "StackFrameInfoMap"),
|
||||
("read_only_space", 0x06165): (171, "TemplateObjectDescriptionMap"),
|
||||
("read_only_space", 0x0618d): (172, "Tuple2Map"),
|
||||
("read_only_space", 0x061b5): (173, "WasmContinuationObjectMap"),
|
||||
("read_only_space", 0x061dd): (174, "WasmExceptionTagMap"),
|
||||
("read_only_space", 0x06205): (175, "WasmIndirectFunctionTableMap"),
|
||||
("read_only_space", 0x0622d): (193, "SloppyArgumentsElementsMap"),
|
||||
("read_only_space", 0x06255): (224, "DescriptorArrayMap"),
|
||||
("read_only_space", 0x0627d): (229, "UncompiledDataWithoutPreparseDataMap"),
|
||||
("read_only_space", 0x062a5): (228, "UncompiledDataWithPreparseDataMap"),
|
||||
("read_only_space", 0x062cd): (246, "OnHeapBasicBlockProfilerDataMap"),
|
||||
("read_only_space", 0x062f5): (207, "TurbofanBitsetTypeMap"),
|
||||
("read_only_space", 0x0631d): (211, "TurbofanUnionTypeMap"),
|
||||
("read_only_space", 0x06345): (210, "TurbofanRangeTypeMap"),
|
||||
("read_only_space", 0x0636d): (208, "TurbofanHeapConstantTypeMap"),
|
||||
("read_only_space", 0x06395): (209, "TurbofanOtherNumberConstantTypeMap"),
|
||||
("read_only_space", 0x063bd): (242, "InternalClassMap"),
|
||||
("read_only_space", 0x063e5): (253, "SmiPairMap"),
|
||||
("read_only_space", 0x0640d): (252, "SmiBoxMap"),
|
||||
("read_only_space", 0x06435): (216, "ExportedSubClassBaseMap"),
|
||||
("read_only_space", 0x0645d): (217, "ExportedSubClassMap"),
|
||||
("read_only_space", 0x06485): (222, "AbstractInternalClassSubclass1Map"),
|
||||
("read_only_space", 0x064ad): (223, "AbstractInternalClassSubclass2Map"),
|
||||
("read_only_space", 0x064d5): (192, "InternalClassWithSmiElementsMap"),
|
||||
("read_only_space", 0x064fd): (243, "InternalClassWithStructElementsMap"),
|
||||
("read_only_space", 0x06525): (218, "ExportedSubClass2Map"),
|
||||
("read_only_space", 0x0654d): (254, "SortStateMap"),
|
||||
("read_only_space", 0x06575): (232, "CallRefDataMap"),
|
||||
("read_only_space", 0x0659d): (146, "AllocationSiteWithWeakNextMap"),
|
||||
("read_only_space", 0x065c5): (146, "AllocationSiteWithoutWeakNextMap"),
|
||||
("read_only_space", 0x065ed): (137, "LoadHandler1Map"),
|
||||
("read_only_space", 0x06615): (137, "LoadHandler2Map"),
|
||||
("read_only_space", 0x0663d): (137, "LoadHandler3Map"),
|
||||
("read_only_space", 0x06665): (138, "StoreHandler0Map"),
|
||||
("read_only_space", 0x0668d): (138, "StoreHandler1Map"),
|
||||
("read_only_space", 0x066b5): (138, "StoreHandler2Map"),
|
||||
("read_only_space", 0x066dd): (138, "StoreHandler3Map"),
|
||||
("map_space", 0x02119): (1057, "ExternalMap"),
|
||||
("map_space", 0x02141): (2114, "JSMessageObjectMap"),
|
||||
}
|
||||
@ -447,32 +449,32 @@ KNOWN_OBJECTS = {
|
||||
("read_only_space", 0x02831): "TerminationException",
|
||||
("read_only_space", 0x02899): "OptimizedOut",
|
||||
("read_only_space", 0x028f9): "StaleRegister",
|
||||
("read_only_space", 0x032b9): "EmptyPropertyArray",
|
||||
("read_only_space", 0x032c1): "EmptyByteArray",
|
||||
("read_only_space", 0x032c9): "EmptyObjectBoilerplateDescription",
|
||||
("read_only_space", 0x032fd): "EmptyArrayBoilerplateDescription",
|
||||
("read_only_space", 0x03309): "EmptyClosureFeedbackCellArray",
|
||||
("read_only_space", 0x03311): "EmptySlowElementDictionary",
|
||||
("read_only_space", 0x03335): "EmptyOrderedHashMap",
|
||||
("read_only_space", 0x03349): "EmptyOrderedHashSet",
|
||||
("read_only_space", 0x0335d): "EmptyFeedbackMetadata",
|
||||
("read_only_space", 0x03369): "EmptyPropertyDictionary",
|
||||
("read_only_space", 0x03391): "EmptyOrderedPropertyDictionary",
|
||||
("read_only_space", 0x033a9): "EmptySwissPropertyDictionary",
|
||||
("read_only_space", 0x033fd): "NoOpInterceptorInfo",
|
||||
("read_only_space", 0x03425): "EmptyWeakFixedArray",
|
||||
("read_only_space", 0x0342d): "InfinityValue",
|
||||
("read_only_space", 0x03439): "MinusZeroValue",
|
||||
("read_only_space", 0x03445): "MinusInfinityValue",
|
||||
("read_only_space", 0x03451): "SelfReferenceMarker",
|
||||
("read_only_space", 0x03491): "BasicBlockCountersMarker",
|
||||
("read_only_space", 0x034d5): "OffHeapTrampolineRelocationInfo",
|
||||
("read_only_space", 0x034e1): "TrampolineTrivialCodeDataContainer",
|
||||
("read_only_space", 0x034ed): "TrampolinePromiseRejectionCodeDataContainer",
|
||||
("read_only_space", 0x034f9): "GlobalThisBindingScopeInfo",
|
||||
("read_only_space", 0x03529): "EmptyFunctionScopeInfo",
|
||||
("read_only_space", 0x0354d): "NativeScopeInfo",
|
||||
("read_only_space", 0x03565): "HashSeed",
|
||||
("read_only_space", 0x032e1): "EmptyPropertyArray",
|
||||
("read_only_space", 0x032e9): "EmptyByteArray",
|
||||
("read_only_space", 0x032f1): "EmptyObjectBoilerplateDescription",
|
||||
("read_only_space", 0x03325): "EmptyArrayBoilerplateDescription",
|
||||
("read_only_space", 0x03331): "EmptyClosureFeedbackCellArray",
|
||||
("read_only_space", 0x03339): "EmptySlowElementDictionary",
|
||||
("read_only_space", 0x0335d): "EmptyOrderedHashMap",
|
||||
("read_only_space", 0x03371): "EmptyOrderedHashSet",
|
||||
("read_only_space", 0x03385): "EmptyFeedbackMetadata",
|
||||
("read_only_space", 0x03391): "EmptyPropertyDictionary",
|
||||
("read_only_space", 0x033b9): "EmptyOrderedPropertyDictionary",
|
||||
("read_only_space", 0x033d1): "EmptySwissPropertyDictionary",
|
||||
("read_only_space", 0x03425): "NoOpInterceptorInfo",
|
||||
("read_only_space", 0x0344d): "EmptyWeakFixedArray",
|
||||
("read_only_space", 0x03455): "InfinityValue",
|
||||
("read_only_space", 0x03461): "MinusZeroValue",
|
||||
("read_only_space", 0x0346d): "MinusInfinityValue",
|
||||
("read_only_space", 0x03479): "SelfReferenceMarker",
|
||||
("read_only_space", 0x034b9): "BasicBlockCountersMarker",
|
||||
("read_only_space", 0x034fd): "OffHeapTrampolineRelocationInfo",
|
||||
("read_only_space", 0x03509): "TrampolineTrivialCodeDataContainer",
|
||||
("read_only_space", 0x03515): "TrampolinePromiseRejectionCodeDataContainer",
|
||||
("read_only_space", 0x03521): "GlobalThisBindingScopeInfo",
|
||||
("read_only_space", 0x03551): "EmptyFunctionScopeInfo",
|
||||
("read_only_space", 0x03575): "NativeScopeInfo",
|
||||
("read_only_space", 0x0358d): "HashSeed",
|
||||
("old_space", 0x04211): "ArgumentsIteratorAccessor",
|
||||
("old_space", 0x04255): "ArrayLengthAccessor",
|
||||
("old_space", 0x04299): "BoundFunctionLengthAccessor",
|
||||
|
Loading…
Reference in New Issue
Block a user