[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:
Manos Koukoutos 2021-11-23 14:31:18 +00:00 committed by V8 LUCI CQ
parent 42da0c3918
commit f60132e96a
39 changed files with 796 additions and 577 deletions

View File

@ -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(

View File

@ -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(

View File

@ -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};

View File

@ -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);

View File

@ -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),
&not_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(&not_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));

View File

@ -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);
//-----------------------------------------------------------------------

View File

@ -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,

View File

@ -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(

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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)

View File

@ -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,

View File

@ -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 {

View File

@ -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:

View File

@ -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) \

View File

@ -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) \

View File

@ -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:

View File

@ -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) \

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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++) {

View File

@ -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 =

View File

@ -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(); }

View File

@ -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

View File

@ -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(

View File

@ -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)
};

View File

@ -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;

View File

@ -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());

View File

@ -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

View File

@ -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(

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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",