[js weak refs] Add WeakRef
- Add the WeakRef class and its deref() function. - Add WeakFactory.prototype.makeRef - Implement the "keep during job" behavior for WeakRef constructor and deref(). - Here we keep the targets alive longer than until the end of the job (microtask), contradicting the spec. However, this is probably the indended behavior, see https://github.com/tc39/proposal-weakrefs/issues/39 . BUG=v8:8179 Change-Id: I41990d41ac1799e34f675d8431b9a7aa7ed3d48d Reviewed-on: https://chromium-review.googlesource.com/c/1306435 Commit-Queue: Marja Hölttä <marja@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Cr-Commit-Position: refs/heads/master@{#57242}
This commit is contained in:
parent
986aa36b1f
commit
a51f3fc652
@ -4577,9 +4577,11 @@ void Genesis::InitializeGlobal_harmony_weak_refs() {
|
||||
JSObject::AddProperty(isolate(), global, weak_factory_name,
|
||||
weak_factory_fun, DONT_ENUM);
|
||||
|
||||
Handle<String> make_cell_name = factory->makeCell_string();
|
||||
SimpleInstallFunction(isolate(), weak_factory_prototype, make_cell_name,
|
||||
SimpleInstallFunction(isolate(), weak_factory_prototype, "makeCell",
|
||||
Builtins::kWeakFactoryMakeCell, 2, false);
|
||||
|
||||
SimpleInstallFunction(isolate(), weak_factory_prototype, "makeRef",
|
||||
Builtins::kWeakFactoryMakeRef, 2, false);
|
||||
}
|
||||
{
|
||||
// Create %WeakCellPrototype%
|
||||
@ -4597,11 +4599,28 @@ void Genesis::InitializeGlobal_harmony_weak_refs() {
|
||||
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
|
||||
|
||||
SimpleInstallGetter(isolate(), weak_cell_prototype,
|
||||
factory->holdings_string(),
|
||||
factory->InternalizeUtf8String("holdings"),
|
||||
Builtins::kWeakCellHoldingsGetter, false);
|
||||
Handle<String> clear_name = factory->clear_string();
|
||||
SimpleInstallFunction(isolate(), weak_cell_prototype, clear_name,
|
||||
SimpleInstallFunction(isolate(), weak_cell_prototype, "clear",
|
||||
Builtins::kWeakCellClear, 0, false);
|
||||
|
||||
// Create %WeakRefPrototype%
|
||||
Handle<Map> weak_ref_map =
|
||||
factory->NewMap(JS_WEAK_REF_TYPE, JSWeakRef::kSize);
|
||||
native_context()->set_js_weak_ref_map(*weak_ref_map);
|
||||
|
||||
Handle<JSObject> weak_ref_prototype =
|
||||
factory->NewJSObject(isolate()->object_function(), TENURED);
|
||||
Map::SetPrototype(isolate(), weak_ref_map, weak_ref_prototype);
|
||||
JSObject::ForceSetPrototype(weak_ref_prototype, weak_cell_prototype);
|
||||
|
||||
JSObject::AddProperty(
|
||||
isolate(), weak_ref_prototype, factory->to_string_tag_symbol(),
|
||||
factory->WeakRef_string(),
|
||||
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
|
||||
|
||||
SimpleInstallFunction(isolate(), weak_ref_prototype, "deref",
|
||||
Builtins::kWeakRefDeref, 0, false);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1335,7 +1335,9 @@ namespace internal {
|
||||
CPP(WeakCellHoldingsGetter) \
|
||||
CPP(WeakFactoryCleanupIteratorNext) \
|
||||
CPP(WeakFactoryConstructor) \
|
||||
CPP(WeakFactoryMakeCell)
|
||||
CPP(WeakFactoryMakeCell) \
|
||||
CPP(WeakFactoryMakeRef) \
|
||||
CPP(WeakRefDeref)
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#define BUILTIN_LIST_INTL(CPP, TFJ, TFS) \
|
||||
|
@ -37,24 +37,25 @@ BUILTIN(WeakFactoryConstructor) {
|
||||
|
||||
BUILTIN(WeakFactoryMakeCell) {
|
||||
HandleScope scope(isolate);
|
||||
const char* method = "WeakFactory.makeCell";
|
||||
const char* method_name = "WeakFactory.prototype.makeCell";
|
||||
|
||||
CHECK_RECEIVER(JSWeakFactory, weak_factory, method);
|
||||
CHECK_RECEIVER(JSWeakFactory, weak_factory, method_name);
|
||||
|
||||
Handle<Object> target = args.atOrUndefined(isolate, 1);
|
||||
if (!target->IsJSReceiver()) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate,
|
||||
NewTypeError(MessageTemplate::kMakeCellTargetMustBeObject,
|
||||
isolate->factory()->NewStringFromAsciiChecked(method)));
|
||||
isolate, NewTypeError(MessageTemplate::kMakeCellTargetMustBeObject,
|
||||
isolate->factory()->NewStringFromAsciiChecked(
|
||||
method_name)));
|
||||
}
|
||||
Handle<JSReceiver> target_receiver = Handle<JSReceiver>::cast(target);
|
||||
Handle<Object> holdings = args.atOrUndefined(isolate, 2);
|
||||
if (target->SameValue(*holdings)) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate,
|
||||
NewTypeError(MessageTemplate::kMakeCellTargetAndHoldingsMustNotBeSame,
|
||||
isolate->factory()->NewStringFromAsciiChecked(method)));
|
||||
NewTypeError(
|
||||
MessageTemplate::kMakeCellTargetAndHoldingsMustNotBeSame,
|
||||
isolate->factory()->NewStringFromAsciiChecked(method_name)));
|
||||
}
|
||||
|
||||
// TODO(marja): Realms.
|
||||
@ -74,6 +75,46 @@ BUILTIN(WeakFactoryMakeCell) {
|
||||
return *weak_cell;
|
||||
}
|
||||
|
||||
BUILTIN(WeakFactoryMakeRef) {
|
||||
HandleScope scope(isolate);
|
||||
const char* method_name = "WeakFactory.prototype.makeRef";
|
||||
|
||||
CHECK_RECEIVER(JSWeakFactory, weak_factory, method_name);
|
||||
|
||||
Handle<Object> target = args.atOrUndefined(isolate, 1);
|
||||
if (!target->IsJSReceiver()) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kMakeRefTargetMustBeObject,
|
||||
isolate->factory()->NewStringFromAsciiChecked(
|
||||
method_name)));
|
||||
}
|
||||
Handle<JSReceiver> target_receiver = Handle<JSReceiver>::cast(target);
|
||||
Handle<Object> holdings = args.atOrUndefined(isolate, 2);
|
||||
if (target->SameValue(*holdings)) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate,
|
||||
NewTypeError(
|
||||
MessageTemplate::kMakeRefTargetAndHoldingsMustNotBeSame,
|
||||
isolate->factory()->NewStringFromAsciiChecked(method_name)));
|
||||
}
|
||||
|
||||
// TODO(marja): Realms.
|
||||
|
||||
Handle<Map> weak_ref_map(isolate->native_context()->js_weak_ref_map(),
|
||||
isolate);
|
||||
|
||||
Handle<JSWeakRef> weak_ref =
|
||||
Handle<JSWeakRef>::cast(isolate->factory()->NewJSObjectFromMap(
|
||||
weak_ref_map, TENURED, Handle<AllocationSite>::null()));
|
||||
weak_ref->set_target(*target_receiver);
|
||||
weak_ref->set_holdings(*holdings);
|
||||
weak_factory->AddWeakCell(*weak_ref);
|
||||
|
||||
isolate->heap()->AddKeepDuringJobTarget(target_receiver);
|
||||
|
||||
return *weak_ref;
|
||||
}
|
||||
|
||||
BUILTIN(WeakFactoryCleanupIteratorNext) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSWeakFactoryCleanupIterator, iterator, "next");
|
||||
@ -97,10 +138,25 @@ BUILTIN(WeakCellHoldingsGetter) {
|
||||
|
||||
BUILTIN(WeakCellClear) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSWeakCell, weak_cell, "WeakCell.clear");
|
||||
CHECK_RECEIVER(JSWeakCell, weak_cell, "WeakCell.prototype.clear");
|
||||
weak_cell->Clear(isolate);
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
BUILTIN(WeakRefDeref) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSWeakRef, weak_ref, "WeakRef.prototype.deref");
|
||||
if (weak_ref->target()->IsJSReceiver()) {
|
||||
Handle<JSReceiver> target =
|
||||
handle(JSReceiver::cast(weak_ref->target()), isolate);
|
||||
// AddKeepDuringJobTarget might allocate and cause a GC, but it won't clear
|
||||
// weak_ref since we hold a Handle to its target.
|
||||
isolate->heap()->AddKeepDuringJobTarget(target);
|
||||
} else {
|
||||
DCHECK(weak_ref->target()->IsUndefined(isolate));
|
||||
}
|
||||
return weak_ref->target();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -52,6 +52,7 @@ class JSWeakCollection;
|
||||
class JSWeakFactory;
|
||||
class JSWeakFactoryCleanupIterator;
|
||||
class JSWeakMap;
|
||||
class JSWeakRef;
|
||||
class JSWeakSet;
|
||||
class MaybeObject;
|
||||
class PromiseCapability;
|
||||
|
@ -245,6 +245,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
|
||||
case JS_WEAK_FACTORY_TYPE:
|
||||
case JS_WEAK_FACTORY_CLEANUP_ITERATOR_TYPE:
|
||||
case JS_WEAK_MAP_TYPE:
|
||||
case JS_WEAK_REF_TYPE:
|
||||
case JS_WEAK_SET_TYPE:
|
||||
case JS_PROMISE_TYPE:
|
||||
case WASM_EXCEPTION_TYPE:
|
||||
|
@ -227,6 +227,7 @@ enum ContextLookupFlags {
|
||||
V(JS_WEAK_FACTORY_CLEANUP_ITERATOR_MAP_INDEX, Map, \
|
||||
js_weak_factory_cleanup_iterator_map) \
|
||||
V(JS_WEAK_MAP_FUN_INDEX, JSFunction, js_weak_map_fun) \
|
||||
V(JS_WEAK_REF_MAP_INDEX, Map, js_weak_ref_map) \
|
||||
V(JS_WEAK_SET_FUN_INDEX, JSFunction, js_weak_set_fun) \
|
||||
V(MAP_CACHE_INDEX, Object, map_cache) \
|
||||
V(MAP_KEY_ITERATOR_MAP_INDEX, Map, map_key_iterator_map) \
|
||||
|
@ -120,7 +120,6 @@
|
||||
V(_, cell_value_string, "%cell_value") \
|
||||
V(_, char_at_string, "CharAt") \
|
||||
V(_, character_string, "character") \
|
||||
V(_, clear_string, "clear") \
|
||||
V(_, closure_string, "(closure)") \
|
||||
V(_, code_string, "code") \
|
||||
V(_, column_string, "column") \
|
||||
@ -175,7 +174,6 @@
|
||||
V(_, globalThis_string, "globalThis") \
|
||||
V(_, groups_string, "groups") \
|
||||
V(_, has_string, "has") \
|
||||
V(_, holdings_string, "holdings") \
|
||||
V(_, ignoreCase_string, "ignoreCase") \
|
||||
V(_, illegal_access_string, "illegal access") \
|
||||
V(_, illegal_argument_string, "illegal argument") \
|
||||
@ -197,7 +195,6 @@
|
||||
V(_, line_string, "line") \
|
||||
V(_, LinkError_string, "LinkError") \
|
||||
V(_, long_string, "long") \
|
||||
V(_, makeCell_string, "makeCell") \
|
||||
V(_, Map_string, "Map") \
|
||||
V(_, MapIterator_string, "Map Iterator") \
|
||||
V(_, message_string, "message") \
|
||||
@ -299,6 +296,7 @@
|
||||
V(_, WeakCell_string, "WeakCell") \
|
||||
V(_, WeakFactory_string, "WeakFactory") \
|
||||
V(_, WeakMap_string, "WeakMap") \
|
||||
V(_, WeakRef_string, "WeakRef") \
|
||||
V(_, WeakSet_string, "WeakSet") \
|
||||
V(_, week_string, "week") \
|
||||
V(_, will_handle_string, "willHandle") \
|
||||
|
@ -5267,6 +5267,25 @@ void Heap::AddDirtyJSWeakFactory(
|
||||
// for the root pointing to the first JSWeakFactory.
|
||||
}
|
||||
|
||||
void Heap::AddKeepDuringJobTarget(Handle<JSReceiver> target) {
|
||||
DCHECK(FLAG_harmony_weak_refs);
|
||||
DCHECK(weak_refs_keep_during_job()->IsUndefined() ||
|
||||
weak_refs_keep_during_job()->IsOrderedHashSet());
|
||||
Handle<OrderedHashSet> table;
|
||||
if (weak_refs_keep_during_job()->IsUndefined(isolate())) {
|
||||
table = isolate()->factory()->NewOrderedHashSet();
|
||||
} else {
|
||||
table =
|
||||
handle(OrderedHashSet::cast(weak_refs_keep_during_job()), isolate());
|
||||
}
|
||||
table = OrderedHashSet::Add(isolate(), table, target);
|
||||
set_weak_refs_keep_during_job(*table);
|
||||
}
|
||||
|
||||
void Heap::ClearKeepDuringJobSet() {
|
||||
set_weak_refs_keep_during_job(ReadOnlyRoots(isolate()).undefined_value());
|
||||
}
|
||||
|
||||
size_t Heap::NumberOfTrackedHeapObjectTypes() {
|
||||
return ObjectStats::OBJECT_STATS_COUNT;
|
||||
}
|
||||
|
@ -669,6 +669,9 @@ class Heap {
|
||||
std::function<void(HeapObject* object, ObjectSlot slot, Object* target)>
|
||||
gc_notify_updated_slot);
|
||||
|
||||
void AddKeepDuringJobTarget(Handle<JSReceiver> target);
|
||||
void ClearKeepDuringJobSet();
|
||||
|
||||
// ===========================================================================
|
||||
// Inline allocation. ========================================================
|
||||
// ===========================================================================
|
||||
|
@ -630,6 +630,7 @@ void Heap::CreateInitialObjects() {
|
||||
set_current_microtask(roots.undefined_value());
|
||||
|
||||
set_dirty_js_weak_factories(roots.undefined_value());
|
||||
set_weak_refs_keep_during_job(roots.undefined_value());
|
||||
|
||||
// Allocate cache for single character one byte strings.
|
||||
set_single_character_string_cache(
|
||||
|
@ -3914,7 +3914,15 @@ void Isolate::FireCallCompletedCallback() {
|
||||
handle_scope_implementer()->microtasks_policy() ==
|
||||
v8::MicrotasksPolicy::kAuto;
|
||||
|
||||
if (run_microtasks) RunMicrotasks();
|
||||
if (run_microtasks) {
|
||||
RunMicrotasks();
|
||||
} else {
|
||||
// TODO(marja): (spec) The discussion about when to clear the KeepDuringJob
|
||||
// set is still open (whether to clear it after every microtask or once
|
||||
// during a microtask checkpoint). See also
|
||||
// https://github.com/tc39/proposal-weakrefs/issues/39 .
|
||||
heap()->ClearKeepDuringJobSet();
|
||||
}
|
||||
|
||||
if (call_completed_callbacks_.empty()) return;
|
||||
// Fire callbacks. Increase call depth to prevent recursive callbacks.
|
||||
@ -4189,6 +4197,12 @@ void Isolate::RunMicrotasks() {
|
||||
CHECK_EQ(0, microtask_queue->queue()->length());
|
||||
is_running_microtasks_ = false;
|
||||
}
|
||||
// TODO(marja): (spec) The discussion about when to clear the KeepDuringJob
|
||||
// set is still open (whether to clear it after every microtask or once
|
||||
// during a microtask checkpoint). See also
|
||||
// https://github.com/tc39/proposal-weakrefs/issues/39 .
|
||||
heap()->ClearKeepDuringJobSet();
|
||||
|
||||
FireMicrotasksCompletedCallback();
|
||||
}
|
||||
|
||||
|
@ -537,7 +537,11 @@ namespace internal {
|
||||
T(MakeCellTargetMustBeObject, \
|
||||
"WeakFactory.makeCell: target must be an object") \
|
||||
T(MakeCellTargetAndHoldingsMustNotBeSame, \
|
||||
"WeakFactory.makeCell: target and holdings must not be same")
|
||||
"WeakFactory.makeCell: target and holdings must not be same") \
|
||||
T(MakeRefTargetMustBeObject, \
|
||||
"WeakFactory.makeRef: target must be an object") \
|
||||
T(MakeRefTargetAndHoldingsMustNotBeSame, \
|
||||
"WeakFactory.makeRef: target and holdings must not be same")
|
||||
|
||||
enum class MessageTemplate {
|
||||
#define TEMPLATE(NAME, STRING) k##NAME,
|
||||
|
@ -860,6 +860,7 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
|
||||
case JS_FUNCTION_TYPE:
|
||||
return Op::template apply<JSFunction::BodyDescriptor>(p1, p2, p3, p4);
|
||||
case JS_WEAK_CELL_TYPE:
|
||||
case JS_WEAK_REF_TYPE:
|
||||
return Op::template apply<JSWeakCell::BodyDescriptor>(p1, p2, p3, p4);
|
||||
case ODDBALL_TYPE:
|
||||
return Op::template apply<Oddball::BodyDescriptor>(p1, p2, p3, p4);
|
||||
|
@ -313,6 +313,7 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
|
||||
isolate);
|
||||
break;
|
||||
case JS_WEAK_CELL_TYPE:
|
||||
case JS_WEAK_REF_TYPE:
|
||||
JSWeakCell::cast(this)->JSWeakCellVerify(isolate);
|
||||
break;
|
||||
case JS_WEAK_FACTORY_TYPE:
|
||||
|
@ -205,6 +205,7 @@ namespace internal {
|
||||
V(JS_SET_VALUE_ITERATOR_TYPE) \
|
||||
V(JS_STRING_ITERATOR_TYPE) \
|
||||
V(JS_WEAK_CELL_TYPE) \
|
||||
V(JS_WEAK_REF_TYPE) \
|
||||
V(JS_WEAK_FACTORY_CLEANUP_ITERATOR_TYPE) \
|
||||
V(JS_WEAK_FACTORY_TYPE) \
|
||||
V(JS_WEAK_MAP_TYPE) \
|
||||
|
@ -285,6 +285,7 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
|
||||
JSMapIterator::cast(this)->JSMapIteratorPrint(os);
|
||||
break;
|
||||
case JS_WEAK_CELL_TYPE:
|
||||
case JS_WEAK_REF_TYPE:
|
||||
JSWeakCell::cast(this)->JSWeakCellPrint(os);
|
||||
break;
|
||||
case JS_WEAK_FACTORY_TYPE:
|
||||
|
@ -3260,6 +3260,7 @@ VisitorId Map::GetVisitorId(Map* map) {
|
||||
return kVisitJSApiObject;
|
||||
|
||||
case JS_WEAK_CELL_TYPE:
|
||||
case JS_WEAK_REF_TYPE:
|
||||
return kVisitJSWeakCell;
|
||||
|
||||
case FILLER_TYPE:
|
||||
|
@ -509,7 +509,8 @@ enum InstanceType : uint16_t {
|
||||
JS_SET_KEY_VALUE_ITERATOR_TYPE,
|
||||
JS_SET_VALUE_ITERATOR_TYPE,
|
||||
JS_STRING_ITERATOR_TYPE,
|
||||
JS_WEAK_CELL_TYPE,
|
||||
JS_WEAK_CELL_TYPE, // FIRST_JS_WEAK_CELL_TYPE
|
||||
JS_WEAK_REF_TYPE, // LAST_JS_WEAK_CELL_TYPE
|
||||
JS_WEAK_FACTORY_CLEANUP_ITERATOR_TYPE,
|
||||
JS_WEAK_FACTORY_TYPE,
|
||||
JS_WEAK_MAP_TYPE,
|
||||
@ -597,6 +598,9 @@ enum InstanceType : uint16_t {
|
||||
|
||||
FIRST_MAP_ITERATOR_TYPE = JS_MAP_KEY_ITERATOR_TYPE,
|
||||
LAST_MAP_ITERATOR_TYPE = JS_MAP_VALUE_ITERATOR_TYPE,
|
||||
|
||||
FIRST_JS_WEAK_CELL_TYPE = JS_WEAK_CELL_TYPE,
|
||||
LAST_JS_WEAK_CELL_TYPE = JS_WEAK_REF_TYPE,
|
||||
};
|
||||
|
||||
STATIC_ASSERT((FIRST_NONSTRING_TYPE & kIsNotStringMask) != kStringTag);
|
||||
@ -778,6 +782,7 @@ class ZoneForwardList;
|
||||
V(JSTypedArray) \
|
||||
V(JSValue) \
|
||||
V(JSWeakCell) \
|
||||
V(JSWeakRef) \
|
||||
V(JSWeakCollection) \
|
||||
V(JSWeakFactory) \
|
||||
V(JSWeakFactoryCleanupIterator) \
|
||||
@ -935,10 +940,10 @@ class ZoneForwardList;
|
||||
V(JSStringIterator, JS_STRING_ITERATOR_TYPE) \
|
||||
V(JSTypedArray, JS_TYPED_ARRAY_TYPE) \
|
||||
V(JSValue, JS_VALUE_TYPE) \
|
||||
V(JSWeakCell, JS_WEAK_CELL_TYPE) \
|
||||
V(JSWeakFactory, JS_WEAK_FACTORY_TYPE) \
|
||||
V(JSWeakFactoryCleanupIterator, JS_WEAK_FACTORY_CLEANUP_ITERATOR_TYPE) \
|
||||
V(JSWeakMap, JS_WEAK_MAP_TYPE) \
|
||||
V(JSWeakRef, JS_WEAK_REF_TYPE) \
|
||||
V(JSWeakSet, JS_WEAK_SET_TYPE) \
|
||||
V(LoadHandler, LOAD_HANDLER_TYPE) \
|
||||
V(Map, MAP_TYPE) \
|
||||
@ -1006,6 +1011,7 @@ class ZoneForwardList;
|
||||
V(HashTable, FIRST_HASH_TABLE_TYPE, LAST_HASH_TABLE_TYPE) \
|
||||
V(JSMapIterator, FIRST_MAP_ITERATOR_TYPE, LAST_MAP_ITERATOR_TYPE) \
|
||||
V(JSSetIterator, FIRST_SET_ITERATOR_TYPE, LAST_SET_ITERATOR_TYPE) \
|
||||
V(JSWeakCell, FIRST_JS_WEAK_CELL_TYPE, LAST_JS_WEAK_CELL_TYPE) \
|
||||
V(Microtask, FIRST_MICROTASK_TYPE, LAST_MICROTASK_TYPE) \
|
||||
V(Name, FIRST_TYPE, LAST_NAME_TYPE) \
|
||||
V(String, FIRST_TYPE, FIRST_NONSTRING_TYPE - 1) \
|
||||
|
@ -31,6 +31,8 @@ ACCESSORS(JSWeakCell, next, Object, kNextOffset)
|
||||
ACCESSORS(JSWeakCell, prev, Object, kPrevOffset)
|
||||
CAST_ACCESSOR(JSWeakCell)
|
||||
|
||||
CAST_ACCESSOR(JSWeakRef)
|
||||
|
||||
ACCESSORS(JSWeakFactoryCleanupIterator, factory, JSWeakFactory, kFactoryOffset)
|
||||
CAST_ACCESSOR(JSWeakFactoryCleanupIterator)
|
||||
|
||||
|
@ -101,6 +101,13 @@ class JSWeakCell : public JSObject {
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakCell);
|
||||
};
|
||||
|
||||
class JSWeakRef : public JSWeakCell {
|
||||
public:
|
||||
DECL_CAST(JSWeakRef)
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakRef);
|
||||
};
|
||||
|
||||
class WeakFactoryCleanupJobTask : public Microtask {
|
||||
public:
|
||||
DECL_ACCESSORS(factory, JSWeakFactory)
|
||||
|
@ -285,7 +285,9 @@ class RootVisitor;
|
||||
/* Support for async stack traces */ \
|
||||
V(HeapObject*, current_microtask, CurrentMicrotask) \
|
||||
/* JSWeakFactory objects which need cleanup */ \
|
||||
V(Object*, dirty_js_weak_factories, DirtyJSWeakFactories)
|
||||
V(Object*, dirty_js_weak_factories, DirtyJSWeakFactories) \
|
||||
/* KeepDuringJob set for JS WeakRefs */ \
|
||||
V(HeapObject*, weak_refs_keep_during_job, WeakRefsKeepDuringJob)
|
||||
|
||||
// Entries in this list are limited to Smis and are not visited during GC.
|
||||
#define SMI_ROOT_LIST(V) \
|
||||
|
@ -50,7 +50,8 @@ bool IsInitiallyMutable(Factory* factory, Address object_address) {
|
||||
V(retained_maps) \
|
||||
V(retaining_path_targets) \
|
||||
V(serialized_global_proxy_sizes) \
|
||||
V(serialized_objects)
|
||||
V(serialized_objects) \
|
||||
V(weak_refs_keep_during_job)
|
||||
|
||||
#define TEST_CAN_BE_READ_ONLY(name) \
|
||||
if (factory->name().address() == object_address) return false;
|
||||
|
@ -82,6 +82,8 @@
|
||||
assertThrows(() => wf.makeCell(false), TypeError, message);
|
||||
assertThrows(() => wf.makeCell("foo"), TypeError, message);
|
||||
assertThrows(() => wf.makeCell(Symbol()), TypeError, message);
|
||||
assertThrows(() => wf.makeCell(null), TypeError, message);
|
||||
assertThrows(() => wf.makeCell(undefined), TypeError, message);
|
||||
})();
|
||||
|
||||
(function TestMakeCellWithProxy() {
|
||||
@ -98,7 +100,6 @@
|
||||
// SameValue(target, holdings) not ok
|
||||
assertThrows(() => wf.makeCell(obj, obj), TypeError,
|
||||
"WeakFactory.makeCell: target and holdings must not be same");
|
||||
// target == holdings ok
|
||||
let holdings = {a: 1};
|
||||
let wc = wf.makeCell(obj, holdings);
|
||||
})();
|
||||
@ -127,3 +128,109 @@
|
||||
// Does not throw:
|
||||
clear.call(wc);
|
||||
})();
|
||||
|
||||
(function TestMakeRef() {
|
||||
let wf = new WeakFactory();
|
||||
let wr = wf.makeRef({});
|
||||
let wc = wf.makeCell({});
|
||||
assertEquals(wr.toString(), "[object WeakRef]");
|
||||
assertNotSame(wr.__proto__, Object.prototype);
|
||||
assertSame(wr.__proto__.__proto__, wc.__proto__);
|
||||
assertEquals(wr.holdings, undefined);
|
||||
|
||||
let deref_desc = Object.getOwnPropertyDescriptor(wr.__proto__, "deref");
|
||||
assertEquals(true, deref_desc.configurable);
|
||||
assertEquals(false, deref_desc.enumerable);
|
||||
assertEquals("function", typeof deref_desc.value);
|
||||
})();
|
||||
|
||||
(function TestMakeRefWithHoldings() {
|
||||
let wf = new WeakFactory();
|
||||
let obj = {a: 1};
|
||||
let holdings = {b: 2};
|
||||
let wr = wf.makeRef(obj, holdings);
|
||||
assertSame(wr.holdings, holdings);
|
||||
})();
|
||||
|
||||
(function TestMakeRefWithHoldingsSetHoldings() {
|
||||
let wf = new WeakFactory();
|
||||
let obj = {a: 1};
|
||||
let holdings = {b: 2};
|
||||
let wr = wf.makeRef(obj, holdings);
|
||||
assertSame(wr.holdings, holdings);
|
||||
wr.holdings = 5;
|
||||
assertSame(wr.holdings, holdings);
|
||||
})();
|
||||
|
||||
(function TestMakeRefWithHoldingsSetHoldingsStrict() {
|
||||
"use strict";
|
||||
let wf = new WeakFactory();
|
||||
let obj = {a: 1};
|
||||
let holdings = {b: 2};
|
||||
let wr = wf.makeRef(obj, holdings);
|
||||
assertSame(wr.holdings, holdings);
|
||||
assertThrows(() => { wr.holdings = 5; }, TypeError);
|
||||
assertSame(wr.holdings, holdings);
|
||||
})();
|
||||
|
||||
(function TestMakeRefWithNonObject() {
|
||||
let wf = new WeakFactory();
|
||||
let message = "WeakFactory.makeRef: target must be an object";
|
||||
assertThrows(() => wf.makeRef(), TypeError, message);
|
||||
assertThrows(() => wf.makeRef(1), TypeError, message);
|
||||
assertThrows(() => wf.makeRef(false), TypeError, message);
|
||||
assertThrows(() => wf.makeRef("foo"), TypeError, message);
|
||||
assertThrows(() => wf.makeRef(Symbol()), TypeError, message);
|
||||
assertThrows(() => wf.makeRef(null), TypeError, message);
|
||||
assertThrows(() => wf.makeRef(undefined), TypeError, message);
|
||||
})();
|
||||
|
||||
(function TestMakeRefWithProxy() {
|
||||
let handler = {};
|
||||
let obj = {};
|
||||
let proxy = new Proxy(obj, handler);
|
||||
let wf = new WeakFactory();
|
||||
let wr = wf.makeRef(proxy);
|
||||
})();
|
||||
|
||||
(function TestMakeRefTargetAndHoldingsSameValue() {
|
||||
let wf = new WeakFactory();
|
||||
let obj = {a: 1};
|
||||
// SameValue(target, holdings) not ok
|
||||
assertThrows(() => wf.makeRef(obj, obj), TypeError,
|
||||
"WeakFactory.makeRef: target and holdings must not be same");
|
||||
let holdings = {a: 1};
|
||||
let wr = wf.makeRef(obj, holdings);
|
||||
})();
|
||||
|
||||
(function TestMakeRefWithoutWeakFactory() {
|
||||
assertThrows(() => WeakFactory.prototype.makeRef.call({}, {}), TypeError);
|
||||
// Does not throw:
|
||||
let wf = new WeakFactory();
|
||||
WeakFactory.prototype.makeRef.call(wf, {});
|
||||
})();
|
||||
|
||||
(function TestDerefWithoutWeakRef() {
|
||||
let wf = new WeakFactory();
|
||||
let wc = wf.makeCell({});
|
||||
let wr = wf.makeRef({});
|
||||
let deref = Object.getOwnPropertyDescriptor(wr.__proto__, "deref").value;
|
||||
assertThrows(() => deref.call({}), TypeError);
|
||||
assertThrows(() => deref.call(wc), TypeError);
|
||||
// Does not throw:
|
||||
deref.call(wr);
|
||||
})();
|
||||
|
||||
(function TestWeakRefClearAfterProtoChange() {
|
||||
let wf = new WeakFactory();
|
||||
let wc = wf.makeCell({});
|
||||
let wr = wf.makeRef({});
|
||||
// Does not throw:
|
||||
wr.clear();
|
||||
wr.__proto__ = {};
|
||||
assertThrows(() => wr.clear(), TypeError);
|
||||
|
||||
let clear = Object.getOwnPropertyDescriptor(wc.__proto__, "clear").value;
|
||||
// Does not throw:
|
||||
clear.call(wr);
|
||||
})();
|
||||
|
46
test/mjsunit/harmony/weakrefs/clear-after-deref.js
Normal file
46
test/mjsunit/harmony/weakrefs/clear-after-deref.js
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking --allow-natives-syntax
|
||||
|
||||
let cleanup_started = false;
|
||||
let cleanup_succeeded = false;
|
||||
let cleanup = function(iter) {
|
||||
cleanup_start = true;
|
||||
let cells = [];
|
||||
for (wc of iter) {
|
||||
cells.push(wc);
|
||||
}
|
||||
assertEquals(1, cells.length);
|
||||
assertEquals(w1, cells[0]);
|
||||
cleanup_succeeded = true;
|
||||
}
|
||||
|
||||
let wf = new WeakFactory(cleanup);
|
||||
let wr;
|
||||
(function() {
|
||||
let o = { foo: "bar" };
|
||||
wr = wf.makeRef(o);
|
||||
})();
|
||||
|
||||
// Since the WeakRef was created during this turn, they're not cleared by GC.
|
||||
gc();
|
||||
assertNotEquals(undefined, wr.deref());
|
||||
|
||||
%RunMicrotasks();
|
||||
// New turn.
|
||||
|
||||
let o = wr.deref();
|
||||
assertEquals("bar", o.foo);
|
||||
|
||||
wr.clear();
|
||||
assertEquals(undefined, wr.deref());
|
||||
|
||||
let timeout_func1 = function() {
|
||||
assertFalse(cleanup_started);
|
||||
assertFalse(cleanup_succeeded);
|
||||
}
|
||||
|
||||
// Assert that the cleanup function won't be called.
|
||||
setTimeout(timeout_func1, 0);
|
71
test/mjsunit/harmony/weakrefs/two-weakrefs.js
Normal file
71
test/mjsunit/harmony/weakrefs/two-weakrefs.js
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking --allow-natives-syntax
|
||||
|
||||
let cleanup_count = 0;
|
||||
let cleared_cells1 = [];
|
||||
let cleared_cells2 = [];
|
||||
let cleanup = function(iter) {
|
||||
if (cleanup_count == 0) {
|
||||
for (wc of iter) {
|
||||
cleared_cells1.push(wc);
|
||||
}
|
||||
} else {
|
||||
assertEquals(1, cleanup_count);
|
||||
for (wc of iter) {
|
||||
cleared_cells2.push(wc);
|
||||
}
|
||||
}
|
||||
++cleanup_count;
|
||||
}
|
||||
|
||||
let wf = new WeakFactory(cleanup);
|
||||
let o1 = {};
|
||||
let o2 = {};
|
||||
let wr1;
|
||||
let wr2;
|
||||
(function() {
|
||||
wr1 = wf.makeRef(o1);
|
||||
wr2 = wf.makeRef(o2);
|
||||
})();
|
||||
|
||||
// Since the WeakRefs were created during this turn, they're not cleared by GC.
|
||||
gc();
|
||||
(function() {
|
||||
assertNotEquals(undefined, wr1.deref());
|
||||
assertNotEquals(undefined, wr2.deref());
|
||||
})();
|
||||
|
||||
%RunMicrotasks();
|
||||
// New turn.
|
||||
|
||||
assertEquals(0, cleanup_count);
|
||||
|
||||
wr1.deref();
|
||||
o1 = null;
|
||||
gc(); // deref makes sure we don't clean up wr1
|
||||
|
||||
%RunMicrotasks();
|
||||
// New turn.
|
||||
|
||||
assertEquals(0, cleanup_count);
|
||||
|
||||
wr2.deref();
|
||||
o2 = null;
|
||||
gc(); // deref makes sure we don't clean up wr2
|
||||
|
||||
%RunMicrotasks();
|
||||
// New turn.
|
||||
|
||||
assertEquals(1, cleanup_count);
|
||||
assertEquals(wr1, cleared_cells1[0]);
|
||||
|
||||
gc();
|
||||
|
||||
%RunMicrotasks();
|
||||
// New turn.
|
||||
|
||||
assertEquals(2, cleanup_count);
|
||||
assertEquals(wr2, cleared_cells2[0]);
|
45
test/mjsunit/harmony/weakrefs/weakcell-and-weakref.js
Normal file
45
test/mjsunit/harmony/weakrefs/weakcell-and-weakref.js
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking --allow-natives-syntax
|
||||
|
||||
let cleanup_called = false;
|
||||
let cleanup = function(iter) {
|
||||
assertFalse(cleanup_called);
|
||||
let cells = [];
|
||||
for (wc of iter) {
|
||||
cells.push(wc);
|
||||
}
|
||||
assertEquals(2, cells.length);
|
||||
assertTrue(cells.includes(weak_ref));
|
||||
assertTrue(cells.includes(weak_cell));
|
||||
cleanup_called = true;
|
||||
}
|
||||
|
||||
let wf = new WeakFactory(cleanup);
|
||||
let weak_ref;
|
||||
let weak_cell;
|
||||
(function() {
|
||||
let o = {};
|
||||
weak_ref = wf.makeRef(o);
|
||||
weak_cell = wf.makeRef(o);
|
||||
})();
|
||||
|
||||
// Since the WeakRef was created during this turn, it is not cleared by GC. The
|
||||
// WeakCell is not cleared either, since the WeakRef keeps the target object
|
||||
// alive.
|
||||
gc();
|
||||
(function() {
|
||||
assertNotEquals(undefined, weak_ref.deref());
|
||||
})();
|
||||
|
||||
%RunMicrotasks();
|
||||
// Next turn.
|
||||
|
||||
gc();
|
||||
|
||||
%RunMicrotasks();
|
||||
// Next turn.
|
||||
|
||||
assertTrue(cleanup_called);
|
@ -0,0 +1,46 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking --allow-natives-syntax
|
||||
|
||||
let cleanup_called = false;
|
||||
let cleanup = function(iter) {
|
||||
assertFalse(cleanup_called);
|
||||
let count = 0;
|
||||
for (wc of iter) {
|
||||
++count;
|
||||
assertEquals(wr, wc);
|
||||
assertEquals(undefined, wc.deref());
|
||||
}
|
||||
assertEquals(1, count);
|
||||
cleanup_called = true;
|
||||
}
|
||||
|
||||
let wf = new WeakFactory(cleanup);
|
||||
let wr;
|
||||
(function() {
|
||||
let o = {};
|
||||
wr = wf.makeRef(o);
|
||||
// Don't deref here, we want to test that the creation is enough to keep the
|
||||
// WeakRef alive until the end of the turn.
|
||||
})();
|
||||
|
||||
gc();
|
||||
|
||||
// Since the WeakRef was created during this turn, it is not cleared by GC.
|
||||
(function() {
|
||||
assertNotEquals(undefined, wr.deref());
|
||||
})();
|
||||
|
||||
%RunMicrotasks();
|
||||
// Next turn.
|
||||
|
||||
assertFalse(cleanup_called);
|
||||
|
||||
gc();
|
||||
|
||||
%RunMicrotasks();
|
||||
// Next turn.
|
||||
|
||||
assertTrue(cleanup_called);
|
76
test/mjsunit/harmony/weakrefs/weakref-deref-keeps-alive.js
Normal file
76
test/mjsunit/harmony/weakrefs/weakref-deref-keeps-alive.js
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking --allow-natives-syntax
|
||||
|
||||
let cleanup_count = 0;
|
||||
let cleanup_cells = [];
|
||||
let cleanup = function(iter) {
|
||||
for (wc of iter) {
|
||||
assertEquals(undefined, wc.deref());
|
||||
cleanup_cells.push(wc);
|
||||
}
|
||||
++cleanup_count;
|
||||
}
|
||||
|
||||
let wf = new WeakFactory(cleanup);
|
||||
let wf_control = new WeakFactory(cleanup);
|
||||
let wr;
|
||||
let wr_control; // control WeakRef for testing what happens without deref
|
||||
(function() {
|
||||
let o1 = {};
|
||||
wr = wf.makeRef(o1);
|
||||
let o2 = {};
|
||||
wr_control = wf_control.makeRef(o2);
|
||||
})();
|
||||
|
||||
let strong = {a: wr.deref(), b: wr_control.deref()};
|
||||
|
||||
gc();
|
||||
|
||||
%RunMicrotasks();
|
||||
// Next turn.
|
||||
|
||||
gc();
|
||||
|
||||
%RunMicrotasks();
|
||||
// Next turn.
|
||||
|
||||
// We have a strong reference to the objects, so the WeakRefs are not cleared yet.
|
||||
assertEquals(0, cleanup_count);
|
||||
|
||||
// Call deref inside a closure, trying to avoid accidentally storing a strong
|
||||
// reference into the object in the stack frame.
|
||||
(function() {
|
||||
wr.deref();
|
||||
})();
|
||||
|
||||
strong = null;
|
||||
|
||||
// This GC will clear wr_control.
|
||||
gc();
|
||||
|
||||
(function() {
|
||||
assertNotEquals(undefined, wr.deref());
|
||||
// Now the control WeakRef got cleared, since nothing was keeping it alive.
|
||||
assertEquals(undefined, wr_control.deref());
|
||||
})();
|
||||
|
||||
%RunMicrotasks();
|
||||
// Next turn.
|
||||
|
||||
assertEquals(1, cleanup_count);
|
||||
assertEquals(1, cleanup_cells.length);
|
||||
assertEquals(wc, cleanup_cells[0]);
|
||||
|
||||
gc();
|
||||
|
||||
%RunMicrotasks();
|
||||
// Next turn.
|
||||
|
||||
assertEquals(2, cleanup_count);
|
||||
assertEquals(2, cleanup_cells.length);
|
||||
assertEquals(wr, cleanup_cells[1]);
|
||||
|
||||
assertEquals(undefined, wr.deref());
|
@ -159,30 +159,31 @@ INSTANCE_TYPES = {
|
||||
1079: "JS_SET_VALUE_ITERATOR_TYPE",
|
||||
1080: "JS_STRING_ITERATOR_TYPE",
|
||||
1081: "JS_WEAK_CELL_TYPE",
|
||||
1082: "JS_WEAK_FACTORY_CLEANUP_ITERATOR_TYPE",
|
||||
1083: "JS_WEAK_FACTORY_TYPE",
|
||||
1084: "JS_WEAK_MAP_TYPE",
|
||||
1085: "JS_WEAK_SET_TYPE",
|
||||
1086: "JS_TYPED_ARRAY_TYPE",
|
||||
1087: "JS_DATA_VIEW_TYPE",
|
||||
1088: "JS_INTL_V8_BREAK_ITERATOR_TYPE",
|
||||
1089: "JS_INTL_COLLATOR_TYPE",
|
||||
1090: "JS_INTL_DATE_TIME_FORMAT_TYPE",
|
||||
1091: "JS_INTL_LIST_FORMAT_TYPE",
|
||||
1092: "JS_INTL_LOCALE_TYPE",
|
||||
1093: "JS_INTL_NUMBER_FORMAT_TYPE",
|
||||
1094: "JS_INTL_PLURAL_RULES_TYPE",
|
||||
1095: "JS_INTL_RELATIVE_TIME_FORMAT_TYPE",
|
||||
1096: "JS_INTL_SEGMENT_ITERATOR_TYPE",
|
||||
1097: "JS_INTL_SEGMENTER_TYPE",
|
||||
1098: "WASM_EXCEPTION_TYPE",
|
||||
1099: "WASM_GLOBAL_TYPE",
|
||||
1100: "WASM_INSTANCE_TYPE",
|
||||
1101: "WASM_MEMORY_TYPE",
|
||||
1102: "WASM_MODULE_TYPE",
|
||||
1103: "WASM_TABLE_TYPE",
|
||||
1104: "JS_BOUND_FUNCTION_TYPE",
|
||||
1105: "JS_FUNCTION_TYPE",
|
||||
1082: "JS_WEAK_REF_TYPE",
|
||||
1083: "JS_WEAK_FACTORY_CLEANUP_ITERATOR_TYPE",
|
||||
1084: "JS_WEAK_FACTORY_TYPE",
|
||||
1085: "JS_WEAK_MAP_TYPE",
|
||||
1086: "JS_WEAK_SET_TYPE",
|
||||
1087: "JS_TYPED_ARRAY_TYPE",
|
||||
1088: "JS_DATA_VIEW_TYPE",
|
||||
1089: "JS_INTL_V8_BREAK_ITERATOR_TYPE",
|
||||
1090: "JS_INTL_COLLATOR_TYPE",
|
||||
1091: "JS_INTL_DATE_TIME_FORMAT_TYPE",
|
||||
1092: "JS_INTL_LIST_FORMAT_TYPE",
|
||||
1093: "JS_INTL_LOCALE_TYPE",
|
||||
1094: "JS_INTL_NUMBER_FORMAT_TYPE",
|
||||
1095: "JS_INTL_PLURAL_RULES_TYPE",
|
||||
1096: "JS_INTL_RELATIVE_TIME_FORMAT_TYPE",
|
||||
1097: "JS_INTL_SEGMENT_ITERATOR_TYPE",
|
||||
1098: "JS_INTL_SEGMENTER_TYPE",
|
||||
1099: "WASM_EXCEPTION_TYPE",
|
||||
1100: "WASM_GLOBAL_TYPE",
|
||||
1101: "WASM_INSTANCE_TYPE",
|
||||
1102: "WASM_MEMORY_TYPE",
|
||||
1103: "WASM_MODULE_TYPE",
|
||||
1104: "WASM_TABLE_TYPE",
|
||||
1105: "JS_BOUND_FUNCTION_TYPE",
|
||||
1106: "JS_FUNCTION_TYPE",
|
||||
}
|
||||
|
||||
# List of known V8 maps.
|
||||
@ -297,42 +298,42 @@ KNOWN_MAPS = {
|
||||
("RO_SPACE", 0x02699): (171, "Tuple2Map"),
|
||||
("RO_SPACE", 0x02739): (173, "ArrayBoilerplateDescriptionMap"),
|
||||
("RO_SPACE", 0x02a79): (161, "InterceptorInfoMap"),
|
||||
("RO_SPACE", 0x05131): (153, "AccessCheckInfoMap"),
|
||||
("RO_SPACE", 0x05181): (154, "AccessorInfoMap"),
|
||||
("RO_SPACE", 0x051d1): (155, "AccessorPairMap"),
|
||||
("RO_SPACE", 0x05221): (156, "AliasedArgumentsEntryMap"),
|
||||
("RO_SPACE", 0x05271): (157, "AllocationMementoMap"),
|
||||
("RO_SPACE", 0x052c1): (158, "AsyncGeneratorRequestMap"),
|
||||
("RO_SPACE", 0x05311): (159, "DebugInfoMap"),
|
||||
("RO_SPACE", 0x05361): (160, "FunctionTemplateInfoMap"),
|
||||
("RO_SPACE", 0x053b1): (162, "InterpreterDataMap"),
|
||||
("RO_SPACE", 0x05401): (163, "ModuleInfoEntryMap"),
|
||||
("RO_SPACE", 0x05451): (164, "ModuleMap"),
|
||||
("RO_SPACE", 0x054a1): (165, "ObjectTemplateInfoMap"),
|
||||
("RO_SPACE", 0x054f1): (166, "PromiseCapabilityMap"),
|
||||
("RO_SPACE", 0x05541): (167, "PromiseReactionMap"),
|
||||
("RO_SPACE", 0x05591): (168, "PrototypeInfoMap"),
|
||||
("RO_SPACE", 0x055e1): (169, "ScriptMap"),
|
||||
("RO_SPACE", 0x05631): (170, "StackFrameInfoMap"),
|
||||
("RO_SPACE", 0x05681): (172, "Tuple3Map"),
|
||||
("RO_SPACE", 0x056d1): (174, "WasmDebugInfoMap"),
|
||||
("RO_SPACE", 0x05721): (175, "WasmExportedFunctionDataMap"),
|
||||
("RO_SPACE", 0x05771): (176, "CallableTaskMap"),
|
||||
("RO_SPACE", 0x057c1): (177, "CallbackTaskMap"),
|
||||
("RO_SPACE", 0x05811): (178, "PromiseFulfillReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x05861): (179, "PromiseRejectReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x058b1): (180, "PromiseResolveThenableJobTaskMap"),
|
||||
("RO_SPACE", 0x05901): (181, "WeakFactoryCleanupJobTaskMap"),
|
||||
("RO_SPACE", 0x05951): (182, "MicrotaskQueueMap"),
|
||||
("RO_SPACE", 0x059a1): (183, "AllocationSiteWithWeakNextMap"),
|
||||
("RO_SPACE", 0x059f1): (183, "AllocationSiteWithoutWeakNextMap"),
|
||||
("RO_SPACE", 0x05a41): (215, "LoadHandler1Map"),
|
||||
("RO_SPACE", 0x05a91): (215, "LoadHandler2Map"),
|
||||
("RO_SPACE", 0x05ae1): (215, "LoadHandler3Map"),
|
||||
("RO_SPACE", 0x05b31): (222, "StoreHandler0Map"),
|
||||
("RO_SPACE", 0x05b81): (222, "StoreHandler1Map"),
|
||||
("RO_SPACE", 0x05bd1): (222, "StoreHandler2Map"),
|
||||
("RO_SPACE", 0x05c21): (222, "StoreHandler3Map"),
|
||||
("RO_SPACE", 0x05101): (153, "AccessCheckInfoMap"),
|
||||
("RO_SPACE", 0x05151): (154, "AccessorInfoMap"),
|
||||
("RO_SPACE", 0x051a1): (155, "AccessorPairMap"),
|
||||
("RO_SPACE", 0x051f1): (156, "AliasedArgumentsEntryMap"),
|
||||
("RO_SPACE", 0x05241): (157, "AllocationMementoMap"),
|
||||
("RO_SPACE", 0x05291): (158, "AsyncGeneratorRequestMap"),
|
||||
("RO_SPACE", 0x052e1): (159, "DebugInfoMap"),
|
||||
("RO_SPACE", 0x05331): (160, "FunctionTemplateInfoMap"),
|
||||
("RO_SPACE", 0x05381): (162, "InterpreterDataMap"),
|
||||
("RO_SPACE", 0x053d1): (163, "ModuleInfoEntryMap"),
|
||||
("RO_SPACE", 0x05421): (164, "ModuleMap"),
|
||||
("RO_SPACE", 0x05471): (165, "ObjectTemplateInfoMap"),
|
||||
("RO_SPACE", 0x054c1): (166, "PromiseCapabilityMap"),
|
||||
("RO_SPACE", 0x05511): (167, "PromiseReactionMap"),
|
||||
("RO_SPACE", 0x05561): (168, "PrototypeInfoMap"),
|
||||
("RO_SPACE", 0x055b1): (169, "ScriptMap"),
|
||||
("RO_SPACE", 0x05601): (170, "StackFrameInfoMap"),
|
||||
("RO_SPACE", 0x05651): (172, "Tuple3Map"),
|
||||
("RO_SPACE", 0x056a1): (174, "WasmDebugInfoMap"),
|
||||
("RO_SPACE", 0x056f1): (175, "WasmExportedFunctionDataMap"),
|
||||
("RO_SPACE", 0x05741): (176, "CallableTaskMap"),
|
||||
("RO_SPACE", 0x05791): (177, "CallbackTaskMap"),
|
||||
("RO_SPACE", 0x057e1): (178, "PromiseFulfillReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x05831): (179, "PromiseRejectReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x05881): (180, "PromiseResolveThenableJobTaskMap"),
|
||||
("RO_SPACE", 0x058d1): (181, "WeakFactoryCleanupJobTaskMap"),
|
||||
("RO_SPACE", 0x05921): (182, "MicrotaskQueueMap"),
|
||||
("RO_SPACE", 0x05971): (183, "AllocationSiteWithWeakNextMap"),
|
||||
("RO_SPACE", 0x059c1): (183, "AllocationSiteWithoutWeakNextMap"),
|
||||
("RO_SPACE", 0x05a11): (215, "LoadHandler1Map"),
|
||||
("RO_SPACE", 0x05a61): (215, "LoadHandler2Map"),
|
||||
("RO_SPACE", 0x05ab1): (215, "LoadHandler3Map"),
|
||||
("RO_SPACE", 0x05b01): (222, "StoreHandler0Map"),
|
||||
("RO_SPACE", 0x05b51): (222, "StoreHandler1Map"),
|
||||
("RO_SPACE", 0x05ba1): (222, "StoreHandler2Map"),
|
||||
("RO_SPACE", 0x05bf1): (222, "StoreHandler3Map"),
|
||||
("MAP_SPACE", 0x00139): (1057, "ExternalMap"),
|
||||
("MAP_SPACE", 0x00189): (1073, "JSMessageObjectMap"),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user