Commit d7fb4a64 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Basic brokerization for ReduceNamedAccess

Bug: v8:7790
Change-Id: I65e050929a45c3391c5c9c9b0d814ae536664cf4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1564067
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60828}
parent 20a93efe
...@@ -3787,7 +3787,7 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) { ...@@ -3787,7 +3787,7 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
// Try to specialize JSConstruct {node}s with constant {target}s. // Try to specialize JSConstruct {node}s with constant {target}s.
HeapObjectMatcher m(target); HeapObjectMatcher m(target);
if (m.HasValue()) { if (m.HasValue()) {
HeapObjectRef target_ref = m.Ref(broker()).AsHeapObject(); HeapObjectRef target_ref = m.Ref(broker());
// Raise a TypeError if the {target} is not a constructor. // Raise a TypeError if the {target} is not a constructor.
if (!target_ref.map().is_constructor()) { if (!target_ref.map().is_constructor()) {
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <algorithm> #include <algorithm>
#endif #endif
#include "src/api-inl.h"
#include "src/ast/modules.h" #include "src/ast/modules.h"
#include "src/bootstrapper.h" #include "src/bootstrapper.h"
#include "src/boxed-float.h" #include "src/boxed-float.h"
...@@ -16,6 +17,7 @@ ...@@ -16,6 +17,7 @@
#include "src/compiler/per-isolate-compiler-cache.h" #include "src/compiler/per-isolate-compiler-cache.h"
#include "src/objects-inl.h" #include "src/objects-inl.h"
#include "src/objects/allocation-site-inl.h" #include "src/objects/allocation-site-inl.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/cell-inl.h" #include "src/objects/cell-inl.h"
#include "src/objects/heap-number-inl.h" #include "src/objects/heap-number-inl.h"
#include "src/objects/instance-type-inl.h" #include "src/objects/instance-type-inl.h"
...@@ -23,6 +25,7 @@ ...@@ -23,6 +25,7 @@
#include "src/objects/js-array-inl.h" #include "src/objects/js-array-inl.h"
#include "src/objects/js-regexp-inl.h" #include "src/objects/js-regexp-inl.h"
#include "src/objects/module-inl.h" #include "src/objects/module-inl.h"
#include "src/objects/templates.h"
#include "src/utils.h" #include "src/utils.h"
#include "src/vector-slot-pair.h" #include "src/vector-slot-pair.h"
...@@ -108,7 +111,7 @@ class PropertyCellData : public HeapObjectData { ...@@ -108,7 +111,7 @@ class PropertyCellData : public HeapObjectData {
PropertyDetails property_details() const { return property_details_; } PropertyDetails property_details() const { return property_details_; }
void Serialize(JSHeapBroker* broker); void Serialize(JSHeapBroker* broker);
ObjectData* value() { return value_; } ObjectData* value() const { return value_; }
private: private:
PropertyDetails const property_details_; PropertyDetails const property_details_;
...@@ -117,6 +120,47 @@ class PropertyCellData : public HeapObjectData { ...@@ -117,6 +120,47 @@ class PropertyCellData : public HeapObjectData {
ObjectData* value_ = nullptr; ObjectData* value_ = nullptr;
}; };
class FunctionTemplateInfoData : public HeapObjectData {
public:
FunctionTemplateInfoData(JSHeapBroker* broker, ObjectData** storage,
Handle<FunctionTemplateInfo> object);
void Serialize(JSHeapBroker* broker);
ObjectData* call_code() const { return call_code_; }
private:
bool serialized_ = false;
ObjectData* call_code_ = nullptr;
};
class CallHandlerInfoData : public HeapObjectData {
public:
CallHandlerInfoData(JSHeapBroker* broker, ObjectData** storage,
Handle<CallHandlerInfo> object);
Address callback() const { return callback_; }
void Serialize(JSHeapBroker* broker);
ObjectData* data() const { return data_; }
private:
Address const callback_;
bool serialized_ = false;
ObjectData* data_ = nullptr;
};
FunctionTemplateInfoData::FunctionTemplateInfoData(
JSHeapBroker* broker, ObjectData** storage,
Handle<FunctionTemplateInfo> object)
: HeapObjectData(broker, storage, object) {}
CallHandlerInfoData::CallHandlerInfoData(JSHeapBroker* broker,
ObjectData** storage,
Handle<CallHandlerInfo> object)
: HeapObjectData(broker, storage, object),
callback_(v8::ToCData<Address>(object->callback())) {}
void JSHeapBroker::IncrementTracingIndentation() { ++trace_indentation_; } void JSHeapBroker::IncrementTracingIndentation() { ++trace_indentation_; }
void JSHeapBroker::DecrementTracingIndentation() { --trace_indentation_; } void JSHeapBroker::DecrementTracingIndentation() { --trace_indentation_; }
...@@ -156,6 +200,30 @@ void PropertyCellData::Serialize(JSHeapBroker* broker) { ...@@ -156,6 +200,30 @@ void PropertyCellData::Serialize(JSHeapBroker* broker) {
value_ = broker->GetOrCreateData(cell->value()); value_ = broker->GetOrCreateData(cell->value());
} }
void FunctionTemplateInfoData::Serialize(JSHeapBroker* broker) {
if (serialized_) return;
serialized_ = true;
TraceScope tracer(broker, this, "FunctionTemplateInfoData::Serialize");
auto function_template_info = Handle<FunctionTemplateInfo>::cast(object());
DCHECK_NULL(call_code_);
call_code_ = broker->GetOrCreateData(function_template_info->call_code());
if (call_code_->IsCallHandlerInfo()) {
call_code_->AsCallHandlerInfo()->Serialize(broker);
}
}
void CallHandlerInfoData::Serialize(JSHeapBroker* broker) {
if (serialized_) return;
serialized_ = true;
TraceScope tracer(broker, this, "CallHandlerInfoData::Serialize");
auto call_handler_info = Handle<CallHandlerInfo>::cast(object());
DCHECK_NULL(data_);
data_ = broker->GetOrCreateData(call_handler_info->data());
}
class JSObjectField { class JSObjectField {
public: public:
bool IsDouble() const { return object_ == nullptr; } bool IsDouble() const { return object_ == nullptr; }
...@@ -799,6 +867,12 @@ class MapData : public HeapObjectData { ...@@ -799,6 +867,12 @@ class MapData : public HeapObjectData {
return constructor_; return constructor_;
} }
void SerializeBackPointer(JSHeapBroker* broker);
HeapObjectData* GetBackPointer() const {
CHECK(serialized_backpointer_);
return backpointer_;
}
void SerializePrototype(JSHeapBroker* broker); void SerializePrototype(JSHeapBroker* broker);
bool serialized_prototype() const { return serialized_prototype_; } bool serialized_prototype() const { return serialized_prototype_; }
ObjectData* prototype() const { ObjectData* prototype() const {
...@@ -836,6 +910,9 @@ class MapData : public HeapObjectData { ...@@ -836,6 +910,9 @@ class MapData : public HeapObjectData {
bool serialized_constructor_ = false; bool serialized_constructor_ = false;
ObjectData* constructor_ = nullptr; ObjectData* constructor_ = nullptr;
bool serialized_backpointer_ = false;
HeapObjectData* backpointer_ = nullptr;
bool serialized_prototype_ = false; bool serialized_prototype_ = false;
ObjectData* prototype_ = nullptr; ObjectData* prototype_ = nullptr;
...@@ -1554,6 +1631,16 @@ void MapData::SerializeConstructor(JSHeapBroker* broker) { ...@@ -1554,6 +1631,16 @@ void MapData::SerializeConstructor(JSHeapBroker* broker) {
constructor_ = broker->GetOrCreateData(map->GetConstructor()); constructor_ = broker->GetOrCreateData(map->GetConstructor());
} }
void MapData::SerializeBackPointer(JSHeapBroker* broker) {
if (serialized_backpointer_) return;
serialized_backpointer_ = true;
TraceScope tracer(broker, this, "MapData::SerializeBackPointer");
Handle<Map> map = Handle<Map>::cast(object());
DCHECK_NULL(backpointer_);
backpointer_ = broker->GetOrCreateData(map->GetBackPointer())->AsHeapObject();
}
void MapData::SerializePrototype(JSHeapBroker* broker) { void MapData::SerializePrototype(JSHeapBroker* broker) {
if (serialized_prototype_) return; if (serialized_prototype_) return;
serialized_prototype_ = true; serialized_prototype_ = true;
...@@ -2541,6 +2628,7 @@ BIMODAL_ACCESSOR_C(Map, int, UnusedPropertyFields) ...@@ -2541,6 +2628,7 @@ BIMODAL_ACCESSOR_C(Map, int, UnusedPropertyFields)
BIMODAL_ACCESSOR(Map, HeapObject, prototype) BIMODAL_ACCESSOR(Map, HeapObject, prototype)
BIMODAL_ACCESSOR_C(Map, InstanceType, instance_type) BIMODAL_ACCESSOR_C(Map, InstanceType, instance_type)
BIMODAL_ACCESSOR(Map, Object, GetConstructor) BIMODAL_ACCESSOR(Map, Object, GetConstructor)
BIMODAL_ACCESSOR(Map, HeapObject, GetBackPointer)
#define DEF_NATIVE_CONTEXT_ACCESSOR(type, name) \ #define DEF_NATIVE_CONTEXT_ACCESSOR(type, name) \
BIMODAL_ACCESSOR(NativeContext, type, name) BIMODAL_ACCESSOR(NativeContext, type, name)
...@@ -2550,6 +2638,10 @@ BROKER_NATIVE_CONTEXT_FIELDS(DEF_NATIVE_CONTEXT_ACCESSOR) ...@@ -2550,6 +2638,10 @@ BROKER_NATIVE_CONTEXT_FIELDS(DEF_NATIVE_CONTEXT_ACCESSOR)
BIMODAL_ACCESSOR(PropertyCell, Object, value) BIMODAL_ACCESSOR(PropertyCell, Object, value)
BIMODAL_ACCESSOR_C(PropertyCell, PropertyDetails, property_details) BIMODAL_ACCESSOR_C(PropertyCell, PropertyDetails, property_details)
BIMODAL_ACCESSOR(FunctionTemplateInfo, Object, call_code)
BIMODAL_ACCESSOR(CallHandlerInfo, Object, data)
BIMODAL_ACCESSOR_C(SharedFunctionInfo, int, builtin_id) BIMODAL_ACCESSOR_C(SharedFunctionInfo, int, builtin_id)
BIMODAL_ACCESSOR(SharedFunctionInfo, BytecodeArray, GetBytecodeArray) BIMODAL_ACCESSOR(SharedFunctionInfo, BytecodeArray, GetBytecodeArray)
#define DEF_SFI_ACCESSOR(type, name) \ #define DEF_SFI_ACCESSOR(type, name) \
...@@ -2615,6 +2707,13 @@ bool StringRef::IsExternalString() const { ...@@ -2615,6 +2707,13 @@ bool StringRef::IsExternalString() const {
return data()->AsString()->is_external_string(); return data()->AsString()->is_external_string();
} }
Address CallHandlerInfoRef::callback() const {
if (broker()->mode() == JSHeapBroker::kDisabled) {
return v8::ToCData<Address>(object()->callback());
}
return HeapObjectRef::data()->AsCallHandlerInfo()->callback();
}
bool StringRef::IsSeqString() const { bool StringRef::IsSeqString() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(String, IsSeqString); IF_BROKER_DISABLED_ACCESS_HANDLE_C(String, IsSeqString);
return data()->AsString()->is_seq_string(); return data()->AsString()->is_seq_string();
...@@ -2888,6 +2987,11 @@ void FeedbackVectorRef::SerializeSlots() { ...@@ -2888,6 +2987,11 @@ void FeedbackVectorRef::SerializeSlots() {
data()->AsFeedbackVector()->SerializeSlots(broker()); data()->AsFeedbackVector()->SerializeSlots(broker());
} }
bool NameRef::IsUniqueName() const {
// Must match Name::IsUniqueName.
return IsInternalizedString() || IsSymbol();
}
ObjectRef JSRegExpRef::data() const { ObjectRef JSRegExpRef::data() const {
IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, data); IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, data);
return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->data()); return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->data());
...@@ -3027,6 +3131,12 @@ void MapRef::SerializeOwnDescriptors() { ...@@ -3027,6 +3131,12 @@ void MapRef::SerializeOwnDescriptors() {
data()->AsMap()->SerializeOwnDescriptors(broker()); data()->AsMap()->SerializeOwnDescriptors(broker());
} }
void MapRef::SerializeBackPointer() {
if (broker()->mode() == JSHeapBroker::kDisabled) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsMap()->SerializeBackPointer(broker());
}
void MapRef::SerializePrototype() { void MapRef::SerializePrototype() {
if (broker()->mode() == JSHeapBroker::kDisabled) return; if (broker()->mode() == JSHeapBroker::kDisabled) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
...@@ -3085,6 +3195,12 @@ void PropertyCellRef::Serialize() { ...@@ -3085,6 +3195,12 @@ void PropertyCellRef::Serialize() {
data()->AsPropertyCell()->Serialize(broker()); data()->AsPropertyCell()->Serialize(broker());
} }
void FunctionTemplateInfoRef::Serialize() {
if (broker()->mode() == JSHeapBroker::kDisabled) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsFunctionTemplateInfo()->Serialize(broker());
}
base::Optional<PropertyCellRef> JSGlobalProxyRef::GetPropertyCell( base::Optional<PropertyCellRef> JSGlobalProxyRef::GetPropertyCell(
NameRef const& name, bool serialize) const { NameRef const& name, bool serialize) const {
if (broker()->mode() == JSHeapBroker::kDisabled) { if (broker()->mode() == JSHeapBroker::kDisabled) {
......
...@@ -21,8 +21,9 @@ namespace v8 { ...@@ -21,8 +21,9 @@ namespace v8 {
namespace internal { namespace internal {
class BytecodeArray; class BytecodeArray;
class VectorSlotPair; class CallHandlerInfo;
class FixedDoubleArray; class FixedDoubleArray;
class FunctionTemplateInfo;
class HeapNumber; class HeapNumber;
class InternalizedString; class InternalizedString;
class JSBoundFunction; class JSBoundFunction;
...@@ -32,6 +33,7 @@ class JSRegExp; ...@@ -32,6 +33,7 @@ class JSRegExp;
class JSTypedArray; class JSTypedArray;
class NativeContext; class NativeContext;
class ScriptContextTable; class ScriptContextTable;
class VectorSlotPair;
namespace compiler { namespace compiler {
...@@ -72,11 +74,13 @@ enum class OddballType : uint8_t { ...@@ -72,11 +74,13 @@ enum class OddballType : uint8_t {
V(Symbol) \ V(Symbol) \
/* Subtypes of HeapObject */ \ /* Subtypes of HeapObject */ \
V(AllocationSite) \ V(AllocationSite) \
V(CallHandlerInfo) \
V(Cell) \ V(Cell) \
V(Code) \ V(Code) \
V(DescriptorArray) \ V(DescriptorArray) \
V(FeedbackVector) \ V(FeedbackVector) \
V(FixedArrayBase) \ V(FixedArrayBase) \
V(FunctionTemplateInfo) \
V(HeapNumber) \ V(HeapNumber) \
V(JSObject) \ V(JSObject) \
V(Map) \ V(Map) \
...@@ -377,6 +381,8 @@ class NameRef : public HeapObjectRef { ...@@ -377,6 +381,8 @@ class NameRef : public HeapObjectRef {
public: public:
using HeapObjectRef::HeapObjectRef; using HeapObjectRef::HeapObjectRef;
Handle<Name> object() const; Handle<Name> object() const;
bool IsUniqueName() const;
}; };
class ScriptContextTableRef : public HeapObjectRef { class ScriptContextTableRef : public HeapObjectRef {
...@@ -409,6 +415,26 @@ class FeedbackVectorRef : public HeapObjectRef { ...@@ -409,6 +415,26 @@ class FeedbackVectorRef : public HeapObjectRef {
void SerializeSlots(); void SerializeSlots();
}; };
class FunctionTemplateInfoRef : public HeapObjectRef {
public:
using HeapObjectRef::HeapObjectRef;
Handle<FunctionTemplateInfo> object() const;
void Serialize();
ObjectRef call_code() const;
};
class CallHandlerInfoRef : public HeapObjectRef {
public:
using HeapObjectRef::HeapObjectRef;
Handle<CallHandlerInfo> object() const;
Address callback() const;
void Serialize();
ObjectRef data() const;
};
class AllocationSiteRef : public HeapObjectRef { class AllocationSiteRef : public HeapObjectRef {
public: public:
using HeapObjectRef::HeapObjectRef; using HeapObjectRef::HeapObjectRef;
...@@ -467,13 +493,14 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef { ...@@ -467,13 +493,14 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef {
bool supports_fast_array_resize() const; bool supports_fast_array_resize() const;
bool IsMapOfCurrentGlobalProxy() const; bool IsMapOfCurrentGlobalProxy() const;
OddballType oddball_type() const;
#define DEF_TESTER(Type, ...) bool Is##Type##Map() const; #define DEF_TESTER(Type, ...) bool Is##Type##Map() const;
INSTANCE_TYPE_CHECKERS(DEF_TESTER) INSTANCE_TYPE_CHECKERS(DEF_TESTER)
#undef DEF_TESTER #undef DEF_TESTER
ObjectRef GetConstructor() const; void SerializeBackPointer();
OddballType oddball_type() const; HeapObjectRef GetBackPointer() const;
base::Optional<MapRef> AsElementsKind(ElementsKind kind) const;
void SerializePrototype(); void SerializePrototype();
bool serialized_prototype() const; bool serialized_prototype() const;
...@@ -493,6 +520,11 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef { ...@@ -493,6 +520,11 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef {
FieldIndex GetFieldIndexFor(int descriptor_index) const; FieldIndex GetFieldIndexFor(int descriptor_index) const;
ObjectRef GetFieldType(int descriptor_index) const; ObjectRef GetFieldType(int descriptor_index) const;
bool IsUnboxedDoubleField(int descriptor_index) const; bool IsUnboxedDoubleField(int descriptor_index) const;
// Available after calling JSFunctionRef::Serialize on a function that has
// this map as initial map.
ObjectRef GetConstructor() const;
base::Optional<MapRef> AsElementsKind(ElementsKind kind) const;
}; };
class FixedArrayBaseRef : public HeapObjectRef { class FixedArrayBaseRef : public HeapObjectRef {
......
...@@ -774,7 +774,7 @@ namespace { ...@@ -774,7 +774,7 @@ namespace {
FieldAccess ForPropertyCellValue(MachineRepresentation representation, FieldAccess ForPropertyCellValue(MachineRepresentation representation,
Type type, MaybeHandle<Map> map, Type type, MaybeHandle<Map> map,
Handle<Name> name) { NameRef const& name) {
WriteBarrierKind kind = kFullWriteBarrier; WriteBarrierKind kind = kFullWriteBarrier;
if (representation == MachineRepresentation::kTaggedSigned) { if (representation == MachineRepresentation::kTaggedSigned) {
kind = kNoWriteBarrier; kind = kNoWriteBarrier;
...@@ -783,25 +783,25 @@ FieldAccess ForPropertyCellValue(MachineRepresentation representation, ...@@ -783,25 +783,25 @@ FieldAccess ForPropertyCellValue(MachineRepresentation representation,
} }
MachineType r = MachineType::TypeForRepresentation(representation); MachineType r = MachineType::TypeForRepresentation(representation);
FieldAccess access = { FieldAccess access = {
kTaggedBase, PropertyCell::kValueOffset, name, map, type, r, kind}; kTaggedBase, PropertyCell::kValueOffset, name.object(), map, type, r,
kind};
return access; return access;
} }
} // namespace } // namespace
Reduction JSNativeContextSpecialization::ReduceGlobalAccess( Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
Node* node, Node* receiver, Node* value, Handle<Name> name, Node* node, Node* receiver, Node* value, NameRef const& name,
AccessMode access_mode, Node* key) { AccessMode access_mode, Node* key) {
NameRef name_ref(broker(), name);
base::Optional<PropertyCellRef> cell = base::Optional<PropertyCellRef> cell =
native_context().global_proxy_object().GetPropertyCell(name_ref); native_context().global_proxy_object().GetPropertyCell(name);
return cell.has_value() ? ReduceGlobalAccess(node, receiver, value, name, return cell.has_value() ? ReduceGlobalAccess(node, receiver, value, name,
access_mode, key, *cell) access_mode, key, *cell)
: NoChange(); : NoChange();
} }
Reduction JSNativeContextSpecialization::ReduceGlobalAccess( Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
Node* node, Node* receiver, Node* value, Handle<Name> name, Node* node, Node* receiver, Node* value, NameRef const& name,
AccessMode access_mode, Node* key, PropertyCellRef const& property_cell) { AccessMode access_mode, Node* key, PropertyCellRef const& property_cell) {
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
...@@ -1024,8 +1024,9 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadGlobal(Node* node) { ...@@ -1024,8 +1024,9 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadGlobal(Node* node) {
} }
CHECK(processed->IsPropertyCell()); CHECK(processed->IsPropertyCell());
return ReduceGlobalAccess(node, nullptr, nullptr, p.name(), AccessMode::kLoad, return ReduceGlobalAccess(node, nullptr, nullptr, NameRef(broker(), p.name()),
nullptr, processed->property_cell()); AccessMode::kLoad, nullptr,
processed->property_cell());
} }
Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) { Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) {
...@@ -1057,7 +1058,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) { ...@@ -1057,7 +1058,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) {
} }
if (processed->IsPropertyCell()) { if (processed->IsPropertyCell()) {
return ReduceGlobalAccess(node, nullptr, value, p.name(), return ReduceGlobalAccess(node, nullptr, value, NameRef(broker(), p.name()),
AccessMode::kStore, nullptr, AccessMode::kStore, nullptr,
processed->property_cell()); processed->property_cell());
} }
...@@ -1066,8 +1067,8 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) { ...@@ -1066,8 +1067,8 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) {
} }
Reduction JSNativeContextSpecialization::ReduceNamedAccess( Reduction JSNativeContextSpecialization::ReduceNamedAccess(
Node* node, Node* value, MapHandles const& receiver_maps, Handle<Name> name, Node* node, Node* value, MapHandles const& receiver_maps,
AccessMode access_mode, Node* key) { NameRef const& name, AccessMode access_mode, Node* key) {
DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
node->opcode() == IrOpcode::kJSStoreNamed || node->opcode() == IrOpcode::kJSStoreNamed ||
node->opcode() == IrOpcode::kJSLoadProperty || node->opcode() == IrOpcode::kJSLoadProperty ||
...@@ -1095,7 +1096,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( ...@@ -1095,7 +1096,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
graph()->zone()); graph()->zone());
ZoneVector<PropertyAccessInfo> access_infos(zone()); ZoneVector<PropertyAccessInfo> access_infos(zone());
if (!access_info_factory.ComputePropertyAccessInfos( if (!access_info_factory.ComputePropertyAccessInfos(
receiver_maps, name, access_mode, &access_infos)) { receiver_maps, name.object(), access_mode, &access_infos)) {
return NoChange(); return NoChange();
} }
...@@ -1330,7 +1331,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( ...@@ -1330,7 +1331,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
} }
Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus( Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus(
Node* node, Node* value, FeedbackNexus const& nexus, Handle<Name> name, Node* node, Node* value, FeedbackNexus const& nexus, NameRef const& name,
AccessMode access_mode) { AccessMode access_mode) {
DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
node->opcode() == IrOpcode::kJSStoreNamed || node->opcode() == IrOpcode::kJSStoreNamed ||
...@@ -1364,12 +1365,12 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { ...@@ -1364,12 +1365,12 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) {
DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode());
NamedAccess const& p = NamedAccessOf(node->op()); NamedAccess const& p = NamedAccessOf(node->op());
Node* const receiver = NodeProperties::GetValueInput(node, 0); Node* const receiver = NodeProperties::GetValueInput(node, 0);
NameRef name(broker(), p.name());
// Check if we have a constant receiver. // Check if we have a constant receiver.
HeapObjectMatcher m(receiver); HeapObjectMatcher m(receiver);
if (m.HasValue()) { if (m.HasValue()) {
ObjectRef object = m.Ref(broker()); ObjectRef object = m.Ref(broker());
NameRef name(broker(), p.name());
if (object.IsJSFunction() && if (object.IsJSFunction() &&
name.equals(ObjectRef(broker(), factory()->prototype_string()))) { name.equals(ObjectRef(broker(), factory()->prototype_string()))) {
// Optimize "prototype" property of functions. // Optimize "prototype" property of functions.
...@@ -1404,7 +1405,7 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { ...@@ -1404,7 +1405,7 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) {
FeedbackNexus nexus(p.feedback().vector(), p.feedback().slot()); FeedbackNexus nexus(p.feedback().vector(), p.feedback().slot());
// Try to lower the named access based on the {receiver_maps}. // Try to lower the named access based on the {receiver_maps}.
return ReduceNamedAccessFromNexus(node, jsgraph()->Dead(), nexus, p.name(), return ReduceNamedAccessFromNexus(node, jsgraph()->Dead(), nexus, name,
AccessMode::kLoad); AccessMode::kLoad);
} }
...@@ -1418,8 +1419,8 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) { ...@@ -1418,8 +1419,8 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) {
FeedbackNexus nexus(p.feedback().vector(), p.feedback().slot()); FeedbackNexus nexus(p.feedback().vector(), p.feedback().slot());
// Try to lower the named access based on the {receiver_maps}. // Try to lower the named access based on the {receiver_maps}.
return ReduceNamedAccessFromNexus(node, value, nexus, p.name(), return ReduceNamedAccessFromNexus(
AccessMode::kStore); node, value, nexus, NameRef(broker(), p.name()), AccessMode::kStore);
} }
Reduction JSNativeContextSpecialization::ReduceJSStoreNamedOwn(Node* node) { Reduction JSNativeContextSpecialization::ReduceJSStoreNamedOwn(Node* node) {
...@@ -1432,7 +1433,8 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreNamedOwn(Node* node) { ...@@ -1432,7 +1433,8 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreNamedOwn(Node* node) {
FeedbackNexus nexus(p.feedback().vector(), p.feedback().slot()); FeedbackNexus nexus(p.feedback().vector(), p.feedback().slot());
// Try to lower the creation of a named property based on the {receiver_maps}. // Try to lower the creation of a named property based on the {receiver_maps}.
return ReduceNamedAccessFromNexus(node, value, nexus, p.name(), return ReduceNamedAccessFromNexus(node, value, nexus,
NameRef(broker(), p.name()),
AccessMode::kStoreInLiteral); AccessMode::kStoreInLiteral);
} }
...@@ -1714,7 +1716,7 @@ Reduction JSNativeContextSpecialization::ReduceKeyedLoadFromHeapConstant( ...@@ -1714,7 +1716,7 @@ Reduction JSNativeContextSpecialization::ReduceKeyedLoadFromHeapConstant(
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
HeapObjectMatcher mreceiver(receiver); HeapObjectMatcher mreceiver(receiver);
HeapObjectRef receiver_ref = mreceiver.Ref(broker()).AsHeapObject(); HeapObjectRef receiver_ref = mreceiver.Ref(broker());
if (receiver_ref.map().oddball_type() == OddballType::kHole || if (receiver_ref.map().oddball_type() == OddballType::kHole ||
receiver_ref.map().oddball_type() == OddballType::kNull || receiver_ref.map().oddball_type() == OddballType::kNull ||
receiver_ref.map().oddball_type() == OddballType::kUndefined || receiver_ref.map().oddball_type() == OddballType::kUndefined ||
...@@ -1821,8 +1823,9 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess( ...@@ -1821,8 +1823,9 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
// Check if we have feedback for a named access. // Check if we have feedback for a named access.
base::Optional<NameRef> name = GetNameFeedback(broker(), nexus); base::Optional<NameRef> name = GetNameFeedback(broker(), nexus);
if (name.has_value()) { if (name.has_value()) {
return ReduceNamedAccess(node, value, receiver_maps, name->object(), DCHECK_EQ(nexus.GetKeyType(), PROPERTY);
access_mode, key); return ReduceNamedAccess(node, value, receiver_maps, *name, access_mode,
key);
} }
// Try to lower element access based on the {receiver_maps}. // Try to lower element access based on the {receiver_maps}.
...@@ -2026,24 +2029,23 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall( ...@@ -2026,24 +2029,23 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall(
PropertyAccessInfo const& access_info) { PropertyAccessInfo const& access_info) {
Node* target = jsgraph()->Constant(access_info.constant()); Node* target = jsgraph()->Constant(access_info.constant());
FrameStateInfo const& frame_info = FrameStateInfoOf(frame_state->op()); FrameStateInfo const& frame_info = FrameStateInfoOf(frame_state->op());
Handle<SharedFunctionInfo> shared_info =
frame_info.shared_info().ToHandleChecked();
// Introduce the call to the getter function. // Introduce the call to the getter function.
Node* value; Node* value;
if (access_info.constant()->IsJSFunction()) { ObjectRef constant(broker(), access_info.constant());
if (constant.IsJSFunction()) {
value = *effect = *control = graph()->NewNode( value = *effect = *control = graph()->NewNode(
jsgraph()->javascript()->Call(2, CallFrequency(), VectorSlotPair(), jsgraph()->javascript()->Call(2, CallFrequency(), VectorSlotPair(),
ConvertReceiverMode::kNotNullOrUndefined), ConvertReceiverMode::kNotNullOrUndefined),
target, receiver, context, frame_state, *effect, *control); target, receiver, context, frame_state, *effect, *control);
} else { } else {
DCHECK(access_info.constant()->IsFunctionTemplateInfo()); auto function_template_info = constant.AsFunctionTemplateInfo();
Handle<FunctionTemplateInfo> function_template_info( function_template_info.Serialize();
Handle<FunctionTemplateInfo>::cast(access_info.constant()));
DCHECK(!function_template_info->call_code()->IsUndefined(isolate()));
Node* holder = Node* holder =
access_info.holder().is_null() access_info.holder().is_null()
? receiver ? receiver
: jsgraph()->Constant(access_info.holder().ToHandleChecked()); : jsgraph()->Constant(access_info.holder().ToHandleChecked());
SharedFunctionInfoRef shared_info(
broker(), frame_info.shared_info().ToHandleChecked());
value = InlineApiCall(receiver, holder, frame_state, nullptr, effect, value = InlineApiCall(receiver, holder, frame_state, nullptr, effect,
control, shared_info, function_template_info); control, shared_info, function_template_info);
} }
...@@ -2065,23 +2067,22 @@ void JSNativeContextSpecialization::InlinePropertySetterCall( ...@@ -2065,23 +2067,22 @@ void JSNativeContextSpecialization::InlinePropertySetterCall(
PropertyAccessInfo const& access_info) { PropertyAccessInfo const& access_info) {
Node* target = jsgraph()->Constant(access_info.constant()); Node* target = jsgraph()->Constant(access_info.constant());
FrameStateInfo const& frame_info = FrameStateInfoOf(frame_state->op()); FrameStateInfo const& frame_info = FrameStateInfoOf(frame_state->op());
Handle<SharedFunctionInfo> shared_info =
frame_info.shared_info().ToHandleChecked();
// Introduce the call to the setter function. // Introduce the call to the setter function.
if (access_info.constant()->IsJSFunction()) { ObjectRef constant(broker(), access_info.constant());
if (constant.IsJSFunction()) {
*effect = *control = graph()->NewNode( *effect = *control = graph()->NewNode(
jsgraph()->javascript()->Call(3, CallFrequency(), VectorSlotPair(), jsgraph()->javascript()->Call(3, CallFrequency(), VectorSlotPair(),
ConvertReceiverMode::kNotNullOrUndefined), ConvertReceiverMode::kNotNullOrUndefined),
target, receiver, value, context, frame_state, *effect, *control); target, receiver, value, context, frame_state, *effect, *control);
} else { } else {
DCHECK(access_info.constant()->IsFunctionTemplateInfo()); auto function_template_info = constant.AsFunctionTemplateInfo();
Handle<FunctionTemplateInfo> function_template_info( function_template_info.Serialize();
Handle<FunctionTemplateInfo>::cast(access_info.constant()));
DCHECK(!function_template_info->call_code()->IsUndefined(isolate()));
Node* holder = Node* holder =
access_info.holder().is_null() access_info.holder().is_null()
? receiver ? receiver
: jsgraph()->Constant(access_info.holder().ToHandleChecked()); : jsgraph()->Constant(access_info.holder().ToHandleChecked());
SharedFunctionInfoRef shared_info(
broker(), frame_info.shared_info().ToHandleChecked());
InlineApiCall(receiver, holder, frame_state, value, effect, control, InlineApiCall(receiver, holder, frame_state, value, effect, control,
shared_info, function_template_info); shared_info, function_template_info);
} }
...@@ -2098,11 +2099,10 @@ void JSNativeContextSpecialization::InlinePropertySetterCall( ...@@ -2098,11 +2099,10 @@ void JSNativeContextSpecialization::InlinePropertySetterCall(
Node* JSNativeContextSpecialization::InlineApiCall( Node* JSNativeContextSpecialization::InlineApiCall(
Node* receiver, Node* holder, Node* frame_state, Node* value, Node** effect, Node* receiver, Node* holder, Node* frame_state, Node* value, Node** effect,
Node** control, Handle<SharedFunctionInfo> shared_info, Node** control, SharedFunctionInfoRef const& shared_info,
Handle<FunctionTemplateInfo> function_template_info) { FunctionTemplateInfoRef const& function_template_info) {
Handle<CallHandlerInfo> call_handler_info = handle( auto call_handler_info =
CallHandlerInfo::cast(function_template_info->call_code()), isolate()); function_template_info.call_code().AsCallHandlerInfo();
Handle<Object> call_data_object(call_handler_info->data(), isolate());
// Only setters have a value. // Only setters have a value.
int const argc = value == nullptr ? 0 : 1; int const argc = value == nullptr ? 0 : 1;
...@@ -2116,8 +2116,8 @@ Node* JSNativeContextSpecialization::InlineApiCall( ...@@ -2116,8 +2116,8 @@ Node* JSNativeContextSpecialization::InlineApiCall(
1 /* implicit receiver */, 1 /* implicit receiver */,
CallDescriptor::kNeedsFrameState); CallDescriptor::kNeedsFrameState);
Node* data = jsgraph()->Constant(call_data_object); Node* data = jsgraph()->Constant(call_handler_info.data());
ApiFunction function(v8::ToCData<Address>(call_handler_info->callback())); ApiFunction function(call_handler_info.callback());
Node* function_reference = Node* function_reference =
graph()->NewNode(common()->ExternalConstant(ExternalReference::Create( graph()->NewNode(common()->ExternalConstant(ExternalReference::Create(
&function, ExternalReference::DIRECT_API_CALL))); &function, ExternalReference::DIRECT_API_CALL)));
...@@ -2146,11 +2146,10 @@ Node* JSNativeContextSpecialization::InlineApiCall( ...@@ -2146,11 +2146,10 @@ Node* JSNativeContextSpecialization::InlineApiCall(
JSNativeContextSpecialization::ValueEffectControl JSNativeContextSpecialization::ValueEffectControl
JSNativeContextSpecialization::BuildPropertyLoad( JSNativeContextSpecialization::BuildPropertyLoad(
Node* receiver, Node* context, Node* frame_state, Node* effect, Node* receiver, Node* context, Node* frame_state, Node* effect,
Node* control, Handle<Name> name, ZoneVector<Node*>* if_exceptions, Node* control, NameRef const& name, ZoneVector<Node*>* if_exceptions,
PropertyAccessInfo const& access_info) { PropertyAccessInfo const& access_info) {
// Determine actual holder and perform prototype chain checks. // Determine actual holder and perform prototype chain checks.
Handle<JSObject> holder; Handle<JSObject> holder;
PropertyAccessBuilder access_builder(jsgraph(), broker(), dependencies());
if (access_info.holder().ToHandle(&holder)) { if (access_info.holder().ToHandle(&holder)) {
dependencies()->DependOnStablePrototypeChains( dependencies()->DependOnStablePrototypeChains(
access_info.receiver_maps(), kStartAtPrototype, access_info.receiver_maps(), kStartAtPrototype,
...@@ -2176,6 +2175,7 @@ JSNativeContextSpecialization::BuildPropertyLoad( ...@@ -2176,6 +2175,7 @@ JSNativeContextSpecialization::BuildPropertyLoad(
value = graph()->NewNode(simplified()->StringLength(), receiver); value = graph()->NewNode(simplified()->StringLength(), receiver);
} else { } else {
DCHECK(access_info.IsDataField() || access_info.IsDataConstantField()); DCHECK(access_info.IsDataField() || access_info.IsDataConstantField());
PropertyAccessBuilder access_builder(jsgraph(), broker(), dependencies());
value = access_builder.BuildLoadDataField(name, access_info, receiver, value = access_builder.BuildLoadDataField(name, access_info, receiver,
&effect, &control); &effect, &control);
} }
...@@ -2196,14 +2196,13 @@ JSNativeContextSpecialization::BuildPropertyTest( ...@@ -2196,14 +2196,13 @@ JSNativeContextSpecialization::BuildPropertyTest(
Node* value = access_info.IsNotFound() ? jsgraph()->FalseConstant() Node* value = access_info.IsNotFound() ? jsgraph()->FalseConstant()
: jsgraph()->TrueConstant(); : jsgraph()->TrueConstant();
return ValueEffectControl(value, effect, control); return ValueEffectControl(value, effect, control);
} }
JSNativeContextSpecialization::ValueEffectControl JSNativeContextSpecialization::ValueEffectControl
JSNativeContextSpecialization::BuildPropertyAccess( JSNativeContextSpecialization::BuildPropertyAccess(
Node* receiver, Node* value, Node* context, Node* frame_state, Node* effect, Node* receiver, Node* value, Node* context, Node* frame_state, Node* effect,
Node* control, Handle<Name> name, ZoneVector<Node*>* if_exceptions, Node* control, NameRef const& name, ZoneVector<Node*>* if_exceptions,
PropertyAccessInfo const& access_info, AccessMode access_mode) { PropertyAccessInfo const& access_info, AccessMode access_mode) {
switch (access_mode) { switch (access_mode) {
case AccessMode::kLoad: case AccessMode::kLoad:
...@@ -2223,7 +2222,7 @@ JSNativeContextSpecialization::BuildPropertyAccess( ...@@ -2223,7 +2222,7 @@ JSNativeContextSpecialization::BuildPropertyAccess(
JSNativeContextSpecialization::ValueEffectControl JSNativeContextSpecialization::ValueEffectControl
JSNativeContextSpecialization::BuildPropertyStore( JSNativeContextSpecialization::BuildPropertyStore(
Node* receiver, Node* value, Node* context, Node* frame_state, Node* effect, Node* receiver, Node* value, Node* context, Node* frame_state, Node* effect,
Node* control, Handle<Name> name, ZoneVector<Node*>* if_exceptions, Node* control, NameRef const& name, ZoneVector<Node*>* if_exceptions,
PropertyAccessInfo const& access_info, AccessMode access_mode) { PropertyAccessInfo const& access_info, AccessMode access_mode) {
// Determine actual holder and perform prototype chain checks. // Determine actual holder and perform prototype chain checks.
Handle<JSObject> holder; Handle<JSObject> holder;
...@@ -2265,7 +2264,7 @@ JSNativeContextSpecialization::BuildPropertyStore( ...@@ -2265,7 +2264,7 @@ JSNativeContextSpecialization::BuildPropertyStore(
FieldAccess field_access = { FieldAccess field_access = {
kTaggedBase, kTaggedBase,
field_index.offset(), field_index.offset(),
name, name.object(),
MaybeHandle<Map>(), MaybeHandle<Map>(),
field_type, field_type,
MachineType::TypeForRepresentation(field_representation), MachineType::TypeForRepresentation(field_representation),
...@@ -2298,12 +2297,10 @@ JSNativeContextSpecialization::BuildPropertyStore( ...@@ -2298,12 +2297,10 @@ JSNativeContextSpecialization::BuildPropertyStore(
field_access.write_barrier_kind = kPointerWriteBarrier; field_access.write_barrier_kind = kPointerWriteBarrier;
} else { } else {
// We just store directly to the MutableHeapNumber. // We just store directly to the MutableHeapNumber.
FieldAccess const storage_access = {kTaggedBase, FieldAccess const storage_access = {
field_index.offset(), kTaggedBase, field_index.offset(),
name, name.object(), MaybeHandle<Map>(),
MaybeHandle<Map>(), Type::OtherInternal(), MachineType::TaggedPointer(),
Type::OtherInternal(),
MachineType::TaggedPointer(),
kPointerWriteBarrier}; kPointerWriteBarrier};
storage = effect = storage = effect =
graph()->NewNode(simplified()->LoadField(storage_access), graph()->NewNode(simplified()->LoadField(storage_access),
...@@ -2393,14 +2390,15 @@ JSNativeContextSpecialization::BuildPropertyStore( ...@@ -2393,14 +2390,15 @@ JSNativeContextSpecialization::BuildPropertyStore(
if (access_info.transition_map().ToHandle(&transition_map)) { if (access_info.transition_map().ToHandle(&transition_map)) {
// Check if we need to grow the properties backing store // Check if we need to grow the properties backing store
// with this transitioning store. // with this transitioning store.
Handle<Map> original_map(Map::cast(transition_map->GetBackPointer()), MapRef transition_map_ref(broker(), transition_map);
isolate()); transition_map_ref.SerializeBackPointer();
if (original_map->UnusedPropertyFields() == 0) { MapRef original_map = transition_map_ref.GetBackPointer().AsMap();
if (original_map.UnusedPropertyFields() == 0) {
DCHECK(!field_index.is_inobject()); DCHECK(!field_index.is_inobject());
// Reallocate the properties {storage}. // Reallocate the properties {storage}.
storage = effect = BuildExtendPropertiesBackingStore( storage = effect = BuildExtendPropertiesBackingStore(
MapRef(broker(), original_map), storage, effect, control); original_map, storage, effect, control);
// Perform the actual store. // Perform the actual store.
effect = graph()->NewNode(simplified()->StoreField(field_access), effect = graph()->NewNode(simplified()->StoreField(field_access),
...@@ -2459,15 +2457,16 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral( ...@@ -2459,15 +2457,16 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral(
if (!Map::TryUpdate(isolate(), receiver_map).ToHandle(&receiver_map)) if (!Map::TryUpdate(isolate(), receiver_map).ToHandle(&receiver_map))
return NoChange(); return NoChange();
Handle<Name> cached_name( NameRef cached_name(
Name::cast(nexus.GetFeedbackExtra()->GetHeapObjectAssumeStrong()), broker(),
isolate()); handle(Name::cast(nexus.GetFeedbackExtra()->GetHeapObjectAssumeStrong()),
isolate()));
PropertyAccessInfo access_info; PropertyAccessInfo access_info;
AccessInfoFactory access_info_factory(broker(), dependencies(), AccessInfoFactory access_info_factory(broker(), dependencies(),
graph()->zone()); graph()->zone());
if (!access_info_factory.ComputePropertyAccessInfo( if (!access_info_factory.ComputePropertyAccessInfo(
receiver_map, cached_name, AccessMode::kStoreInLiteral, receiver_map, cached_name.object(), AccessMode::kStoreInLiteral,
&access_info)) { &access_info)) {
return NoChange(); return NoChange();
} }
...@@ -2485,7 +2484,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral( ...@@ -2485,7 +2484,7 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral(
// Ensure that {name} matches the cached name. // Ensure that {name} matches the cached name.
Node* name = NodeProperties::GetValueInput(node, 1); Node* name = NodeProperties::GetValueInput(node, 1);
Node* check = graph()->NewNode(simplified()->ReferenceEqual(), name, Node* check = graph()->NewNode(simplified()->ReferenceEqual(), name,
jsgraph()->HeapConstant(cached_name)); jsgraph()->Constant(cached_name));
effect = graph()->NewNode(simplified()->CheckIf(DeoptimizeReason::kWrongName), effect = graph()->NewNode(simplified()->CheckIf(DeoptimizeReason::kWrongName),
check, effect, control); check, effect, control);
...@@ -3249,15 +3248,15 @@ Node* JSNativeContextSpecialization::BuildExtendPropertiesBackingStore( ...@@ -3249,15 +3248,15 @@ Node* JSNativeContextSpecialization::BuildExtendPropertiesBackingStore(
return a.Finish(); return a.Finish();
} }
Node* JSNativeContextSpecialization::BuildCheckEqualsName(Handle<Name> name, Node* JSNativeContextSpecialization::BuildCheckEqualsName(NameRef const& name,
Node* value, Node* value,
Node* effect, Node* effect,
Node* control) { Node* control) {
DCHECK(name->IsUniqueName()); DCHECK(name.IsUniqueName());
Operator const* const op = Operator const* const op =
name->IsSymbol() ? simplified()->CheckEqualsSymbol() name.IsSymbol() ? simplified()->CheckEqualsSymbol()
: simplified()->CheckEqualsInternalizedString(); : simplified()->CheckEqualsInternalizedString();
return graph()->NewNode(op, jsgraph()->HeapConstant(name), value, effect, return graph()->NewNode(op, jsgraph()->Constant(name), value, effect,
control); control);
} }
......
...@@ -105,17 +105,17 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final ...@@ -105,17 +105,17 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
KeyedAccessStoreMode store_mode); KeyedAccessStoreMode store_mode);
Reduction ReduceNamedAccessFromNexus(Node* node, Node* value, Reduction ReduceNamedAccessFromNexus(Node* node, Node* value,
FeedbackNexus const& nexus, FeedbackNexus const& nexus,
Handle<Name> name, NameRef const& name,
AccessMode access_mode); AccessMode access_mode);
Reduction ReduceNamedAccess(Node* node, Node* value, Reduction ReduceNamedAccess(Node* node, Node* value,
MapHandles const& receiver_maps, MapHandles const& receiver_maps,
Handle<Name> name, AccessMode access_mode, NameRef const& name, AccessMode access_mode,
Node* key = nullptr); Node* key = nullptr);
Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value, Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value,
Handle<Name> name, AccessMode access_mode, NameRef const& name, AccessMode access_mode,
Node* key = nullptr); Node* key = nullptr);
Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value, Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value,
Handle<Name> name, AccessMode access_mode, NameRef const& name, AccessMode access_mode,
Node* key, PropertyCellRef const& property_cell); Node* key, PropertyCellRef const& property_cell);
Reduction ReduceKeyedLoadFromHeapConstant(Node* node, Node* key, Reduction ReduceKeyedLoadFromHeapConstant(Node* node, Node* key,
FeedbackNexus const& nexus, FeedbackNexus const& nexus,
...@@ -154,20 +154,20 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final ...@@ -154,20 +154,20 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
ValueEffectControl BuildPropertyAccess(Node* receiver, Node* value, ValueEffectControl BuildPropertyAccess(Node* receiver, Node* value,
Node* context, Node* frame_state, Node* context, Node* frame_state,
Node* effect, Node* control, Node* effect, Node* control,
Handle<Name> name, NameRef const& name,
ZoneVector<Node*>* if_exceptions, ZoneVector<Node*>* if_exceptions,
PropertyAccessInfo const& access_info, PropertyAccessInfo const& access_info,
AccessMode access_mode); AccessMode access_mode);
ValueEffectControl BuildPropertyLoad(Node* receiver, Node* context, ValueEffectControl BuildPropertyLoad(Node* receiver, Node* context,
Node* frame_state, Node* effect, Node* frame_state, Node* effect,
Node* control, Handle<Name> name, Node* control, NameRef const& name,
ZoneVector<Node*>* if_exceptions, ZoneVector<Node*>* if_exceptions,
PropertyAccessInfo const& access_info); PropertyAccessInfo const& access_info);
ValueEffectControl BuildPropertyStore(Node* receiver, Node* value, ValueEffectControl BuildPropertyStore(Node* receiver, Node* value,
Node* context, Node* frame_state, Node* context, Node* frame_state,
Node* effect, Node* control, Node* effect, Node* control,
Handle<Name> name, NameRef const& name,
ZoneVector<Node*>* if_exceptions, ZoneVector<Node*>* if_exceptions,
PropertyAccessInfo const& access_info, PropertyAccessInfo const& access_info,
AccessMode access_mode); AccessMode access_mode);
...@@ -188,8 +188,8 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final ...@@ -188,8 +188,8 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
PropertyAccessInfo const& access_info); PropertyAccessInfo const& access_info);
Node* InlineApiCall(Node* receiver, Node* holder, Node* frame_state, Node* InlineApiCall(Node* receiver, Node* holder, Node* frame_state,
Node* value, Node** effect, Node** control, Node* value, Node** effect, Node** control,
Handle<SharedFunctionInfo> shared_info, SharedFunctionInfoRef const& shared_info,
Handle<FunctionTemplateInfo> function_template_info); FunctionTemplateInfoRef const& function_template_info);
// Construct the appropriate subgraph for element access. // Construct the appropriate subgraph for element access.
ValueEffectControl BuildElementAccess( ValueEffectControl BuildElementAccess(
...@@ -208,7 +208,7 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final ...@@ -208,7 +208,7 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
// Construct appropriate subgraph to check that the {value} matches // Construct appropriate subgraph to check that the {value} matches
// the previously recorded {name} feedback. // the previously recorded {name} feedback.
Node* BuildCheckEqualsName(Handle<Name> name, Node* value, Node* effect, Node* BuildCheckEqualsName(NameRef const& name, Node* value, Node* effect,
Node* control); Node* control);
// Checks if we can turn the hole into undefined when loading an element // Checks if we can turn the hole into undefined when loading an element
......
...@@ -196,8 +196,8 @@ struct HeapObjectMatcher final ...@@ -196,8 +196,8 @@ struct HeapObjectMatcher final
return this->HasValue() && this->Value().address() == value.address(); return this->HasValue() && this->Value().address() == value.address();
} }
ObjectRef Ref(JSHeapBroker* broker) const { HeapObjectRef Ref(JSHeapBroker* broker) const {
return ObjectRef(broker, this->Value()); return HeapObjectRef(broker, this->Value());
} }
}; };
......
...@@ -391,7 +391,7 @@ NodeProperties::InferReceiverMapsResult NodeProperties::InferReceiverMaps( ...@@ -391,7 +391,7 @@ NodeProperties::InferReceiverMapsResult NodeProperties::InferReceiverMaps(
ZoneHandleSet<Map>* maps_return) { ZoneHandleSet<Map>* maps_return) {
HeapObjectMatcher m(receiver); HeapObjectMatcher m(receiver);
if (m.HasValue()) { if (m.HasValue()) {
HeapObjectRef receiver = m.Ref(broker).AsHeapObject(); HeapObjectRef receiver = m.Ref(broker);
// We don't use ICs for the Array.prototype and the Object.prototype // We don't use ICs for the Array.prototype and the Object.prototype
// because the runtime has to be able to intercept them properly, so // because the runtime has to be able to intercept them properly, so
// we better make sure that TurboFan doesn't outsmart the system here // we better make sure that TurboFan doesn't outsmart the system here
...@@ -575,8 +575,7 @@ bool NodeProperties::CanBePrimitive(JSHeapBroker* broker, Node* receiver, ...@@ -575,8 +575,7 @@ bool NodeProperties::CanBePrimitive(JSHeapBroker* broker, Node* receiver,
case IrOpcode::kJSToObject: case IrOpcode::kJSToObject:
return false; return false;
case IrOpcode::kHeapConstant: { case IrOpcode::kHeapConstant: {
HeapObjectRef value = HeapObjectRef value = HeapObjectMatcher(receiver).Ref(broker);
HeapObjectMatcher(receiver).Ref(broker).AsHeapObject();
return value.map().IsPrimitiveMap(); return value.map().IsPrimitiveMap();
} }
default: { default: {
...@@ -617,8 +616,7 @@ bool NodeProperties::CanBeNullOrUndefined(JSHeapBroker* broker, Node* receiver, ...@@ -617,8 +616,7 @@ bool NodeProperties::CanBeNullOrUndefined(JSHeapBroker* broker, Node* receiver,
case IrOpcode::kToBoolean: case IrOpcode::kToBoolean:
return false; return false;
case IrOpcode::kHeapConstant: { case IrOpcode::kHeapConstant: {
HeapObjectRef value = HeapObjectRef value = HeapObjectMatcher(receiver).Ref(broker);
HeapObjectMatcher(receiver).Ref(broker).AsHeapObject();
OddballType type = value.map().oddball_type(); OddballType type = value.map().oddball_type();
return type == OddballType::kNull || type == OddballType::kUndefined; return type == OddballType::kNull || type == OddballType::kUndefined;
} }
......
...@@ -148,7 +148,7 @@ void PropertyAccessBuilder::BuildCheckMaps(Node* receiver, Node** effect, ...@@ -148,7 +148,7 @@ void PropertyAccessBuilder::BuildCheckMaps(Node* receiver, Node** effect,
MapHandles const& receiver_maps) { MapHandles const& receiver_maps) {
HeapObjectMatcher m(receiver); HeapObjectMatcher m(receiver);
if (m.HasValue()) { if (m.HasValue()) {
MapRef receiver_map = m.Ref(broker()).AsHeapObject().map(); MapRef receiver_map = m.Ref(broker()).map();
if (receiver_map.is_stable()) { if (receiver_map.is_stable()) {
for (Handle<Map> map : receiver_maps) { for (Handle<Map> map : receiver_maps) {
if (MapRef(broker(), map).equals(receiver_map)) { if (MapRef(broker(), map).equals(receiver_map)) {
...@@ -195,7 +195,8 @@ Node* PropertyAccessBuilder::ResolveHolder( ...@@ -195,7 +195,8 @@ Node* PropertyAccessBuilder::ResolveHolder(
} }
Node* PropertyAccessBuilder::TryBuildLoadConstantDataField( Node* PropertyAccessBuilder::TryBuildLoadConstantDataField(
Handle<Name> name, PropertyAccessInfo const& access_info, Node* receiver) { NameRef const& name, PropertyAccessInfo const& access_info,
Node* receiver) {
// Optimize immutable property loads. // Optimize immutable property loads.
// First, determine if we have a constant holder to load from. // First, determine if we have a constant holder to load from.
...@@ -204,14 +205,14 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField( ...@@ -204,14 +205,14 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField(
if (!access_info.holder().ToHandle(&holder)) { if (!access_info.holder().ToHandle(&holder)) {
// Otherwise, try to match the {receiver} as a constant. // Otherwise, try to match the {receiver} as a constant.
HeapObjectMatcher m(receiver); HeapObjectMatcher m(receiver);
if (!m.HasValue() || !m.Value()->IsJSObject()) return nullptr; if (!m.HasValue() || !m.Ref(broker()).IsJSObject()) return nullptr;
// Let us make sure the actual map of the constant receiver is among // Let us make sure the actual map of the constant receiver is among
// the maps in {access_info}. // the maps in {access_info}.
Handle<Map> receiver_map = handle(m.Value()->map(), isolate()); MapRef receiver_map = m.Ref(broker()).map();
if (std::find_if(access_info.receiver_maps().begin(), if (std::find_if(access_info.receiver_maps().begin(),
access_info.receiver_maps().end(), [&](Handle<Map> map) { access_info.receiver_maps().end(), [&](Handle<Map> map) {
return map.address() == receiver_map.address(); return map.address() == receiver_map.object().address();
}) == access_info.receiver_maps().end()) { }) == access_info.receiver_maps().end()) {
// The map of the receiver is not in the feedback, let us bail out. // The map of the receiver is not in the feedback, let us bail out.
return nullptr; return nullptr;
...@@ -229,7 +230,7 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField( ...@@ -229,7 +230,7 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField(
// TODO(turbofan): Given that we already have the field_index here, we // TODO(turbofan): Given that we already have the field_index here, we
// might be smarter in the future and not rely on the LookupIterator. // might be smarter in the future and not rely on the LookupIterator.
LookupIterator it(isolate(), holder, name, LookupIterator it(isolate(), holder, name.object(),
LookupIterator::OWN_SKIP_INTERCEPTOR); LookupIterator::OWN_SKIP_INTERCEPTOR);
if (it.state() == LookupIterator::DATA) { if (it.state() == LookupIterator::DATA) {
bool is_readonly_non_configurable = it.IsReadOnly() && !it.IsConfigurable(); bool is_readonly_non_configurable = it.IsReadOnly() && !it.IsConfigurable();
...@@ -257,7 +258,7 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField( ...@@ -257,7 +258,7 @@ Node* PropertyAccessBuilder::TryBuildLoadConstantDataField(
} }
Node* PropertyAccessBuilder::BuildLoadDataField( Node* PropertyAccessBuilder::BuildLoadDataField(
Handle<Name> name, PropertyAccessInfo const& access_info, Node* receiver, NameRef const& name, PropertyAccessInfo const& access_info, Node* receiver,
Node** effect, Node** control) { Node** effect, Node** control) {
DCHECK(access_info.IsDataField() || access_info.IsDataConstantField()); DCHECK(access_info.IsDataField() || access_info.IsDataConstantField());
if (Node* value = if (Node* value =
...@@ -278,7 +279,7 @@ Node* PropertyAccessBuilder::BuildLoadDataField( ...@@ -278,7 +279,7 @@ Node* PropertyAccessBuilder::BuildLoadDataField(
FieldAccess field_access = { FieldAccess field_access = {
kTaggedBase, kTaggedBase,
field_index.offset(), field_index.offset(),
name, name.object(),
MaybeHandle<Map>(), MaybeHandle<Map>(),
field_type, field_type,
MachineType::TypeForRepresentation(field_representation), MachineType::TypeForRepresentation(field_representation),
...@@ -287,14 +288,11 @@ Node* PropertyAccessBuilder::BuildLoadDataField( ...@@ -287,14 +288,11 @@ Node* PropertyAccessBuilder::BuildLoadDataField(
if (field_representation == MachineRepresentation::kFloat64) { if (field_representation == MachineRepresentation::kFloat64) {
if (!field_index.is_inobject() || field_index.is_hidden_field() || if (!field_index.is_inobject() || field_index.is_hidden_field() ||
!FLAG_unbox_double_fields) { !FLAG_unbox_double_fields) {
FieldAccess const storage_access = {kTaggedBase, FieldAccess const storage_access = {
field_index.offset(), kTaggedBase, field_index.offset(),
name, name.object(), MaybeHandle<Map>(),
MaybeHandle<Map>(), Type::OtherInternal(), MachineType::TaggedPointer(),
Type::OtherInternal(), kPointerWriteBarrier, LoadSensitivity::kCritical};
MachineType::TaggedPointer(),
kPointerWriteBarrier,
LoadSensitivity::kCritical};
storage = *effect = graph()->NewNode( storage = *effect = graph()->NewNode(
simplified()->LoadField(storage_access), storage, *effect, *control); simplified()->LoadField(storage_access), storage, *effect, *control);
field_access.offset = HeapNumber::kValueOffset; field_access.offset = HeapNumber::kValueOffset;
...@@ -305,8 +303,9 @@ Node* PropertyAccessBuilder::BuildLoadDataField( ...@@ -305,8 +303,9 @@ Node* PropertyAccessBuilder::BuildLoadDataField(
// used by the LoadElimination to eliminate map checks on the result. // used by the LoadElimination to eliminate map checks on the result.
Handle<Map> field_map; Handle<Map> field_map;
if (access_info.field_map().ToHandle(&field_map)) { if (access_info.field_map().ToHandle(&field_map)) {
if (field_map->is_stable()) { MapRef field_map_ref(broker(), field_map);
dependencies()->DependOnStableMap(MapRef(broker(), field_map)); if (field_map_ref.is_stable()) {
dependencies()->DependOnStableMap(field_map_ref);
field_access.map = field_map; field_access.map = field_map;
} }
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <vector> #include <vector>
#include "src/compiler/js-heap-broker.h"
#include "src/handles.h" #include "src/handles.h"
#include "src/objects/map.h" #include "src/objects/map.h"
#include "src/zone/zone-containers.h" #include "src/zone/zone-containers.h"
...@@ -46,7 +47,7 @@ class PropertyAccessBuilder { ...@@ -46,7 +47,7 @@ class PropertyAccessBuilder {
// Builds the actual load for data-field and data-constant-field // Builds the actual load for data-field and data-constant-field
// properties (without heap-object or map checks). // properties (without heap-object or map checks).
Node* BuildLoadDataField(Handle<Name> name, Node* BuildLoadDataField(NameRef const& name,
PropertyAccessInfo const& access_info, PropertyAccessInfo const& access_info,
Node* receiver, Node** effect, Node** control); Node* receiver, Node** effect, Node** control);
...@@ -59,7 +60,7 @@ class PropertyAccessBuilder { ...@@ -59,7 +60,7 @@ class PropertyAccessBuilder {
CommonOperatorBuilder* common() const; CommonOperatorBuilder* common() const;
SimplifiedOperatorBuilder* simplified() const; SimplifiedOperatorBuilder* simplified() const;
Node* TryBuildLoadConstantDataField(Handle<Name> name, Node* TryBuildLoadConstantDataField(NameRef const& name,
PropertyAccessInfo const& access_info, PropertyAccessInfo const& access_info,
Node* receiver); Node* receiver);
// Returns a node with the holder for the property access described by // Returns a node with the holder for the property access described by
......
...@@ -684,10 +684,10 @@ void Map::AppendDescriptor(Isolate* isolate, Descriptor* desc) { ...@@ -684,10 +684,10 @@ void Map::AppendDescriptor(Isolate* isolate, Descriptor* desc) {
#endif #endif
} }
Object Map::GetBackPointer() const { HeapObject Map::GetBackPointer() const {
Object object = constructor_or_backpointer(); Object object = constructor_or_backpointer();
if (object->IsMap()) { if (object->IsMap()) {
return object; return Map::cast(object);
} }
return GetReadOnlyRoots().undefined_value(); return GetReadOnlyRoots().undefined_value();
} }
......
...@@ -576,7 +576,7 @@ class Map : public HeapObject { ...@@ -576,7 +576,7 @@ class Map : public HeapObject {
WriteBarrierMode mode = UPDATE_WRITE_BARRIER); WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// [back pointer]: points back to the parent map from which a transition // [back pointer]: points back to the parent map from which a transition
// leads to this map. The field overlaps with the constructor (see above). // leads to this map. The field overlaps with the constructor (see above).
inline Object GetBackPointer() const; inline HeapObject GetBackPointer() const;
inline void SetBackPointer(Object value, inline void SetBackPointer(Object value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER); WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
......
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