blob: 659fbd1da6e2b5829cb0d3d5a0e4d305c106ba9b [file] [log] [blame]
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001// Copyright 2012 the V8 project authors. All rights reserved.
danno@chromium.orgc612e022011-11-10 11:38:15 +00002// 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
36enum PropertyAttributes {
37 NONE = v8::None,
38 READ_ONLY = v8::ReadOnly,
39 DONT_ENUM = v8::DontEnum,
40 DONT_DELETE = v8::DontDelete,
ulan@chromium.org8e8d8822012-11-23 14:36:46 +000041
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +000042 SEALED = DONT_DELETE,
ulan@chromium.org8e8d8822012-11-23 14:36:46 +000043 FROZEN = SEALED | READ_ONLY,
44
ulan@chromium.org750145a2013-03-07 15:14:13 +000045 SYMBOLIC = 8, // Used to filter symbol names
46 DONT_SHOW = DONT_ENUM | SYMBOLIC,
danno@chromium.orgc612e022011-11-10 11:38:15 +000047 ABSENT = 16 // Used in runtime to indicate a property is absent.
48 // ABSENT can never be stored in or returned from a descriptor's attributes
49 // bitfield. It is only used as a return value meaning the attributes of
50 // a non-existent property.
51};
52
53
54namespace v8 {
55namespace internal {
56
57class Smi;
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +000058class Type;
59class TypeInfo;
danno@chromium.orgc612e022011-11-10 11:38:15 +000060
61// Type of properties.
62// Order of properties is significant.
63// Must fit in the BitField PropertyDetails::TypeField.
64// A copy of this is in mirror-debugger.js.
65enum PropertyType {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000066 // Only in slow mode.
67 NORMAL = 0,
68 // Only in fast mode.
69 FIELD = 1,
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +000070 CONSTANT = 2,
danno@chromium.orgc612e022011-11-10 11:38:15 +000071 CALLBACKS = 3,
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000072 // Only in lookup results, not in descriptors.
73 HANDLER = 4,
74 INTERCEPTOR = 5,
75 TRANSITION = 6,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +000076 // Only used as a marker in LookupResult.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000077 NONEXISTENT = 7
danno@chromium.orgc612e022011-11-10 11:38:15 +000078};
79
80
danno@chromium.orgf005df62013-04-30 16:36:45 +000081class Representation {
82 public:
83 enum Kind {
84 kNone,
jkummerow@chromium.orgd8a3a142013-10-03 12:15:05 +000085 kByte,
danno@chromium.orgf005df62013-04-30 16:36:45 +000086 kSmi,
87 kInteger32,
88 kDouble,
ulan@chromium.org906e2fb2013-05-14 08:14:38 +000089 kHeapObject,
danno@chromium.orgf005df62013-04-30 16:36:45 +000090 kTagged,
91 kExternal,
92 kNumRepresentations
93 };
94
95 Representation() : kind_(kNone) { }
96
97 static Representation None() { return Representation(kNone); }
98 static Representation Tagged() { return Representation(kTagged); }
jkummerow@chromium.orgd8a3a142013-10-03 12:15:05 +000099 static Representation Byte() { return Representation(kByte); }
danno@chromium.orgf005df62013-04-30 16:36:45 +0000100 static Representation Smi() { return Representation(kSmi); }
101 static Representation Integer32() { return Representation(kInteger32); }
102 static Representation Double() { return Representation(kDouble); }
ulan@chromium.org906e2fb2013-05-14 08:14:38 +0000103 static Representation HeapObject() { return Representation(kHeapObject); }
danno@chromium.orgf005df62013-04-30 16:36:45 +0000104 static Representation External() { return Representation(kExternal); }
105
106 static Representation FromKind(Kind kind) { return Representation(kind); }
107
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000108 // TODO(rossberg): this should die eventually.
109 static Representation FromType(TypeInfo info);
110 static Representation FromType(Handle<Type> type);
111
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000112 bool Equals(const Representation& other) const {
danno@chromium.orgf005df62013-04-30 16:36:45 +0000113 return kind_ == other.kind_;
114 }
115
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000116 bool IsCompatibleForLoad(const Representation& other) const {
117 return (IsDouble() && other.IsDouble()) ||
118 (!IsDouble() && !other.IsDouble());
119 }
120
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000121 bool IsCompatibleForStore(const Representation& other) const {
122 return Equals(other);
123 }
124
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000125 bool is_more_general_than(const Representation& other) const {
danno@chromium.orgf005df62013-04-30 16:36:45 +0000126 ASSERT(kind_ != kExternal);
127 ASSERT(other.kind_ != kExternal);
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000128 if (IsHeapObject()) return other.IsDouble() || other.IsNone();
danno@chromium.orgf005df62013-04-30 16:36:45 +0000129 return kind_ > other.kind_;
130 }
131
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000132 bool fits_into(const Representation& other) const {
133 return other.is_more_general_than(*this) || other.Equals(*this);
134 }
135
danno@chromium.orgf005df62013-04-30 16:36:45 +0000136 Representation generalize(Representation other) {
ulan@chromium.org906e2fb2013-05-14 08:14:38 +0000137 if (other.fits_into(*this)) return *this;
138 if (other.is_more_general_than(*this)) return other;
139 return Representation::Tagged();
danno@chromium.orgf005df62013-04-30 16:36:45 +0000140 }
141
142 Kind kind() const { return static_cast<Kind>(kind_); }
143 bool IsNone() const { return kind_ == kNone; }
jkummerow@chromium.orgd8a3a142013-10-03 12:15:05 +0000144 bool IsByte() const { return kind_ == kByte; }
danno@chromium.orgf005df62013-04-30 16:36:45 +0000145 bool IsTagged() const { return kind_ == kTagged; }
146 bool IsSmi() const { return kind_ == kSmi; }
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000147 bool IsSmiOrTagged() const { return IsSmi() || IsTagged(); }
danno@chromium.orgf005df62013-04-30 16:36:45 +0000148 bool IsInteger32() const { return kind_ == kInteger32; }
svenpanne@chromium.org53ad1752013-05-27 12:20:38 +0000149 bool IsSmiOrInteger32() const { return IsSmi() || IsInteger32(); }
danno@chromium.orgf005df62013-04-30 16:36:45 +0000150 bool IsDouble() const { return kind_ == kDouble; }
ulan@chromium.org906e2fb2013-05-14 08:14:38 +0000151 bool IsHeapObject() const { return kind_ == kHeapObject; }
danno@chromium.orgf005df62013-04-30 16:36:45 +0000152 bool IsExternal() const { return kind_ == kExternal; }
153 bool IsSpecialization() const {
jkummerow@chromium.orgd8a3a142013-10-03 12:15:05 +0000154 return IsByte() || IsSmi() || IsInteger32() || IsDouble();
danno@chromium.orgf005df62013-04-30 16:36:45 +0000155 }
156 const char* Mnemonic() const;
157
158 private:
159 explicit Representation(Kind k) : kind_(k) { }
160
161 // Make sure kind fits in int8.
162 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
163
164 int8_t kind_;
165};
166
167
danno@chromium.orgc612e022011-11-10 11:38:15 +0000168// PropertyDetails captures type and attributes for a property.
169// They are used both in property dictionaries and instance descriptors.
170class PropertyDetails BASE_EMBEDDED {
171 public:
172 PropertyDetails(PropertyAttributes attributes,
173 PropertyType type,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000174 int index) {
danno@chromium.orgc612e022011-11-10 11:38:15 +0000175 value_ = TypeField::encode(type)
176 | AttributesField::encode(attributes)
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000177 | DictionaryStorageField::encode(index);
danno@chromium.orgc612e022011-11-10 11:38:15 +0000178
179 ASSERT(type == this->type());
180 ASSERT(attributes == this->attributes());
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000181 }
182
183 PropertyDetails(PropertyAttributes attributes,
184 PropertyType type,
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000185 Representation representation,
186 int field_index = 0) {
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000187 value_ = TypeField::encode(type)
188 | AttributesField::encode(attributes)
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000189 | RepresentationField::encode(EncodeRepresentation(representation))
190 | FieldIndexField::encode(field_index);
danno@chromium.orgc612e022011-11-10 11:38:15 +0000191 }
192
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000193 int pointer() { return DescriptorPointer::decode(value_); }
194
195 PropertyDetails set_pointer(int i) { return PropertyDetails(value_, i); }
196
danno@chromium.orgf005df62013-04-30 16:36:45 +0000197 PropertyDetails CopyWithRepresentation(Representation representation) {
198 return PropertyDetails(value_, representation);
199 }
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000200 PropertyDetails CopyAddAttributes(PropertyAttributes new_attributes) {
201 new_attributes =
202 static_cast<PropertyAttributes>(attributes() | new_attributes);
203 return PropertyDetails(value_, new_attributes);
204 }
danno@chromium.orgf005df62013-04-30 16:36:45 +0000205
danno@chromium.orgc612e022011-11-10 11:38:15 +0000206 // Conversion for storing details as Object*.
207 explicit inline PropertyDetails(Smi* smi);
208 inline Smi* AsSmi();
209
danno@chromium.orgf005df62013-04-30 16:36:45 +0000210 static uint8_t EncodeRepresentation(Representation representation) {
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000211 return representation.kind();
danno@chromium.orgf005df62013-04-30 16:36:45 +0000212 }
213
214 static Representation DecodeRepresentation(uint32_t bits) {
danno@chromium.orgf005df62013-04-30 16:36:45 +0000215 return Representation::FromKind(static_cast<Representation::Kind>(bits));
216 }
217
danno@chromium.orgc612e022011-11-10 11:38:15 +0000218 PropertyType type() { return TypeField::decode(value_); }
219
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +0000220 PropertyAttributes attributes() const {
221 return AttributesField::decode(value_);
222 }
danno@chromium.orgc612e022011-11-10 11:38:15 +0000223
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000224 int dictionary_index() {
225 return DictionaryStorageField::decode(value_);
226 }
227
danno@chromium.orgf005df62013-04-30 16:36:45 +0000228 Representation representation() {
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000229 ASSERT(type() != NORMAL);
danno@chromium.orgf005df62013-04-30 16:36:45 +0000230 return DecodeRepresentation(RepresentationField::decode(value_));
231 }
232
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000233 int field_index() {
234 return FieldIndexField::decode(value_);
235 }
236
danno@chromium.orgc612e022011-11-10 11:38:15 +0000237 inline PropertyDetails AsDeleted();
238
239 static bool IsValidIndex(int index) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000240 return DictionaryStorageField::is_valid(index);
danno@chromium.orgc612e022011-11-10 11:38:15 +0000241 }
242
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +0000243 bool IsReadOnly() const { return (attributes() & READ_ONLY) != 0; }
244 bool IsDontDelete() const { return (attributes() & DONT_DELETE) != 0; }
245 bool IsDontEnum() const { return (attributes() & DONT_ENUM) != 0; }
246 bool IsDeleted() const { return DeletedField::decode(value_) != 0;}
danno@chromium.orgc612e022011-11-10 11:38:15 +0000247
248 // Bit fields in value_ (type, shift, size). Must be public so the
249 // constants can be embedded in generated code.
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000250 class TypeField: public BitField<PropertyType, 0, 3> {};
251 class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000252
253 // Bit fields for normalized objects.
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000254 class DeletedField: public BitField<uint32_t, 6, 1> {};
255 class DictionaryStorageField: public BitField<uint32_t, 7, 24> {};
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000256
257 // Bit fields for fast objects.
258 class DescriptorPointer: public BitField<uint32_t, 6, 11> {};
259 class RepresentationField: public BitField<uint32_t, 17, 3> {};
260 class FieldIndexField: public BitField<uint32_t, 20, 11> {};
danno@chromium.orgc612e022011-11-10 11:38:15 +0000261
262 static const int kInitialIndex = 1;
263
264 private:
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000265 PropertyDetails(int value, int pointer) {
danno@chromium.orgf005df62013-04-30 16:36:45 +0000266 value_ = DescriptorPointer::update(value, pointer);
267 }
268 PropertyDetails(int value, Representation representation) {
269 value_ = RepresentationField::update(
270 value, EncodeRepresentation(representation));
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000271 }
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000272 PropertyDetails(int value, PropertyAttributes attributes) {
273 value_ = AttributesField::update(value, attributes);
274 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000275
danno@chromium.orgc612e022011-11-10 11:38:15 +0000276 uint32_t value_;
277};
278
279} } // namespace v8::internal
280
281#endif // V8_PROPERTY_DETAILS_H_