[runtime] Merge redirected and non-redirected callback fields

Namely:
 - AccessorInfo::getter and AccessorInfo::js_getter,
 - CallHandlerInfo::callback and CallHandlerInfo::js_callback.

The redirected/non-redirected callback distinction is required only
for simulated builds but we wasted memory also for all native builds.

Now we store these fields in "redirected" form which allows us to call
them directly from builtins or generated code. In case it's necessary
to call a callback from C++ code the C function address is read from
the redirection. This additional indirection makes the callback calls
from C++ code in simulated builds slower but saves memory for native
builds.

This CL should recover a part of memory regression caused by inlining
Foreign fields into AccessorInfo and CallHandlerInfo.

Bug: v8:12949, chromium:1336105, chromium:1335930
Change-Id: I38470ed21ee23b281247c11a9531542c7e4acca1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3835686
Reviewed-by: Jakob Linke <jgruber@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82631}
This commit is contained in:
ishell@chromium.org 2022-08-22 13:33:15 +02:00 committed by V8 LUCI CQ
parent 4392e0a4ad
commit 134ca75cd3
37 changed files with 301 additions and 209 deletions

View File

@ -386,14 +386,12 @@ constexpr uint64_t kAllExternalPointerTypeTags[] = {
V(kCodeEntryPointTag, unsandboxed, TAG(13)) \
V(kExternalObjectValueTag, sandboxed, TAG(14)) \
V(kCallHandlerInfoCallbackTag, sandboxed, TAG(15)) \
V(kCallHandlerInfoJsCallbackTag, sandboxed, TAG(16)) \
V(kAccessorInfoGetterTag, sandboxed, TAG(17)) \
V(kAccessorInfoJsGetterTag, sandboxed, TAG(18)) \
V(kAccessorInfoSetterTag, sandboxed, TAG(19)) \
V(kWasmInternalFunctionCallTargetTag, sandboxed, TAG(20)) \
V(kWasmTypeInfoNativeTypeTag, sandboxed, TAG(21)) \
V(kWasmExportedFunctionDataSignatureTag, sandboxed, TAG(22)) \
V(kWasmContinuationJmpbufTag, sandboxed, TAG(23))
V(kAccessorInfoGetterTag, sandboxed, TAG(16)) \
V(kAccessorInfoSetterTag, sandboxed, TAG(17)) \
V(kWasmInternalFunctionCallTargetTag, sandboxed, TAG(18)) \
V(kWasmTypeInfoNativeTypeTag, sandboxed, TAG(19)) \
V(kWasmExportedFunctionDataSignatureTag, sandboxed, TAG(20)) \
V(kWasmContinuationJmpbufTag, sandboxed, TAG(21))
// All external pointer tags.
#define ALL_EXTERNAL_POINTER_TAGS(V) \

View File

@ -1444,7 +1444,6 @@ void FunctionTemplate::SetCallHandler(
i::Handle<i::CallHandlerInfo> obj = i_isolate->factory()->NewCallHandlerInfo(
side_effect_type == SideEffectType::kHasNoSideEffect);
obj->set_callback(i_isolate, reinterpret_cast<i::Address>(callback));
obj->set_js_callback(i_isolate, obj->redirected_callback());
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(i_isolate));
}
@ -1490,10 +1489,6 @@ i::Handle<i::AccessorInfo> MakeAccessorInfo(
setter = reinterpret_cast<Setter>(&i::Accessors::ReconfigureToDataProperty);
}
obj->set_setter(i_isolate, reinterpret_cast<i::Address>(setter));
i::Address redirected = obj->redirected_getter();
if (redirected != i::kNullAddress) {
obj->set_js_getter(i_isolate, redirected);
}
i::Handle<i::Name> accessor_name = Utils::OpenHandle(*name);
if (!accessor_name->IsUniqueName()) {
@ -1900,7 +1895,6 @@ void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
i::Handle<i::CallHandlerInfo> obj =
i_isolate->factory()->NewCallHandlerInfo();
obj->set_callback(i_isolate, reinterpret_cast<i::Address>(callback));
obj->set_js_callback(i_isolate, obj->redirected_callback());
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(i_isolate));
}

View File

@ -38,13 +38,9 @@ Handle<AccessorInfo> Accessors::MakeAccessor(
info->set_setter_side_effect_type(SideEffectType::kHasSideEffect);
name = factory->InternalizeName(name);
info->set_name(*name);
info->set_getter(isolate, reinterpret_cast<Address>(getter));
if (setter == nullptr) setter = &ReconfigureToDataProperty;
info->set_setter(isolate, reinterpret_cast<Address>(setter));
info->set_getter(isolate, reinterpret_cast<Address>(getter));
Address redirected = info->redirected_getter();
if (redirected != kNullAddress) {
info->set_js_getter(isolate, redirected);
}
return info;
}

View File

@ -3167,7 +3167,7 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
ExternalReference::invoke_accessor_getter_callback();
__ ldr(api_function_address,
FieldMemOperand(callback, AccessorInfo::kJsGetterOffset));
FieldMemOperand(callback, AccessorInfo::kMaybeRedirectedGetterOffset));
// +3 is to skip prolog, return address and name handle.
MemOperand return_value_operand(

View File

@ -3648,8 +3648,8 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
Register api_function_address = x2;
__ LoadExternalPointerField(
api_function_address,
FieldMemOperand(callback, AccessorInfo::kJsGetterOffset),
kAccessorInfoJsGetterTag);
FieldMemOperand(callback, AccessorInfo::kMaybeRedirectedGetterOffset),
kAccessorInfoGetterTag);
const int spill_offset = 1 + kApiStackSpace;
// +3 is to skip prolog, return address and name handle.

View File

