[debug][wasm] Store debug proxy maps on native context.

This was originally proposed by yangguo@ on the original CL that
introduced this, but back then it looked easier to put the map cache
onto the global object than on the native context. However it turns out
that this is indeed quite strange and also not necessarily supported (we
got crashes from the wild indicating that the `Object::GetProperty()`
might fail on the global object). So this CL simplifies the original
design and just puts the map cache onto the native context like with do
with other context specific maps.

Fixed: chromium:1167399
Bug: chromium:1127914, chromium:1159402, chromium:1071432, chromium:1164241
Change-Id: Ie16f892dd19b55b4c49e9d4829cab3c24ae64ad3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2637226
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Auto-Submit: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72159}
This commit is contained in:
Benedikt Meurer 2021-01-19 15:05:14 +01:00 committed by Commit Bot
parent 3ad2342415
commit 975ded1d3d
3 changed files with 27 additions and 24 deletions

View File

@ -124,26 +124,6 @@ enum DebugProxyId {
kNumInstanceProxies = kLastInstanceProxyId + 1
};
// Creates a FixedArray with the given |length| as cache on-demand on
// the |object|, stored under the |wasm_debug_proxy_cache_symbol|.
// This is currently used to cache the debug proxy object maps on the
// JSGlobalObject (per native context), and various debug proxy objects
// (functions, globals, tables, and memories) on the WasmInstanceObject.
Handle<FixedArray> GetOrCreateDebugProxyCache(Isolate* isolate,
Handle<Object> object,
int length) {
Handle<Object> cache;
Handle<Symbol> symbol = isolate->factory()->wasm_debug_proxy_cache_symbol();
if (!Object::GetProperty(isolate, object, symbol).ToHandle(&cache) ||
cache->IsUndefined(isolate)) {
cache = isolate->factory()->NewFixedArrayWithHoles(length);
Object::SetProperty(isolate, object, symbol, cache).Check();
} else {
DCHECK_EQ(length, Handle<FixedArray>::cast(cache)->length());
}
return Handle<FixedArray>::cast(cache);
}
// Creates a Map for the given debug proxy |id| using the |create_template_fn|
// on-demand and caches this map in the global object. The map is derived from
// the FunctionTemplate returned by |create_template_fn| and has it's prototype
@ -151,8 +131,12 @@ Handle<FixedArray> GetOrCreateDebugProxyCache(Isolate* isolate,
Handle<Map> GetOrCreateDebugProxyMap(
Isolate* isolate, DebugProxyId id,
v8::Local<v8::FunctionTemplate> (*create_template_fn)(v8::Isolate*)) {
Handle<FixedArray> maps = GetOrCreateDebugProxyCache(
isolate, isolate->global_object(), kNumProxies);
Handle<FixedArray> maps = isolate->wasm_debug_proxy_maps();
if (maps->length() == 0) {
maps = isolate->factory()->NewFixedArrayWithHoles(kNumProxies);
isolate->native_context()->set_wasm_debug_proxy_maps(*maps);
}
CHECK_EQ(kNumProxies, maps->length());
if (!maps->is_the_hole(isolate, id)) {
return handle(Map::cast(maps->get(id)), isolate);
}
@ -539,14 +523,29 @@ struct StackProxy : IndexedDebugProxy<StackProxy, kStackProxy, FixedArray> {
}
};
// Creates FixedArray with size |kNumInstanceProxies| as cache on-demand
// on the |instance|, stored under the |wasm_debug_proxy_cache_symbol|.
// This is used to cache the various instance debug proxies (functions,
// globals, tables, and memories) on the WasmInstanceObject.
Handle<FixedArray> GetOrCreateInstanceProxyCache(
Isolate* isolate, Handle<WasmInstanceObject> instance) {
Handle<Object> cache;
Handle<Symbol> symbol = isolate->factory()->wasm_debug_proxy_cache_symbol();
if (!Object::GetProperty(isolate, instance, symbol).ToHandle(&cache) ||
cache->IsUndefined(isolate)) {
cache = isolate->factory()->NewFixedArrayWithHoles(kNumInstanceProxies);
Object::SetProperty(isolate, instance, symbol, cache).Check();
}
return Handle<FixedArray>::cast(cache);
}
// Creates an instance of the |Proxy| on-demand and caches that on the
// |instance|.
template <typename Proxy>
Handle<JSObject> GetOrCreateInstanceProxy(Isolate* isolate,
Handle<WasmInstanceObject> instance) {
STATIC_ASSERT(Proxy::kId < kNumInstanceProxies);
Handle<FixedArray> proxies =
GetOrCreateDebugProxyCache(isolate, instance, kNumInstanceProxies);
Handle<FixedArray> proxies = GetOrCreateInstanceProxyCache(isolate, instance);
if (!proxies->is_the_hole(isolate, Proxy::kId)) {
return handle(JSObject::cast(proxies->get(Proxy::kId)), isolate);
}

View File

@ -4630,6 +4630,9 @@ bool Genesis::InstallABunchOfRandomThings() {
native_context()->set_slow_template_instantiations_cache(
*slow_template_instantiations_cache);
auto wasm_debug_proxy_maps = isolate()->factory()->empty_fixed_array();
native_context()->set_wasm_debug_proxy_maps(*wasm_debug_proxy_maps);
// Store the map for the %ObjectPrototype% after the natives has been compiled
// and the Object function has been set up.
{

View File

@ -236,6 +236,7 @@ enum ContextLookupFlags {
V(SLOW_TEMPLATE_INSTANTIATIONS_CACHE_INDEX, SimpleNumberDictionary, \
slow_template_instantiations_cache) \
V(ATOMICS_WAITASYNC_PROMISES, OrderedHashSet, atomics_waitasync_promises) \
V(WASM_DEBUG_PROXY_MAPS, FixedArray, wasm_debug_proxy_maps) \
/* Fast Path Protectors */ \
V(REGEXP_SPECIES_PROTECTOR_INDEX, PropertyCell, regexp_species_protector) \
/* All *_FUNCTION_MAP_INDEX definitions used by Context::FunctionMapIndex */ \