Commit f4d48210 authored by Camillo Bruni's avatar Camillo Bruni Committed by V8 LUCI CQ

[runtime] Move CacheInitialArrayMaps to the bootstrapper

CacheInitialJSArrayMaps was called in the middle of
JSFunction::SetPrototype even though this only happens during
bootstrapping given that Array.prototype os non-configurable and
non-writable.

Changes:
- Rename CacheInitialArrayMaps to InitializeJSArrayMaps
- Add more explicit checks in InitializeJSArrayMaps to link back
  to the Context indices for better code searching


Change-Id: Iad6d20e3d67d715bfd6429037c75ac35ab7f399f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3571889Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79973}
parent 7830edd7
......@@ -1185,6 +1185,37 @@ void ReplaceAccessors(Isolate* isolate, Handle<Map> map, Handle<String> name,
Descriptor d = Descriptor::AccessorConstant(name, accessor_pair, attributes);
descriptors.Replace(entry, &d);
}
void InitializeJSArrayMaps(Isolate* isolate, Handle<Context> native_context,
Handle<Map> initial_map) {
// Replace all of the cached initial array maps in the native context with
// the appropriate transitioned elements kind maps.
Handle<Map> current_map = initial_map;
ElementsKind kind = current_map->elements_kind();
DCHECK_EQ(GetInitialFastElementsKind(), kind);
DCHECK_EQ(PACKED_SMI_ELEMENTS, kind);
DCHECK_EQ(Context::ArrayMapIndex(kind),
Context::JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX);
native_context->set(Context::ArrayMapIndex(kind), *current_map,
UPDATE_WRITE_BARRIER, kReleaseStore);
for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
i < kFastElementsKindCount; ++i) {
Handle<Map> new_map;
ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
Map maybe_elements_transition = current_map->ElementsTransitionMap(
isolate, ConcurrencyMode::kSynchronous);
if (!maybe_elements_transition.is_null()) {
new_map = handle(maybe_elements_transition, isolate);
} else {
new_map = Map::CopyAsElementsKind(isolate, current_map, next_kind,
INSERT_TRANSITION);
}
DCHECK_EQ(next_kind, new_map->elements_kind());
native_context->set(Context::ArrayMapIndex(next_kind), *new_map,
UPDATE_WRITE_BARRIER, kReleaseStore);
current_map = new_map;
}
}
} // namespace
void Genesis::AddRestrictedFunctionProperties(Handle<JSFunction> empty) {
......@@ -1710,8 +1741,10 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
Context::ARRAY_FUNCTION_INDEX);
InstallSpeciesGetter(isolate_, array_function);
// Cache the array maps, needed by ArrayConstructorStub
CacheInitialJSArrayMaps(isolate_, native_context(), initial_map);
// Create the initial array map for Array.prototype which is required by
// the used ArrayConstructorStub.
// This is repeated after properly instantiating the Array.prototype.
InitializeJSArrayMaps(isolate_, native_context(), initial_map);
// Set up %ArrayPrototype%.
// The %ArrayPrototype% has TERMINAL_FAST_ELEMENTS_KIND in order to ensure
......@@ -1722,6 +1755,10 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
JSFunction::SetPrototype(array_function, proto);
native_context()->set_initial_array_prototype(*proto);
InitializeJSArrayMaps(isolate_, native_context(),
handle(array_function->initial_map(), isolate_));
SimpleInstallFunction(isolate_, array_function, "isArray",
Builtin::kArrayIsArray, 1, true);
SimpleInstallFunction(isolate_, array_function, "from", Builtin::kArrayFrom,
......
......@@ -141,10 +141,6 @@ class JSArray : public TorqueGeneratedJSArray<JSArray, JSObject> {
TQ_OBJECT_CONSTRUCTORS(JSArray)
};
Handle<Object> CacheInitialJSArrayMaps(Isolate* isolate,
Handle<Context> native_context,
Handle<Map> initial_map);
// The JSArrayIterator describes JavaScript Array Iterators Objects, as
// defined in ES section #sec-array-iterator-objects.
class JSArrayIterator
......
......@@ -642,16 +642,8 @@ void SetInstancePrototype(Isolate* isolate, Handle<JSFunction> function,
Handle<Map> new_map =
Map::Copy(isolate, initial_map, "SetInstancePrototype");
JSFunction::SetInitialMap(isolate, function, new_map, value);
// If the function is used as the global Array function, cache the
// updated initial maps (and transitioned versions) in the native context.
Handle<Context> native_context(function->native_context(), isolate);
Handle<Object> array_function(
native_context->get(Context::ARRAY_FUNCTION_INDEX), isolate);
if (array_function->IsJSFunction() &&
*function == JSFunction::cast(*array_function)) {
CacheInitialJSArrayMaps(isolate, native_context, new_map);
}
DCHECK_IMPLIES(!isolate->bootstrapper()->IsActive(),
*function != function->native_context().array_function());
}
// Deoptimize all code that embeds the previous initial map.
......
......@@ -4774,36 +4774,6 @@ uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
return value;
}
Handle<Object> CacheInitialJSArrayMaps(Isolate* isolate,
Handle<Context> native_context,
Handle<Map> initial_map) {
// Replace all of the cached initial array maps in the native context with
// the appropriate transitioned elements kind maps.
Handle<Map> current_map = initial_map;
ElementsKind kind = current_map->elements_kind();
DCHECK_EQ(GetInitialFastElementsKind(), kind);
native_context->set(Context::ArrayMapIndex(kind), *current_map,
UPDATE_WRITE_BARRIER, kReleaseStore);
for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
i < kFastElementsKindCount; ++i) {
Handle<Map> new_map;
ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
Map maybe_elements_transition = current_map->ElementsTransitionMap(
isolate, ConcurrencyMode::kSynchronous);
if (!maybe_elements_transition.is_null()) {
new_map = handle(maybe_elements_transition, isolate);
} else {
new_map = Map::CopyAsElementsKind(isolate, current_map, next_kind,
INSERT_TRANSITION);
}
DCHECK_EQ(next_kind, new_map->elements_kind());
native_context->set(Context::ArrayMapIndex(next_kind), *new_map,
UPDATE_WRITE_BARRIER, kReleaseStore);
current_map = new_map;
}
return initial_map;
}
STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
Oddball::kToNumberRawOffset);
......
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