[turbofan] Get rid of HeapObjectType-related heap reads.
This removes the last unconditional read accesses to the heap, but required a significant refactoring. - Remove HeapObjectRef::type(). - Change HeapObjectData::Is* testers to look at the instance type in HeapObjectData::map(). - Remove ObjectRef::oddball_type() - Add MapRef::oddball_type() - Add MapRef::is_undetectable(). - Add MapRef::is_callable(). - Remove JSHeapBroker::HeapObjectTypeFromMap() - Remove Type::For(JSHeapBroker*, Handle<Map>) - Add BitsetType::Lub(MapRef). - Add Type::For(MapRef). - Add Type::For(HeapObjectType). - Add HeapObjectRef::GetHeapObjectType(). THIS IS TEMPORARY. As the last item suggests, I couldn't actually remove the HeapObjectType class yet. See the explanation in the code. Bug: v8:7790 Change-Id: I508e4bd5337277b0050f2204392fc36f41032fe9 Reviewed-on: https://chromium-review.googlesource.com/1228033 Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Reviewed-by: Maya Lekova <mslekova@chromium.org> Commit-Queue: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#55994}
This commit is contained in:
parent
7f5d299649
commit
253c2469f2
@ -409,7 +409,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
|
||||
dependencies()->DependOnFieldType(map_ref, number);
|
||||
// Remember the field map, and try to infer a useful type.
|
||||
Handle<Map> map(descriptors_field_type->AsClass(), isolate());
|
||||
field_type = Type::For(js_heap_broker(), map);
|
||||
field_type = Type::For(MapRef(js_heap_broker(), map));
|
||||
field_map = MaybeHandle<Map>(map);
|
||||
}
|
||||
}
|
||||
@ -714,7 +714,7 @@ bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name,
|
||||
dependencies()->DependOnFieldType(transition_map_ref, number);
|
||||
// Remember the field map, and try to infer a useful type.
|
||||
Handle<Map> map(descriptors_field_type->AsClass(), isolate());
|
||||
field_type = Type::For(js_heap_broker(), map);
|
||||
field_type = Type::For(MapRef(js_heap_broker(), map));
|
||||
field_map = MaybeHandle<Map>(map);
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) {
|
||||
// We must be conservative and check if the value in the slot is currently
|
||||
// the hole or undefined. Only if it is neither of these, can we be sure
|
||||
// that it won't change anymore.
|
||||
OddballType oddball_type = maybe_value->oddball_type();
|
||||
OddballType oddball_type = maybe_value->AsHeapObject().map().oddball_type();
|
||||
if (oddball_type == OddballType::kUndefined ||
|
||||
oddball_type == OddballType::kHole) {
|
||||
maybe_value.reset();
|
||||
|
@ -1352,7 +1352,7 @@ base::Optional<MapRef> GetObjectCreateMap(JSHeapBroker* broker,
|
||||
if (prototype.equals(standard_map.prototype())) {
|
||||
return standard_map;
|
||||
}
|
||||
if (prototype.oddball_type() == OddballType::kNull) {
|
||||
if (prototype.map().oddball_type() == OddballType::kNull) {
|
||||
return broker->native_context().slow_object_with_null_prototype_map();
|
||||
}
|
||||
if (prototype.IsJSObject()) {
|
||||
@ -1378,7 +1378,7 @@ Reduction JSCreateLowering::ReduceJSCreateObject(Node* node) {
|
||||
|
||||
Node* properties = jsgraph()->EmptyFixedArrayConstant();
|
||||
if (instance_map.is_dictionary_map()) {
|
||||
DCHECK_EQ(prototype_const.type().oddball_type(), OddballType::kNull);
|
||||
DCHECK_EQ(prototype_const.map().oddball_type(), OddballType::kNull);
|
||||
// Allocate an empty NameDictionary as backing store for the properties.
|
||||
Handle<Map> map = isolate()->factory()->name_dictionary_map();
|
||||
int capacity =
|
||||
@ -1689,7 +1689,11 @@ Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control,
|
||||
value = effect = builder.Finish();
|
||||
} else if (property_details.representation().IsSmi()) {
|
||||
// Ensure that value is stored as smi.
|
||||
value = boilerplate_value.oddball_type() == OddballType::kUninitialized
|
||||
bool is_uninitialized =
|
||||
boilerplate_value.IsHeapObject() &&
|
||||
boilerplate_value.AsHeapObject().map().oddball_type() ==
|
||||
OddballType::kUninitialized;
|
||||
value = is_uninitialized
|
||||
? jsgraph()->ZeroConstant()
|
||||
: jsgraph()->Constant(boilerplate_value.AsSmi());
|
||||
} else {
|
||||
@ -1717,7 +1721,7 @@ Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control,
|
||||
// Actually allocate and initialize the object.
|
||||
AllocationBuilder builder(jsgraph(), effect, control);
|
||||
builder.Allocate(boilerplate_map.instance_size(), pretenure,
|
||||
Type::For(js_heap_broker(), boilerplate_map.object<Map>()));
|
||||
Type::For(boilerplate_map));
|
||||
builder.Store(AccessBuilder::ForMap(), boilerplate_map);
|
||||
builder.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
|
||||
builder.Store(AccessBuilder::ForJSObjectElements(), elements);
|
||||
@ -1805,8 +1809,7 @@ Node* JSCreateLowering::AllocateLiteralRegExp(Node* effect, Node* control,
|
||||
JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
|
||||
|
||||
AllocationBuilder builder(jsgraph(), effect, control);
|
||||
builder.Allocate(size, pretenure,
|
||||
Type::For(js_heap_broker(), boilerplate_map.object<Map>()));
|
||||
builder.Allocate(size, pretenure, Type::For(boilerplate_map));
|
||||
builder.Store(AccessBuilder::ForMap(), boilerplate_map);
|
||||
builder.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
|
||||
boilerplate.raw_properties_or_hash());
|
||||
|
@ -68,7 +68,8 @@ Node* JSGraph::Constant(Handle<Object> value) {
|
||||
|
||||
Node* JSGraph::Constant(const ObjectRef& ref) {
|
||||
if (ref.IsSmi()) return Constant(ref.AsSmi());
|
||||
OddballType oddball_type = ref.oddball_type();
|
||||
OddballType oddball_type =
|
||||
ref.AsHeapObject().GetHeapObjectType().oddball_type();
|
||||
if (ref.IsHeapNumber()) {
|
||||
return Constant(ref.AsHeapNumber().value());
|
||||
} else if (oddball_type == OddballType::kUndefined) {
|
||||
|
@ -52,27 +52,22 @@ class ObjectData : public ZoneObject {
|
||||
|
||||
class HeapObjectData : public ObjectData {
|
||||
public:
|
||||
HeapObjectData(JSHeapBroker* broker, Handle<HeapObject> object,
|
||||
HeapObjectType type);
|
||||
HeapObjectData(JSHeapBroker* broker, Handle<HeapObject> object);
|
||||
|
||||
bool boolean_value() const { return boolean_value_; }
|
||||
MapData* map() const { return map_; }
|
||||
|
||||
static HeapObjectData* Serialize(JSHeapBroker* broker,
|
||||
Handle<HeapObject> object);
|
||||
|
||||
HeapObjectType type() const { return type_; }
|
||||
bool boolean_value() const { return boolean_value_; }
|
||||
MapData* map() const { return map_; }
|
||||
|
||||
|
||||
private:
|
||||
HeapObjectType const type_;
|
||||
bool const boolean_value_;
|
||||
MapData* const map_;
|
||||
};
|
||||
|
||||
class PropertyCellData : public HeapObjectData {
|
||||
public:
|
||||
PropertyCellData(JSHeapBroker* broker, Handle<PropertyCell> object,
|
||||
HeapObjectType type);
|
||||
PropertyCellData(JSHeapBroker* broker, Handle<PropertyCell> object);
|
||||
|
||||
PropertyDetails property_details() const { return property_details_; }
|
||||
|
||||
@ -87,9 +82,8 @@ class PropertyCellData : public HeapObjectData {
|
||||
};
|
||||
|
||||
PropertyCellData::PropertyCellData(JSHeapBroker* broker,
|
||||
Handle<PropertyCell> object,
|
||||
HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type),
|
||||
Handle<PropertyCell> object)
|
||||
: HeapObjectData(broker, object),
|
||||
property_details_(object->property_details()) {}
|
||||
|
||||
void PropertyCellData::Serialize() {
|
||||
@ -125,8 +119,7 @@ class JSObjectField {
|
||||
|
||||
class JSObjectData : public HeapObjectData {
|
||||
public:
|
||||
JSObjectData(JSHeapBroker* broker, Handle<JSObject> object,
|
||||
HeapObjectType type);
|
||||
JSObjectData(JSHeapBroker* broker, Handle<JSObject> object);
|
||||
|
||||
// Recursively serializes all reachable JSObjects.
|
||||
void SerializeAsBoilerplate();
|
||||
@ -183,8 +176,7 @@ void JSObjectData::SerializeObjectCreateMap() {
|
||||
|
||||
class JSFunctionData : public JSObjectData {
|
||||
public:
|
||||
JSFunctionData(JSHeapBroker* broker, Handle<JSFunction> object,
|
||||
HeapObjectType type);
|
||||
JSFunctionData(JSHeapBroker* broker, Handle<JSFunction> object);
|
||||
|
||||
bool has_initial_map() const { return has_initial_map_; }
|
||||
bool has_prototype() const { return has_prototype_; }
|
||||
@ -219,9 +211,8 @@ class JSFunctionData : public JSObjectData {
|
||||
|
||||
class JSRegExpData : public JSObjectData {
|
||||
public:
|
||||
JSRegExpData(JSHeapBroker* broker, Handle<JSRegExp> object,
|
||||
HeapObjectType type)
|
||||
: JSObjectData(broker, object, type) {}
|
||||
JSRegExpData(JSHeapBroker* broker, Handle<JSRegExp> object)
|
||||
: JSObjectData(broker, object) {}
|
||||
|
||||
void SerializeAsRegExpBoilerplate();
|
||||
|
||||
@ -243,9 +234,8 @@ class JSRegExpData : public JSObjectData {
|
||||
|
||||
class HeapNumberData : public HeapObjectData {
|
||||
public:
|
||||
HeapNumberData(JSHeapBroker* broker, Handle<HeapNumber> object,
|
||||
HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type), value_(object->value()) {}
|
||||
HeapNumberData(JSHeapBroker* broker, Handle<HeapNumber> object)
|
||||
: HeapObjectData(broker, object), value_(object->value()) {}
|
||||
|
||||
double value() const { return value_; }
|
||||
|
||||
@ -255,9 +245,8 @@ class HeapNumberData : public HeapObjectData {
|
||||
|
||||
class MutableHeapNumberData : public HeapObjectData {
|
||||
public:
|
||||
MutableHeapNumberData(JSHeapBroker* broker, Handle<MutableHeapNumber> object,
|
||||
HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type), value_(object->value()) {}
|
||||
MutableHeapNumberData(JSHeapBroker* broker, Handle<MutableHeapNumber> object)
|
||||
: HeapObjectData(broker, object), value_(object->value()) {}
|
||||
|
||||
double value() const { return value_; }
|
||||
|
||||
@ -267,8 +256,7 @@ class MutableHeapNumberData : public HeapObjectData {
|
||||
|
||||
class ContextData : public HeapObjectData {
|
||||
public:
|
||||
ContextData(JSHeapBroker* broker, Handle<Context> object,
|
||||
HeapObjectType type);
|
||||
ContextData(JSHeapBroker* broker, Handle<Context> object);
|
||||
void Serialize();
|
||||
|
||||
ContextData* previous() const {
|
||||
@ -281,9 +269,8 @@ class ContextData : public HeapObjectData {
|
||||
ContextData* previous_ = nullptr;
|
||||
};
|
||||
|
||||
ContextData::ContextData(JSHeapBroker* broker, Handle<Context> object,
|
||||
HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type) {}
|
||||
ContextData::ContextData(JSHeapBroker* broker, Handle<Context> object)
|
||||
: HeapObjectData(broker, object) {}
|
||||
|
||||
void ContextData::Serialize() {
|
||||
if (serialized_) return;
|
||||
@ -311,8 +298,7 @@ class NativeContextData : public ContextData {
|
||||
return function_maps_;
|
||||
}
|
||||
|
||||
NativeContextData(JSHeapBroker* broker, Handle<NativeContext> object,
|
||||
HeapObjectType type);
|
||||
NativeContextData(JSHeapBroker* broker, Handle<NativeContext> object);
|
||||
void Serialize();
|
||||
|
||||
private:
|
||||
@ -325,13 +311,13 @@ class NativeContextData : public ContextData {
|
||||
|
||||
class NameData : public HeapObjectData {
|
||||
public:
|
||||
NameData(JSHeapBroker* broker, Handle<Name> object, HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type) {}
|
||||
NameData(JSHeapBroker* broker, Handle<Name> object)
|
||||
: HeapObjectData(broker, object) {}
|
||||
};
|
||||
|
||||
class StringData : public NameData {
|
||||
public:
|
||||
StringData(JSHeapBroker* broker, Handle<String> object, HeapObjectType type);
|
||||
StringData(JSHeapBroker* broker, Handle<String> object);
|
||||
|
||||
int length() const { return length_; }
|
||||
uint16_t first_char() const { return first_char_; }
|
||||
@ -349,9 +335,8 @@ class StringData : public NameData {
|
||||
static constexpr int kMaxLengthForDoubleConversion = 23;
|
||||
};
|
||||
|
||||
StringData::StringData(JSHeapBroker* broker, Handle<String> object,
|
||||
HeapObjectType type)
|
||||
: NameData(broker, object, type),
|
||||
StringData::StringData(JSHeapBroker* broker, Handle<String> object)
|
||||
: NameData(broker, object),
|
||||
length_(object->length()),
|
||||
first_char_(length_ > 0 ? object->Get(0) : 0),
|
||||
is_external_string_(object->IsExternalString()),
|
||||
@ -366,8 +351,8 @@ StringData::StringData(JSHeapBroker* broker, Handle<String> object,
|
||||
class InternalizedStringData : public StringData {
|
||||
public:
|
||||
InternalizedStringData(JSHeapBroker* broker,
|
||||
Handle<InternalizedString> object, HeapObjectType type)
|
||||
: StringData(broker, object, type) {}
|
||||
Handle<InternalizedString> object)
|
||||
: StringData(broker, object) {}
|
||||
};
|
||||
|
||||
namespace {
|
||||
@ -458,8 +443,7 @@ bool IsInlinableFastLiteral(Handle<JSObject> boilerplate) {
|
||||
|
||||
class AllocationSiteData : public HeapObjectData {
|
||||
public:
|
||||
AllocationSiteData(JSHeapBroker* broker, Handle<AllocationSite> object,
|
||||
HeapObjectType type);
|
||||
AllocationSiteData(JSHeapBroker* broker, Handle<AllocationSite> object);
|
||||
void SerializeBoilerplate();
|
||||
|
||||
bool PointsToLiteral() const { return PointsToLiteral_; }
|
||||
@ -487,8 +471,8 @@ class AllocationSiteData : public HeapObjectData {
|
||||
class ScriptContextTableData : public HeapObjectData {
|
||||
public:
|
||||
ScriptContextTableData(JSHeapBroker* broker,
|
||||
Handle<ScriptContextTable> object, HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type) {}
|
||||
Handle<ScriptContextTable> object)
|
||||
: HeapObjectData(broker, object) {}
|
||||
};
|
||||
|
||||
struct PropertyDescriptor {
|
||||
@ -502,7 +486,7 @@ struct PropertyDescriptor {
|
||||
|
||||
class MapData : public HeapObjectData {
|
||||
public:
|
||||
MapData(JSHeapBroker* broker, Handle<Map> object, HeapObjectType type);
|
||||
MapData(JSHeapBroker* broker, Handle<Map> object);
|
||||
|
||||
InstanceType instance_type() const { return instance_type_; }
|
||||
int instance_size() const { return instance_size_; }
|
||||
@ -572,9 +556,8 @@ class MapData : public HeapObjectData {
|
||||
};
|
||||
|
||||
AllocationSiteData::AllocationSiteData(JSHeapBroker* broker,
|
||||
Handle<AllocationSite> object,
|
||||
HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type),
|
||||
Handle<AllocationSite> object)
|
||||
: HeapObjectData(broker, object),
|
||||
PointsToLiteral_(object->PointsToLiteral()),
|
||||
GetPretenureMode_(object->GetPretenureMode()) {
|
||||
if (PointsToLiteral_) {
|
||||
@ -604,17 +587,20 @@ void AllocationSiteData::SerializeBoilerplate() {
|
||||
}
|
||||
}
|
||||
|
||||
HeapObjectData::HeapObjectData(JSHeapBroker* broker, Handle<HeapObject> object,
|
||||
HeapObjectType type)
|
||||
HeapObjectData::HeapObjectData(JSHeapBroker* broker, Handle<HeapObject> object)
|
||||
: ObjectData(broker, object, false),
|
||||
type_(type),
|
||||
boolean_value_(object->BooleanValue(broker->isolate())),
|
||||
map_(broker->GetOrCreateData(object->map())->AsMap()) {
|
||||
// We have to use a raw cast below instead of AsMap() because of
|
||||
// recursion. AsMap() would call IsMap(), which accesses the
|
||||
// instance_type_ member. In the case of constructing the MapData for the
|
||||
// meta map (whose map is itself), this member has not yet been
|
||||
// initialized.
|
||||
map_(static_cast<MapData*>(broker->GetOrCreateData(object->map()))) {
|
||||
CHECK(broker->SerializingAllowed());
|
||||
}
|
||||
|
||||
MapData::MapData(JSHeapBroker* broker, Handle<Map> object, HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type),
|
||||
MapData::MapData(JSHeapBroker* broker, Handle<Map> object)
|
||||
: HeapObjectData(broker, object),
|
||||
instance_type_(object->instance_type()),
|
||||
instance_size_(object->instance_size()),
|
||||
bit_field_(object->bit_field()),
|
||||
@ -632,9 +618,8 @@ MapData::MapData(JSHeapBroker* broker, Handle<Map> object, HeapObjectType type)
|
||||
elements_kind_generalizations_(broker->zone()),
|
||||
descriptors_(broker->zone()) {}
|
||||
|
||||
JSFunctionData::JSFunctionData(JSHeapBroker* broker, Handle<JSFunction> object,
|
||||
HeapObjectType type)
|
||||
: JSObjectData(broker, object, type),
|
||||
JSFunctionData::JSFunctionData(JSHeapBroker* broker, Handle<JSFunction> object)
|
||||
: JSObjectData(broker, object),
|
||||
has_initial_map_(object->has_prototype_slot() &&
|
||||
object->has_initial_map()),
|
||||
has_prototype_(object->has_prototype_slot() && object->has_prototype()),
|
||||
@ -702,8 +687,7 @@ class FeedbackVectorData : public HeapObjectData {
|
||||
public:
|
||||
const ZoneVector<ObjectData*>& feedback() { return feedback_; }
|
||||
|
||||
FeedbackVectorData(JSHeapBroker* broker, Handle<FeedbackVector> object,
|
||||
HeapObjectType type);
|
||||
FeedbackVectorData(JSHeapBroker* broker, Handle<FeedbackVector> object);
|
||||
|
||||
void SerializeSlots();
|
||||
|
||||
@ -713,9 +697,8 @@ class FeedbackVectorData : public HeapObjectData {
|
||||
};
|
||||
|
||||
FeedbackVectorData::FeedbackVectorData(JSHeapBroker* broker,
|
||||
Handle<FeedbackVector> object,
|
||||
HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type), feedback_(broker->zone()) {}
|
||||
Handle<FeedbackVector> object)
|
||||
: HeapObjectData(broker, object), feedback_(broker->zone()) {}
|
||||
|
||||
void FeedbackVectorData::SerializeSlots() {
|
||||
if (serialized_) return;
|
||||
@ -744,9 +727,8 @@ void FeedbackVectorData::SerializeSlots() {
|
||||
|
||||
class FixedArrayBaseData : public HeapObjectData {
|
||||
public:
|
||||
FixedArrayBaseData(JSHeapBroker* broker, Handle<FixedArrayBase> object,
|
||||
HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type), length_(object->length()) {}
|
||||
FixedArrayBaseData(JSHeapBroker* broker, Handle<FixedArrayBase> object)
|
||||
: HeapObjectData(broker, object), length_(object->length()) {}
|
||||
|
||||
int length() const { return length_; }
|
||||
|
||||
@ -754,14 +736,12 @@ class FixedArrayBaseData : public HeapObjectData {
|
||||
int const length_;
|
||||
};
|
||||
|
||||
JSObjectData::JSObjectData(JSHeapBroker* broker, Handle<JSObject> object,
|
||||
HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type), inobject_fields_(broker->zone()) {}
|
||||
JSObjectData::JSObjectData(JSHeapBroker* broker, Handle<JSObject> object)
|
||||
: HeapObjectData(broker, object), inobject_fields_(broker->zone()) {}
|
||||
|
||||
class FixedArrayData : public FixedArrayBaseData {
|
||||
public:
|
||||
FixedArrayData(JSHeapBroker* broker, Handle<FixedArray> object,
|
||||
HeapObjectType type);
|
||||
FixedArrayData(JSHeapBroker* broker, Handle<FixedArray> object);
|
||||
|
||||
// Creates all elements of the fixed array.
|
||||
void SerializeContents();
|
||||
@ -788,14 +768,12 @@ void FixedArrayData::SerializeContents() {
|
||||
}
|
||||
}
|
||||
|
||||
FixedArrayData::FixedArrayData(JSHeapBroker* broker, Handle<FixedArray> object,
|
||||
HeapObjectType type)
|
||||
: FixedArrayBaseData(broker, object, type), contents_(broker->zone()) {}
|
||||
FixedArrayData::FixedArrayData(JSHeapBroker* broker, Handle<FixedArray> object)
|
||||
: FixedArrayBaseData(broker, object), contents_(broker->zone()) {}
|
||||
|
||||
class FixedDoubleArrayData : public FixedArrayBaseData {
|
||||
public:
|
||||
FixedDoubleArrayData(JSHeapBroker* broker, Handle<FixedDoubleArray> object,
|
||||
HeapObjectType type);
|
||||
FixedDoubleArrayData(JSHeapBroker* broker, Handle<FixedDoubleArray> object);
|
||||
|
||||
// Serializes all elements of the fixed array.
|
||||
void SerializeContents();
|
||||
@ -808,9 +786,8 @@ class FixedDoubleArrayData : public FixedArrayBaseData {
|
||||
};
|
||||
|
||||
FixedDoubleArrayData::FixedDoubleArrayData(JSHeapBroker* broker,
|
||||
Handle<FixedDoubleArray> object,
|
||||
HeapObjectType type)
|
||||
: FixedArrayBaseData(broker, object, type), contents_(broker->zone()) {}
|
||||
Handle<FixedDoubleArray> object)
|
||||
: FixedArrayBaseData(broker, object), contents_(broker->zone()) {}
|
||||
|
||||
void FixedDoubleArrayData::SerializeContents() {
|
||||
if (serialized_contents_) return;
|
||||
@ -830,9 +807,8 @@ class BytecodeArrayData : public FixedArrayBaseData {
|
||||
public:
|
||||
int register_count() const { return register_count_; }
|
||||
|
||||
BytecodeArrayData(JSHeapBroker* broker, Handle<BytecodeArray> object,
|
||||
HeapObjectType type)
|
||||
: FixedArrayBaseData(broker, object, type),
|
||||
BytecodeArrayData(JSHeapBroker* broker, Handle<BytecodeArray> object)
|
||||
: FixedArrayBaseData(broker, object),
|
||||
register_count_(object->register_count()) {}
|
||||
|
||||
private:
|
||||
@ -841,8 +817,7 @@ class BytecodeArrayData : public FixedArrayBaseData {
|
||||
|
||||
class JSArrayData : public JSObjectData {
|
||||
public:
|
||||
JSArrayData(JSHeapBroker* broker, Handle<JSArray> object,
|
||||
HeapObjectType type);
|
||||
JSArrayData(JSHeapBroker* broker, Handle<JSArray> object);
|
||||
void Serialize();
|
||||
|
||||
ObjectData* length() const { return length_; }
|
||||
@ -852,9 +827,8 @@ class JSArrayData : public JSObjectData {
|
||||
ObjectData* length_ = nullptr;
|
||||
};
|
||||
|
||||
JSArrayData::JSArrayData(JSHeapBroker* broker, Handle<JSArray> object,
|
||||
HeapObjectType type)
|
||||
: JSObjectData(broker, object, type) {}
|
||||
JSArrayData::JSArrayData(JSHeapBroker* broker, Handle<JSArray> object)
|
||||
: JSObjectData(broker, object) {}
|
||||
|
||||
void JSArrayData::Serialize() {
|
||||
if (serialized_) return;
|
||||
@ -867,8 +841,7 @@ void JSArrayData::Serialize() {
|
||||
|
||||
class ScopeInfoData : public HeapObjectData {
|
||||
public:
|
||||
ScopeInfoData(JSHeapBroker* broker, Handle<ScopeInfo> object,
|
||||
HeapObjectType type);
|
||||
ScopeInfoData(JSHeapBroker* broker, Handle<ScopeInfo> object);
|
||||
|
||||
int context_length() const { return context_length_; }
|
||||
|
||||
@ -876,9 +849,8 @@ class ScopeInfoData : public HeapObjectData {
|
||||
int const context_length_;
|
||||
};
|
||||
|
||||
ScopeInfoData::ScopeInfoData(JSHeapBroker* broker, Handle<ScopeInfo> object,
|
||||
HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type),
|
||||
ScopeInfoData::ScopeInfoData(JSHeapBroker* broker, Handle<ScopeInfo> object)
|
||||
: HeapObjectData(broker, object),
|
||||
context_length_(object->ContextLength()) {}
|
||||
|
||||
class SharedFunctionInfoData : public HeapObjectData {
|
||||
@ -891,8 +863,8 @@ class SharedFunctionInfoData : public HeapObjectData {
|
||||
#undef DECL_ACCESSOR
|
||||
|
||||
SharedFunctionInfoData(JSHeapBroker* broker,
|
||||
Handle<SharedFunctionInfo> object, HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type),
|
||||
Handle<SharedFunctionInfo> object)
|
||||
: HeapObjectData(broker, object),
|
||||
builtin_id_(object->HasBuiltinId() ? object->builtin_id()
|
||||
: Builtins::kNoBuiltinId),
|
||||
GetBytecodeArray_(
|
||||
@ -918,7 +890,7 @@ class SharedFunctionInfoData : public HeapObjectData {
|
||||
|
||||
class ModuleData : public HeapObjectData {
|
||||
public:
|
||||
ModuleData(JSHeapBroker* broker, Handle<Module> object, HeapObjectType type);
|
||||
ModuleData(JSHeapBroker* broker, Handle<Module> object);
|
||||
void Serialize();
|
||||
|
||||
CellData* GetCell(int cell_index) const;
|
||||
@ -929,9 +901,8 @@ class ModuleData : public HeapObjectData {
|
||||
ZoneVector<CellData*> exports_;
|
||||
};
|
||||
|
||||
ModuleData::ModuleData(JSHeapBroker* broker, Handle<Module> object,
|
||||
HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type),
|
||||
ModuleData::ModuleData(JSHeapBroker* broker, Handle<Module> object)
|
||||
: HeapObjectData(broker, object),
|
||||
imports_(broker->zone()),
|
||||
exports_(broker->zone()) {}
|
||||
|
||||
@ -980,21 +951,20 @@ void ModuleData::Serialize() {
|
||||
|
||||
class CellData : public HeapObjectData {
|
||||
public:
|
||||
CellData(JSHeapBroker* broker, Handle<Cell> object, HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type) {}
|
||||
CellData(JSHeapBroker* broker, Handle<Cell> object)
|
||||
: HeapObjectData(broker, object) {}
|
||||
};
|
||||
|
||||
class JSGlobalProxyData : public JSObjectData {
|
||||
public:
|
||||
JSGlobalProxyData(JSHeapBroker* broker, Handle<JSGlobalProxy> object,
|
||||
HeapObjectType type)
|
||||
: JSObjectData(broker, object, type) {}
|
||||
JSGlobalProxyData(JSHeapBroker* broker, Handle<JSGlobalProxy> object)
|
||||
: JSObjectData(broker, object) {}
|
||||
};
|
||||
|
||||
class CodeData : public HeapObjectData {
|
||||
public:
|
||||
CodeData(JSHeapBroker* broker, Handle<Code> object, HeapObjectType type)
|
||||
: HeapObjectData(broker, object, type) {}
|
||||
CodeData(JSHeapBroker* broker, Handle<Code> object)
|
||||
: HeapObjectData(broker, object) {}
|
||||
};
|
||||
|
||||
#define DEFINE_IS_AND_AS(Name) \
|
||||
@ -1005,7 +975,7 @@ class CodeData : public HeapObjectData {
|
||||
} \
|
||||
if (is_smi()) return false; \
|
||||
InstanceType instance_type = \
|
||||
static_cast<const HeapObjectData*>(this)->type().instance_type(); \
|
||||
static_cast<const HeapObjectData*>(this)->map()->instance_type(); \
|
||||
return InstanceTypeChecker::Is##Name(instance_type); \
|
||||
} \
|
||||
Name##Data* ObjectData::As##Name() { \
|
||||
@ -1214,12 +1184,11 @@ HeapObjectData* HeapObjectData::Serialize(JSHeapBroker* broker,
|
||||
Handle<HeapObject> object) {
|
||||
CHECK(broker->SerializingAllowed());
|
||||
Handle<Map> map(object->map(), broker->isolate());
|
||||
HeapObjectType type = broker->HeapObjectTypeFromMap(map);
|
||||
|
||||
#define RETURN_CREATE_DATA_IF_MATCH(name) \
|
||||
if (object->Is##name()) { \
|
||||
return new (broker->zone()) \
|
||||
name##Data(broker, Handle<name>::cast(object), type); \
|
||||
#define RETURN_CREATE_DATA_IF_MATCH(name) \
|
||||
if (object->Is##name()) { \
|
||||
return new (broker->zone()) \
|
||||
name##Data(broker, Handle<name>::cast(object)); \
|
||||
}
|
||||
HEAP_BROKER_OBJECT_LIST(RETURN_CREATE_DATA_IF_MATCH)
|
||||
#undef RETURN_CREATE_DATA_IF_MATCH
|
||||
@ -1392,36 +1361,6 @@ void JSHeapBroker::SerializeStandardObjects() {
|
||||
Trace("Finished serializing standard objects.\n");
|
||||
}
|
||||
|
||||
HeapObjectType JSHeapBroker::HeapObjectTypeFromMap(Map* map) const {
|
||||
AllowHandleDereference allow_handle_dereference;
|
||||
OddballType oddball_type = OddballType::kNone;
|
||||
if (map->instance_type() == ODDBALL_TYPE) {
|
||||
ReadOnlyRoots roots(isolate_);
|
||||
if (map == roots.undefined_map()) {
|
||||
oddball_type = OddballType::kUndefined;
|
||||
} else if (map == roots.null_map()) {
|
||||
oddball_type = OddballType::kNull;
|
||||
} else if (map == roots.boolean_map()) {
|
||||
oddball_type = OddballType::kBoolean;
|
||||
} else if (map == roots.the_hole_map()) {
|
||||
oddball_type = OddballType::kHole;
|
||||
} else if (map == roots.uninitialized_map()) {
|
||||
oddball_type = OddballType::kUninitialized;
|
||||
} else {
|
||||
oddball_type = OddballType::kOther;
|
||||
DCHECK(map == roots.termination_exception_map() ||
|
||||
map == roots.arguments_marker_map() ||
|
||||
map == roots.optimized_out_map() ||
|
||||
map == roots.stale_register_map());
|
||||
}
|
||||
}
|
||||
HeapObjectType::Flags flags(0);
|
||||
if (map->is_undetectable()) flags |= HeapObjectType::kUndetectable;
|
||||
if (map->is_callable()) flags |= HeapObjectType::kCallable;
|
||||
|
||||
return HeapObjectType(map->instance_type(), flags, oddball_type);
|
||||
}
|
||||
|
||||
ObjectData* JSHeapBroker::GetData(Handle<Object> object) const {
|
||||
auto it = refs_.find(object.address());
|
||||
return it != refs_.end() ? it->second : nullptr;
|
||||
@ -1473,14 +1412,6 @@ int ObjectRef::AsSmi() const {
|
||||
return object<Smi>()->value();
|
||||
}
|
||||
|
||||
HeapObjectType HeapObjectRef::type() const {
|
||||
if (broker()->mode() == JSHeapBroker::kDisabled) {
|
||||
AllowHandleDereference allow_handle_dereference;
|
||||
return broker()->HeapObjectTypeFromMap(object<HeapObject>()->map());
|
||||
}
|
||||
return data()->AsHeapObject()->type();
|
||||
}
|
||||
|
||||
NativeContextRef JSHeapBroker::native_context() {
|
||||
AllowHandleAllocation handle_allocation;
|
||||
return NativeContextRef(this, isolate()->native_context());
|
||||
@ -1552,8 +1483,31 @@ ScriptContextTableRef::lookup(const NameRef& name) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
OddballType ObjectRef::oddball_type() const {
|
||||
return IsSmi() ? OddballType::kNone : AsHeapObject().type().oddball_type();
|
||||
OddballType MapRef::oddball_type() const {
|
||||
if (instance_type() != ODDBALL_TYPE) {
|
||||
return OddballType::kNone;
|
||||
}
|
||||
Factory* f = broker()->isolate()->factory();
|
||||
if (equals(MapRef(broker(), f->undefined_map()))) {
|
||||
return OddballType::kUndefined;
|
||||
}
|
||||
if (equals(MapRef(broker(), f->null_map()))) {
|
||||
return OddballType::kNull;
|
||||
}
|
||||
if (equals(MapRef(broker(), f->boolean_map()))) {
|
||||
return OddballType::kBoolean;
|
||||
}
|
||||
if (equals(MapRef(broker(), f->the_hole_map()))) {
|
||||
return OddballType::kHole;
|
||||
}
|
||||
if (equals(MapRef(broker(), f->uninitialized_map()))) {
|
||||
return OddballType::kUninitialized;
|
||||
}
|
||||
DCHECK(equals(MapRef(broker(), f->termination_exception_map())) ||
|
||||
equals(MapRef(broker(), f->arguments_marker_map())) ||
|
||||
equals(MapRef(broker(), f->optimized_out_map())) ||
|
||||
equals(MapRef(broker(), f->stale_register_map())));
|
||||
return OddballType::kOther;
|
||||
}
|
||||
|
||||
ObjectRef FeedbackVectorRef::get(FeedbackSlot slot) const {
|
||||
@ -1817,7 +1771,9 @@ BIMODAL_ACCESSOR_B(Map, bit_field3, is_dictionary_map, Map::IsDictionaryMapBit)
|
||||
BIMODAL_ACCESSOR_B(Map, bit_field3, NumberOfOwnDescriptors,
|
||||
Map::NumberOfOwnDescriptorsBits)
|
||||
BIMODAL_ACCESSOR_B(Map, bit_field, has_prototype_slot, Map::HasPrototypeSlotBit)
|
||||
BIMODAL_ACCESSOR_B(Map, bit_field, is_callable, Map::IsCallableBit)
|
||||
BIMODAL_ACCESSOR_B(Map, bit_field, is_constructor, Map::IsConstructorBit)
|
||||
BIMODAL_ACCESSOR_B(Map, bit_field, is_undetectable, Map::IsUndetectableBit)
|
||||
BIMODAL_ACCESSOR_C(Map, int, instance_size)
|
||||
BIMODAL_ACCESSOR(Map, Object, prototype)
|
||||
BIMODAL_ACCESSOR_C(Map, InstanceType, instance_type)
|
||||
@ -1925,7 +1881,7 @@ bool ObjectRef::BooleanValue() const {
|
||||
}
|
||||
|
||||
double ObjectRef::OddballToNumber() const {
|
||||
OddballType type = oddball_type();
|
||||
OddballType type = AsHeapObject().map().oddball_type();
|
||||
|
||||
switch (type) {
|
||||
case OddballType::kBoolean: {
|
||||
@ -1990,6 +1946,49 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object) {
|
||||
CHECK_NOT_NULL(data_);
|
||||
}
|
||||
|
||||
namespace {
|
||||
OddballType GetOddballType(Isolate* isolate, Map* map) {
|
||||
if (map->instance_type() != ODDBALL_TYPE) {
|
||||
return OddballType::kNone;
|
||||
}
|
||||
ReadOnlyRoots roots(isolate);
|
||||
if (map == roots.undefined_map()) {
|
||||
return OddballType::kUndefined;
|
||||
}
|
||||
if (map == roots.null_map()) {
|
||||
return OddballType::kNull;
|
||||
}
|
||||
if (map == roots.boolean_map()) {
|
||||
return OddballType::kBoolean;
|
||||
}
|
||||
if (map == roots.the_hole_map()) {
|
||||
return OddballType::kHole;
|
||||
}
|
||||
if (map == roots.uninitialized_map()) {
|
||||
return OddballType::kUninitialized;
|
||||
}
|
||||
DCHECK(map == roots.termination_exception_map() ||
|
||||
map == roots.arguments_marker_map() ||
|
||||
map == roots.optimized_out_map() || map == roots.stale_register_map());
|
||||
return OddballType::kOther;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
HeapObjectType HeapObjectRef::GetHeapObjectType() const {
|
||||
if (broker()->mode() == JSHeapBroker::kDisabled) {
|
||||
AllowHandleDereference handle_dereference;
|
||||
Map* map = Handle<HeapObject>::cast(object())->map();
|
||||
HeapObjectType::Flags flags(0);
|
||||
if (map->is_undetectable()) flags |= HeapObjectType::kUndetectable;
|
||||
if (map->is_callable()) flags |= HeapObjectType::kCallable;
|
||||
return HeapObjectType(map->instance_type(), flags,
|
||||
GetOddballType(broker()->isolate(), map));
|
||||
}
|
||||
HeapObjectType::Flags flags(0);
|
||||
if (map().is_undetectable()) flags |= HeapObjectType::kUndetectable;
|
||||
if (map().is_callable()) flags |= HeapObjectType::kCallable;
|
||||
return HeapObjectType(map().instance_type(), flags, map().oddball_type());
|
||||
}
|
||||
base::Optional<JSObjectRef> AllocationSiteRef::boilerplate() const {
|
||||
if (broker()->mode() == JSHeapBroker::kDisabled) {
|
||||
AllowHandleAllocation handle_allocation;
|
||||
@ -2080,9 +2079,8 @@ Reduction NoChangeBecauseOfMissingData(JSHeapBroker* broker,
|
||||
}
|
||||
|
||||
NativeContextData::NativeContextData(JSHeapBroker* broker,
|
||||
Handle<NativeContext> object,
|
||||
HeapObjectType type)
|
||||
: ContextData(broker, object, type), function_maps_(broker->zone()) {}
|
||||
Handle<NativeContext> object)
|
||||
: ContextData(broker, object), function_maps_(broker->zone()) {}
|
||||
|
||||
void NativeContextData::Serialize() {
|
||||
if (serialized_) return;
|
||||
|
@ -25,35 +25,6 @@ enum class OddballType : uint8_t {
|
||||
kOther // Oddball, but none of the above.
|
||||
};
|
||||
|
||||
// TODO(neis): Get rid of the HeapObjectType class.
|
||||
class HeapObjectType {
|
||||
public:
|
||||
enum Flag : uint8_t { kUndetectable = 1 << 0, kCallable = 1 << 1 };
|
||||
|
||||
typedef base::Flags<Flag> Flags;
|
||||
|
||||
HeapObjectType(InstanceType instance_type, Flags flags,
|
||||
OddballType oddball_type)
|
||||
: instance_type_(instance_type),
|
||||
oddball_type_(oddball_type),
|
||||
flags_(flags) {
|
||||
DCHECK_EQ(instance_type == ODDBALL_TYPE,
|
||||
oddball_type != OddballType::kNone);
|
||||
}
|
||||
|
||||
OddballType oddball_type() const { return oddball_type_; }
|
||||
InstanceType instance_type() const { return instance_type_; }
|
||||
Flags flags() const { return flags_; }
|
||||
|
||||
bool is_callable() const { return flags_ & kCallable; }
|
||||
bool is_undetectable() const { return flags_ & kUndetectable; }
|
||||
|
||||
private:
|
||||
InstanceType const instance_type_;
|
||||
OddballType const oddball_type_;
|
||||
Flags const flags_;
|
||||
};
|
||||
|
||||
// This list is sorted such that subtypes appear before their supertypes.
|
||||
// DO NOT VIOLATE THIS PROPERTY!
|
||||
#define HEAP_BROKER_OBJECT_LIST(V) \
|
||||
@ -114,8 +85,6 @@ class ObjectRef {
|
||||
return Handle<T>::cast(object());
|
||||
}
|
||||
|
||||
OddballType oddball_type() const;
|
||||
|
||||
bool IsSmi() const;
|
||||
int AsSmi() const;
|
||||
|
||||
@ -140,12 +109,49 @@ class ObjectRef {
|
||||
ObjectData* data_;
|
||||
};
|
||||
|
||||
// Temporary class that carries information from a Map. We'd like to remove
|
||||
// this class and use MapRef instead, but we can't as long as we support the
|
||||
// kDisabled broker mode. That's because obtaining the MapRef via
|
||||
// HeapObjectRef::map() requires a HandleScope when the broker is disabled.
|
||||
// During OptimizeGraph we generally don't have a HandleScope, however. There
|
||||
// are two places where we therefore use GetHeapObjectType() instead. Both that
|
||||
// function and this class should eventually be removed.
|
||||
class HeapObjectType {
|
||||
public:
|
||||
enum Flag : uint8_t { kUndetectable = 1 << 0, kCallable = 1 << 1 };
|
||||
|
||||
typedef base::Flags<Flag> Flags;
|
||||
|
||||
HeapObjectType(InstanceType instance_type, Flags flags,
|
||||
OddballType oddball_type)
|
||||
: instance_type_(instance_type),
|
||||
oddball_type_(oddball_type),
|
||||
flags_(flags) {
|
||||
DCHECK_EQ(instance_type == ODDBALL_TYPE,
|
||||
oddball_type != OddballType::kNone);
|
||||
}
|
||||
|
||||
OddballType oddball_type() const { return oddball_type_; }
|
||||
InstanceType instance_type() const { return instance_type_; }
|
||||
Flags flags() const { return flags_; }
|
||||
|
||||
bool is_callable() const { return flags_ & kCallable; }
|
||||
bool is_undetectable() const { return flags_ & kUndetectable; }
|
||||
|
||||
private:
|
||||
InstanceType const instance_type_;
|
||||
OddballType const oddball_type_;
|
||||
Flags const flags_;
|
||||
};
|
||||
|
||||
class HeapObjectRef : public ObjectRef {
|
||||
public:
|
||||
using ObjectRef::ObjectRef;
|
||||
|
||||
HeapObjectType type() const;
|
||||
MapRef map() const;
|
||||
|
||||
// See the comment on the HeapObjectType class.
|
||||
HeapObjectType GetHeapObjectType() const;
|
||||
};
|
||||
|
||||
class PropertyCellRef : public HeapObjectRef {
|
||||
@ -327,10 +333,14 @@ class MapRef : public HeapObjectRef {
|
||||
bool IsInobjectSlackTrackingInProgress() const;
|
||||
bool is_dictionary_map() const;
|
||||
bool IsFixedCowArrayMap() const;
|
||||
bool is_undetectable() const;
|
||||
bool is_callable() const;
|
||||
|
||||
ObjectRef constructor_or_backpointer() const;
|
||||
ObjectRef prototype() const;
|
||||
|
||||
OddballType oddball_type() const;
|
||||
|
||||
base::Optional<MapRef> AsElementsKind(ElementsKind kind) const;
|
||||
|
||||
// Concerning the underlying instance_descriptors:
|
||||
@ -456,11 +466,6 @@ class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) {
|
||||
JSHeapBroker(Isolate* isolate, Zone* zone);
|
||||
void SerializeStandardObjects();
|
||||
|
||||
HeapObjectType HeapObjectTypeFromMap(Handle<Map> map) const {
|
||||
AllowHandleDereference handle_dereference;
|
||||
return HeapObjectTypeFromMap(*map);
|
||||
}
|
||||
|
||||
Isolate* isolate() const { return isolate_; }
|
||||
Zone* zone() const { return zone_; }
|
||||
|
||||
@ -488,9 +493,6 @@ class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) {
|
||||
friend class ObjectRef;
|
||||
friend class ObjectData;
|
||||
|
||||
// TODO(neis): Remove eventually.
|
||||
HeapObjectType HeapObjectTypeFromMap(Map* map) const;
|
||||
|
||||
void AddData(Handle<Object> object, ObjectData* data);
|
||||
|
||||
Isolate* const isolate_;
|
||||
|
@ -664,20 +664,19 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
|
||||
property_cell_value_type = Type::Number();
|
||||
representation = MachineRepresentation::kTaggedPointer;
|
||||
} else {
|
||||
Handle<Map> property_cell_value_map(
|
||||
Handle<HeapObject>::cast(property_cell_value)->map(),
|
||||
isolate());
|
||||
property_cell_value_type =
|
||||
Type::For(js_heap_broker(), property_cell_value_map);
|
||||
MapRef property_cell_value_map(
|
||||
js_heap_broker(),
|
||||
handle(HeapObject::cast(*property_cell_value)->map(),
|
||||
isolate()));
|
||||
property_cell_value_type = Type::For(property_cell_value_map);
|
||||
representation = MachineRepresentation::kTaggedPointer;
|
||||
|
||||
// We can only use the property cell value map for map check
|
||||
// elimination if it's stable, i.e. the HeapObject wasn't
|
||||
// mutated without the cell state being updated.
|
||||
if (property_cell_value_map->is_stable()) {
|
||||
dependencies()->DependOnStableMap(
|
||||
MapRef(js_heap_broker(), property_cell_value_map));
|
||||
map = property_cell_value_map;
|
||||
if (property_cell_value_map.is_stable()) {
|
||||
dependencies()->DependOnStableMap(property_cell_value_map);
|
||||
map = property_cell_value_map.object<Map>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -780,8 +779,8 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadGlobal(Node* node) {
|
||||
native_context().script_context_table().lookup(name);
|
||||
if (result) {
|
||||
ObjectRef contents = result->context.get(result->index);
|
||||
OddballType oddball_type = contents.oddball_type();
|
||||
if (oddball_type == OddballType::kHole) {
|
||||
if (contents.IsHeapObject() &&
|
||||
contents.AsHeapObject().map().oddball_type() == OddballType::kHole) {
|
||||
return NoChange();
|
||||
}
|
||||
Node* context = jsgraph()->Constant(result->context);
|
||||
@ -809,8 +808,9 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) {
|
||||
native_context().script_context_table().lookup(name);
|
||||
if (result) {
|
||||
ObjectRef contents = result->context.get(result->index);
|
||||
OddballType oddball_type = contents.oddball_type();
|
||||
if (oddball_type == OddballType::kHole || result->immutable) {
|
||||
if ((contents.IsHeapObject() &&
|
||||
contents.AsHeapObject().map().oddball_type() == OddballType::kHole) ||
|
||||
result->immutable) {
|
||||
return NoChange();
|
||||
}
|
||||
Node* context = jsgraph()->Constant(result->context);
|
||||
|
@ -952,8 +952,8 @@ Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) {
|
||||
}
|
||||
}
|
||||
if (input_type.IsHeapConstant()) {
|
||||
ObjectRef input_value = input_type.AsHeapConstant()->Ref();
|
||||
if (input_value.oddball_type() != OddballType::kNone) {
|
||||
HeapObjectRef input_value = input_type.AsHeapConstant()->Ref();
|
||||
if (input_value.map().oddball_type() != OddballType::kNone) {
|
||||
return Replace(jsgraph()->Constant(input_value.OddballToNumber()));
|
||||
}
|
||||
}
|
||||
|
@ -132,8 +132,11 @@ Type::bitset Type::BitsetLub() const {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
Type::bitset BitsetType::Lub(HeapObjectType const& type) {
|
||||
switch (type.instance_type()) {
|
||||
// TODO(neis): Once the broker mode kDisabled is gone, change the input type to
|
||||
// MapRef and get rid of the HeapObjectType class.
|
||||
template <typename MapRefLike>
|
||||
Type::bitset BitsetType::Lub(const MapRefLike& map) {
|
||||
switch (map.instance_type()) {
|
||||
case CONS_STRING_TYPE:
|
||||
case CONS_ONE_BYTE_STRING_TYPE:
|
||||
case THIN_STRING_TYPE:
|
||||
@ -163,7 +166,7 @@ Type::bitset BitsetType::Lub(HeapObjectType const& type) {
|
||||
case BIGINT_TYPE:
|
||||
return kBigInt;
|
||||
case ODDBALL_TYPE:
|
||||
switch (type.oddball_type()) {
|
||||
switch (map.oddball_type()) {
|
||||
case OddballType::kNone:
|
||||
break;
|
||||
case OddballType::kHole:
|
||||
@ -189,15 +192,15 @@ Type::bitset BitsetType::Lub(HeapObjectType const& type) {
|
||||
case JS_GLOBAL_PROXY_TYPE:
|
||||
case JS_API_OBJECT_TYPE:
|
||||
case JS_SPECIAL_API_OBJECT_TYPE:
|
||||
if (type.is_undetectable()) {
|
||||
if (map.is_undetectable()) {
|
||||
// Currently we assume that every undetectable receiver is also
|
||||
// callable, which is what we need to support document.all. We
|
||||
// could add another Type bit to support other use cases in the
|
||||
// future if necessary.
|
||||
DCHECK(type.is_callable());
|
||||
DCHECK(map.is_callable());
|
||||
return kOtherUndetectable;
|
||||
}
|
||||
if (type.is_callable()) {
|
||||
if (map.is_callable()) {
|
||||
return kOtherCallable;
|
||||
}
|
||||
return kOtherObject;
|
||||
@ -244,18 +247,18 @@ Type::bitset BitsetType::Lub(HeapObjectType const& type) {
|
||||
case WASM_MEMORY_TYPE:
|
||||
case WASM_MODULE_TYPE:
|
||||
case WASM_TABLE_TYPE:
|
||||
DCHECK(!type.is_callable());
|
||||
DCHECK(!type.is_undetectable());
|
||||
DCHECK(!map.is_callable());
|
||||
DCHECK(!map.is_undetectable());
|
||||
return kOtherObject;
|
||||
case JS_BOUND_FUNCTION_TYPE:
|
||||
DCHECK(!type.is_undetectable());
|
||||
DCHECK(!map.is_undetectable());
|
||||
return kBoundFunction;
|
||||
case JS_FUNCTION_TYPE:
|
||||
DCHECK(!type.is_undetectable());
|
||||
DCHECK(!map.is_undetectable());
|
||||
return kFunction;
|
||||
case JS_PROXY_TYPE:
|
||||
DCHECK(!type.is_undetectable());
|
||||
if (type.is_callable()) return kCallableProxy;
|
||||
DCHECK(!map.is_undetectable());
|
||||
if (map.is_callable()) return kCallableProxy;
|
||||
return kOtherProxy;
|
||||
case MAP_TYPE:
|
||||
case ALLOCATION_SITE_TYPE:
|
||||
@ -352,6 +355,9 @@ Type::bitset BitsetType::Lub(HeapObjectType const& type) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// Explicit instantiation.
|
||||
template Type::bitset BitsetType::Lub<MapRef>(const MapRef& map);
|
||||
|
||||
Type::bitset BitsetType::Lub(double value) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (IsMinusZero(value)) return kMinusZero;
|
||||
|
@ -253,7 +253,10 @@ class V8_EXPORT_PRIVATE BitsetType {
|
||||
static double Max(bitset);
|
||||
|
||||
static bitset Glb(double min, double max);
|
||||
static bitset Lub(HeapObjectType const& type);
|
||||
static bitset Lub(HeapObjectType const& type) {
|
||||
return Lub<HeapObjectType>(type);
|
||||
}
|
||||
static bitset Lub(MapRef const& map) { return Lub<MapRef>(map); }
|
||||
static bitset Lub(double value);
|
||||
static bitset Lub(double min, double max);
|
||||
static bitset ExpandInternals(bitset bits);
|
||||
@ -275,6 +278,9 @@ class V8_EXPORT_PRIVATE BitsetType {
|
||||
static const Boundary BoundariesArray[];
|
||||
static inline const Boundary* Boundaries();
|
||||
static inline size_t BoundariesSize();
|
||||
|
||||
template <typename MapRefLike>
|
||||
static bitset Lub(MapRefLike const& map);
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -379,8 +385,10 @@ class V8_EXPORT_PRIVATE Type {
|
||||
static Type Union(Type type1, Type type2, Zone* zone);
|
||||
static Type Intersect(Type type1, Type type2, Zone* zone);
|
||||
|
||||
static Type For(JSHeapBroker* js_heap_broker, Handle<i::Map> map) {
|
||||
HeapObjectType type = js_heap_broker->HeapObjectTypeFromMap(map);
|
||||
static Type For(HeapObjectType const& type) {
|
||||
return NewBitset(BitsetType::ExpandInternals(BitsetType::Lub(type)));
|
||||
}
|
||||
static Type For(MapRef const& type) {
|
||||
return NewBitset(BitsetType::ExpandInternals(BitsetType::Lub(type)));
|
||||
}
|
||||
|
||||
@ -547,7 +555,7 @@ class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) {
|
||||
static HeapConstantType* New(const HeapObjectRef& heap_ref, Zone* zone) {
|
||||
DCHECK(!heap_ref.IsHeapNumber());
|
||||
DCHECK_IMPLIES(heap_ref.IsString(), heap_ref.IsInternalizedString());
|
||||
BitsetType::bitset bitset = BitsetType::Lub(heap_ref.type());
|
||||
BitsetType::bitset bitset = BitsetType::Lub(heap_ref.GetHeapObjectType());
|
||||
return new (zone->New(sizeof(HeapConstantType)))
|
||||
HeapConstantType(bitset, heap_ref);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user