v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
property-details.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_PROPERTY_DETAILS_H_
29 #define V8_PROPERTY_DETAILS_H_
30 
31 #include "../include/v8.h"
32 #include "allocation.h"
33 #include "utils.h"
34 
35 // Ecma-262 3rd 8.6.1
41 
44 
45  STRING = 8, // Used to filter symbols and string names
46  SYMBOLIC = 16,
48 
50  ABSENT = 64 // Used in runtime to indicate a property is absent.
51  // ABSENT can never be stored in or returned from a descriptor's attributes
52  // bitfield. It is only used as a return value meaning the attributes of
53  // a non-existent property.
54 };
55 
56 
57 namespace v8 {
58 namespace internal {
59 
60 class Smi;
61 template<class> class TypeImpl;
64 class TypeInfo;
65 
66 // Type of properties.
67 // Order of properties is significant.
68 // Must fit in the BitField PropertyDetails::TypeField.
69 // A copy of this is in mirror-debugger.js.
71  // Only in slow mode.
72  NORMAL = 0,
73  // Only in fast mode.
74  FIELD = 1,
75  CONSTANT = 2,
76  CALLBACKS = 3,
77  // Only in lookup results, not in descriptors.
78  HANDLER = 4,
81  // Only used as a marker in LookupResult.
83 };
84 
85 
87  public:
88  enum Kind {
101  };
102 
103  Representation() : kind_(kNone) { }
104 
105  static Representation None() { return Representation(kNone); }
111  static Representation Smi() { return Representation(kSmi); }
116 
117  static Representation FromKind(Kind kind) { return Representation(kind); }
118 
119  static Representation FromType(Type* type);
120 
121  bool Equals(const Representation& other) const {
122  return kind_ == other.kind_;
123  }
124 
125  bool IsCompatibleForLoad(const Representation& other) const {
126  return (IsDouble() && other.IsDouble()) ||
127  (!IsDouble() && !other.IsDouble());
128  }
129 
130  bool IsCompatibleForStore(const Representation& other) const {
131  return Equals(other);
132  }
133 
134  bool is_more_general_than(const Representation& other) const {
135  if (kind_ == kExternal && other.kind_ == kNone) return true;
136  if (kind_ == kExternal && other.kind_ == kExternal) return false;
137  if (kind_ == kNone && other.kind_ == kExternal) return false;
138 
139  ASSERT(kind_ != kExternal);
140  ASSERT(other.kind_ != kExternal);
141  if (IsHeapObject()) return other.IsNone();
142  if (kind_ == kUInteger8 && other.kind_ == kInteger8) return false;
143  if (kind_ == kUInteger16 && other.kind_ == kInteger16) return false;
144  return kind_ > other.kind_;
145  }
146 
147  bool fits_into(const Representation& other) const {
148  return other.is_more_general_than(*this) || other.Equals(*this);
149  }
150 
151  bool CanContainDouble(double value);
152 
154  if (other.fits_into(*this)) return *this;
155  if (other.is_more_general_than(*this)) return other;
156  return Representation::Tagged();
157  }
158 
159  int size() const {
160  ASSERT(!IsNone());
161  if (IsInteger8() || IsUInteger8()) {
162  return sizeof(uint8_t);
163  }
164  if (IsInteger16() || IsUInteger16()) {
165  return sizeof(uint16_t);
166  }
167  if (IsInteger32()) {
168  return sizeof(uint32_t);
169  }
170  return kPointerSize;
171  }
172 
173  Kind kind() const { return static_cast<Kind>(kind_); }
174  bool IsNone() const { return kind_ == kNone; }
175  bool IsInteger8() const { return kind_ == kInteger8; }
176  bool IsUInteger8() const { return kind_ == kUInteger8; }
177  bool IsInteger16() const { return kind_ == kInteger16; }
178  bool IsUInteger16() const { return kind_ == kUInteger16; }
179  bool IsTagged() const { return kind_ == kTagged; }
180  bool IsSmi() const { return kind_ == kSmi; }
181  bool IsSmiOrTagged() const { return IsSmi() || IsTagged(); }
182  bool IsInteger32() const { return kind_ == kInteger32; }
183  bool IsSmiOrInteger32() const { return IsSmi() || IsInteger32(); }
184  bool IsDouble() const { return kind_ == kDouble; }
185  bool IsHeapObject() const { return kind_ == kHeapObject; }
186  bool IsExternal() const { return kind_ == kExternal; }
187  bool IsSpecialization() const {
188  return IsInteger8() || IsUInteger8() ||
189  IsInteger16() || IsUInteger16() ||
190  IsSmi() || IsInteger32() || IsDouble();
191  }
192  const char* Mnemonic() const;
193 
194  private:
195  explicit Representation(Kind k) : kind_(k) { }
196 
197  // Make sure kind fits in int8.
198  STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
199 
200  int8_t kind_;
201 };
202 
203 
204 static const int kDescriptorIndexBitCount = 10;
205 // The maximum number of descriptors we want in a descriptor array (should
206 // fit in a page).
207 static const int kMaxNumberOfDescriptors =
208  (1 << kDescriptorIndexBitCount) - 2;
209 static const int kInvalidEnumCacheSentinel =
210  (1 << kDescriptorIndexBitCount) - 1;
211 
212 
213 // PropertyDetails captures type and attributes for a property.
214 // They are used both in property dictionaries and instance descriptors.
215 class PropertyDetails BASE_EMBEDDED {
216  public:
218  PropertyType type,
219  int index) {
220  value_ = TypeField::encode(type)
221  | AttributesField::encode(attributes)
222  | DictionaryStorageField::encode(index);
223 
224  ASSERT(type == this->type());
225  ASSERT(attributes == this->attributes());
226  }
227 
229  PropertyType type,
230  Representation representation,
231  int field_index = 0) {
232  value_ = TypeField::encode(type)
233  | AttributesField::encode(attributes)
234  | RepresentationField::encode(EncodeRepresentation(representation))
235  | FieldIndexField::encode(field_index);
236  }
237 
238  int pointer() const { return DescriptorPointer::decode(value_); }
239 
240  PropertyDetails set_pointer(int i) { return PropertyDetails(value_, i); }
241 
242  PropertyDetails CopyWithRepresentation(Representation representation) const {
243  return PropertyDetails(value_, representation);
244  }
245  PropertyDetails CopyAddAttributes(PropertyAttributes new_attributes) {
246  new_attributes =
247  static_cast<PropertyAttributes>(attributes() | new_attributes);
248  return PropertyDetails(value_, new_attributes);
249  }
250 
251  // Conversion for storing details as Object*.
252  explicit inline PropertyDetails(Smi* smi);
253  inline Smi* AsSmi() const;
254 
255  static uint8_t EncodeRepresentation(Representation representation) {
256  return representation.kind();
257  }
258 
259  static Representation DecodeRepresentation(uint32_t bits) {
260  return Representation::FromKind(static_cast<Representation::Kind>(bits));
261  }
262 
263  PropertyType type() const { return TypeField::decode(value_); }
264 
266  return AttributesField::decode(value_);
267  }
268 
269  int dictionary_index() const {
270  return DictionaryStorageField::decode(value_);
271  }
272 
274  ASSERT(type() != NORMAL);
275  return DecodeRepresentation(RepresentationField::decode(value_));
276  }
277 
278  int field_index() const {
279  return FieldIndexField::decode(value_);
280  }
281 
282  inline PropertyDetails AsDeleted() const;
283 
284  static bool IsValidIndex(int index) {
285  return DictionaryStorageField::is_valid(index);
286  }
287 
288  bool IsReadOnly() const { return (attributes() & READ_ONLY) != 0; }
289  bool IsDontDelete() const { return (attributes() & DONT_DELETE) != 0; }
290  bool IsDontEnum() const { return (attributes() & DONT_ENUM) != 0; }
291  bool IsDeleted() const { return DeletedField::decode(value_) != 0;}
292 
293  // Bit fields in value_ (type, shift, size). Must be public so the
294  // constants can be embedded in generated code.
295  class TypeField: public BitField<PropertyType, 0, 3> {};
296  class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
297 
298  // Bit fields for normalized objects.
299  class DeletedField: public BitField<uint32_t, 6, 1> {};
300  class DictionaryStorageField: public BitField<uint32_t, 7, 24> {};
301 
302  // Bit fields for fast objects.
303  class RepresentationField: public BitField<uint32_t, 6, 4> {};
304  class DescriptorPointer: public BitField<uint32_t, 10,
305  kDescriptorIndexBitCount> {}; // NOLINT
306  class FieldIndexField: public BitField<uint32_t,
307  10 + kDescriptorIndexBitCount,
308  kDescriptorIndexBitCount> {}; // NOLINT
309  // All bits for fast objects must fix in a smi.
310  STATIC_ASSERT(10 + kDescriptorIndexBitCount + kDescriptorIndexBitCount <= 31);
311 
312  static const int kInitialIndex = 1;
313 
314  private:
315  PropertyDetails(int value, int pointer) {
316  value_ = DescriptorPointer::update(value, pointer);
317  }
318  PropertyDetails(int value, Representation representation) {
319  value_ = RepresentationField::update(
320  value, EncodeRepresentation(representation));
321  }
322  PropertyDetails(int value, PropertyAttributes attributes) {
323  value_ = AttributesField::update(value, attributes);
324  }
325 
326  uint32_t value_;
327 };
328 
329 } } // namespace v8::internal
330 
331 #endif // V8_PROPERTY_DETAILS_H_
bool is_more_general_than(const Representation &other) const
static Representation UInteger8()
PropertyDetails CopyAddAttributes(PropertyAttributes new_attributes)
static Representation Smi()
Representation representation() const
bool IsCompatibleForStore(const Representation &other) const
static uint8_t EncodeRepresentation(Representation representation)
static Representation Integer32()
PropertyType type() const
TypeImpl< ZoneTypeConfig > Type
PropertyDetails set_pointer(int i)
#define ASSERT(condition)
Definition: checks.h:329
unsigned short uint16_t
Definition: unicode.cc:46
static Representation Double()
static Representation Integer16()
PropertyAttributes
static Representation FromType(Type *type)
Definition: types.cc:570
const char * Mnemonic() const
Definition: objects.cc:2251
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
static Representation FromKind(Kind kind)
static Representation HeapObject()
const int kPointerSize
Definition: globals.h:268
PropertyAttributes attributes() const
static bool IsValidIndex(int index)
bool Equals(const Representation &other) const
const int kBitsPerByte
Definition: globals.h:287
static Representation DecodeRepresentation(uint32_t bits)
static Representation External()
#define BASE_EMBEDDED
Definition: allocation.h:68
Representation generalize(Representation other)
Definition: v8.h:2107
bool IsCompatibleForLoad(const Representation &other) const
PropertyDetails(PropertyAttributes attributes, PropertyType type, int index)
PropertyDetails(PropertyAttributes attributes, PropertyType type, Representation representation, int field_index=0)
bool fits_into(const Representation &other) const
PropertyDetails CopyWithRepresentation(Representation representation) const
static Representation UInteger16()
static Representation Integer8()
static Representation None()
static Representation Tagged()