5 #ifndef V8_PROPERTY_DETAILS_H_ 6 #define V8_PROPERTY_DETAILS_H_ 8 #include "include/v8.h" 9 #include "src/allocation.h" 11 #include "src/flags.h" 12 #include "src/utils.h" 18 enum PropertyAttributes {
20 READ_ONLY = ::v8::ReadOnly,
21 DONT_ENUM = ::v8::DontEnum,
22 DONT_DELETE = ::v8::DontDelete,
24 ALL_ATTRIBUTES_MASK = READ_ONLY | DONT_ENUM | DONT_DELETE,
27 FROZEN = SEALED | READ_ONLY,
40 ONLY_CONFIGURABLE = 4,
43 ONLY_ALL_CAN_READ = 32,
44 ENUMERABLE_STRINGS = ONLY_ENUMERABLE | SKIP_SYMBOLS,
47 STATIC_ASSERT(ALL_PROPERTIES == static_cast<PropertyFilter>(NONE));
48 STATIC_ASSERT(ONLY_WRITABLE == static_cast<PropertyFilter>(READ_ONLY));
49 STATIC_ASSERT(ONLY_ENUMERABLE == static_cast<PropertyFilter>(DONT_ENUM));
50 STATIC_ASSERT(ONLY_CONFIGURABLE == static_cast<PropertyFilter>(DONT_DELETE));
51 STATIC_ASSERT(((SKIP_STRINGS | SKIP_SYMBOLS | ONLY_ALL_CAN_READ) &
52 ALL_ATTRIBUTES_MASK) == 0);
53 STATIC_ASSERT(ALL_PROPERTIES ==
54 static_cast<PropertyFilter>(v8::PropertyFilter::ALL_PROPERTIES));
55 STATIC_ASSERT(ONLY_WRITABLE ==
56 static_cast<PropertyFilter>(v8::PropertyFilter::ONLY_WRITABLE));
57 STATIC_ASSERT(ONLY_ENUMERABLE ==
58 static_cast<PropertyFilter>(v8::PropertyFilter::ONLY_ENUMERABLE));
59 STATIC_ASSERT(ONLY_CONFIGURABLE == static_cast<PropertyFilter>(
60 v8::PropertyFilter::ONLY_CONFIGURABLE));
61 STATIC_ASSERT(SKIP_STRINGS ==
62 static_cast<PropertyFilter>(v8::PropertyFilter::SKIP_STRINGS));
63 STATIC_ASSERT(SKIP_SYMBOLS ==
64 static_cast<PropertyFilter>(v8::PropertyFilter::SKIP_SYMBOLS));
71 enum PropertyKind { kData = 0, kAccessor = 1 };
75 enum PropertyLocation { kField = 0, kDescriptor = 1 };
79 enum class PropertyConstness { kMutable = 0, kConst = 1 };
82 const PropertyConstness kDefaultFieldConstness =
83 FLAG_track_constant_fields ? PropertyConstness::kConst
84 : PropertyConstness::kMutable;
120 return kind_ == other.kind_;
124 return (IsDouble() && other.IsDouble()) ||
125 (!IsDouble() && !other.IsDouble());
129 return Equals(other);
133 if (kind_ == kExternal && other.kind_ == kNone)
return true;
134 if (kind_ == kExternal && other.kind_ == kExternal)
return false;
135 if (kind_ == kNone && other.kind_ == kExternal)
return false;
137 DCHECK_NE(kind_, kExternal);
138 DCHECK_NE(other.kind_, kExternal);
139 if (IsHeapObject())
return other.IsNone();
140 if (kind_ == kUInteger8 && other.kind_ == kInteger8)
return false;
141 if (kind_ == kUInteger16 && other.kind_ == kInteger16)
return false;
142 return kind_ > other.kind_;
146 return other.is_more_general_than(*
this) || other.Equals(*
this);
150 if (other.fits_into(*
this))
return *
this;
151 if (other.is_more_general_than(*
this))
return other;
152 return Representation::Tagged();
157 if (IsInteger8() || IsUInteger8()) {
158 return sizeof(uint8_t);
160 if (IsInteger16() || IsUInteger16()) {
161 return sizeof(uint16_t);
169 Kind kind()
const {
return static_cast<Kind
>(kind_); }
170 bool IsNone()
const {
return kind_ == kNone; }
171 bool IsInteger8()
const {
return kind_ == kInteger8; }
172 bool IsUInteger8()
const {
return kind_ == kUInteger8; }
173 bool IsInteger16()
const {
return kind_ == kInteger16; }
174 bool IsUInteger16()
const {
return kind_ == kUInteger16; }
175 bool IsTagged()
const {
return kind_ == kTagged; }
176 bool IsSmi()
const {
return kind_ == kSmi; }
177 bool IsSmiOrTagged()
const {
return IsSmi() || IsTagged(); }
178 bool IsInteger32()
const {
return kind_ == kInteger32; }
179 bool IsSmiOrInteger32()
const {
return IsSmi() || IsInteger32(); }
180 bool IsDouble()
const {
return kind_ == kDouble; }
181 bool IsHeapObject()
const {
return kind_ == kHeapObject; }
182 bool IsExternal()
const {
return kind_ == kExternal; }
183 bool IsSpecialization()
const {
184 return IsInteger8() || IsUInteger8() ||
185 IsInteger16() || IsUInteger16() ||
186 IsSmi() || IsInteger32() || IsDouble();
188 const char* Mnemonic()
const;
194 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
200 static const int kDescriptorIndexBitCount = 10;
201 static const int kFirstInobjectPropertyOffsetBitCount = 7;
205 static const int kMaxNumberOfDescriptors = (1 << kDescriptorIndexBitCount) - 4;
206 static const int kInvalidEnumCacheSentinel =
207 (1 << kDescriptorIndexBitCount) - 1;
209 enum class PropertyCellType {
217 kUninitialized = kUndefined,
218 kInvalidated = kConstant,
225 enum class PropertyCellConstantType {
237 PropertyCellType cell_type,
int dictionary_index = 0) {
238 value_ = KindField::encode(kind) | LocationField::encode(kField) |
239 AttributesField::encode(attributes) |
240 DictionaryStorageField::encode(dictionary_index) |
241 PropertyCellTypeField::encode(cell_type);
246 PropertyLocation location, PropertyConstness constness,
248 value_ = KindField::encode(kind) | AttributesField::encode(attributes) |
249 LocationField::encode(location) |
250 ConstnessField::encode(constness) |
251 RepresentationField::encode(EncodeRepresentation(representation)) |
252 FieldIndexField::encode(field_index);
256 PropertyCellType cell_type = PropertyCellType::kNoCell) {
260 int pointer()
const {
return DescriptorPointer::decode(value_); }
268 details.value_ = PropertyCellTypeField::update(details.value_,
type);
274 details.value_ = DictionaryStorageField::update(details.value_, index);
284 PropertyDetails CopyAddAttributes(PropertyAttributes new_attributes)
const {
286 static_cast<PropertyAttributes
>(attributes() | new_attributes);
292 inline Smi AsSmi()
const;
294 static uint8_t EncodeRepresentation(
Representation representation) {
295 return representation.kind();
299 return Representation::FromKind(static_cast<Representation::Kind>(bits));
302 PropertyKind kind()
const {
return KindField::decode(value_); }
303 PropertyLocation location()
const {
return LocationField::decode(value_); }
304 PropertyConstness constness()
const {
return ConstnessField::decode(value_); }
306 PropertyAttributes attributes()
const {
307 return AttributesField::decode(value_);
310 int dictionary_index()
const {
311 return DictionaryStorageField::decode(value_);
315 return DecodeRepresentation(RepresentationField::decode(value_));
318 int field_index()
const {
return FieldIndexField::decode(value_); }
320 inline int field_width_in_words()
const;
322 static bool IsValidIndex(
int index) {
323 return DictionaryStorageField::is_valid(index);
326 bool IsReadOnly()
const {
return (attributes() & READ_ONLY) != 0; }
327 bool IsConfigurable()
const {
return (attributes() & DONT_DELETE) == 0; }
328 bool IsDontEnum()
const {
return (attributes() & DONT_ENUM) != 0; }
329 bool IsEnumerable()
const {
return !IsDontEnum(); }
330 PropertyCellType cell_type()
const {
331 return PropertyCellTypeField::decode(value_);
340 :
public BitField<PropertyConstness, LocationField::kNext, 1> {};
342 :
public BitField<PropertyAttributes, ConstnessField::kNext, 3> {};
343 static const int kAttributesReadOnlyMask =
344 (READ_ONLY << AttributesField::kShift);
345 static const int kAttributesDontDeleteMask =
346 (DONT_DELETE << AttributesField::kShift);
347 static const int kAttributesDontEnumMask =
348 (DONT_ENUM << AttributesField::kShift);
352 :
public BitField<PropertyCellType, AttributesField::kNext, 2> {};
354 :
public BitField<uint32_t, PropertyCellTypeField::kNext, 23> {};
358 :
public BitField<uint32_t, AttributesField::kNext, 4> {};
360 :
public BitField<uint32_t, RepresentationField::kNext,
361 kDescriptorIndexBitCount> {};
363 kDescriptorIndexBitCount> {
367 STATIC_ASSERT(DictionaryStorageField::kNext <= 31);
368 STATIC_ASSERT(FieldIndexField::kNext <= 31);
370 static const int kInitialIndex = 1;
374 void Print(
bool dictionary_mode);
378 kPrintAttributes = 1 << 0,
379 kPrintFieldIndex = 1 << 1,
380 kPrintRepresentation = 1 << 2,
381 kPrintPointer = 1 << 3,
383 kForProperties = kPrintFieldIndex,
384 kForTransitions = kPrintAttributes,
387 void PrintAsSlowTo(std::ostream& out);
388 void PrintAsFastTo(std::ostream& out, PrintMode mode = kPrintFull);
392 value_ = DescriptorPointer::update(value, pointer);
394 PropertyDetails(
int value, Representation representation) {
395 value_ = RepresentationField::update(
396 value, EncodeRepresentation(representation));
398 PropertyDetails(
int value, PropertyConstness constness) {
399 value_ = ConstnessField::update(value, constness);
401 PropertyDetails(
int value, PropertyAttributes attributes) {
402 value_ = AttributesField::update(value, attributes);
410 inline bool IsGeneralizableTo(PropertyLocation a, PropertyLocation b) {
411 return b == kField || a == kDescriptor;
416 inline bool IsGeneralizableTo(PropertyConstness a, PropertyConstness b) {
417 return b == PropertyConstness::kMutable || a == PropertyConstness::kConst;
420 inline PropertyConstness GeneralizeConstness(PropertyConstness a,
421 PropertyConstness b) {
422 return a == PropertyConstness::kMutable ? PropertyConstness::kMutable : b;
425 std::ostream& operator<<(std::ostream& os,
426 const PropertyAttributes& attributes);
430 #endif // V8_PROPERTY_DETAILS_H_