[compiler] Rewrite JSGlobalObjectRef::IsDetached

Call it NativeContextRef::GlobalIsDetached and implement it on top of
Refs such that it can benefit from direct reads.

Drive-by: inline a JSNativeContextSpecialization::ReduceGlobalAccess
overload into its only callsite.

Bug: v8:7790
Change-Id: I1c6891e0fc65a476b0c4587f3fde2c6461b302a4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2959614
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75454}
This commit is contained in:
Jakob Gruber 2021-06-30 09:46:10 +02:00 committed by V8 LUCI CQ
parent e6371af86a
commit 01b0a6a987
5 changed files with 26 additions and 25 deletions

View File

@ -3397,8 +3397,6 @@ BIMODAL_ACCESSOR(JSFunction, SharedFunctionInfo, shared)
BIMODAL_ACCESSOR(JSFunction, FeedbackCell, raw_feedback_cell)
BIMODAL_ACCESSOR(JSFunction, FeedbackVector, feedback_vector)
BIMODAL_ACCESSOR_C(JSGlobalObject, bool, IsDetached)
BIMODAL_ACCESSOR_WITH_FLAG_B(Map, bit_field2, elements_kind,
Map::Bits2::ElementsKindBits)
BIMODAL_ACCESSOR_WITH_FLAG_B(Map, bit_field3, is_dictionary_map,
@ -3634,8 +3632,8 @@ DescriptorArrayRef MapRef::instance_descriptors() const {
base::Optional<HeapObjectRef> MapRef::prototype() const {
if (data_->should_access_heap() || broker()->is_concurrent_inlining()) {
return MakeRefAssumeMemoryFence(broker(),
HeapObject::cast(object()->prototype()));
return TryMakeRef(broker(), HeapObject::cast(object()->prototype()),
kAssumeMemoryFence);
}
ObjectData* prototype_data = data()->AsMap()->prototype();
if (prototype_data == nullptr) {
@ -4653,6 +4651,12 @@ void FunctionTemplateInfoRef::SerializeCallCode() {
data()->AsFunctionTemplateInfo()->SerializeCallCode(broker());
}
bool NativeContextRef::GlobalIsDetached() const {
base::Optional<ObjectRef> proxy_proto =
global_proxy_object().map().prototype();
return !proxy_proto.has_value() || !proxy_proto->equals(global_object());
}
base::Optional<PropertyCellRef> JSGlobalObjectRef::GetPropertyCell(
NameRef const& name, SerializationPolicy policy) const {
if (data_->should_access_heap()) {

View File

@ -559,6 +559,7 @@ class NativeContextRef : public ContextRef {
MapRef GetFunctionMapFromIndex(int index) const;
MapRef GetInitialJSArrayMap(ElementsKind kind) const;
base::Optional<JSFunctionRef> GetConstructorFunction(const MapRef& map) const;
bool GlobalIsDetached() const;
};
class NameRef : public HeapObjectRef {
@ -1020,7 +1021,7 @@ class JSGlobalObjectRef : public JSObjectRef {
Handle<JSGlobalObject> object() const;
bool IsDetached() const;
bool IsDetachedFrom(JSGlobalProxyRef const& proxy) const;
// If {serialize} is false:
// If the property is known to exist as a property cell (on the global

View File

@ -783,17 +783,6 @@ FieldAccess ForPropertyCellValue(MachineRepresentation representation,
} // namespace
Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
Node* node, Node* lookup_start_object, Node* receiver, Node* value,
NameRef const& name, AccessMode access_mode, Node* key, Node* effect) {
base::Optional<PropertyCellRef> cell =
native_context().global_object().GetPropertyCell(name);
return cell.has_value()
? ReduceGlobalAccess(node, lookup_start_object, receiver, value,
name, access_mode, key, *cell, effect)
: NoChange();
}
// TODO(neis): Try to merge this with ReduceNamedAccess by introducing a new
// PropertyAccessInfo kind for global accesses and using the existing mechanism
// for building loads/stores.
@ -855,12 +844,14 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
// If we have a {lookup_start_object} to validate, we do so by checking that
// its map is the (target) global proxy's map. This guarantees that in fact
// the lookup start object is the global proxy.
// Note: we rely on the map constant below being the same as what is used in
// NativeContextRef::GlobalIsDetached().
if (lookup_start_object != nullptr) {
effect = graph()->NewNode(
simplified()->CheckMaps(
CheckMapsFlag::kNone,
ZoneHandleSet<Map>(
MakeRef(broker(), global_proxy()).map().object())),
native_context().global_proxy_object().map().object())),
lookup_start_object, effect, control);
}
@ -1186,10 +1177,17 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
MapRef lookup_start_object_map =
MakeRef(broker(), lookup_start_object_maps[0]);
if (lookup_start_object_map.equals(
broker()->target_native_context().global_proxy_object().map()) &&
!broker()->target_native_context().global_object().IsDetached()) {
return ReduceGlobalAccess(node, lookup_start_object, receiver, value,
feedback.name(), access_mode, key, effect);
native_context().global_proxy_object().map())) {
if (!native_context().GlobalIsDetached()) {
base::Optional<PropertyCellRef> cell =
native_context().global_object().GetPropertyCell(feedback.name());
if (!cell.has_value()) return NoChange();
// Note: The map check generated by ReduceGlobalAccesses ensures that we
// will deopt when/if GlobalIsDetached becomes true.
return ReduceGlobalAccess(node, lookup_start_object, receiver, value,
feedback.name(), access_mode, key, *cell,
effect);
}
}
}

View File

@ -110,10 +110,6 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
Node* node, Node* value,
MinimorphicLoadPropertyAccessFeedback const& feedback,
FeedbackSource const& source);
Reduction ReduceGlobalAccess(Node* node, Node* lookup_start_object,
Node* receiver, Node* value, NameRef const& name,
AccessMode access_mode, Node* key = nullptr,
Node* effect = nullptr);
Reduction ReduceGlobalAccess(Node* node, Node* lookup_start_object,
Node* receiver, Node* value, NameRef const& name,
AccessMode access_mode, Node* key,

View File

@ -368,6 +368,8 @@ void Bootstrapper::DetachGlobal(Handle<Context> env) {
ReadOnlyRoots roots(isolate_);
Handle<JSGlobalProxy> global_proxy(env->global_proxy(), isolate_);
global_proxy->set_native_context(roots.null_value());
// NOTE: Turbofan's JSNativeContextSpecialization depends on DetachGlobal
// causing a map change.
JSObject::ForceSetPrototype(isolate_, global_proxy,
isolate_->factory()->null_value());
global_proxy->map().SetConstructor(roots.null_value());