blob: b0d10e1270aaaceca63430166ef5524e90043598 [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;
58
59// Type of properties.
60// Order of properties is significant.
61// Must fit in the BitField PropertyDetails::TypeField.
62// A copy of this is in mirror-debugger.js.
63enum PropertyType {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000064 // Only in slow mode.
65 NORMAL = 0,
66 // Only in fast mode.
67 FIELD = 1,
68 CONSTANT_FUNCTION = 2,
danno@chromium.orgc612e022011-11-10 11:38:15 +000069 CALLBACKS = 3,
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000070 // Only in lookup results, not in descriptors.
71 HANDLER = 4,
72 INTERCEPTOR = 5,
73 TRANSITION = 6,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +000074 // Only used as a marker in LookupResult.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000075 NONEXISTENT = 7
danno@chromium.orgc612e022011-11-10 11:38:15 +000076};
77
78
danno@chromium.orgf005df62013-04-30 16:36:45 +000079class Representation {
80 public:
81 enum Kind {
82 kNone,
83 kSmi,
84 kInteger32,
85 kDouble,
ulan@chromium.org906e2fb2013-05-14 08:14:38 +000086 kHeapObject,
danno@chromium.orgf005df62013-04-30 16:36:45 +000087 kTagged,
88 kExternal,
89 kNumRepresentations
90 };
91
92 Representation() : kind_(kNone) { }
93
94 static Representation None() { return Representation(kNone); }
95 static Representation Tagged() { return Representation(kTagged); }
96 static Representation Smi() { return Representation(kSmi); }
97 static Representation Integer32() { return Representation(kInteger32); }
98 static Representation Double() { return Representation(kDouble); }
ulan@chromium.org906e2fb2013-05-14 08:14:38 +000099 static Representation HeapObject() { return Representation(kHeapObject); }
danno@chromium.orgf005df62013-04-30 16:36:45 +0000100 static Representation External() { return Representation(kExternal); }
101
102 static Representation FromKind(Kind kind) { return Representation(kind); }
103
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000104 bool Equals(const Representation& other) const {
danno@chromium.orgf005df62013-04-30 16:36:45 +0000105 return kind_ == other.kind_;
106 }
107
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000108 bool IsCompatibleForLoad(const Representation& other) const {
109 return (IsDouble() && other.IsDouble()) ||
110 (!IsDouble() && !other.IsDouble());
111 }
112
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000113 bool IsCompatibleForStore(const Representation& other) const {
114 return Equals(other);
115 }
116
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000117 bool is_more_general_than(const Representation& other) const {
danno@chromium.orgf005df62013-04-30 16:36:45 +0000118 ASSERT(kind_ != kExternal);
119 ASSERT(other.kind_ != kExternal);
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000120 if (IsHeapObject()) return other.IsDouble() || other.IsNone();
danno@chromium.orgf005df62013-04-30 16:36:45 +0000121 return kind_ > other.kind_;
122 }
123
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000124 bool fits_into(const Representation& other) const {
125 return other.is_more_general_than(*this) || other.Equals(*this);
126 }
127
danno@chromium.orgf005df62013-04-30 16:36:45 +0000128 Representation generalize(Representation other) {
ulan@chromium.org906e2fb2013-05-14 08:14:38 +0000129 if (other.fits_into(*this)) return *this;
130 if (other.is_more_general_than(*this)) return other;
131 return Representation::Tagged();
danno@chromium.orgf005df62013-04-30 16:36:45 +0000132 }
133
134 Kind kind() const { return static_cast<Kind>(kind_); }
135 bool IsNone() const { return kind_ == kNone; }
136 bool IsTagged() const { return kind_ == kTagged; }
137 bool IsSmi() const { return kind_ == kSmi; }
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000138 bool IsSmiOrTagged() const { return IsSmi() || IsTagged(); }
danno@chromium.orgf005df62013-04-30 16:36:45 +0000139 bool IsInteger32() const { return kind_ == kInteger32; }
svenpanne@chromium.org53ad1752013-05-27 12:20:38 +0000140 bool IsSmiOrInteger32() const { return IsSmi() || IsInteger32(); }
danno@chromium.orgf005df62013-04-30 16:36:45 +0000141 bool IsDouble() const { return kind_ == kDouble; }
ulan@chromium.org906e2fb2013-05-14 08:14:38 +0000142 bool IsHeapObject() const { return kind_ == kHeapObject; }
danno@chromium.orgf005df62013-04-30 16:36:45 +0000143 bool IsExternal() const { return kind_ == kExternal; }
144 bool IsSpecialization() const {
145 return kind_ == kInteger32 || kind_ == kDouble;
146 }
147 const char* Mnemonic() const;
148
149 private:
150 explicit Representation(Kind k) : kind_(k) { }
151
152 // Make sure kind fits in int8.
153 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
154
155 int8_t kind_;
156};
157
158
danno@chromium.orgc612e022011-11-10 11:38:15 +0000159// PropertyDetails captures type and attributes for a property.
160// They are used both in property dictionaries and instance descriptors.
161class PropertyDetails BASE_EMBEDDED {
162 public:
163 PropertyDetails(PropertyAttributes attributes,
164 PropertyType type,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000165 int index) {
danno@chromium.orgc612e022011-11-10 11:38:15 +0000166 value_ = TypeField::encode(type)
167 | AttributesField::encode(attributes)
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000168 | DictionaryStorageField::encode(index);
danno@chromium.orgc612e022011-11-10 11:38:15 +0000169
170 ASSERT(type == this->type());
171 ASSERT(attributes == this->attributes());
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000172 }
173
174 PropertyDetails(PropertyAttributes attributes,
175 PropertyType type,
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000176 Representation representation,
177 int field_index = 0) {
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000178 value_ = TypeField::encode(type)
179 | AttributesField::encode(attributes)
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000180 | RepresentationField::encode(EncodeRepresentation(representation))
181 | FieldIndexField::encode(field_index);
danno@chromium.orgc612e022011-11-10 11:38:15 +0000182 }
183
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000184 int pointer() { return DescriptorPointer::decode(value_); }
185
186 PropertyDetails set_pointer(int i) { return PropertyDetails(value_, i); }
187
danno@chromium.orgf005df62013-04-30 16:36:45 +0000188 PropertyDetails CopyWithRepresentation(Representation representation) {
189 return PropertyDetails(value_, representation);
190 }
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000191 PropertyDetails CopyAddAttributes(PropertyAttributes new_attributes) {
192 new_attributes =
193 static_cast<PropertyAttributes>(attributes() | new_attributes);
194 return PropertyDetails(value_, new_attributes);
195 }
danno@chromium.orgf005df62013-04-30 16:36:45 +0000196
danno@chromium.orgc612e022011-11-10 11:38:15 +0000197 // Conversion for storing details as Object*.
198 explicit inline PropertyDetails(Smi* smi);
199 inline Smi* AsSmi();
200
danno@chromium.orgf005df62013-04-30 16:36:45 +0000201 static uint8_t EncodeRepresentation(Representation representation) {
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000202 return representation.kind();
danno@chromium.orgf005df62013-04-30 16:36:45 +0000203 }
204
205 static Representation DecodeRepresentation(uint32_t bits) {
danno@chromium.orgf005df62013-04-30 16:36:45 +0000206 return Representation::FromKind(static_cast<Representation::Kind>(bits));
207 }
208
danno@chromium.orgc612e022011-11-10 11:38:15 +0000209 PropertyType type() { return TypeField::decode(value_); }
210
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +0000211 PropertyAttributes attributes() const {
212 return AttributesField::decode(value_);
213 }
danno@chromium.orgc612e022011-11-10 11:38:15 +0000214
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000215 int dictionary_index() {
216 return DictionaryStorageField::decode(value_);
217 }
218
danno@chromium.orgf005df62013-04-30 16:36:45 +0000219 Representation representation() {
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000220 ASSERT(type() != NORMAL);
danno@chromium.orgf005df62013-04-30 16:36:45 +0000221 return DecodeRepresentation(RepresentationField::decode(value_));
222 }
223
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000224 int field_index() {
225 return FieldIndexField::decode(value_);
226 }
227
danno@chromium.orgc612e022011-11-10 11:38:15 +0000228 inline PropertyDetails AsDeleted();
229
230 static bool IsValidIndex(int index) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000231 return DictionaryStorageField::is_valid(index);
danno@chromium.orgc612e022011-11-10 11:38:15 +0000232 }
233
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +0000234 bool IsReadOnly() const { return (attributes() & READ_ONLY) != 0; }
235 bool IsDontDelete() const { return (attributes() & DONT_DELETE) != 0; }
236 bool IsDontEnum() const { return (attributes() & DONT_ENUM) != 0; }
237 bool IsDeleted() const { return DeletedField::decode(value_) != 0;}
danno@chromium.orgc612e022011-11-10 11:38:15 +0000238
239 // Bit fields in value_ (type, shift, size). Must be public so the
240 // constants can be embedded in generated code.
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000241 class TypeField: public BitField<PropertyType, 0, 3> {};
242 class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000243
244 // Bit fields for normalized objects.
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000245 class DeletedField: public BitField<uint32_t, 6, 1> {};
246 class DictionaryStorageField: public BitField<uint32_t, 7, 24> {};
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000247
248 // Bit fields for fast objects.
249 class DescriptorPointer: public BitField<uint32_t, 6, 11> {};
250 class RepresentationField: public BitField<uint32_t, 17, 3> {};
251 class FieldIndexField: public BitField<uint32_t, 20, 11> {};
danno@chromium.orgc612e022011-11-10 11:38:15 +0000252
253 static const int kInitialIndex = 1;
254
255 private:
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000256 PropertyDetails(int value, int pointer) {
danno@chromium.orgf005df62013-04-30 16:36:45 +0000257 value_ = DescriptorPointer::update(value, pointer);
258 }
259 PropertyDetails(int value, Representation representation) {
260 value_ = RepresentationField::update(
261 value, EncodeRepresentation(representation));
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000262 }
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000263 PropertyDetails(int value, PropertyAttributes attributes) {
264 value_ = AttributesField::update(value, attributes);
265 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000266
danno@chromium.orgc612e022011-11-10 11:38:15 +0000267 uint32_t value_;
268};
269
270} } // namespace v8::internal
271
272#endif // V8_PROPERTY_DETAILS_H_