@ -3462,7 +3462,7 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
Register function_address = edx;
__ mov(function_address,
FieldOperand(callback, AccessorInfo::kJsGetterOffset));
FieldOperand(callback, AccessorInfo::kMaybeRedirectedGetterOffset));
// +3 is to skip prolog, return address and name handle.
Operand return_value_operand(
ebp,

View File

@ -3248,8 +3248,9 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback();
__ Ld_d(api_function_address,
FieldMemOperand(callback, AccessorInfo::kJsGetterOffset));
__ Ld_d(
api_function_address,
FieldMemOperand(callback, AccessorInfo::kMaybeRedirectedGetterOffset));
// +3 is to skip prolog, return address and name handle.
MemOperand return_value_operand(

View File

@ -3314,7 +3314,7 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
ExternalReference::invoke_accessor_getter_callback();
__ lw(api_function_address,
FieldMemOperand(callback, AccessorInfo::kJsGetterOffset));
FieldMemOperand(callback, AccessorInfo::kMaybeRedirectedGetterOffset));
// +3 is to skip prolog, return address and name handle.
MemOperand return_value_operand(

View File

@ -3267,7 +3267,7 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
ExternalReference::invoke_accessor_getter_callback();
__ Ld(api_function_address,
FieldMemOperand(callback, AccessorInfo::kJsGetterOffset));
FieldMemOperand(callback, AccessorInfo::kMaybeRedirectedGetterOffset));
// +3 is to skip prolog, return address and name handle.
MemOperand return_value_operand(

View File

@ -3499,8 +3499,10 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback();
__ LoadU64(api_function_address,
FieldMemOperand(callback, AccessorInfo::kJsGetterOffset), r0);
__ LoadU64(
api_function_address,
FieldMemOperand(callback, AccessorInfo::kMaybeRedirectedGetterOffset),
r0);
// +3 is to skip prolog, return address and name handle.
MemOperand return_value_operand(

View File

@ -3303,8 +3303,9 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback();
__ LoadWord(api_function_address,
FieldMemOperand(callback, AccessorInfo::kJsGetterOffset));
__ LoadWord(
api_function_address,
FieldMemOperand(callback, AccessorInfo::kMaybeRedirectedGetterOffset));
// +3 is to skip prolog, return address and name handle.
MemOperand return_value_operand(

View File

@ -3480,8 +3480,9 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback();
__ LoadU64(api_function_address,
FieldMemOperand(callback, AccessorInfo::kJsGetterOffset));
__ LoadU64(
api_function_address,
FieldMemOperand(callback, AccessorInfo::kMaybeRedirectedGetterOffset));
// +3 is to skip prolog, return address and name handle.
MemOperand return_value_operand(

View File

@ -4750,8 +4750,8 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
DCHECK(api_function_address != name_arg);
__ LoadExternalPointerField(
api_function_address,
FieldOperand(callback, AccessorInfo::kJsGetterOffset),
kAccessorInfoJsGetterTag, kScratchRegister);
FieldOperand(callback, AccessorInfo::kMaybeRedirectedGetterOffset),
kAccessorInfoGetterTag, kScratchRegister);
// +3 is to skip prolog, return address and name handle.
Operand return_value_operand(

View File

@ -1137,9 +1137,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<RawPtrT> LoadCallHandlerInfoJsCallbackPtr(
TNode<CallHandlerInfo> object) {
return LoadExternalPointerFromObject(object,
CallHandlerInfo::kJsCallbackOffset,
kCallHandlerInfoJsCallbackTag);
return LoadExternalPointerFromObject(
object, CallHandlerInfo::kMaybeRedirectedCallbackOffset,
kCallHandlerInfoCallbackTag);
}
TNode<RawPtrT> LoadExternalStringResourcePtr(TNode<ExternalString> object) {

View File

@ -364,11 +364,20 @@ ExternalReference::runtime_function_table_address_for_unittests(
}
// static
Address ExternalReference::Redirect(Address address, Type type) {
Address ExternalReference::Redirect(Address external_function, Type type) {
#ifdef USE_SIMULATOR
return SimulatorBase::RedirectExternalReference(address, type);
return SimulatorBase::RedirectExternalReference(external_function, type);
#else
return address;
return external_function;
#endif
}
// static
Address ExternalReference::UnwrapRedirection(Address redirection_trampoline) {
#ifdef USE_SIMULATOR
return SimulatorBase::UnwrapRedirection(redirection_trampoline);
#else
return redirection_trampoline;
#endif
}

View File

@ -453,15 +453,23 @@ class ExternalReference {
Address address() const { return address_; }
// Creates a redirection trampoline for given C function and signature for
// simulated builds.
// Returns the same address otherwise.
static Address Redirect(Address external_function,
Type type = ExternalReference::BUILTIN_CALL);
// Returns C function associated with given redirection trampoline for
// simulated builds.
// Returns the same address otherwise.
static Address UnwrapRedirection(Address redirection_trampoline);
private:
explicit ExternalReference(Address address) : address_(address) {}
explicit ExternalReference(void* address)
: address_(reinterpret_cast<Address>(address)) {}
static Address Redirect(Address address_arg,
Type type = ExternalReference::BUILTIN_CALL);
Address address_;
};
ASSERT_TRIVIALLY_COPYABLE(ExternalReference);

View File

@ -66,6 +66,12 @@ namespace internal {
#endif
#endif
#if USE_SIMULATOR
#define USE_SIMULATOR_BOOL true
#else
#define USE_SIMULATOR_BOOL false
#endif
// Determine whether the architecture uses an embedded constant pool
// (contiguous constant pool embedded in code object).
#if V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64

View File

@ -847,7 +847,10 @@ void AccessorInfo::AccessorInfoPrint(std::ostream& os) {
<< SideEffectType2String(setter_side_effect_type());
os << "\n - initial_attributes: " << initial_property_attributes();
os << "\n - getter: " << reinterpret_cast<void*>(getter());
os << "\n - js_getter: " << reinterpret_cast<void*>(js_getter());
if (USE_SIMULATOR_BOOL) {
os << "\n - maybe_redirected_getter: "
<< reinterpret_cast<void*>(maybe_redirected_getter());
}
os << "\n - setter: " << reinterpret_cast<void*>(setter());
os << '\n';
}
@ -2192,7 +2195,10 @@ void StoreHandler::StoreHandlerPrint(std::ostream& os) {
void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) {
PrintHeader(os, "CallHandlerInfo");
os << "\n - callback: " << reinterpret_cast<void*>(callback());
os << "\n - js_callback: " << reinterpret_cast<void*>(js_callback());
if (USE_SIMULATOR_BOOL) {
os << "\n - maybe_redirected_callback: "
<< reinterpret_cast<void*>(maybe_redirected_callback());
}
os << "\n - data: " << Brief(data());
os << "\n - side_effect_free: "
<< (IsSideEffectFreeCallHandlerInfo() ? "true" : "false");

View File

@ -1642,7 +1642,7 @@ void UnsafeDirectApiCall(intptr_t function, int32_t arg0) {
void UnsafeProfilingApiCall(intptr_t function, int32_t arg0, int32_t arg1) {
SimulatorRuntimeProfilingApiCall target =
reinterpret_cast<SimulatorRuntimeProfilingApiCall>(function);
target(arg0, Redirection::ReverseRedirection(arg1));
target(arg0, Redirection::UnwrapRedirection(arg1));
}
void UnsafeDirectGetterCall(intptr_t function, int32_t arg0, int32_t arg1) {
SimulatorRuntimeDirectGetterCall target =
@ -1844,7 +1844,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
CHECK(stack_aligned);
SimulatorRuntimeProfilingGetterCall target =
reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
target(arg0, arg1, Redirection::ReverseRedirection(arg2));
target(arg0, arg1, Redirection::UnwrapRedirection(arg2));
#ifdef DEBUG
TrashCallerSaveRegisters();
#endif

View File

@ -872,7 +872,7 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
case ExternalReference::PROFILING_API_CALL: {
// void f(v8::FunctionCallbackInfo&, v8::FunctionCallback)
TraceSim("Type: PROFILING_API_CALL\n");
void* arg1 = Redirection::ReverseRedirection(xreg(1));
void* arg1 = Redirection::UnwrapRedirection(xreg(1));
TraceSim("Arguments: 0x%016" PRIx64 ", %p\n", xreg(0), arg1);
UnsafeProfilingApiCall(external, xreg(0), arg1);
TraceSim("No return value.");
@ -888,7 +888,7 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
TraceSim("Type: PROFILING_GETTER_CALL\n");
SimulatorRuntimeProfilingGetterCall target =
reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
void* arg2 = Redirection::ReverseRedirection(xreg(2));
void* arg2 = Redirection::UnwrapRedirection(xreg(2));
TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 ", %p\n", xreg(0),
xreg(1), arg2);
target(xreg(0), xreg(1), arg2);

View File

@ -2375,7 +2375,7 @@ void Simulator::SoftwareInterrupt() {
}
SimulatorRuntimeProfilingApiCall target =
reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
target(arg0, Redirection::ReverseRedirection(arg1));
target(arg0, Redirection::UnwrapRedirection(arg1));
} else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
if (::v8::internal::FLAG_trace_sim) {
PrintF("Call to host function at %p args %08" PRIx64 " %08" PRIx64
@ -2394,7 +2394,7 @@ void Simulator::SoftwareInterrupt() {
}
SimulatorRuntimeProfilingGetterCall target =
reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
target(arg0, arg1, Redirection::ReverseRedirection(arg2));
target(arg0, arg1, Redirection::UnwrapRedirection(arg2));
} else {
DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL ||
redirection->type() == ExternalReference::BUILTIN_CALL_PAIR);

View File

@ -2400,7 +2400,7 @@ void Simulator::SoftwareInterrupt() {
}
SimulatorRuntimeProfilingApiCall target =
reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
target(arg0, Redirection::ReverseRedirection(arg1));
target(arg0, Redirection::UnwrapRedirection(arg1));
} else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
if (::v8::internal::FLAG_trace_sim) {
PrintF("Call to host function at %p args %08x %08x\n",
@ -2417,7 +2417,7 @@ void Simulator::SoftwareInterrupt() {
}
SimulatorRuntimeProfilingGetterCall target =
reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
target(arg0, arg1, Redirection::ReverseRedirection(arg2));
target(arg0, arg1, Redirection::UnwrapRedirection(arg2));
} else {
DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL ||
redirection->type() == ExternalReference::BUILTIN_CALL_PAIR);

View File

@ -2540,7 +2540,7 @@ void Simulator::SoftwareInterrupt() {
}
SimulatorRuntimeProfilingApiCall target =
reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
target(arg0, Redirection::ReverseRedirection(arg1));
target(arg0, Redirection::UnwrapRedirection(arg1));
} else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
if (::v8::internal::FLAG_trace_sim) {
PrintF("Call to host function at %p args %08" PRIx64 " %08" PRIx64
@ -2559,7 +2559,7 @@ void Simulator::SoftwareInterrupt() {
}
SimulatorRuntimeProfilingGetterCall target =
reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
target(arg0, arg1, Redirection::ReverseRedirection(arg2));
target(arg0, arg1, Redirection::UnwrapRedirection(arg2));
} else {
DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL ||
redirection->type() == ExternalReference::BUILTIN_CALL_PAIR);

View File

@ -1127,7 +1127,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
CHECK(stack_aligned);
SimulatorRuntimeProfilingApiCall target =
reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
target(arg[0], Redirection::ReverseRedirection(arg[1]));
target(arg[0], Redirection::UnwrapRedirection(arg[1]));
} else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
// See callers of MacroAssembler::CallApiFunctionAndReturn for
// explanation of register usage.
@ -1166,7 +1166,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
if (!ABI_PASSES_HANDLES_IN_REGS) {
arg[0] = base::bit_cast<intptr_t>(arg[0]);
}
target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2]));
target(arg[0], arg[1], Redirection::UnwrapRedirection(arg[2]));
} else {
// builtin call.
if (::v8::internal::FLAG_trace_sim || !stack_aligned) {

View File

@ -3126,7 +3126,7 @@ void Simulator::SoftwareInterrupt() {
}
SimulatorRuntimeProfilingApiCall target =
reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
target(arg0, Redirection::ReverseRedirection(arg1));
target(arg0, Redirection::UnwrapRedirection(arg1));
} else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
if (::v8::internal::FLAG_trace_sim) {
PrintF("Call to host function %s at %p args %08" REGIx_FORMAT
@ -3147,7 +3147,7 @@ void Simulator::SoftwareInterrupt() {
}
SimulatorRuntimeProfilingGetterCall target =
reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
target(arg0, arg1, Redirection::ReverseRedirection(arg2));
target(arg0, arg1, Redirection::UnwrapRedirection(arg2));
} else {
DCHECK(
redirection->type() == ExternalReference::BUILTIN_CALL ||

View File

@ -2129,7 +2129,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
CHECK(stack_aligned);
SimulatorRuntimeProfilingApiCall target =
reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
target(arg[0], Redirection::ReverseRedirection(arg[1]));
target(arg[0], Redirection::UnwrapRedirection(arg[1]));
} else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
// See callers of MacroAssembler::CallApiFunctionAndReturn for
// explanation of register usage.
@ -2168,7 +2168,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
if (!ABI_PASSES_HANDLES_IN_REGS) {
arg[0] = base::bit_cast<intptr_t>(arg[0]);
}
target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2]));
target(arg[0], arg[1], Redirection::UnwrapRedirection(arg[2]));
} else {
// builtin call.
if (::v8::internal::FLAG_trace_sim || !stack_aligned) {

View File

@ -65,6 +65,12 @@ Address SimulatorBase::RedirectExternalReference(Address external_function,
return redirection->address_of_instruction();
}
// static
Address SimulatorBase::UnwrapRedirection(Address redirection_trampoline) {
return reinterpret_cast<Address>(
Redirection::UnwrapRedirection(redirection_trampoline));
}
Redirection::Redirection(Address external_function,
ExternalReference::Type type)
: external_function_(external_function), type_(type), next_(nullptr) {

View File

@ -36,10 +36,14 @@ class SimulatorBase {
static base::Mutex* i_cache_mutex() { return i_cache_mutex_; }
static base::CustomMatcherHashMap* i_cache() { return i_cache_; }
// Runtime call support.
// Runtime/C function call support.
// Creates a trampoline to a given C function callable from generated code.
static Address RedirectExternalReference(Address external_function,
ExternalReference::Type type);
// Extracts the target C function address from a given redirection trampoline.
static Address UnwrapRedirection(Address redirection_trampoline);
protected:
template <typename Return, typename SimT, typename CallImpl, typename... Args>
static Return VariadicCall(SimT* sim, CallImpl call, Address entry,
@ -175,7 +179,7 @@ class Redirection {
return reinterpret_cast<Redirection*>(addr_of_redirection);
}
static void* ReverseRedirection(intptr_t reg) {
static void* UnwrapRedirection(intptr_t reg) {
Redirection* redirection = FromInstruction(
reinterpret_cast<Instruction*>(reinterpret_cast<void*>(reg)));
return redirection->external_function();

View File

@ -1441,7 +1441,6 @@ Handle<AccessorInfo> Factory::NewAccessorInfo() {
info.set_initial_property_attributes(NONE);
info.init_getter(isolate(), kNullAddress);
info.init_js_getter(isolate(), kNullAddress);
info.init_setter(isolate(), kNullAddress);
info.clear_padding();
@ -3901,7 +3900,6 @@ Handle<CallHandlerInfo> Factory::NewCallHandlerInfo(bool has_no_side_effect) {
DisallowGarbageCollection no_gc;
info.set_data(*undefined_value(), SKIP_WRITE_BARRIER);
info.init_callback(isolate(), kNullAddress);
info.init_js_callback(isolate(), kNullAddress);
return handle(info, isolate());
}

View File

@ -28,14 +28,55 @@ TQ_OBJECT_CONSTRUCTORS_IMPL(InterceptorInfo)
TQ_OBJECT_CONSTRUCTORS_IMPL(CallHandlerInfo)
EXTERNAL_POINTER_ACCESSORS(AccessorInfo, getter, Address, kGetterOffset,
kAccessorInfoGetterTag)
EXTERNAL_POINTER_ACCESSORS(AccessorInfo, js_getter, Address, kJsGetterOffset,
kAccessorInfoJsGetterTag)
EXTERNAL_POINTER_ACCESSORS(AccessorInfo, maybe_redirected_getter, Address,
kMaybeRedirectedGetterOffset, kAccessorInfoGetterTag)
EXTERNAL_POINTER_ACCESSORS(AccessorInfo, setter, Address, kSetterOffset,
kAccessorInfoSetterTag)
bool AccessorInfo::has_getter() { return getter() != kNullAddress; }
Address AccessorInfo::getter() const {
i::Isolate* isolate_for_sandbox = GetIsolateForSandbox(*this);
return AccessorInfo::getter(isolate_for_sandbox);
}
Address AccessorInfo::getter(i::Isolate* isolate_for_sandbox) const {
Address result = maybe_redirected_getter(isolate_for_sandbox);
if (!USE_SIMULATOR_BOOL) return result;
if (result == kNullAddress) return kNullAddress;
return ExternalReference::UnwrapRedirection(result);
}
void AccessorInfo::init_getter(i::Isolate* isolate, Address initial_value) {
init_maybe_redirected_getter(isolate, initial_value);
if (USE_SIMULATOR_BOOL) {
init_getter_redirection(isolate);
}
}
void AccessorInfo::set_getter(i::Isolate* isolate, Address value) {
set_maybe_redirected_getter(isolate, value);
if (USE_SIMULATOR_BOOL) {
init_getter_redirection(isolate);
}
}
void AccessorInfo::init_getter_redirection(i::Isolate* isolate) {
CHECK(USE_SIMULATOR_BOOL);
Address value = maybe_redirected_getter(isolate);
if (value == kNullAddress) return;
value =
ExternalReference::Redirect(value, ExternalReference::DIRECT_GETTER_CALL);
set_maybe_redirected_getter(isolate, value);
}
void AccessorInfo::remove_getter_redirection(i::Isolate* isolate) {
CHECK(USE_SIMULATOR_BOOL);
Address value = getter(isolate);
set_maybe_redirected_getter(isolate, value);
}
bool AccessorInfo::has_getter() {
return maybe_redirected_getter() != kNullAddress;
}
bool AccessorInfo::has_setter() { return setter() != kNullAddress; }
@ -111,11 +152,51 @@ bool CallHandlerInfo::NextCallHasNoSideEffect() {
return false;
}
EXTERNAL_POINTER_ACCESSORS(CallHandlerInfo, callback, Address, kCallbackOffset,
EXTERNAL_POINTER_ACCESSORS(CallHandlerInfo, maybe_redirected_callback, Address,
kMaybeRedirectedCallbackOffset,
kCallHandlerInfoCallbackTag)
EXTERNAL_POINTER_ACCESSORS(CallHandlerInfo, js_callback, Address,
kJsCallbackOffset, kCallHandlerInfoJsCallbackTag)
Address CallHandlerInfo::callback() const {
i::Isolate* isolate_for_sandbox = GetIsolateForSandbox(*this);
return CallHandlerInfo::callback(isolate_for_sandbox);
}
Address CallHandlerInfo::callback(i::Isolate* isolate_for_sandbox) const {
Address result = maybe_redirected_callback(isolate_for_sandbox);
if (!USE_SIMULATOR_BOOL) return result;
if (result == kNullAddress) return kNullAddress;
return ExternalReference::UnwrapRedirection(result);
}
void CallHandlerInfo::init_callback(i::Isolate* isolate,
Address initial_value) {
init_maybe_redirected_callback(isolate, initial_value);
if (USE_SIMULATOR_BOOL) {
init_callback_redirection(isolate);
}
}
void CallHandlerInfo::set_callback(i::Isolate* isolate, Address value) {
set_maybe_redirected_callback(isolate, value);
if (USE_SIMULATOR_BOOL) {
init_callback_redirection(isolate);
}
}
void CallHandlerInfo::init_callback_redirection(i::Isolate* isolate) {
CHECK(USE_SIMULATOR_BOOL);
Address value = maybe_redirected_callback(isolate);
if (value == kNullAddress) return;
value =
ExternalReference::Redirect(value, ExternalReference::DIRECT_API_CALL);
set_maybe_redirected_callback(isolate, value);
}
void CallHandlerInfo::remove_callback_redirection(i::Isolate* isolate) {
CHECK(USE_SIMULATOR_BOOL);
Address value = callback(isolate);
set_maybe_redirected_callback(isolate, value);
}
} // namespace internal
} // namespace v8

View File

@ -30,15 +30,17 @@ class StructBodyDescriptor;
class AccessorInfo
: public TorqueGeneratedAccessorInfo<AccessorInfo, HeapObject> {
public:
// This directly points at a foreign C function to be used from the runtime.
// This is a wrapper around |maybe_redirected_getter| accessor which
// returns/accepts C function and converts the value from and to redirected
// pointer.
DECL_EXTERNAL_POINTER_ACCESSORS(getter, Address)
inline void init_getter_redirection(i::Isolate* isolate);
inline void remove_getter_redirection(i::Isolate* isolate);
inline bool has_getter();
// The field contains the address of the C function.
DECL_EXTERNAL_POINTER_ACCESSORS(setter, Address)
inline bool has_setter();
DECL_EXTERNAL_POINTER_ACCESSORS(js_getter, Address)
static Address redirect(Address address, AccessorComponent component);
Address redirected_getter() const;
DECL_BOOLEAN_ACCESSORS(all_can_read)
DECL_BOOLEAN_ACCESSORS(all_can_write)
@ -75,6 +77,15 @@ class AccessorInfo
class BodyDescriptor;
private:
// When simulator is enabled the field stores the "redirected" address of the
// C function (the one that's callabled from simulated compiled code), in
// this case the original address of the C function has to be taken from the
// redirection.
// For native builds the field contains the address of the C function.
// This field is initialized implicitly via respective |getter|-related
// methods.
DECL_EXTERNAL_POINTER_ACCESSORS(maybe_redirected_getter, Address)
// Bit positions in |flags|.
DEFINE_TORQUE_GENERATED_ACCESSOR_INFO_FLAGS()
@ -121,19 +132,25 @@ class CallHandlerInfo
DECL_PRINTER(CallHandlerInfo)
DECL_VERIFIER(CallHandlerInfo)
// [callback]: the address of the callback function.
// This is a wrapper around |maybe_redirected_callback| accessor which
// returns/accepts C function and converts the value from and to redirected
// pointer.
DECL_EXTERNAL_POINTER_ACCESSORS(callback, Address)
// [js_callback]: either the address of the callback function as above,
// or a trampoline in case we are running with the simulator.
// Use this entry from generated code.
DECL_EXTERNAL_POINTER_ACCESSORS(js_callback, Address)
Address redirected_callback() const;
inline void init_callback_redirection(i::Isolate* isolate);
inline void remove_callback_redirection(i::Isolate* isolate);
class BodyDescriptor;
private:
// When simulator is enabled the field stores the "redirected" address of the
// C function (the one that's callabled from simulated compiled code), in
// this case the original address of the C function has to be taken from the
// redirection.
// For native builds the field contains the address of the C function.
// This field is initialized implicitly via respective |callback|-related
// methods.
DECL_EXTERNAL_POINTER_ACCESSORS(maybe_redirected_callback, Address)
TQ_OBJECT_CONSTRUCTORS(CallHandlerInfo)
};

View File

@ -4,10 +4,10 @@
extern class CallHandlerInfo extends HeapObject {
data: Object;
callback: ExternalPointer;
// This either points at the same as above, or a trampoline in case we are
// running with the simulator. Use this entry from generated code.
js_callback: ExternalPointer;
// For simulator builds this field contains the address of the trampoline
// callable from generated code and for native builds - the address of
// the callback C function.
maybe_redirected_callback: ExternalPointer;
}
bitfield struct InterceptorInfoFlags extends uint31 {
@ -53,11 +53,11 @@ bitfield struct AccessorInfoFlags extends uint32 {
extern class AccessorInfo extends HeapObject {
name: Name;
data: Object;
// For simulator builds this field contains the address of the trampoline
// callable from generated code and for native builds - the address of
// the getter C function.
maybe_redirected_getter: ExternalPointer;
setter: ExternalPointer;
getter: ExternalPointer;
// This either points at the same as above, or a trampoline in case we are
// running with the simulator. Use this entry from generated code.
js_getter: ExternalPointer;
flags: AccessorInfoFlags;
@if(TAGGED_SIZE_8_BYTES) optional_padding: uint32;
@ifnot(TAGGED_SIZE_8_BYTES) optional_padding: void;

View File

@ -1471,10 +1471,10 @@ class EphemeronHashTable::BodyDescriptor final : public BodyDescriptorBase {
class AccessorInfo::BodyDescriptor final : public BodyDescriptorBase {
public:
static_assert(AccessorInfo::kEndOfStrongFieldsOffset ==
AccessorInfo::kMaybeRedirectedGetterOffset);
static_assert(AccessorInfo::kMaybeRedirectedGetterOffset <
AccessorInfo::kSetterOffset);
static_assert(AccessorInfo::kSetterOffset < AccessorInfo::kGetterOffset);
static_assert(AccessorInfo::kGetterOffset < AccessorInfo::kJsGetterOffset);
static_assert(AccessorInfo::kJsGetterOffset < AccessorInfo::kFlagsOffset);
static_assert(AccessorInfo::kSetterOffset < AccessorInfo::kFlagsOffset);
static_assert(AccessorInfo::kFlagsOffset < AccessorInfo::kSize);
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
@ -1487,14 +1487,12 @@ class AccessorInfo::BodyDescriptor final : public BodyDescriptorBase {
IteratePointers(obj, HeapObject::kHeaderSize,
AccessorInfo::kEndOfStrongFieldsOffset, v);
v->VisitExternalPointer(
obj, obj.RawExternalPointerField(AccessorInfo::kSetterOffset),
kAccessorInfoSetterTag);
v->VisitExternalPointer(
obj, obj.RawExternalPointerField(AccessorInfo::kGetterOffset),
obj,
obj.RawExternalPointerField(AccessorInfo::kMaybeRedirectedGetterOffset),
kAccessorInfoGetterTag);
v->VisitExternalPointer(
obj, obj.RawExternalPointerField(AccessorInfo::kJsGetterOffset),
kAccessorInfoJsGetterTag);
obj, obj.RawExternalPointerField(AccessorInfo::kSetterOffset),
kAccessorInfoSetterTag);
}
static inline int SizeOf(Map map, HeapObject object) { return kSize; }
@ -1503,9 +1501,7 @@ class AccessorInfo::BodyDescriptor final : public BodyDescriptorBase {
class CallHandlerInfo::BodyDescriptor final : public BodyDescriptorBase {
public:
static_assert(CallHandlerInfo::kEndOfStrongFieldsOffset ==
CallHandlerInfo::kCallbackOffset);
static_assert(CallHandlerInfo::kCallbackOffset <
CallHandlerInfo::kJsCallbackOffset);
CallHandlerInfo::kMaybeRedirectedCallbackOffset);
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
return offset < CallHandlerInfo::kEndOfStrongFieldsOffset;
@ -1517,11 +1513,10 @@ class CallHandlerInfo::BodyDescriptor final : public BodyDescriptorBase {
IteratePointers(obj, HeapObject::kHeaderSize,
CallHandlerInfo::kEndOfStrongFieldsOffset, v);
v->VisitExternalPointer(
obj, obj.RawExternalPointerField(CallHandlerInfo::kCallbackOffset),
obj,
obj.RawExternalPointerField(
CallHandlerInfo::kMaybeRedirectedCallbackOffset),
kCallHandlerInfoCallbackTag);
v->VisitExternalPointer(
obj, obj.RawExternalPointerField(CallHandlerInfo::kJsCallbackOffset),
kCallHandlerInfoJsCallbackTag);
}
static inline int SizeOf(Map map, HeapObject object) { return kSize; }

View File

@ -1473,27 +1473,6 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
return isolate->factory()->undefined_value();
}
// static
Address AccessorInfo::redirect(Address address, AccessorComponent component) {
ApiFunction fun(address);
DCHECK_EQ(ACCESSOR_GETTER, component);
ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
return ExternalReference::Create(&fun, type).address();
}
Address AccessorInfo::redirected_getter() const {
Address accessor = getter();
if (accessor == kNullAddress) return kNullAddress;
return redirect(accessor, ACCESSOR_GETTER);
}
Address CallHandlerInfo::redirected_callback() const {
Address address = callback();
ApiFunction fun(address);
ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
return ExternalReference::Create(&fun, type).address();
}
Maybe<bool> Object::SetPropertyWithAccessor(
LookupIterator* it, Handle<Object> value,
Maybe<ShouldThrow> maybe_should_throw) {
@ -2144,7 +2123,6 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) {
CallHandlerInfo info = CallHandlerInfo::cast(*this);
os << "<CallHandlerInfo ";
os << "callback= " << reinterpret_cast<void*>(info.callback());
os << ", js_callback= " << reinterpret_cast<void*>(info.js_callback());
os << ", data= " << Brief(info.data());
if (info.IsSideEffectFreeCallHandlerInfo()) {
os << ", side_effect_free= true>";

View File

@ -62,15 +62,13 @@ bool SerializerDeserializer::CanBeDeferred(HeapObject o) {
void SerializerDeserializer::RestoreExternalReferenceRedirector(
Isolate* isolate, AccessorInfo accessor_info) {
DisallowGarbageCollection no_gc;
// Restore wiped accessor infos.
accessor_info.set_js_getter(isolate, accessor_info.redirected_getter());
accessor_info.init_getter_redirection(isolate);
}
void SerializerDeserializer::RestoreExternalReferenceRedirector(
Isolate* isolate, CallHandlerInfo call_handler_info) {
DisallowGarbageCollection no_gc;
call_handler_info.set_js_callback(isolate,
call_handler_info.redirected_callback());
call_handler_info.init_callback_redirection(isolate);
}
} // namespace internal

View File

@ -123,21 +123,14 @@ void StartupSerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
if (SerializeUsingSharedHeapObjectCache(&sink_, obj)) return;
if (SerializeBackReference(*obj)) return;
bool use_simulator = false;
#ifdef USE_SIMULATOR
use_simulator = true;
#endif
if (use_simulator && obj->IsAccessorInfo(cage_base)) {
if (USE_SIMULATOR_BOOL && obj->IsAccessorInfo(cage_base)) {
// Wipe external reference redirects in the accessor info.
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(obj);
Address original_address = info->getter();
info->set_js_getter(isolate(), original_address);
info->remove_getter_redirection(isolate());
accessor_infos_.Push(*info);
} else if (use_simulator && obj->IsCallHandlerInfo(cage_base)) {
} else if (USE_SIMULATOR_BOOL && obj->IsCallHandlerInfo(cage_base)) {
Handle<CallHandlerInfo> info = Handle<CallHandlerInfo>::cast(obj);
Address original_address = info->callback();
info->set_js_callback(isolate(), original_address);
info->remove_callback_redirection(isolate());
call_handler_infos_.Push(*info);
} else if (obj->IsScript(cage_base) &&
Handle<Script>::cast(obj)->IsUserJavaScript()) {

View File

@ -507,67 +507,67 @@ KNOWN_OBJECTS = {
("read_only_space", 0x04aa9): "NativeScopeInfo",
("read_only_space", 0x04ac1): "HashSeed",
("old_space", 0x04221): "ArgumentsIteratorAccessor",
("old_space", 0x04249): "ArrayLengthAccessor",
("old_space", 0x04271): "BoundFunctionLengthAccessor",
("old_space", 0x04299): "BoundFunctionNameAccessor",
("old_space", 0x042c1): "ErrorStackAccessor",
("old_space", 0x042e9): "FunctionArgumentsAccessor",
("old_space", 0x04311): "FunctionCallerAccessor",
("old_space", 0x04339): "FunctionNameAccessor",
("old_space", 0x04361): "FunctionLengthAccessor",
("old_space", 0x04389): "FunctionPrototypeAccessor",
("old_space", 0x043b1): "SharedArrayLengthAccessor",
("old_space", 0x043d9): "StringLengthAccessor",
("old_space", 0x04401): "ValueUnavailableAccessor",
("old_space", 0x04429): "WrappedFunctionLengthAccessor",
("old_space", 0x04451): "WrappedFunctionNameAccessor",
("old_space", 0x04479): "InvalidPrototypeValidityCell",
("old_space", 0x04481): "EmptyScript",
("old_space", 0x044c5): "ManyClosuresCell",
("old_space", 0x044d1): "ArrayConstructorProtector",
("old_space", 0x044e5): "NoElementsProtector",
("old_space", 0x044f9): "MegaDOMProtector",
("old_space", 0x0450d): "IsConcatSpreadableProtector",
("old_space", 0x04521): "ArraySpeciesProtector",
("old_space", 0x04535): "TypedArraySpeciesProtector",
("old_space", 0x04549): "PromiseSpeciesProtector",
("old_space", 0x0455d): "RegExpSpeciesProtector",
("old_space", 0x04571): "StringLengthProtector",
("old_space", 0x04585): "ArrayIteratorProtector",
("old_space", 0x04599): "ArrayBufferDetachingProtector",
("old_space", 0x045ad): "PromiseHookProtector",
("old_space", 0x045c1): "PromiseResolveProtector",
("old_space", 0x045d5): "MapIteratorProtector",
("old_space", 0x045e9): "PromiseThenProtector",
("old_space", 0x045fd): "SetIteratorProtector",
("old_space", 0x04611): "StringIteratorProtector",
("old_space", 0x04625): "StringSplitCache",
("old_space", 0x04a2d): "RegExpMultipleCache",
("old_space", 0x04e35): "BuiltinsConstantsTable",
("old_space", 0x05285): "AsyncFunctionAwaitRejectSharedFun",
("old_space", 0x052a9): "AsyncFunctionAwaitResolveSharedFun",
("old_space", 0x052cd): "AsyncGeneratorAwaitRejectSharedFun",
("old_space", 0x052f1): "AsyncGeneratorAwaitResolveSharedFun",
("old_space", 0x05315): "AsyncGeneratorYieldResolveSharedFun",
("old_space", 0x05339): "AsyncGeneratorReturnResolveSharedFun",
("old_space", 0x0535d): "AsyncGeneratorReturnClosedRejectSharedFun",
("old_space", 0x05381): "AsyncGeneratorReturnClosedResolveSharedFun",
("old_space", 0x053a5): "AsyncIteratorValueUnwrapSharedFun",
("old_space", 0x053c9): "PromiseAllResolveElementSharedFun",
("old_space", 0x053ed): "PromiseAllSettledResolveElementSharedFun",
("old_space", 0x05411): "PromiseAllSettledRejectElementSharedFun",
("old_space", 0x05435): "PromiseAnyRejectElementSharedFun",
("old_space", 0x05459): "PromiseCapabilityDefaultRejectSharedFun",
("old_space", 0x0547d): "PromiseCapabilityDefaultResolveSharedFun",
("old_space", 0x054a1): "PromiseCatchFinallySharedFun",
("old_space", 0x054c5): "PromiseGetCapabilitiesExecutorSharedFun",
("old_space", 0x054e9): "PromiseThenFinallySharedFun",
("old_space", 0x0550d): "PromiseThrowerFinallySharedFun",
("old_space", 0x05531): "PromiseValueThunkFinallySharedFun",
("old_space", 0x05555): "ProxyRevokeSharedFun",
("old_space", 0x05579): "ShadowRealmImportValueFulfilledSFI",
("old_space", 0x0559d): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
("old_space", 0x055c1): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
("old_space", 0x04241): "ArrayLengthAccessor",
("old_space", 0x04261): "BoundFunctionLengthAccessor",
("old_space", 0x04281): "BoundFunctionNameAccessor",
("old_space", 0x042a1): "ErrorStackAccessor",
("old_space", 0x042c1): "FunctionArgumentsAccessor",
("old_space", 0x042e1): "FunctionCallerAccessor",
("old_space", 0x04301): "FunctionNameAccessor",
("old_space", 0x04321): "FunctionLengthAccessor",
("old_space", 0x04341): "FunctionPrototypeAccessor",
("old_space", 0x04361): "SharedArrayLengthAccessor",
("old_space", 0x04381): "StringLengthAccessor",
("old_space", 0x043a1): "ValueUnavailableAccessor",
("old_space", 0x043c1): "WrappedFunctionLengthAccessor",
("old_space", 0x043e1): "WrappedFunctionNameAccessor",
("old_space", 0x04401): "InvalidPrototypeValidityCell",
("old_space", 0x04409): "EmptyScript",
("old_space", 0x0444d): "ManyClosuresCell",
("old_space", 0x04459): "ArrayConstructorProtector",
("old_space", 0x0446d): "NoElementsProtector",
("old_space", 0x04481): "MegaDOMProtector",
("old_space", 0x04495): "IsConcatSpreadableProtector",
("old_space", 0x044a9): "ArraySpeciesProtector",
("old_space", 0x044bd): "TypedArraySpeciesProtector",
("old_space", 0x044d1): "PromiseSpeciesProtector",
("old_space", 0x044e5): "RegExpSpeciesProtector",
("old_space", 0x044f9): "StringLengthProtector",
("old_space", 0x0450d): "ArrayIteratorProtector",
("old_space", 0x04521): "ArrayBufferDetachingProtector",
("old_space", 0x04535): "PromiseHookProtector",
("old_space", 0x04549): "PromiseResolveProtector",
("old_space", 0x0455d): "MapIteratorProtector",
("old_space", 0x04571): "PromiseThenProtector",
("old_space", 0x04585): "SetIteratorProtector",
("old_space", 0x04599): "StringIteratorProtector",
("old_space", 0x045ad): "StringSplitCache",
("old_space", 0x049b5): "RegExpMultipleCache",
("old_space", 0x04dbd): "BuiltinsConstantsTable",
("old_space", 0x0520d): "AsyncFunctionAwaitRejectSharedFun",
("old_space", 0x05231): "AsyncFunctionAwaitResolveSharedFun",
("old_space", 0x05255): "AsyncGeneratorAwaitRejectSharedFun",
("old_space", 0x05279): "AsyncGeneratorAwaitResolveSharedFun",
("old_space", 0x0529d): "AsyncGeneratorYieldResolveSharedFun",
("old_space", 0x052c1): "AsyncGeneratorReturnResolveSharedFun",
("old_space", 0x052e5): "AsyncGeneratorReturnClosedRejectSharedFun",
("old_space", 0x05309): "AsyncGeneratorReturnClosedResolveSharedFun",
("old_space", 0x0532d): "AsyncIteratorValueUnwrapSharedFun",
("old_space", 0x05351): "PromiseAllResolveElementSharedFun",
("old_space", 0x05375): "PromiseAllSettledResolveElementSharedFun",
("old_space", 0x05399): "PromiseAllSettledRejectElementSharedFun",
("old_space", 0x053bd): "PromiseAnyRejectElementSharedFun",
("old_space", 0x053e1): "PromiseCapabilityDefaultRejectSharedFun",
("old_space", 0x05405): "PromiseCapabilityDefaultResolveSharedFun",
("old_space", 0x05429): "PromiseCatchFinallySharedFun",
("old_space", 0x0544d): "PromiseGetCapabilitiesExecutorSharedFun",
("old_space", 0x05471): "PromiseThenFinallySharedFun",
("old_space", 0x05495): "PromiseThrowerFinallySharedFun",
("old_space", 0x054b9): "PromiseValueThunkFinallySharedFun",
("old_space", 0x054dd): "ProxyRevokeSharedFun",
("old_space", 0x05501): "ShadowRealmImportValueFulfilledSFI",
("old_space", 0x05525): "SourceTextModuleExecuteAsyncModuleFulfilledSFI",
("old_space", 0x05549): "SourceTextModuleExecuteAsyncModuleRejectedSFI",
}
# Lower 32 bits of first page addresses for various heap spaces.