Commit 01b0a6a9 authored by Jakob Gruber's avatar Jakob Gruber Committed by V8 LUCI CQ

[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/+/2959614Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75454}
parent e6371af8
...@@ -3397,8 +3397,6 @@ BIMODAL_ACCESSOR(JSFunction, SharedFunctionInfo, shared) ...@@ -3397,8 +3397,6 @@ BIMODAL_ACCESSOR(JSFunction, SharedFunctionInfo, shared)
BIMODAL_ACCESSOR(JSFunction, FeedbackCell, raw_feedback_cell) BIMODAL_ACCESSOR(JSFunction, FeedbackCell, raw_feedback_cell)
BIMODAL_ACCESSOR(JSFunction, FeedbackVector, feedback_vector) BIMODAL_ACCESSOR(JSFunction, FeedbackVector, feedback_vector)
BIMODAL_ACCESSOR_C(JSGlobalObject, bool, IsDetached)
BIMODAL_ACCESSOR_WITH_FLAG_B(Map, bit_field2, elements_kind, BIMODAL_ACCESSOR_WITH_FLAG_B(Map, bit_field2, elements_kind,
Map::Bits2::ElementsKindBits) Map::Bits2::ElementsKindBits)
BIMODAL_ACCESSOR_WITH_FLAG_B(Map, bit_field3, is_dictionary_map, BIMODAL_ACCESSOR_WITH_FLAG_B(Map, bit_field3, is_dictionary_map,
...@@ -3634,8 +3632,8 @@ DescriptorArrayRef MapRef::instance_descriptors() const { ...@@ -3634,8 +3632,8 @@ DescriptorArrayRef MapRef::instance_descriptors() const {
base::Optional<HeapObjectRef> MapRef::prototype() const { base::Optional<HeapObjectRef> MapRef::prototype() const {
if (data_->should_access_heap() || broker()->is_concurrent_inlining()) { if (data_->should_access_heap() || broker()->is_concurrent_inlining()) {
return MakeRefAssumeMemoryFence(broker(), return TryMakeRef(broker(), HeapObject::cast(object()->prototype()),
HeapObject::cast(object()->prototype())); kAssumeMemoryFence);
} }
ObjectData* prototype_data = data()->AsMap()->prototype(); ObjectData* prototype_data = data()->AsMap()->prototype();
if (prototype_data == nullptr) { if (prototype_data == nullptr) {
...@@ -4653,6 +4651,12 @@ void FunctionTemplateInfoRef::SerializeCallCode() { ...@@ -4653,6 +4651,12 @@ void FunctionTemplateInfoRef::SerializeCallCode() {
data()->AsFunctionTemplateInfo()->SerializeCallCode(broker()); 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( base::Optional<PropertyCellRef> JSGlobalObjectRef::GetPropertyCell(
NameRef const& name, SerializationPolicy policy) const { NameRef const& name, SerializationPolicy policy) const {
if (data_->should_access_heap()) { if (data_->should_access_heap()) {
......
...@@ -559,6 +559,7 @@ class NativeContextRef : public ContextRef { ...@@ -559,6 +559,7 @@ class NativeContextRef : public ContextRef {
MapRef GetFunctionMapFromIndex(int index) const; MapRef GetFunctionMapFromIndex(int index) const;
MapRef GetInitialJSArrayMap(ElementsKind kind) const; MapRef GetInitialJSArrayMap(ElementsKind kind) const;
base::Optional<JSFunctionRef> GetConstructorFunction(const MapRef& map) const; base::Optional<JSFunctionRef> GetConstructorFunction(const MapRef& map) const;
bool GlobalIsDetached() const;
}; };
class NameRef : public HeapObjectRef { class NameRef : public HeapObjectRef {
...@@ -1020,7 +1021,7 @@ class JSGlobalObjectRef : public JSObjectRef { ...@@ -1020,7 +1021,7 @@ class JSGlobalObjectRef : public JSObjectRef {
Handle<JSGlobalObject> object() const; Handle<JSGlobalObject> object() const;
bool IsDetached() const; bool IsDetachedFrom(JSGlobalProxyRef const& proxy) const;
// If {serialize} is false: // If {serialize} is false:
// If the property is known to exist as a property cell (on the global // If the property is known to exist as a property cell (on the global
......
...@@ -783,17 +783,6 @@ FieldAccess ForPropertyCellValue(MachineRepresentation representation, ...@@ -783,17 +783,6 @@ FieldAccess ForPropertyCellValue(MachineRepresentation representation,
} // namespace } // 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 // TODO(neis): Try to merge this with ReduceNamedAccess by introducing a new
// PropertyAccessInfo kind for global accesses and using the existing mechanism // PropertyAccessInfo kind for global accesses and using the existing mechanism
// for building loads/stores. // for building loads/stores.
...@@ -855,12 +844,14 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess( ...@@ -855,12 +844,14 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
// If we have a {lookup_start_object} to validate, we do so by checking that // 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 // its map is the (target) global proxy's map. This guarantees that in fact
// the lookup start object is the global proxy. // 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) { if (lookup_start_object != nullptr) {
effect = graph()->NewNode( effect = graph()->NewNode(
simplified()->CheckMaps( simplified()->CheckMaps(
CheckMapsFlag::kNone, CheckMapsFlag::kNone,
ZoneHandleSet<Map>( ZoneHandleSet<Map>(
MakeRef(broker(), global_proxy()).map().object())), native_context().global_proxy_object().map().object())),
lookup_start_object, effect, control); lookup_start_object, effect, control);
} }
...@@ -1186,10 +1177,17 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( ...@@ -1186,10 +1177,17 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
MapRef lookup_start_object_map = MapRef lookup_start_object_map =
MakeRef(broker(), lookup_start_object_maps[0]); MakeRef(broker(), lookup_start_object_maps[0]);
if (lookup_start_object_map.equals( if (lookup_start_object_map.equals(
broker()->target_native_context().global_proxy_object().map()) && native_context().global_proxy_object().map())) {
!broker()->target_native_context().global_object().IsDetached()) { 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, return ReduceGlobalAccess(node, lookup_start_object, receiver, value,
feedback.name(), access_mode, key, effect); feedback.name(), access_mode, key, *cell,
effect);
}
} }
} }
......
...@@ -110,10 +110,6 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final ...@@ -110,10 +110,6 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
Node* node, Node* value, Node* node, Node* value,
MinimorphicLoadPropertyAccessFeedback const& feedback, MinimorphicLoadPropertyAccessFeedback const& feedback,
FeedbackSource const& source); 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, Reduction ReduceGlobalAccess(Node* node, Node* lookup_start_object,
Node* receiver, Node* value, NameRef const& name, Node* receiver, Node* value, NameRef const& name,
AccessMode access_mode, Node* key, AccessMode access_mode, Node* key,
......
...@@ -368,6 +368,8 @@ void Bootstrapper::DetachGlobal(Handle<Context> env) { ...@@ -368,6 +368,8 @@ void Bootstrapper::DetachGlobal(Handle<Context> env) {
ReadOnlyRoots roots(isolate_); ReadOnlyRoots roots(isolate_);
Handle<JSGlobalProxy> global_proxy(env->global_proxy(), isolate_); Handle<JSGlobalProxy> global_proxy(env->global_proxy(), isolate_);
global_proxy->set_native_context(roots.null_value()); global_proxy->set_native_context(roots.null_value());
// NOTE: Turbofan's JSNativeContextSpecialization depends on DetachGlobal
// causing a map change.
JSObject::ForceSetPrototype(isolate_, global_proxy, JSObject::ForceSetPrototype(isolate_, global_proxy,
isolate_->factory()->null_value()); isolate_->factory()->null_value());
global_proxy->map().SetConstructor(roots.null_value()); global_proxy->map().SetConstructor(roots.null_value());
......
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