v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
property.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_H_
29 #define V8_PROPERTY_H_
30 
31 #include "allocation.h"
32 #include "transitions.h"
33 
34 namespace v8 {
35 namespace internal {
36 
37 
38 // Abstraction for elements in instance-descriptor arrays.
39 //
40 // Each descriptor has a key, property attributes, property type,
41 // property index (in the actual instance-descriptor array) and
42 // optionally a piece of data.
43 //
44 
45 class Descriptor BASE_EMBEDDED {
46  public:
47  static int IndexFromValue(Object* value) {
48  return Smi::cast(value)->value();
49  }
50 
51  MUST_USE_RESULT MaybeObject* KeyToSymbol() {
52  if (!StringShape(key_).IsSymbol()) {
53  MaybeObject* maybe_result = HEAP->LookupSymbol(key_);
54  if (!maybe_result->To(&key_)) return maybe_result;
55  }
56  return key_;
57  }
58 
59  String* GetKey() { return key_; }
60  Object* GetValue() { return value_; }
61  PropertyDetails GetDetails() { return details_; }
62 
63 #ifdef OBJECT_PRINT
64  void Print(FILE* out);
65 #endif
66 
67  void SetEnumerationIndex(int index) {
68  details_ = PropertyDetails(details_.attributes(), details_.type(), index);
69  }
70 
71  void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
72 
73  private:
74  String* key_;
75  Object* value_;
76  PropertyDetails details_;
77 
78  protected:
79  Descriptor() : details_(Smi::FromInt(0)) {}
80 
81  void Init(String* key, Object* value, PropertyDetails details) {
82  key_ = key;
83  value_ = value;
84  details_ = details;
85  }
86 
87  Descriptor(String* key, Object* value, PropertyDetails details)
88  : key_(key),
89  value_(value),
90  details_(details) { }
91 
93  Object* value,
94  PropertyAttributes attributes,
95  PropertyType type,
96  int index)
97  : key_(key),
98  value_(value),
99  details_(attributes, type, index) { }
100 
101  friend class DescriptorArray;
102 };
103 
104 
105 class FieldDescriptor: public Descriptor {
106  public:
108  int field_index,
109  PropertyAttributes attributes,
110  int index = 0)
111  : Descriptor(key, Smi::FromInt(field_index), attributes, FIELD, index) {}
112 };
113 
114 
115 class ConstantFunctionDescriptor: public Descriptor {
116  public:
118  JSFunction* function,
119  PropertyAttributes attributes,
120  int index)
121  : Descriptor(key, function, attributes, CONSTANT_FUNCTION, index) {}
122 };
123 
124 
125 class CallbacksDescriptor: public Descriptor {
126  public:
128  Object* foreign,
129  PropertyAttributes attributes,
130  int index = 0)
131  : Descriptor(key, foreign, attributes, CALLBACKS, index) {}
132 };
133 
134 
135 class LookupResult BASE_EMBEDDED {
136  public:
137  explicit LookupResult(Isolate* isolate)
138  : isolate_(isolate),
139  next_(isolate->top_lookup_result()),
140  lookup_type_(NOT_FOUND),
141  holder_(NULL),
142  cacheable_(true),
143  details_(NONE, NONEXISTENT) {
144  isolate->SetTopLookupResult(this);
145  }
146 
148  ASSERT(isolate_->top_lookup_result() == this);
149  isolate_->SetTopLookupResult(next_);
150  }
151 
152  void DescriptorResult(JSObject* holder, PropertyDetails details, int number) {
153  lookup_type_ = DESCRIPTOR_TYPE;
154  holder_ = holder;
155  details_ = details;
156  number_ = number;
157  }
158 
159  void TransitionResult(JSObject* holder, int number) {
160  lookup_type_ = TRANSITION_TYPE;
161  details_ = PropertyDetails(NONE, TRANSITION);
162  holder_ = holder;
163  number_ = number;
164  }
165 
166  void ConstantResult(JSObject* holder) {
167  lookup_type_ = CONSTANT_TYPE;
168  holder_ = holder;
169  details_ =
170  PropertyDetails(static_cast<PropertyAttributes>(DONT_ENUM |
171  DONT_DELETE),
172  CALLBACKS);
173  number_ = -1;
174  }
175 
176  void DictionaryResult(JSObject* holder, int entry) {
177  lookup_type_ = DICTIONARY_TYPE;
178  holder_ = holder;
179  details_ = holder->property_dictionary()->DetailsAt(entry);
180  number_ = entry;
181  }
182 
183  void HandlerResult(JSProxy* proxy) {
184  lookup_type_ = HANDLER_TYPE;
185  holder_ = proxy;
186  details_ = PropertyDetails(NONE, HANDLER);
187  cacheable_ = false;
188  }
189 
190  void InterceptorResult(JSObject* holder) {
191  lookup_type_ = INTERCEPTOR_TYPE;
192  holder_ = holder;
193  details_ = PropertyDetails(NONE, INTERCEPTOR);
194  }
195 
196  void NotFound() {
197  lookup_type_ = NOT_FOUND;
198  details_ = PropertyDetails(NONE, NONEXISTENT);
199  holder_ = NULL;
200  }
201 
203  ASSERT(IsFound());
204  return JSObject::cast(holder_);
205  }
206 
208  ASSERT(IsFound());
209  return JSProxy::cast(holder_);
210  }
211 
213  ASSERT(IsFound());
214  return details_.type();
215  }
216 
218  ASSERT(!IsTransition());
219  ASSERT(IsFound());
220  ASSERT(details_.type() != NONEXISTENT);
221  return details_.attributes();
222  }
223 
224  PropertyDetails GetPropertyDetails() {
225  ASSERT(!IsTransition());
226  return details_;
227  }
228 
230  ASSERT(IsFound());
231  return IsTransition() || type() != NORMAL;
232  }
233 
234  // Property callbacks does not include transitions to callbacks.
236  ASSERT(!(details_.type() == CALLBACKS && !IsFound()));
237  return details_.type() == CALLBACKS;
238  }
239 
240  bool IsReadOnly() {
241  ASSERT(IsFound());
242  ASSERT(!IsTransition());
243  ASSERT(details_.type() != NONEXISTENT);
244  return details_.IsReadOnly();
245  }
246 
247  bool IsField() {
248  ASSERT(!(details_.type() == FIELD && !IsFound()));
249  return details_.type() == FIELD;
250  }
251 
252  bool IsNormal() {
253  ASSERT(!(details_.type() == NORMAL && !IsFound()));
254  return details_.type() == NORMAL;
255  }
256 
258  ASSERT(!(details_.type() == CONSTANT_FUNCTION && !IsFound()));
259  return details_.type() == CONSTANT_FUNCTION;
260  }
261 
262  bool IsDontDelete() { return details_.IsDontDelete(); }
263  bool IsDontEnum() { return details_.IsDontEnum(); }
264  bool IsDeleted() { return details_.IsDeleted(); }
265  bool IsFound() { return lookup_type_ != NOT_FOUND; }
266  bool IsTransition() { return lookup_type_ == TRANSITION_TYPE; }
267  bool IsHandler() { return lookup_type_ == HANDLER_TYPE; }
268  bool IsInterceptor() { return lookup_type_ == INTERCEPTOR_TYPE; }
269 
270  // Is the result is a property excluding transitions and the null descriptor?
271  bool IsProperty() {
272  return IsFound() && !IsTransition();
273  }
274 
275  bool IsCacheable() { return cacheable_; }
276  void DisallowCaching() { cacheable_ = false; }
277 
279  switch (type()) {
280  case FIELD:
281  return holder()->FastPropertyAt(GetFieldIndex());
282  case NORMAL: {
283  Object* value;
284  value = holder()->property_dictionary()->ValueAt(GetDictionaryEntry());
285  if (holder()->IsGlobalObject()) {
286  value = JSGlobalPropertyCell::cast(value)->value();
287  }
288  return value;
289  }
290  case CONSTANT_FUNCTION:
291  return GetConstantFunction();
292  default:
293  return Smi::FromInt(0);
294  }
295  }
296 
298  ASSERT(IsTransition());
299  TransitionArray* transitions = holder()->map()->transitions();
300  return transitions->GetTarget(number_);
301  }
302 
303  PropertyDetails GetTransitionDetails(Map* map) {
304  ASSERT(IsTransition());
305  TransitionArray* transitions = map->transitions();
306  return transitions->GetTargetDetails(number_);
307  }
308 
309  PropertyDetails GetTransitionDetails() {
310  return GetTransitionDetails(holder()->map());
311  }
312 
314  return IsTransition() && GetTransitionDetails(map).type() == FIELD;
315  }
316 
318  ASSERT(IsTransition());
319  return Map::cast(GetValue());
320  }
321 
323  ASSERT(IsTransition());
324  return map->transitions()->GetTarget(number_);
325  }
326 
328  ASSERT(IsTransition());
329  return number_;
330  }
331 
333  ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
334  return number_;
335  }
336 
338  ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
339  ASSERT(IsField());
340  return Descriptor::IndexFromValue(GetValue());
341  }
342 
344  ASSERT(IsField());
345  return Descriptor::IndexFromValue(GetValueFromMap(map)) -
346  map->inobject_properties();
347  }
348 
350  ASSERT(lookup_type_ == DICTIONARY_TYPE);
351  return number_;
352  }
353 
355  ASSERT(type() == CONSTANT_FUNCTION);
356  return JSFunction::cast(GetValue());
357  }
358 
360  ASSERT(type() == CONSTANT_FUNCTION);
361  return JSFunction::cast(GetValueFromMap(map));
362  }
363 
365  if (lookup_type_ == CONSTANT_TYPE) {
366  return HEAP->prototype_accessors();
367  }
368  ASSERT(!IsTransition());
369  return GetValue();
370  }
371 
372 #ifdef OBJECT_PRINT
373  void Print(FILE* out);
374 #endif
375 
377  if (lookup_type_ == DESCRIPTOR_TYPE) {
378  return GetValueFromMap(holder()->map());
379  }
380  // In the dictionary case, the data is held in the value field.
381  ASSERT(lookup_type_ == DICTIONARY_TYPE);
382  return holder()->GetNormalizedProperty(this);
383  }
384 
385  Object* GetValueFromMap(Map* map) const {
386  ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
387  ASSERT(number_ < map->NumberOfOwnDescriptors());
388  return map->instance_descriptors()->GetValue(number_);
389  }
390 
391  void Iterate(ObjectVisitor* visitor);
392 
393  private:
394  Isolate* isolate_;
395  LookupResult* next_;
396 
397  // Where did we find the result;
398  enum {
399  NOT_FOUND,
400  DESCRIPTOR_TYPE,
401  TRANSITION_TYPE,
402  DICTIONARY_TYPE,
403  HANDLER_TYPE,
404  INTERCEPTOR_TYPE,
405  CONSTANT_TYPE
406  } lookup_type_;
407 
408  JSReceiver* holder_;
409  int number_;
410  bool cacheable_;
411  PropertyDetails details_;
412 };
413 
414 
415 } } // namespace v8::internal
416 
417 #endif // V8_PROPERTY_H_
void DescriptorResult(JSObject *holder, PropertyDetails details, int number)
Definition: property.h:152
bool IsTransitionToField(Map *map)
Definition: property.h:313
void ConstantResult(JSObject *holder)
Definition: property.h:166
int GetLocalFieldIndexFromMap(Map *map)
Definition: property.h:343
MUST_USE_RESULT MaybeObject * KeyToSymbol()
Definition: property.h:51
static Smi * FromInt(int value)
Definition: objects-inl.h:981
Object * GetValueFromMap(Map *map) const
Definition: property.h:385
static Map * cast(Object *obj)
#define ASSERT(condition)
Definition: checks.h:270
v8::Handle< v8::Value > Print(const v8::Arguments &args)
void SetEnumerationIndex(int index)
Definition: property.h:67
Object * GetCallbackObject()
Definition: property.h:364
PropertyDetails GetPropertyDetails()
Definition: property.h:224
PropertyAttributes
PropertyDetails GetTransitionDetails()
Definition: property.h:309
static Smi * cast(Object *object)
ConstantFunctionDescriptor(String *key, JSFunction *function, PropertyAttributes attributes, int index)
Definition: property.h:117
void SetSortedKeyIndex(int index)
Definition: property.h:71
static int IndexFromValue(Object *value)
Definition: property.h:47
LookupResult(Isolate *isolate)
Definition: property.h:137
PropertyAttributes GetAttributes()
Definition: property.h:217
#define MUST_USE_RESULT
Definition: globals.h:346
FieldDescriptor(String *key, int field_index, PropertyAttributes attributes, int index=0)
Definition: property.h:107
void TransitionResult(JSObject *holder, int number)
Definition: property.h:159
Descriptor(String *key, Object *value, PropertyDetails details)
Definition: property.h:87
JSFunction * GetConstantFunctionFromMap(Map *map)
Definition: property.h:359
#define BASE_EMBEDDED
Definition: allocation.h:68
void SetTopLookupResult(LookupResult *top)
Definition: isolate.h:1035
PropertyDetails GetTransitionDetails(Map *map)
Definition: property.h:303
Map * GetTarget(int transition_number)
void HandlerResult(JSProxy *proxy)
Definition: property.h:183
static JSGlobalPropertyCell * cast(Object *obj)
PropertyDetails DetailsAt(int entry)
Definition: objects.h:3077
#define HEAP
Definition: isolate.h:1433
static JSProxy * cast(Object *obj)
void InterceptorResult(JSObject *holder)
Definition: property.h:190
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
void DictionaryResult(JSObject *holder, int entry)
Definition: property.h:176
Descriptor(String *key, Object *value, PropertyAttributes attributes, PropertyType type, int index)
Definition: property.h:92
Map * GetTransitionMapFromMap(Map *map)
Definition: property.h:322
CallbacksDescriptor(String *key, Object *foreign, PropertyAttributes attributes, int index=0)
Definition: property.h:127
JSFunction * GetConstantFunction()
Definition: property.h:354
void Init(String *key, Object *value, PropertyDetails details)
Definition: property.h:81
StringDictionary * property_dictionary()
Definition: objects-inl.h:4899
static JSObject * cast(Object *obj)
PropertyDetails GetTargetDetails(int transition_number)
PropertyDetails GetDetails()
Definition: property.h:61
static JSFunction * cast(Object *obj)