Commit ddc43d9c authored by Igor Sheludko's avatar Igor Sheludko Committed by V8 LUCI CQ

[wasm-gc][ic] Support WasmObjects in LoadIC

Bug: v8:11804
Change-Id: I6eddf2d836c3916622768ef2a7d878157e89e4c8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2772980Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74796}
parent 6d6438eb
......@@ -9286,6 +9286,9 @@ void CodeStubAssembler::LoadPropertyFromFastObject(
TNode<Uint32T> representation =
DecodeWord32<PropertyDetails::RepresentationField>(details);
// TODO(ishell): support WasmValues.
CSA_ASSERT(this, Word32NotEqual(representation,
Int32Constant(Representation::kWasmValue)));
field_index =
IntPtrAdd(field_index, LoadMapInobjectPropertiesStartInWords(map));
TNode<IntPtrT> instance_size_in_words = LoadMapInstanceSizeInWords(map);
......
......@@ -287,7 +287,7 @@ void AccessorAssembler::HandleLoadField(TNode<JSObject> holder,
TVariable<Float64T>* var_double_value,
Label* rebox_double, Label* miss,
ExitPoint* exit_point) {
Comment("field_load");
Comment("LoadField");
TNode<IntPtrT> index =
Signed(DecodeWord<LoadHandler::FieldIndexBits>(handler_word));
TNode<IntPtrT> offset = IntPtrMul(index, IntPtrConstant(kTaggedSize));
......@@ -332,6 +332,108 @@ void AccessorAssembler::HandleLoadField(TNode<JSObject> holder,
}
}
#if V8_ENABLE_WEBASSEMBLY
void AccessorAssembler::HandleLoadWasmField(
TNode<WasmObject> holder, TNode<Int32T> wasm_value_type,
TNode<IntPtrT> field_offset, TVariable<Float64T>* var_double_value,
Label* rebox_double, ExitPoint* exit_point) {
Label type_I8(this), type_I16(this), type_I32(this), type_U32(this),
type_I64(this), type_U64(this), type_F32(this), type_F64(this),
unsupported_type(this, Label::kDeferred),
unexpected_type(this, Label::kDeferred);
Label* wasm_value_type_labels[] = {
&type_I8, &type_I16, &type_I32, &type_U32,
&type_I64, &type_F32, &type_F64, &unsupported_type,
&unsupported_type, &unsupported_type};
int32_t wasm_value_types[] = {
static_cast<int32_t>(WasmValueType::kI8),
static_cast<int32_t>(WasmValueType::kI16),
static_cast<int32_t>(WasmValueType::kI32),
static_cast<int32_t>(WasmValueType::kU32),
static_cast<int32_t>(WasmValueType::kI64),
static_cast<int32_t>(WasmValueType::kF32),
static_cast<int32_t>(WasmValueType::kF64),
// TODO(ishell): support the following value types.
static_cast<int32_t>(WasmValueType::kS128),
static_cast<int32_t>(WasmValueType::kRef),
static_cast<int32_t>(WasmValueType::kOptRef)};
const size_t kWasmValueTypeCount =
static_cast<size_t>(WasmValueType::kNumTypes);
DCHECK_EQ(kWasmValueTypeCount, arraysize(wasm_value_types));
DCHECK_EQ(kWasmValueTypeCount, arraysize(wasm_value_type_labels));
Switch(wasm_value_type, &unexpected_type, wasm_value_types,
wasm_value_type_labels, kWasmValueTypeCount);
BIND(&type_I8);
{
Comment("type_I8");
TNode<Int32T> value = LoadObjectField<Int8T>(holder, field_offset);
exit_point->Return(SmiFromInt32(value));
}
BIND(&type_I16);
{
Comment("type_I16");
TNode<Int32T> value = LoadObjectField<Int16T>(holder, field_offset);
exit_point->Return(SmiFromInt32(value));
}
BIND(&type_I32);
{
Comment("type_I32");
TNode<Int32T> value = LoadObjectField<Int32T>(holder, field_offset);
exit_point->Return(ChangeInt32ToTagged(value));
}
BIND(&type_U32);
{
Comment("type_U32");
TNode<Uint32T> value = LoadObjectField<Uint32T>(holder, field_offset);
exit_point->Return(ChangeUint32ToTagged(value));
}
BIND(&type_I64);
{
Comment("type_I64");
Unreachable();
}
BIND(&type_F32);
{
Comment("type_F32");
TNode<Float32T> value = LoadObjectField<Float32T>(holder, field_offset);
*var_double_value = ChangeFloat32ToFloat64(value);
Goto(rebox_double);
}
BIND(&type_F64);
{
Comment("type_F64");
TNode<Float64T> value = LoadObjectField<Float64T>(holder, field_offset);
*var_double_value = value;
Goto(rebox_double);
}
BIND(&unsupported_type);
{
Print("Not supported Wasm field type");
Unreachable();
}
BIND(&unexpected_type);
{ Unreachable(); }
}
void AccessorAssembler::HandleLoadWasmField(
TNode<WasmObject> holder, TNode<WordT> handler_word,
TVariable<Float64T>* var_double_value, Label* rebox_double,
ExitPoint* exit_point) {
Comment("LoadWasmField");
TNode<Int32T> wasm_value_type =
Signed(DecodeWord32<LoadHandler::WasmFieldTypeBits>(
TruncateWordToInt32(handler_word)));
TNode<IntPtrT> field_offset =
Signed(DecodeWord<LoadHandler::WasmFieldOffsetBits>(handler_word));
HandleLoadWasmField(holder, wasm_value_type, field_offset, var_double_value,
rebox_double, exit_point);
}
#endif // V8_ENABLE_WEBASSEMBLY
TNode<Object> AccessorAssembler::LoadDescriptorValue(
TNode<Map> map, TNode<IntPtrT> descriptor_entry) {
return CAST(LoadDescriptorValueOrFieldType(map, descriptor_entry));
......@@ -378,6 +480,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
BIND(&if_element);
{
Comment("element_load");
// TODO(ishell): implement
CSA_ASSERT(this, IsClearWord<LoadHandler::IsWasmArrayBits>(handler_word));
TVARIABLE(Int32T, var_instance_type);
TNode<IntPtrT> intptr_index = TryToIntptr(
p->name(), &try_string_to_array_index, &var_instance_type);
......@@ -558,8 +662,24 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase(
&module_export, &interceptor);
BIND(&field);
HandleLoadField(CAST(holder), handler_word, var_double_value, rebox_double,
miss, exit_point);
{
#if V8_ENABLE_WEBASSEMBLY
Label is_wasm_field(this);
GotoIf(IsSetWord<LoadHandler::IsWasmStructBits>(handler_word),
&is_wasm_field);
#else
CSA_ASSERT(this, IsClearWord<LoadHandler::IsWasmStructBits>(handler_word));
#endif // V8_ENABLE_WEBASSEMBLY
HandleLoadField(CAST(holder), handler_word, var_double_value, rebox_double,
miss, exit_point);
#if V8_ENABLE_WEBASSEMBLY
BIND(&is_wasm_field);
HandleLoadWasmField(CAST(holder), handler_word, var_double_value,
rebox_double, exit_point);
#endif // V8_ENABLE_WEBASSEMBLY
}
BIND(&nonexistent);
// This is a handler for a load of a non-existent value.
......@@ -2633,6 +2753,7 @@ void AccessorAssembler::GenericPropertyLoad(
BIND(&special_receiver);
{
// TODO(ishell): Consider supporting WasmObjects.
// TODO(jkummerow): Consider supporting JSModuleNamespace.
GotoIfNot(
InstanceTypeEqual(lookup_start_object_instance_type, JS_PROXY_TYPE),
......
......@@ -355,6 +355,18 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler {
TVariable<Float64T>* var_double_value,
Label* rebox_double, Label* miss, ExitPoint* exit_point);
#if V8_ENABLE_WEBASSEMBLY
void HandleLoadWasmField(TNode<WasmObject> holder,
TNode<Int32T> wasm_value_type,
TNode<IntPtrT> field_offset,
TVariable<Float64T>* var_double_value,
Label* rebox_double, ExitPoint* exit_point);
void HandleLoadWasmField(TNode<WasmObject> holder, TNode<WordT> handler_word,
TVariable<Float64T>* var_double_value,
Label* rebox_double, ExitPoint* exit_point);
#endif // V8_ENABLE_WEBASSEMBLY
void EmitAccessCheck(TNode<Context> expected_native_context,
TNode<Context> context, TNode<Object> receiver,
Label* can_access, Label* miss);
......
......@@ -56,6 +56,14 @@ Handle<Smi> LoadHandler::LoadField(Isolate* isolate, FieldIndex field_index) {
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadWasmStructField(Isolate* isolate,
WasmValueType type, int offset) {
int config = KindBits::encode(kField) | IsWasmStructBits::encode(true) |
WasmFieldTypeBits::encode(type) |
WasmFieldOffsetBits::encode(offset);
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadConstantFromPrototype(Isolate* isolate) {
int config = KindBits::encode(kConstantFromPrototype);
return handle(Smi::FromInt(config), isolate);
......@@ -118,6 +126,13 @@ Handle<Smi> LoadHandler::LoadIndexedString(Isolate* isolate,
return handle(Smi::FromInt(config), isolate);
}
Handle<Smi> LoadHandler::LoadWasmArrayElement(Isolate* isolate,
WasmValueType type) {
int config = KindBits::encode(kElement) | IsWasmArrayBits::encode(true) |
WasmArrayTypeBits::encode(type);
return handle(Smi::FromInt(config), isolate);
}
OBJECT_CONSTRUCTORS_IMPL(StoreHandler, DataHandler)
CAST_ACCESSOR(StoreHandler)
......@@ -190,6 +205,35 @@ Handle<Smi> StoreHandler::StoreApiSetter(Isolate* isolate,
return handle(Smi::FromInt(config), isolate);
}
inline const char* WasmValueType2String(WasmValueType type) {
switch (type) {
case WasmValueType::kI8:
return "i8";
case WasmValueType::kI16:
return "i16";
case WasmValueType::kI32:
return "i32";
case WasmValueType::kU32:
return "u32";
case WasmValueType::kI64:
return "i64";
case WasmValueType::kF32:
return "f32";
case WasmValueType::kF64:
return "f64";
case WasmValueType::kS128:
return "s128";
case WasmValueType::kRef:
return "Ref";
case WasmValueType::kOptRef:
return "OptRef";
case WasmValueType::kNumTypes:
return "???";
}
}
} // namespace internal
} // namespace v8
......
......@@ -315,14 +315,22 @@ void PrintSmiLoadHandler(int raw_handler, std::ostream& os) {
os << "kind = ";
switch (kind) {
case LoadHandler::Kind::kElement:
os << "kElement, allow out of bounds = "
<< LoadHandler::AllowOutOfBoundsBits::decode(raw_handler)
<< ", is JSArray = " << LoadHandler::IsJsArrayBits::decode(raw_handler)
<< ", convert hole = "
<< LoadHandler::ConvertHoleBits::decode(raw_handler)
<< ", elements kind = "
<< ElementsKindToString(
LoadHandler::ElementsKindBits::decode(raw_handler));
os << "kElement, ";
if (LoadHandler::IsWasmArrayBits::decode(raw_handler)) {
os << "WasmArray, "
<< LoadHandler::WasmArrayTypeBits::decode(raw_handler);
} else {
os << "allow out of bounds = "
<< LoadHandler::AllowOutOfBoundsBits::decode(raw_handler)
<< ", is JSArray = "
<< LoadHandler::IsJsArrayBits::decode(raw_handler)
<< ", convert hole = "
<< LoadHandler::ConvertHoleBits::decode(raw_handler)
<< ", elements kind = "
<< ElementsKindToString(
LoadHandler::ElementsKindBits::decode(raw_handler));
}
break;
case LoadHandler::Kind::kIndexedString:
os << "kIndexedString, allow out of bounds = "
......@@ -335,11 +343,18 @@ void PrintSmiLoadHandler(int raw_handler, std::ostream& os) {
os << "kGlobal";
break;
case LoadHandler::Kind::kField: {
os << "kField, is in object = "
<< LoadHandler::IsInobjectBits::decode(raw_handler)
<< ", is double = " << LoadHandler::IsDoubleBits::decode(raw_handler)
<< ", field index = "
<< LoadHandler::FieldIndexBits::decode(raw_handler);
if (LoadHandler::IsWasmStructBits::decode(raw_handler)) {
os << "kField, WasmStruct, type = "
<< LoadHandler::WasmFieldTypeBits::decode(raw_handler)
<< ", field offset = "
<< LoadHandler::WasmFieldOffsetBits::decode(raw_handler);
} else {
os << "kField, is in object = "
<< LoadHandler::IsInobjectBits::decode(raw_handler)
<< ", is double = " << LoadHandler::IsDoubleBits::decode(raw_handler)
<< ", field index = "
<< LoadHandler::FieldIndexBits::decode(raw_handler);
}
break;
}
case LoadHandler::Kind::kConstantFromPrototype: {
......@@ -527,6 +542,11 @@ void StoreHandler::PrintHandler(Object handler, std::ostream& os) {
os << ")" << std::endl;
}
}
std::ostream& operator<<(std::ostream& os, WasmValueType type) {
return os << WasmValueType2String(type);
}
#endif // defined(OBJECT_PRINT)
} // namespace internal
......
......@@ -7,6 +7,7 @@
#include "src/common/globals.h"
#include "src/handles/maybe-handles.h"
#include "src/heap/heap.h"
#include "src/objects/data-handler.h"
#include "src/objects/elements-kind.h"
#include "src/objects/field-index.h"
......@@ -21,6 +22,22 @@ namespace internal {
class JSProxy;
enum class WasmValueType {
kI8,
kI16,
kI32,
kU32, // Used only for loading WasmArray length.
kI64,
kF32,
kF64,
kS128,
kRef,
kOptRef,
kNumTypes
};
// A set of bit fields representing Smi handlers for loads and a HeapObject
// that represents load handlers that can't be encoded in a Smi.
// TODO(ishell): move to load-handler.h
......@@ -75,7 +92,12 @@ class LoadHandler final : public DataHandler {
//
// Encoding when KindBits contains kField.
//
using IsInobjectBits = LookupOnLookupStartObjectBits::Next<bool, 1>;
using IsWasmStructBits = LookupOnLookupStartObjectBits::Next<bool, 1>;
//
// Encoding when KindBits contains kField and IsWasmStructBits is 0.
//
using IsInobjectBits = IsWasmStructBits::Next<bool, 1>;
using IsDoubleBits = IsInobjectBits::Next<bool, 1>;
// +1 here is to cover all possible JSObject header sizes.
using FieldIndexBits =
......@@ -83,6 +105,14 @@ class LoadHandler final : public DataHandler {
// Make sure we don't overflow the smi.
STATIC_ASSERT(FieldIndexBits::kLastUsedBit < kSmiValueSize);
//
// Encoding when KindBits contains kField and IsWasmStructBits is 1.
//
using WasmFieldTypeBits = IsWasmStructBits::Next<WasmValueType, 4>;
using WasmFieldOffsetBits = WasmFieldTypeBits::Next<unsigned, 20>;
// Make sure we don't overflow the smi.
STATIC_ASSERT(WasmFieldOffsetBits::kLastUsedBit < kSmiValueSize);
//
// Encoding when KindBits contains kElement or kIndexedString.
//
......@@ -91,18 +121,31 @@ class LoadHandler final : public DataHandler {
//
// Encoding when KindBits contains kElement.
//
using IsJsArrayBits = AllowOutOfBoundsBits::Next<bool, 1>;
using IsWasmArrayBits = AllowOutOfBoundsBits::Next<bool, 1>;
//
// Encoding when KindBits contains kElement and IsWasmArrayBits is 0.
//
using IsJsArrayBits = IsWasmArrayBits::Next<bool, 1>;
using ConvertHoleBits = IsJsArrayBits::Next<bool, 1>;
using ElementsKindBits = ConvertHoleBits::Next<ElementsKind, 8>;
// Make sure we don't overflow the smi.
STATIC_ASSERT(ElementsKindBits::kLastUsedBit < kSmiValueSize);
//
// Encoding when KindBits contains kElement and IsWasmArrayBits is 1.
//
using WasmArrayTypeBits = IsWasmArrayBits::Next<WasmValueType, 4>;
// Make sure we don't overflow the smi.
STATIC_ASSERT(WasmArrayTypeBits::kLastUsedBit < kSmiValueSize);
//
// Encoding when KindBits contains kModuleExport.
//
using ExportsIndexBits = LookupOnLookupStartObjectBits::Next<
unsigned,
kSmiValueSize - LookupOnLookupStartObjectBits::kLastUsedBit - 1>;
STATIC_ASSERT(ExportsIndexBits::kLastUsedBit < kSmiValueSize);
// Decodes kind from Smi-handler.
static inline Kind GetHandlerKind(Smi smi_handler);
......@@ -146,6 +189,11 @@ class LoadHandler final : public DataHandler {
// dictionary.
static inline Handle<Smi> LoadModuleExport(Isolate* isolate, int index);
static inline Handle<Smi> LoadWasmStructField(Isolate* isolate,
WasmValueType type, int offset);
static inline Handle<Smi> LoadWasmArrayElement(Isolate* isolate,
WasmValueType type);
// Creates a data handler that represents a load of a non-existent property.
// {holder} is the object from which the property is loaded. If no holder is
// needed (e.g., for "nonexistent"), null_value() may be passed in.
......@@ -317,6 +365,10 @@ class StoreHandler final : public DataHandler {
OBJECT_CONSTRUCTORS(StoreHandler, DataHandler);
};
inline const char* WasmValueType2String(WasmValueType type);
std::ostream& operator<<(std::ostream& os, WasmValueType type);
} // namespace internal
} // namespace v8
......
......@@ -43,6 +43,10 @@
#include "src/tracing/tracing-category-observer.h"
#include "src/utils/ostreams.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/struct-types.h"
#endif // V8_ENABLE_WEBASSEMBLY
namespace v8 {
namespace internal {
......@@ -831,6 +835,69 @@ void IC::UpdateMegamorphicCache(Handle<Map> map, Handle<Name> name,
}
}
namespace {
#if V8_ENABLE_WEBASSEMBLY
inline WasmValueType GetWasmValueType(wasm::ValueType type) {
#define TYPE_CASE(Name) \
case wasm::k##Name: \
return WasmValueType::k##Name;
switch (type.kind()) {
TYPE_CASE(I8)
TYPE_CASE(I16)
TYPE_CASE(I32)
TYPE_CASE(I64)
TYPE_CASE(F32)
TYPE_CASE(F64)
TYPE_CASE(S128)
TYPE_CASE(Ref)
TYPE_CASE(OptRef)
case wasm::kRtt:
case wasm::kRttWithDepth:
// Rtt values are not supposed to be made available to JavaScript side.
UNREACHABLE();
case wasm::kVoid:
case wasm::kBottom:
UNREACHABLE();
}
#undef TYPE_CASE
}
Handle<Smi> MakeLoadWasmStructFieldHandler(Isolate* isolate,
Handle<JSReceiver> holder,
LookupIterator* lookup) {
DCHECK(holder->IsWasmObject(isolate));
WasmValueType type;
int field_offset;
if (holder->IsWasmArray(isolate)) {
// The only named property that WasmArray has is length.
DCHECK_EQ(0, lookup->property_details().field_index());
DCHECK_EQ(*isolate->factory()->length_string(), *lookup->name());
type = WasmValueType::kU32;
field_offset = WasmArray::kLengthOffset;
} else {
wasm::StructType* struct_type = Handle<WasmStruct>::cast(holder)->type();
int field_index = lookup->property_details().field_index();
type = GetWasmValueType(struct_type->field(field_index));
field_offset =
WasmStruct::kHeaderSize + struct_type->field_offset(field_index);
const size_t kMaxWasmFieldOffset =
WasmStruct::kHeaderSize + wasm::StructType::kMaxFieldOffset;
static_assert(kMaxWasmFieldOffset <= LoadHandler::WasmFieldOffsetBits::kMax,
"Bigger numbers of struct fields require different approach");
}
return LoadHandler::LoadWasmStructField(isolate, type, field_offset);
}
#endif // V8_ENABLE_WEBASSEMBLY
} // namespace
Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) {
Handle<Object> receiver = lookup->GetReceiver();
ReadOnlyRoots roots(isolate());
......@@ -1040,13 +1107,22 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) {
if (holder_is_lookup_start_object) return smi_handler;
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormalFromPrototypeDH);
} else if (lookup->IsElement(*holder)) {
#if V8_ENABLE_WEBASSEMBLY
if (holder_is_lookup_start_object && holder->IsWasmStruct()) {
// TODO(ishell): Consider supporting indexed access to WasmStruct
// fields.
TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH);
return LoadHandler::LoadNonExistent(isolate());
}
#endif // V8_ENABLE_WEBASSEMBLY
TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
return LoadHandler::LoadSlow(isolate());
} else {
DCHECK_EQ(kField, lookup->property_details().location());
#if V8_ENABLE_WEBASSEMBLY
if (V8_UNLIKELY(holder->IsWasmObject(isolate()))) {
smi_handler = LoadHandler::LoadSlow(isolate());
smi_handler =
MakeLoadWasmStructFieldHandler(isolate(), holder, lookup);
} else // NOLINT(readability/braces)
#endif // V8_ENABLE_WEBASSEMBLY
{
......
......@@ -114,6 +114,9 @@ class StructType : public ZoneObject {
bool* const mutabilities_;
};
static const size_t kMaxFieldOffset =
(kV8MaxWasmStructFields - 1) * kMaxValueTypeSize;
private:
const uint32_t field_count_;
uint32_t* const field_offsets_;
......
......@@ -50,6 +50,8 @@ class Simd128;
V(OptRef, kTaggedSizeLog2, OptRef, AnyTagged, 'n', "ref null") \
V(Bottom, -1, Void, None, '*', "<bot>")
constexpr int kMaxValueTypeSize = 16; // bytes
// Represents a WebAssembly heap type, as per the typed-funcref and gc
// proposals.
// The underlying Representation enumeration encodes heap types as follows:
......
......@@ -4,10 +4,11 @@
// Flags: --allow-natives-syntax --experimental-wasm-gc --wasm-gc-js-interop
// Flags: --expose-gc
// Flags: --no-lazy-feedback-allocation
load("test/mjsunit/wasm/wasm-module-builder.js");
const kIterationsCountForICProgression = 20;
// TODO(ishell): remove once leaked maps could keep NativeModule alive.
let instances = [];
......@@ -71,9 +72,9 @@ function createArray_i() {
(function TestSimpleArrayInterop() {
function f(o) {
for (let i = 0; i < 4; i++) {
for (let i = 0; i < kIterationsCountForICProgression; i++) {
let len = o.length;
print("len = " + len);
assertEquals(10, len);
// Keyed loads are not supported yet
// let v0 = o[0];
// %DebugPrint(v0);
......
......@@ -4,10 +4,11 @@
// Flags: --allow-natives-syntax --experimental-wasm-gc --wasm-gc-js-interop
// Flags: --expose-gc
// Flags: --no-lazy-feedback-allocation
load("test/mjsunit/wasm/wasm-module-builder.js");
const kIterationsCountForICProgression = 20;
// TODO(ishell): remove once leaked maps could keep NativeModule alive.
let instances = [];
......@@ -69,9 +70,9 @@ function createStruct_i() {
(function TestSimpleStructInterop() {
function f(o) {
for (let i = 0; i < 4; i++) {
for (let i = 0; i < kIterationsCountForICProgression; i++) {
let v = o.$field0;
assertEquals(v, 153);
assertEquals(153, v);
}
}
......
......@@ -475,27 +475,27 @@ KNOWN_OBJECTS = {
("old_space", 0x029b5): "StringSplitCache",
("old_space", 0x02dbd): "RegExpMultipleCache",
("old_space", 0x031c5): "BuiltinsConstantsTable",
("old_space", 0x035d1): "AsyncFunctionAwaitRejectSharedFun",
("old_space", 0x035f5): "AsyncFunctionAwaitResolveSharedFun",
("old_space", 0x03619): "AsyncGeneratorAwaitRejectSharedFun",
("old_space", 0x0363d): "AsyncGeneratorAwaitResolveSharedFun",
("old_space", 0x03661): "AsyncGeneratorYieldResolveSharedFun",
("old_space", 0x03685): "AsyncGeneratorReturnResolveSharedFun",
("old_space", 0x036a9): "AsyncGeneratorReturnClosedRejectSharedFun",
("old_space", 0x036cd): "AsyncGeneratorReturnClosedResolveSharedFun",
("old_space", 0x036f1): "AsyncIteratorValueUnwrapSharedFun",
("old_space", 0x03715): "PromiseAllResolveElementSharedFun",
("old_space", 0x03739): "PromiseAllSettledResolveElementSharedFun",
("old_space", 0x0375d): "PromiseAllSettledRejectElementSharedFun",
("old_space", 0x03781): "PromiseAnyRejectElementSharedFun",
("old_space", 0x037a5): "PromiseCapabilityDefaultRejectSharedFun",
("old_space", 0x037c9): "PromiseCapabilityDefaultResolveSharedFun",
("old_space", 0x037ed): "PromiseCatchFinallySharedFun",
("old_space", 0x03811): "PromiseGetCapabilitiesExecutorSharedFun",
("old_space", 0x03835): "PromiseThenFinallySharedFun",
("old_space", 0x03859): "PromiseThrowerFinallySharedFun",
("old_space", 0x0387d): "PromiseValueThunkFinallySharedFun",
("old_space", 0x038a1): "ProxyRevokeSharedFun",
("old_space", 0x035d5): "AsyncFunctionAwaitRejectSharedFun",
("old_space", 0x035f9): "AsyncFunctionAwaitResolveSharedFun",
("old_space", 0x0361d): "AsyncGeneratorAwaitRejectSharedFun",
("old_space", 0x03641): "AsyncGeneratorAwaitResolveSharedFun",
("old_space", 0x03665): "AsyncGeneratorYieldResolveSharedFun",
("old_space", 0x03689): "AsyncGeneratorReturnResolveSharedFun",
("old_space", 0x036ad): "AsyncGeneratorReturnClosedRejectSharedFun",
("old_space", 0x036d1): "AsyncGeneratorReturnClosedResolveSharedFun",
("old_space", 0x036f5): "AsyncIteratorValueUnwrapSharedFun",
("old_space", 0x03719): "PromiseAllResolveElementSharedFun",
("old_space", 0x0373d): "PromiseAllSettledResolveElementSharedFun",
("old_space", 0x03761): "PromiseAllSettledRejectElementSharedFun",
("old_space", 0x03785): "PromiseAnyRejectElementSharedFun",
("old_space", 0x037a9): "PromiseCapabilityDefaultRejectSharedFun",
("old_space", 0x037cd): "PromiseCapabilityDefaultResolveSharedFun",
("old_space", 0x037f1): "PromiseCatchFinallySharedFun",
("old_space", 0x03815): "PromiseGetCapabilitiesExecutorSharedFun",
("old_space", 0x03839): "PromiseThenFinallySharedFun",
("old_space", 0x0385d): "PromiseThrowerFinallySharedFun",
("old_space", 0x03881): "PromiseValueThunkFinallySharedFun",
("old_space", 0x038a5): "ProxyRevokeSharedFun",
}
# Lower 32 bits of first page addresses for various heap spaces.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment