Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / v8 / src / objects-inl.h
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // Review notes:
6 //
7 // - The use of macros in these inline functions may seem superfluous
8 // but it is absolutely needed to make sure gcc generates optimal
9 // code. gcc is not happy when attempting to inline too deep.
10 //
11
12 #ifndef V8_OBJECTS_INL_H_
13 #define V8_OBJECTS_INL_H_
14
15 #include "src/base/atomicops.h"
16 #include "src/base/bits.h"
17 #include "src/contexts.h"
18 #include "src/conversions-inl.h"
19 #include "src/elements.h"
20 #include "src/factory.h"
21 #include "src/field-index-inl.h"
22 #include "src/heap/heap-inl.h"
23 #include "src/heap/heap.h"
24 #include "src/heap/incremental-marking.h"
25 #include "src/heap/objects-visiting.h"
26 #include "src/heap/spaces.h"
27 #include "src/heap/store-buffer.h"
28 #include "src/isolate.h"
29 #include "src/lookup.h"
30 #include "src/objects.h"
31 #include "src/property.h"
32 #include "src/prototype.h"
33 #include "src/transitions-inl.h"
34 #include "src/type-feedback-vector-inl.h"
35 #include "src/v8memory.h"
36
37 namespace v8 {
38 namespace internal {
39
40 PropertyDetails::PropertyDetails(Smi* smi) {
41   value_ = smi->value();
42 }
43
44
45 Smi* PropertyDetails::AsSmi() const {
46   // Ensure the upper 2 bits have the same value by sign extending it. This is
47   // necessary to be able to use the 31st bit of the property details.
48   int value = value_ << 1;
49   return Smi::FromInt(value >> 1);
50 }
51
52
53 PropertyDetails PropertyDetails::AsDeleted() const {
54   Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
55   return PropertyDetails(smi);
56 }
57
58
59 #define TYPE_CHECKER(type, instancetype)                                \
60   bool Object::Is##type() const {                                       \
61   return Object::IsHeapObject() &&                                      \
62       HeapObject::cast(this)->map()->instance_type() == instancetype;   \
63   }
64
65
66 #define CAST_ACCESSOR(type)                       \
67   type* type::cast(Object* object) {              \
68     SLOW_DCHECK(object->Is##type());              \
69     return reinterpret_cast<type*>(object);       \
70   }                                               \
71   const type* type::cast(const Object* object) {  \
72     SLOW_DCHECK(object->Is##type());              \
73     return reinterpret_cast<const type*>(object); \
74   }
75
76
77 #define INT_ACCESSORS(holder, name, offset)                                   \
78   int holder::name() const { return READ_INT_FIELD(this, offset); }           \
79   void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
80
81
82 #define ACCESSORS(holder, name, type, offset)                                 \
83   type* holder::name() const { return type::cast(READ_FIELD(this, offset)); } \
84   void holder::set_##name(type* value, WriteBarrierMode mode) {               \
85     WRITE_FIELD(this, offset, value);                                         \
86     CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);          \
87   }
88
89
90 // Getter that returns a tagged Smi and setter that writes a tagged Smi.
91 #define ACCESSORS_TO_SMI(holder, name, offset)                              \
92   Smi* holder::name() const { return Smi::cast(READ_FIELD(this, offset)); } \
93   void holder::set_##name(Smi* value, WriteBarrierMode mode) {              \
94     WRITE_FIELD(this, offset, value);                                       \
95   }
96
97
98 // Getter that returns a Smi as an int and writes an int as a Smi.
99 #define SMI_ACCESSORS(holder, name, offset)             \
100   int holder::name() const {                            \
101     Object* value = READ_FIELD(this, offset);           \
102     return Smi::cast(value)->value();                   \
103   }                                                     \
104   void holder::set_##name(int value) {                  \
105     WRITE_FIELD(this, offset, Smi::FromInt(value));     \
106   }
107
108 #define SYNCHRONIZED_SMI_ACCESSORS(holder, name, offset)    \
109   int holder::synchronized_##name() const {                 \
110     Object* value = ACQUIRE_READ_FIELD(this, offset);       \
111     return Smi::cast(value)->value();                       \
112   }                                                         \
113   void holder::synchronized_set_##name(int value) {         \
114     RELEASE_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
115   }
116
117 #define NOBARRIER_SMI_ACCESSORS(holder, name, offset)          \
118   int holder::nobarrier_##name() const {                       \
119     Object* value = NOBARRIER_READ_FIELD(this, offset);        \
120     return Smi::cast(value)->value();                          \
121   }                                                            \
122   void holder::nobarrier_set_##name(int value) {               \
123     NOBARRIER_WRITE_FIELD(this, offset, Smi::FromInt(value));  \
124   }
125
126 #define BOOL_GETTER(holder, field, name, offset)           \
127   bool holder::name() const {                              \
128     return BooleanBit::get(field(), offset);               \
129   }                                                        \
130
131
132 #define BOOL_ACCESSORS(holder, field, name, offset)        \
133   bool holder::name() const {                              \
134     return BooleanBit::get(field(), offset);               \
135   }                                                        \
136   void holder::set_##name(bool value) {                    \
137     set_##field(BooleanBit::set(field(), offset, value));  \
138   }
139
140
141 bool Object::IsFixedArrayBase() const {
142   return IsFixedArray() || IsFixedDoubleArray() || IsConstantPoolArray() ||
143          IsFixedTypedArrayBase() || IsExternalArray();
144 }
145
146
147 // External objects are not extensible, so the map check is enough.
148 bool Object::IsExternal() const {
149   return Object::IsHeapObject() &&
150       HeapObject::cast(this)->map() ==
151       HeapObject::cast(this)->GetHeap()->external_map();
152 }
153
154
155 bool Object::IsAccessorInfo() const {
156   return IsExecutableAccessorInfo() || IsDeclaredAccessorInfo();
157 }
158
159
160 bool Object::IsSmi() const {
161   return HAS_SMI_TAG(this);
162 }
163
164
165 bool Object::IsHeapObject() const {
166   return Internals::HasHeapObjectTag(this);
167 }
168
169
170 TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
171 TYPE_CHECKER(MutableHeapNumber, MUTABLE_HEAP_NUMBER_TYPE)
172 TYPE_CHECKER(Symbol, SYMBOL_TYPE)
173
174
175 bool Object::IsString() const {
176   return Object::IsHeapObject()
177     && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
178 }
179
180
181 bool Object::IsName() const {
182   return IsString() || IsSymbol();
183 }
184
185
186 bool Object::IsUniqueName() const {
187   return IsInternalizedString() || IsSymbol();
188 }
189
190
191 bool Object::IsSpecObject() const {
192   return Object::IsHeapObject()
193     && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
194 }
195
196
197 bool Object::IsSpecFunction() const {
198   if (!Object::IsHeapObject()) return false;
199   InstanceType type = HeapObject::cast(this)->map()->instance_type();
200   return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
201 }
202
203
204 bool Object::IsTemplateInfo() const {
205   return IsObjectTemplateInfo() || IsFunctionTemplateInfo();
206 }
207
208
209 bool Object::IsInternalizedString() const {
210   if (!this->IsHeapObject()) return false;
211   uint32_t type = HeapObject::cast(this)->map()->instance_type();
212   STATIC_ASSERT(kNotInternalizedTag != 0);
213   return (type & (kIsNotStringMask | kIsNotInternalizedMask)) ==
214       (kStringTag | kInternalizedTag);
215 }
216
217
218 bool Object::IsConsString() const {
219   if (!IsString()) return false;
220   return StringShape(String::cast(this)).IsCons();
221 }
222
223
224 bool Object::IsSlicedString() const {
225   if (!IsString()) return false;
226   return StringShape(String::cast(this)).IsSliced();
227 }
228
229
230 bool Object::IsSeqString() const {
231   if (!IsString()) return false;
232   return StringShape(String::cast(this)).IsSequential();
233 }
234
235
236 bool Object::IsSeqOneByteString() const {
237   if (!IsString()) return false;
238   return StringShape(String::cast(this)).IsSequential() &&
239          String::cast(this)->IsOneByteRepresentation();
240 }
241
242
243 bool Object::IsSeqTwoByteString() const {
244   if (!IsString()) return false;
245   return StringShape(String::cast(this)).IsSequential() &&
246          String::cast(this)->IsTwoByteRepresentation();
247 }
248
249
250 bool Object::IsExternalString() const {
251   if (!IsString()) return false;
252   return StringShape(String::cast(this)).IsExternal();
253 }
254
255
256 bool Object::IsExternalOneByteString() const {
257   if (!IsString()) return false;
258   return StringShape(String::cast(this)).IsExternal() &&
259          String::cast(this)->IsOneByteRepresentation();
260 }
261
262
263 bool Object::IsExternalTwoByteString() const {
264   if (!IsString()) return false;
265   return StringShape(String::cast(this)).IsExternal() &&
266          String::cast(this)->IsTwoByteRepresentation();
267 }
268
269
270 bool Object::HasValidElements() {
271   // Dictionary is covered under FixedArray.
272   return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray() ||
273          IsFixedTypedArrayBase();
274 }
275
276
277 Handle<Object> Object::NewStorageFor(Isolate* isolate,
278                                      Handle<Object> object,
279                                      Representation representation) {
280   if (representation.IsSmi() && object->IsUninitialized()) {
281     return handle(Smi::FromInt(0), isolate);
282   }
283   if (!representation.IsDouble()) return object;
284   double value;
285   if (object->IsUninitialized()) {
286     value = 0;
287   } else if (object->IsMutableHeapNumber()) {
288     value = HeapNumber::cast(*object)->value();
289   } else {
290     value = object->Number();
291   }
292   return isolate->factory()->NewHeapNumber(value, MUTABLE);
293 }
294
295
296 Handle<Object> Object::WrapForRead(Isolate* isolate,
297                                    Handle<Object> object,
298                                    Representation representation) {
299   DCHECK(!object->IsUninitialized());
300   if (!representation.IsDouble()) {
301     DCHECK(object->FitsRepresentation(representation));
302     return object;
303   }
304   return isolate->factory()->NewHeapNumber(HeapNumber::cast(*object)->value());
305 }
306
307
308 StringShape::StringShape(const String* str)
309   : type_(str->map()->instance_type()) {
310   set_valid();
311   DCHECK((type_ & kIsNotStringMask) == kStringTag);
312 }
313
314
315 StringShape::StringShape(Map* map)
316   : type_(map->instance_type()) {
317   set_valid();
318   DCHECK((type_ & kIsNotStringMask) == kStringTag);
319 }
320
321
322 StringShape::StringShape(InstanceType t)
323   : type_(static_cast<uint32_t>(t)) {
324   set_valid();
325   DCHECK((type_ & kIsNotStringMask) == kStringTag);
326 }
327
328
329 bool StringShape::IsInternalized() {
330   DCHECK(valid());
331   STATIC_ASSERT(kNotInternalizedTag != 0);
332   return (type_ & (kIsNotStringMask | kIsNotInternalizedMask)) ==
333       (kStringTag | kInternalizedTag);
334 }
335
336
337 bool String::IsOneByteRepresentation() const {
338   uint32_t type = map()->instance_type();
339   return (type & kStringEncodingMask) == kOneByteStringTag;
340 }
341
342
343 bool String::IsTwoByteRepresentation() const {
344   uint32_t type = map()->instance_type();
345   return (type & kStringEncodingMask) == kTwoByteStringTag;
346 }
347
348
349 bool String::IsOneByteRepresentationUnderneath() {
350   uint32_t type = map()->instance_type();
351   STATIC_ASSERT(kIsIndirectStringTag != 0);
352   STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
353   DCHECK(IsFlat());
354   switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
355     case kOneByteStringTag:
356       return true;
357     case kTwoByteStringTag:
358       return false;
359     default:  // Cons or sliced string.  Need to go deeper.
360       return GetUnderlying()->IsOneByteRepresentation();
361   }
362 }
363
364
365 bool String::IsTwoByteRepresentationUnderneath() {
366   uint32_t type = map()->instance_type();
367   STATIC_ASSERT(kIsIndirectStringTag != 0);
368   STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
369   DCHECK(IsFlat());
370   switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
371     case kOneByteStringTag:
372       return false;
373     case kTwoByteStringTag:
374       return true;
375     default:  // Cons or sliced string.  Need to go deeper.
376       return GetUnderlying()->IsTwoByteRepresentation();
377   }
378 }
379
380
381 bool String::HasOnlyOneByteChars() {
382   uint32_t type = map()->instance_type();
383   return (type & kOneByteDataHintMask) == kOneByteDataHintTag ||
384          IsOneByteRepresentation();
385 }
386
387
388 bool StringShape::IsCons() {
389   return (type_ & kStringRepresentationMask) == kConsStringTag;
390 }
391
392
393 bool StringShape::IsSliced() {
394   return (type_ & kStringRepresentationMask) == kSlicedStringTag;
395 }
396
397
398 bool StringShape::IsIndirect() {
399   return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
400 }
401
402
403 bool StringShape::IsExternal() {
404   return (type_ & kStringRepresentationMask) == kExternalStringTag;
405 }
406
407
408 bool StringShape::IsSequential() {
409   return (type_ & kStringRepresentationMask) == kSeqStringTag;
410 }
411
412
413 StringRepresentationTag StringShape::representation_tag() {
414   uint32_t tag = (type_ & kStringRepresentationMask);
415   return static_cast<StringRepresentationTag>(tag);
416 }
417
418
419 uint32_t StringShape::encoding_tag() {
420   return type_ & kStringEncodingMask;
421 }
422
423
424 uint32_t StringShape::full_representation_tag() {
425   return (type_ & (kStringRepresentationMask | kStringEncodingMask));
426 }
427
428
429 STATIC_ASSERT((kStringRepresentationMask | kStringEncodingMask) ==
430              Internals::kFullStringRepresentationMask);
431
432 STATIC_ASSERT(static_cast<uint32_t>(kStringEncodingMask) ==
433              Internals::kStringEncodingMask);
434
435
436 bool StringShape::IsSequentialOneByte() {
437   return full_representation_tag() == (kSeqStringTag | kOneByteStringTag);
438 }
439
440
441 bool StringShape::IsSequentialTwoByte() {
442   return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
443 }
444
445
446 bool StringShape::IsExternalOneByte() {
447   return full_representation_tag() == (kExternalStringTag | kOneByteStringTag);
448 }
449
450
451 STATIC_ASSERT((kExternalStringTag | kOneByteStringTag) ==
452               Internals::kExternalOneByteRepresentationTag);
453
454 STATIC_ASSERT(v8::String::ONE_BYTE_ENCODING == kOneByteStringTag);
455
456
457 bool StringShape::IsExternalTwoByte() {
458   return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
459 }
460
461
462 STATIC_ASSERT((kExternalStringTag | kTwoByteStringTag) ==
463              Internals::kExternalTwoByteRepresentationTag);
464
465 STATIC_ASSERT(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
466
467 uc32 FlatStringReader::Get(int index) {
468   DCHECK(0 <= index && index <= length_);
469   if (is_one_byte_) {
470     return static_cast<const byte*>(start_)[index];
471   } else {
472     return static_cast<const uc16*>(start_)[index];
473   }
474 }
475
476
477 Handle<Object> StringTableShape::AsHandle(Isolate* isolate, HashTableKey* key) {
478   return key->AsHandle(isolate);
479 }
480
481
482 Handle<Object> MapCacheShape::AsHandle(Isolate* isolate, HashTableKey* key) {
483   return key->AsHandle(isolate);
484 }
485
486
487 Handle<Object> CompilationCacheShape::AsHandle(Isolate* isolate,
488                                                HashTableKey* key) {
489   return key->AsHandle(isolate);
490 }
491
492
493 Handle<Object> CodeCacheHashTableShape::AsHandle(Isolate* isolate,
494                                                  HashTableKey* key) {
495   return key->AsHandle(isolate);
496 }
497
498 template <typename Char>
499 class SequentialStringKey : public HashTableKey {
500  public:
501   explicit SequentialStringKey(Vector<const Char> string, uint32_t seed)
502       : string_(string), hash_field_(0), seed_(seed) { }
503
504   virtual uint32_t Hash() OVERRIDE {
505     hash_field_ = StringHasher::HashSequentialString<Char>(string_.start(),
506                                                            string_.length(),
507                                                            seed_);
508
509     uint32_t result = hash_field_ >> String::kHashShift;
510     DCHECK(result != 0);  // Ensure that the hash value of 0 is never computed.
511     return result;
512   }
513
514
515   virtual uint32_t HashForObject(Object* other) OVERRIDE {
516     return String::cast(other)->Hash();
517   }
518
519   Vector<const Char> string_;
520   uint32_t hash_field_;
521   uint32_t seed_;
522 };
523
524
525 class OneByteStringKey : public SequentialStringKey<uint8_t> {
526  public:
527   OneByteStringKey(Vector<const uint8_t> str, uint32_t seed)
528       : SequentialStringKey<uint8_t>(str, seed) { }
529
530   virtual bool IsMatch(Object* string) OVERRIDE {
531     return String::cast(string)->IsOneByteEqualTo(string_);
532   }
533
534   virtual Handle<Object> AsHandle(Isolate* isolate) OVERRIDE;
535 };
536
537
538 class SeqOneByteSubStringKey : public HashTableKey {
539  public:
540   SeqOneByteSubStringKey(Handle<SeqOneByteString> string, int from, int length)
541       : string_(string), from_(from), length_(length) {
542     DCHECK(string_->IsSeqOneByteString());
543   }
544
545   virtual uint32_t Hash() OVERRIDE {
546     DCHECK(length_ >= 0);
547     DCHECK(from_ + length_ <= string_->length());
548     const uint8_t* chars = string_->GetChars() + from_;
549     hash_field_ = StringHasher::HashSequentialString(
550         chars, length_, string_->GetHeap()->HashSeed());
551     uint32_t result = hash_field_ >> String::kHashShift;
552     DCHECK(result != 0);  // Ensure that the hash value of 0 is never computed.
553     return result;
554   }
555
556   virtual uint32_t HashForObject(Object* other) OVERRIDE {
557     return String::cast(other)->Hash();
558   }
559
560   virtual bool IsMatch(Object* string) OVERRIDE;
561   virtual Handle<Object> AsHandle(Isolate* isolate) OVERRIDE;
562
563  private:
564   Handle<SeqOneByteString> string_;
565   int from_;
566   int length_;
567   uint32_t hash_field_;
568 };
569
570
571 class TwoByteStringKey : public SequentialStringKey<uc16> {
572  public:
573   explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed)
574       : SequentialStringKey<uc16>(str, seed) { }
575
576   virtual bool IsMatch(Object* string) OVERRIDE {
577     return String::cast(string)->IsTwoByteEqualTo(string_);
578   }
579
580   virtual Handle<Object> AsHandle(Isolate* isolate) OVERRIDE;
581 };
582
583
584 // Utf8StringKey carries a vector of chars as key.
585 class Utf8StringKey : public HashTableKey {
586  public:
587   explicit Utf8StringKey(Vector<const char> string, uint32_t seed)
588       : string_(string), hash_field_(0), seed_(seed) { }
589
590   virtual bool IsMatch(Object* string) OVERRIDE {
591     return String::cast(string)->IsUtf8EqualTo(string_);
592   }
593
594   virtual uint32_t Hash() OVERRIDE {
595     if (hash_field_ != 0) return hash_field_ >> String::kHashShift;
596     hash_field_ = StringHasher::ComputeUtf8Hash(string_, seed_, &chars_);
597     uint32_t result = hash_field_ >> String::kHashShift;
598     DCHECK(result != 0);  // Ensure that the hash value of 0 is never computed.
599     return result;
600   }
601
602   virtual uint32_t HashForObject(Object* other) OVERRIDE {
603     return String::cast(other)->Hash();
604   }
605
606   virtual Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
607     if (hash_field_ == 0) Hash();
608     return isolate->factory()->NewInternalizedStringFromUtf8(
609         string_, chars_, hash_field_);
610   }
611
612   Vector<const char> string_;
613   uint32_t hash_field_;
614   int chars_;  // Caches the number of characters when computing the hash code.
615   uint32_t seed_;
616 };
617
618
619 bool Object::IsNumber() const {
620   return IsSmi() || IsHeapNumber();
621 }
622
623
624 TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
625 TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
626
627
628 bool Object::IsFiller() const {
629   if (!Object::IsHeapObject()) return false;
630   InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
631   return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
632 }
633
634
635 bool Object::IsExternalArray() const {
636   if (!Object::IsHeapObject())
637     return false;
638   InstanceType instance_type =
639       HeapObject::cast(this)->map()->instance_type();
640   return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
641           instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
642 }
643
644
645 #define TYPED_ARRAY_TYPE_CHECKER(Type, type, TYPE, ctype, size)               \
646   TYPE_CHECKER(External##Type##Array, EXTERNAL_##TYPE##_ARRAY_TYPE)           \
647   TYPE_CHECKER(Fixed##Type##Array, FIXED_##TYPE##_ARRAY_TYPE)
648
649 TYPED_ARRAYS(TYPED_ARRAY_TYPE_CHECKER)
650 #undef TYPED_ARRAY_TYPE_CHECKER
651
652
653 bool Object::IsFixedTypedArrayBase() const {
654   if (!Object::IsHeapObject()) return false;
655
656   InstanceType instance_type =
657       HeapObject::cast(this)->map()->instance_type();
658   return (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE &&
659           instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE);
660 }
661
662
663 bool Object::IsJSReceiver() const {
664   STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
665   return IsHeapObject() &&
666       HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
667 }
668
669
670 bool Object::IsJSObject() const {
671   STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
672   return IsHeapObject() &&
673       HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
674 }
675
676
677 bool Object::IsJSProxy() const {
678   if (!Object::IsHeapObject()) return false;
679   return  HeapObject::cast(this)->map()->IsJSProxyMap();
680 }
681
682
683 TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
684 TYPE_CHECKER(JSSet, JS_SET_TYPE)
685 TYPE_CHECKER(JSMap, JS_MAP_TYPE)
686 TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE)
687 TYPE_CHECKER(JSMapIterator, JS_MAP_ITERATOR_TYPE)
688 TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
689 TYPE_CHECKER(JSWeakSet, JS_WEAK_SET_TYPE)
690 TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
691 TYPE_CHECKER(Map, MAP_TYPE)
692 TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
693 TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
694 TYPE_CHECKER(ConstantPoolArray, CONSTANT_POOL_ARRAY_TYPE)
695
696
697 bool Object::IsJSWeakCollection() const {
698   return IsJSWeakMap() || IsJSWeakSet();
699 }
700
701
702 bool Object::IsDescriptorArray() const {
703   return IsFixedArray();
704 }
705
706
707 bool Object::IsTransitionArray() const {
708   return IsFixedArray();
709 }
710
711
712 bool Object::IsTypeFeedbackVector() const { return IsFixedArray(); }
713
714
715 bool Object::IsDeoptimizationInputData() const {
716   // Must be a fixed array.
717   if (!IsFixedArray()) return false;
718
719   // There's no sure way to detect the difference between a fixed array and
720   // a deoptimization data array.  Since this is used for asserts we can
721   // check that the length is zero or else the fixed size plus a multiple of
722   // the entry size.
723   int length = FixedArray::cast(this)->length();
724   if (length == 0) return true;
725
726   length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
727   return length >= 0 && length % DeoptimizationInputData::kDeoptEntrySize == 0;
728 }
729
730
731 bool Object::IsDeoptimizationOutputData() const {
732   if (!IsFixedArray()) return false;
733   // There's actually no way to see the difference between a fixed array and
734   // a deoptimization data array.  Since this is used for asserts we can check
735   // that the length is plausible though.
736   if (FixedArray::cast(this)->length() % 2 != 0) return false;
737   return true;
738 }
739
740
741 bool Object::IsDependentCode() const {
742   if (!IsFixedArray()) return false;
743   // There's actually no way to see the difference between a fixed array and
744   // a dependent codes array.
745   return true;
746 }
747
748
749 bool Object::IsContext() const {
750   if (!Object::IsHeapObject()) return false;
751   Map* map = HeapObject::cast(this)->map();
752   Heap* heap = map->GetHeap();
753   return (map == heap->function_context_map() ||
754       map == heap->catch_context_map() ||
755       map == heap->with_context_map() ||
756       map == heap->native_context_map() ||
757       map == heap->block_context_map() ||
758       map == heap->module_context_map() ||
759       map == heap->global_context_map());
760 }
761
762
763 bool Object::IsNativeContext() const {
764   return Object::IsHeapObject() &&
765       HeapObject::cast(this)->map() ==
766       HeapObject::cast(this)->GetHeap()->native_context_map();
767 }
768
769
770 bool Object::IsScopeInfo() const {
771   return Object::IsHeapObject() &&
772       HeapObject::cast(this)->map() ==
773       HeapObject::cast(this)->GetHeap()->scope_info_map();
774 }
775
776
777 TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
778
779
780 template <> inline bool Is<JSFunction>(Object* obj) {
781   return obj->IsJSFunction();
782 }
783
784
785 TYPE_CHECKER(Code, CODE_TYPE)
786 TYPE_CHECKER(Oddball, ODDBALL_TYPE)
787 TYPE_CHECKER(Cell, CELL_TYPE)
788 TYPE_CHECKER(PropertyCell, PROPERTY_CELL_TYPE)
789 TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
790 TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE)
791 TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
792 TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
793 TYPE_CHECKER(JSDate, JS_DATE_TYPE)
794 TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
795
796
797 bool Object::IsStringWrapper() const {
798   return IsJSValue() && JSValue::cast(this)->value()->IsString();
799 }
800
801
802 TYPE_CHECKER(Foreign, FOREIGN_TYPE)
803
804
805 bool Object::IsBoolean() const {
806   return IsOddball() &&
807       ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
808 }
809
810
811 TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
812 TYPE_CHECKER(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE)
813 TYPE_CHECKER(JSTypedArray, JS_TYPED_ARRAY_TYPE)
814 TYPE_CHECKER(JSDataView, JS_DATA_VIEW_TYPE)
815
816
817 bool Object::IsJSArrayBufferView() const {
818   return IsJSDataView() || IsJSTypedArray();
819 }
820
821
822 TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
823
824
825 template <> inline bool Is<JSArray>(Object* obj) {
826   return obj->IsJSArray();
827 }
828
829
830 bool Object::IsHashTable() const {
831   return Object::IsHeapObject() &&
832       HeapObject::cast(this)->map() ==
833       HeapObject::cast(this)->GetHeap()->hash_table_map();
834 }
835
836
837 bool Object::IsWeakHashTable() const {
838   return IsHashTable();
839 }
840
841
842 bool Object::IsDictionary() const {
843   return IsHashTable() &&
844       this != HeapObject::cast(this)->GetHeap()->string_table();
845 }
846
847
848 bool Object::IsNameDictionary() const {
849   return IsDictionary();
850 }
851
852
853 bool Object::IsSeededNumberDictionary() const {
854   return IsDictionary();
855 }
856
857
858 bool Object::IsUnseededNumberDictionary() const {
859   return IsDictionary();
860 }
861
862
863 bool Object::IsStringTable() const {
864   return IsHashTable();
865 }
866
867
868 bool Object::IsJSFunctionResultCache() const {
869   if (!IsFixedArray()) return false;
870   const FixedArray* self = FixedArray::cast(this);
871   int length = self->length();
872   if (length < JSFunctionResultCache::kEntriesIndex) return false;
873   if ((length - JSFunctionResultCache::kEntriesIndex)
874       % JSFunctionResultCache::kEntrySize != 0) {
875     return false;
876   }
877 #ifdef VERIFY_HEAP
878   if (FLAG_verify_heap) {
879     // TODO(svenpanne) We use const_cast here and below to break our dependency
880     // cycle between the predicates and the verifiers. This can be removed when
881     // the verifiers are const-correct, too.
882     reinterpret_cast<JSFunctionResultCache*>(const_cast<Object*>(this))->
883         JSFunctionResultCacheVerify();
884   }
885 #endif
886   return true;
887 }
888
889
890 bool Object::IsNormalizedMapCache() const {
891   return NormalizedMapCache::IsNormalizedMapCache(this);
892 }
893
894
895 int NormalizedMapCache::GetIndex(Handle<Map> map) {
896   return map->Hash() % NormalizedMapCache::kEntries;
897 }
898
899
900 bool NormalizedMapCache::IsNormalizedMapCache(const Object* obj) {
901   if (!obj->IsFixedArray()) return false;
902   if (FixedArray::cast(obj)->length() != NormalizedMapCache::kEntries) {
903     return false;
904   }
905 #ifdef VERIFY_HEAP
906   if (FLAG_verify_heap) {
907     reinterpret_cast<NormalizedMapCache*>(const_cast<Object*>(obj))->
908         NormalizedMapCacheVerify();
909   }
910 #endif
911   return true;
912 }
913
914
915 bool Object::IsCompilationCacheTable() const {
916   return IsHashTable();
917 }
918
919
920 bool Object::IsCodeCacheHashTable() const {
921   return IsHashTable();
922 }
923
924
925 bool Object::IsPolymorphicCodeCacheHashTable() const {
926   return IsHashTable();
927 }
928
929
930 bool Object::IsMapCache() const {
931   return IsHashTable();
932 }
933
934
935 bool Object::IsObjectHashTable() const {
936   return IsHashTable();
937 }
938
939
940 bool Object::IsOrderedHashTable() const {
941   return IsHeapObject() &&
942       HeapObject::cast(this)->map() ==
943       HeapObject::cast(this)->GetHeap()->ordered_hash_table_map();
944 }
945
946
947 bool Object::IsOrderedHashSet() const {
948   return IsOrderedHashTable();
949 }
950
951
952 bool Object::IsOrderedHashMap() const {
953   return IsOrderedHashTable();
954 }
955
956
957 bool Object::IsPrimitive() const {
958   return IsOddball() || IsNumber() || IsString();
959 }
960
961
962 bool Object::IsJSGlobalProxy() const {
963   bool result = IsHeapObject() &&
964                 (HeapObject::cast(this)->map()->instance_type() ==
965                  JS_GLOBAL_PROXY_TYPE);
966   DCHECK(!result ||
967          HeapObject::cast(this)->map()->is_access_check_needed());
968   return result;
969 }
970
971
972 bool Object::IsGlobalObject() const {
973   if (!IsHeapObject()) return false;
974
975   InstanceType type = HeapObject::cast(this)->map()->instance_type();
976   return type == JS_GLOBAL_OBJECT_TYPE ||
977          type == JS_BUILTINS_OBJECT_TYPE;
978 }
979
980
981 TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
982 TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
983
984
985 bool Object::IsUndetectableObject() const {
986   return IsHeapObject()
987     && HeapObject::cast(this)->map()->is_undetectable();
988 }
989
990
991 bool Object::IsAccessCheckNeeded() const {
992   if (!IsHeapObject()) return false;
993   if (IsJSGlobalProxy()) {
994     const JSGlobalProxy* proxy = JSGlobalProxy::cast(this);
995     GlobalObject* global = proxy->GetIsolate()->context()->global_object();
996     return proxy->IsDetachedFrom(global);
997   }
998   return HeapObject::cast(this)->map()->is_access_check_needed();
999 }
1000
1001
1002 bool Object::IsStruct() const {
1003   if (!IsHeapObject()) return false;
1004   switch (HeapObject::cast(this)->map()->instance_type()) {
1005 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
1006   STRUCT_LIST(MAKE_STRUCT_CASE)
1007 #undef MAKE_STRUCT_CASE
1008     default: return false;
1009   }
1010 }
1011
1012
1013 #define MAKE_STRUCT_PREDICATE(NAME, Name, name)                         \
1014   bool Object::Is##Name() const {                                       \
1015     return Object::IsHeapObject()                                       \
1016       && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
1017   }
1018   STRUCT_LIST(MAKE_STRUCT_PREDICATE)
1019 #undef MAKE_STRUCT_PREDICATE
1020
1021
1022 bool Object::IsUndefined() const {
1023   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
1024 }
1025
1026
1027 bool Object::IsNull() const {
1028   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
1029 }
1030
1031
1032 bool Object::IsTheHole() const {
1033   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
1034 }
1035
1036
1037 bool Object::IsException() const {
1038   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kException;
1039 }
1040
1041
1042 bool Object::IsUninitialized() const {
1043   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUninitialized;
1044 }
1045
1046
1047 bool Object::IsTrue() const {
1048   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
1049 }
1050
1051
1052 bool Object::IsFalse() const {
1053   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
1054 }
1055
1056
1057 bool Object::IsArgumentsMarker() const {
1058   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
1059 }
1060
1061
1062 double Object::Number() {
1063   DCHECK(IsNumber());
1064   return IsSmi()
1065     ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
1066     : reinterpret_cast<HeapNumber*>(this)->value();
1067 }
1068
1069
1070 bool Object::IsNaN() const {
1071   return this->IsHeapNumber() && std::isnan(HeapNumber::cast(this)->value());
1072 }
1073
1074
1075 bool Object::IsMinusZero() const {
1076   return this->IsHeapNumber() &&
1077          i::IsMinusZero(HeapNumber::cast(this)->value());
1078 }
1079
1080
1081 MaybeHandle<Smi> Object::ToSmi(Isolate* isolate, Handle<Object> object) {
1082   if (object->IsSmi()) return Handle<Smi>::cast(object);
1083   if (object->IsHeapNumber()) {
1084     double value = Handle<HeapNumber>::cast(object)->value();
1085     int int_value = FastD2I(value);
1086     if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
1087       return handle(Smi::FromInt(int_value), isolate);
1088     }
1089   }
1090   return Handle<Smi>();
1091 }
1092
1093
1094 MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
1095                                          Handle<Object> object) {
1096   return ToObject(
1097       isolate, object, handle(isolate->context()->native_context(), isolate));
1098 }
1099
1100
1101 bool Object::HasSpecificClassOf(String* name) {
1102   return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
1103 }
1104
1105
1106 MaybeHandle<Object> Object::GetProperty(Handle<Object> object,
1107                                         Handle<Name> name) {
1108   LookupIterator it(object, name);
1109   return GetProperty(&it);
1110 }
1111
1112
1113 MaybeHandle<Object> Object::GetElement(Isolate* isolate,
1114                                        Handle<Object> object,
1115                                        uint32_t index) {
1116   // GetElement can trigger a getter which can cause allocation.
1117   // This was not always the case. This DCHECK is here to catch
1118   // leftover incorrect uses.
1119   DCHECK(AllowHeapAllocation::IsAllowed());
1120   return Object::GetElementWithReceiver(isolate, object, object, index);
1121 }
1122
1123
1124 MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> object,
1125                                                  Handle<Name> name) {
1126   uint32_t index;
1127   Isolate* isolate = name->GetIsolate();
1128   if (name->AsArrayIndex(&index)) return GetElement(isolate, object, index);
1129   return GetProperty(object, name);
1130 }
1131
1132
1133 MaybeHandle<Object> Object::GetProperty(Isolate* isolate,
1134                                         Handle<Object> object,
1135                                         const char* name) {
1136   Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
1137   DCHECK(!str.is_null());
1138 #ifdef DEBUG
1139   uint32_t index;  // Assert that the name is not an array index.
1140   DCHECK(!str->AsArrayIndex(&index));
1141 #endif  // DEBUG
1142   return GetProperty(object, str);
1143 }
1144
1145
1146 MaybeHandle<Object> JSProxy::GetElementWithHandler(Handle<JSProxy> proxy,
1147                                                    Handle<Object> receiver,
1148                                                    uint32_t index) {
1149   return GetPropertyWithHandler(
1150       proxy, receiver, proxy->GetIsolate()->factory()->Uint32ToString(index));
1151 }
1152
1153
1154 MaybeHandle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy,
1155                                                    Handle<JSReceiver> receiver,
1156                                                    uint32_t index,
1157                                                    Handle<Object> value,
1158                                                    StrictMode strict_mode) {
1159   Isolate* isolate = proxy->GetIsolate();
1160   Handle<String> name = isolate->factory()->Uint32ToString(index);
1161   return SetPropertyWithHandler(proxy, receiver, name, value, strict_mode);
1162 }
1163
1164
1165 Maybe<bool> JSProxy::HasElementWithHandler(Handle<JSProxy> proxy,
1166                                            uint32_t index) {
1167   Isolate* isolate = proxy->GetIsolate();
1168   Handle<String> name = isolate->factory()->Uint32ToString(index);
1169   return HasPropertyWithHandler(proxy, name);
1170 }
1171
1172
1173 #define FIELD_ADDR(p, offset) \
1174   (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
1175
1176 #define FIELD_ADDR_CONST(p, offset) \
1177   (reinterpret_cast<const byte*>(p) + offset - kHeapObjectTag)
1178
1179 #define READ_FIELD(p, offset) \
1180   (*reinterpret_cast<Object* const*>(FIELD_ADDR_CONST(p, offset)))
1181
1182 #define ACQUIRE_READ_FIELD(p, offset)           \
1183   reinterpret_cast<Object*>(base::Acquire_Load( \
1184       reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR_CONST(p, offset))))
1185
1186 #define NOBARRIER_READ_FIELD(p, offset)           \
1187   reinterpret_cast<Object*>(base::NoBarrier_Load( \
1188       reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR_CONST(p, offset))))
1189
1190 #define WRITE_FIELD(p, offset, value) \
1191   (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
1192
1193 #define RELEASE_WRITE_FIELD(p, offset, value)                     \
1194   base::Release_Store(                                            \
1195       reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
1196       reinterpret_cast<base::AtomicWord>(value));
1197
1198 #define NOBARRIER_WRITE_FIELD(p, offset, value)                   \
1199   base::NoBarrier_Store(                                          \
1200       reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
1201       reinterpret_cast<base::AtomicWord>(value));
1202
1203 #define WRITE_BARRIER(heap, object, offset, value)                      \
1204   heap->incremental_marking()->RecordWrite(                             \
1205       object, HeapObject::RawField(object, offset), value);             \
1206   if (heap->InNewSpace(value)) {                                        \
1207     heap->RecordWrite(object->address(), offset);                       \
1208   }
1209
1210 #define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode)    \
1211   if (mode == UPDATE_WRITE_BARRIER) {                                   \
1212     heap->incremental_marking()->RecordWrite(                           \
1213       object, HeapObject::RawField(object, offset), value);             \
1214     if (heap->InNewSpace(value)) {                                      \
1215       heap->RecordWrite(object->address(), offset);                     \
1216     }                                                                   \
1217   }
1218
1219 #ifndef V8_TARGET_ARCH_MIPS
1220   #define READ_DOUBLE_FIELD(p, offset) \
1221     (*reinterpret_cast<const double*>(FIELD_ADDR_CONST(p, offset)))
1222 #else  // V8_TARGET_ARCH_MIPS
1223   // Prevent gcc from using load-double (mips ldc1) on (possibly)
1224   // non-64-bit aligned HeapNumber::value.
1225   static inline double read_double_field(const void* p, int offset) {
1226     union conversion {
1227       double d;
1228       uint32_t u[2];
1229     } c;
1230     c.u[0] = (*reinterpret_cast<const uint32_t*>(
1231         FIELD_ADDR_CONST(p, offset)));
1232     c.u[1] = (*reinterpret_cast<const uint32_t*>(
1233         FIELD_ADDR_CONST(p, offset + 4)));
1234     return c.d;
1235   }
1236   #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
1237 #endif  // V8_TARGET_ARCH_MIPS
1238
1239 #ifndef V8_TARGET_ARCH_MIPS
1240   #define WRITE_DOUBLE_FIELD(p, offset, value) \
1241     (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
1242 #else  // V8_TARGET_ARCH_MIPS
1243   // Prevent gcc from using store-double (mips sdc1) on (possibly)
1244   // non-64-bit aligned HeapNumber::value.
1245   static inline void write_double_field(void* p, int offset,
1246                                         double value) {
1247     union conversion {
1248       double d;
1249       uint32_t u[2];
1250     } c;
1251     c.d = value;
1252     (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
1253     (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
1254   }
1255   #define WRITE_DOUBLE_FIELD(p, offset, value) \
1256     write_double_field(p, offset, value)
1257 #endif  // V8_TARGET_ARCH_MIPS
1258
1259
1260 #define READ_INT_FIELD(p, offset) \
1261   (*reinterpret_cast<const int*>(FIELD_ADDR_CONST(p, offset)))
1262
1263 #define WRITE_INT_FIELD(p, offset, value) \
1264   (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
1265
1266 #define READ_INTPTR_FIELD(p, offset) \
1267   (*reinterpret_cast<const intptr_t*>(FIELD_ADDR_CONST(p, offset)))
1268
1269 #define WRITE_INTPTR_FIELD(p, offset, value) \
1270   (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
1271
1272 #define READ_UINT32_FIELD(p, offset) \
1273   (*reinterpret_cast<const uint32_t*>(FIELD_ADDR_CONST(p, offset)))
1274
1275 #define WRITE_UINT32_FIELD(p, offset, value) \
1276   (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
1277
1278 #define READ_INT32_FIELD(p, offset) \
1279   (*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset)))
1280
1281 #define WRITE_INT32_FIELD(p, offset, value) \
1282   (*reinterpret_cast<int32_t*>(FIELD_ADDR(p, offset)) = value)
1283
1284 #define READ_INT64_FIELD(p, offset) \
1285   (*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset)))
1286
1287 #define WRITE_INT64_FIELD(p, offset, value) \
1288   (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
1289
1290 #define READ_SHORT_FIELD(p, offset) \
1291   (*reinterpret_cast<const uint16_t*>(FIELD_ADDR_CONST(p, offset)))
1292
1293 #define WRITE_SHORT_FIELD(p, offset, value) \
1294   (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
1295
1296 #define READ_BYTE_FIELD(p, offset) \
1297   (*reinterpret_cast<const byte*>(FIELD_ADDR_CONST(p, offset)))
1298
1299 #define NOBARRIER_READ_BYTE_FIELD(p, offset) \
1300   static_cast<byte>(base::NoBarrier_Load(    \
1301       reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset))))
1302
1303 #define WRITE_BYTE_FIELD(p, offset, value) \
1304   (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
1305
1306 #define NOBARRIER_WRITE_BYTE_FIELD(p, offset, value)           \
1307   base::NoBarrier_Store(                                       \
1308       reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset)), \
1309       static_cast<base::Atomic8>(value));
1310
1311 Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
1312   return reinterpret_cast<Object**>(FIELD_ADDR(obj, byte_offset));
1313 }
1314
1315
1316 int Smi::value() const {
1317   return Internals::SmiValue(this);
1318 }
1319
1320
1321 Smi* Smi::FromInt(int value) {
1322   DCHECK(Smi::IsValid(value));
1323   return reinterpret_cast<Smi*>(Internals::IntToSmi(value));
1324 }
1325
1326
1327 Smi* Smi::FromIntptr(intptr_t value) {
1328   DCHECK(Smi::IsValid(value));
1329   int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1330   return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
1331 }
1332
1333
1334 bool Smi::IsValid(intptr_t value) {
1335   bool result = Internals::IsValidSmi(value);
1336   DCHECK_EQ(result, value >= kMinValue && value <= kMaxValue);
1337   return result;
1338 }
1339
1340
1341 MapWord MapWord::FromMap(const Map* map) {
1342   return MapWord(reinterpret_cast<uintptr_t>(map));
1343 }
1344
1345
1346 Map* MapWord::ToMap() {
1347   return reinterpret_cast<Map*>(value_);
1348 }
1349
1350
1351 bool MapWord::IsForwardingAddress() {
1352   return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
1353 }
1354
1355
1356 MapWord MapWord::FromForwardingAddress(HeapObject* object) {
1357   Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1358   return MapWord(reinterpret_cast<uintptr_t>(raw));
1359 }
1360
1361
1362 HeapObject* MapWord::ToForwardingAddress() {
1363   DCHECK(IsForwardingAddress());
1364   return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
1365 }
1366
1367
1368 #ifdef VERIFY_HEAP
1369 void HeapObject::VerifyObjectField(int offset) {
1370   VerifyPointer(READ_FIELD(this, offset));
1371 }
1372
1373 void HeapObject::VerifySmiField(int offset) {
1374   CHECK(READ_FIELD(this, offset)->IsSmi());
1375 }
1376 #endif
1377
1378
1379 Heap* HeapObject::GetHeap() const {
1380   Heap* heap =
1381       MemoryChunk::FromAddress(reinterpret_cast<const byte*>(this))->heap();
1382   SLOW_DCHECK(heap != NULL);
1383   return heap;
1384 }
1385
1386
1387 Isolate* HeapObject::GetIsolate() const {
1388   return GetHeap()->isolate();
1389 }
1390
1391
1392 Map* HeapObject::map() const {
1393 #ifdef DEBUG
1394   // Clear mark potentially added by PathTracer.
1395   uintptr_t raw_value =
1396       map_word().ToRawValue() & ~static_cast<uintptr_t>(PathTracer::kMarkTag);
1397   return MapWord::FromRawValue(raw_value).ToMap();
1398 #else
1399   return map_word().ToMap();
1400 #endif
1401 }
1402
1403
1404 void HeapObject::set_map(Map* value) {
1405   set_map_word(MapWord::FromMap(value));
1406   if (value != NULL) {
1407     // TODO(1600) We are passing NULL as a slot because maps can never be on
1408     // evacuation candidate.
1409     value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1410   }
1411 }
1412
1413
1414 Map* HeapObject::synchronized_map() {
1415   return synchronized_map_word().ToMap();
1416 }
1417
1418
1419 void HeapObject::synchronized_set_map(Map* value) {
1420   synchronized_set_map_word(MapWord::FromMap(value));
1421   if (value != NULL) {
1422     // TODO(1600) We are passing NULL as a slot because maps can never be on
1423     // evacuation candidate.
1424     value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1425   }
1426 }
1427
1428
1429 void HeapObject::synchronized_set_map_no_write_barrier(Map* value) {
1430   synchronized_set_map_word(MapWord::FromMap(value));
1431 }
1432
1433
1434 // Unsafe accessor omitting write barrier.
1435 void HeapObject::set_map_no_write_barrier(Map* value) {
1436   set_map_word(MapWord::FromMap(value));
1437 }
1438
1439
1440 MapWord HeapObject::map_word() const {
1441   return MapWord(
1442       reinterpret_cast<uintptr_t>(NOBARRIER_READ_FIELD(this, kMapOffset)));
1443 }
1444
1445
1446 void HeapObject::set_map_word(MapWord map_word) {
1447   NOBARRIER_WRITE_FIELD(
1448       this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1449 }
1450
1451
1452 MapWord HeapObject::synchronized_map_word() const {
1453   return MapWord(
1454       reinterpret_cast<uintptr_t>(ACQUIRE_READ_FIELD(this, kMapOffset)));
1455 }
1456
1457
1458 void HeapObject::synchronized_set_map_word(MapWord map_word) {
1459   RELEASE_WRITE_FIELD(
1460       this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1461 }
1462
1463
1464 HeapObject* HeapObject::FromAddress(Address address) {
1465   DCHECK_TAG_ALIGNED(address);
1466   return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1467 }
1468
1469
1470 Address HeapObject::address() {
1471   return reinterpret_cast<Address>(this) - kHeapObjectTag;
1472 }
1473
1474
1475 int HeapObject::Size() {
1476   return SizeFromMap(map());
1477 }
1478
1479
1480 bool HeapObject::MayContainRawValues() {
1481   InstanceType type = map()->instance_type();
1482   if (type <= LAST_NAME_TYPE) {
1483     if (type == SYMBOL_TYPE) {
1484       return false;
1485     }
1486     DCHECK(type < FIRST_NONSTRING_TYPE);
1487     // There are four string representations: sequential strings, external
1488     // strings, cons strings, and sliced strings.
1489     // Only the former two contain raw values and no heap pointers (besides the
1490     // map-word).
1491     return ((type & kIsIndirectStringMask) != kIsIndirectStringTag);
1492   }
1493   // The ConstantPoolArray contains heap pointers, but also raw values.
1494   if (type == CONSTANT_POOL_ARRAY_TYPE) return true;
1495   return (type <= LAST_DATA_TYPE);
1496 }
1497
1498
1499 void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1500   v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1501                    reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1502 }
1503
1504
1505 void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1506   v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1507 }
1508
1509
1510 void HeapObject::IterateNextCodeLink(ObjectVisitor* v, int offset) {
1511   v->VisitNextCodeLink(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1512 }
1513
1514
1515 double HeapNumber::value() const {
1516   return READ_DOUBLE_FIELD(this, kValueOffset);
1517 }
1518
1519
1520 void HeapNumber::set_value(double value) {
1521   WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1522 }
1523
1524
1525 int HeapNumber::get_exponent() {
1526   return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1527           kExponentShift) - kExponentBias;
1528 }
1529
1530
1531 int HeapNumber::get_sign() {
1532   return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1533 }
1534
1535
1536 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
1537
1538
1539 Object** FixedArray::GetFirstElementAddress() {
1540   return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1541 }
1542
1543
1544 bool FixedArray::ContainsOnlySmisOrHoles() {
1545   Object* the_hole = GetHeap()->the_hole_value();
1546   Object** current = GetFirstElementAddress();
1547   for (int i = 0; i < length(); ++i) {
1548     Object* candidate = *current++;
1549     if (!candidate->IsSmi() && candidate != the_hole) return false;
1550   }
1551   return true;
1552 }
1553
1554
1555 FixedArrayBase* JSObject::elements() const {
1556   Object* array = READ_FIELD(this, kElementsOffset);
1557   return static_cast<FixedArrayBase*>(array);
1558 }
1559
1560
1561 void JSObject::ValidateElements(Handle<JSObject> object) {
1562 #ifdef ENABLE_SLOW_DCHECKS
1563   if (FLAG_enable_slow_asserts) {
1564     ElementsAccessor* accessor = object->GetElementsAccessor();
1565     accessor->Validate(object);
1566   }
1567 #endif
1568 }
1569
1570
1571 void AllocationSite::Initialize() {
1572   set_transition_info(Smi::FromInt(0));
1573   SetElementsKind(GetInitialFastElementsKind());
1574   set_nested_site(Smi::FromInt(0));
1575   set_pretenure_data(Smi::FromInt(0));
1576   set_pretenure_create_count(Smi::FromInt(0));
1577   set_dependent_code(DependentCode::cast(GetHeap()->empty_fixed_array()),
1578                      SKIP_WRITE_BARRIER);
1579 }
1580
1581
1582 void AllocationSite::MarkZombie() {
1583   DCHECK(!IsZombie());
1584   Initialize();
1585   set_pretenure_decision(kZombie);
1586 }
1587
1588
1589 // Heuristic: We only need to create allocation site info if the boilerplate
1590 // elements kind is the initial elements kind.
1591 AllocationSiteMode AllocationSite::GetMode(
1592     ElementsKind boilerplate_elements_kind) {
1593   if (FLAG_pretenuring_call_new ||
1594       IsFastSmiElementsKind(boilerplate_elements_kind)) {
1595     return TRACK_ALLOCATION_SITE;
1596   }
1597
1598   return DONT_TRACK_ALLOCATION_SITE;
1599 }
1600
1601
1602 AllocationSiteMode AllocationSite::GetMode(ElementsKind from,
1603                                            ElementsKind to) {
1604   if (FLAG_pretenuring_call_new ||
1605       (IsFastSmiElementsKind(from) &&
1606        IsMoreGeneralElementsKindTransition(from, to))) {
1607     return TRACK_ALLOCATION_SITE;
1608   }
1609
1610   return DONT_TRACK_ALLOCATION_SITE;
1611 }
1612
1613
1614 inline bool AllocationSite::CanTrack(InstanceType type) {
1615   if (FLAG_allocation_site_pretenuring) {
1616     return type == JS_ARRAY_TYPE ||
1617         type == JS_OBJECT_TYPE ||
1618         type < FIRST_NONSTRING_TYPE;
1619   }
1620   return type == JS_ARRAY_TYPE;
1621 }
1622
1623
1624 inline DependentCode::DependencyGroup AllocationSite::ToDependencyGroup(
1625     Reason reason) {
1626   switch (reason) {
1627     case TENURING:
1628       return DependentCode::kAllocationSiteTenuringChangedGroup;
1629       break;
1630     case TRANSITIONS:
1631       return DependentCode::kAllocationSiteTransitionChangedGroup;
1632       break;
1633   }
1634   UNREACHABLE();
1635   return DependentCode::kAllocationSiteTransitionChangedGroup;
1636 }
1637
1638
1639 inline void AllocationSite::set_memento_found_count(int count) {
1640   int value = pretenure_data()->value();
1641   // Verify that we can count more mementos than we can possibly find in one
1642   // new space collection.
1643   DCHECK((GetHeap()->MaxSemiSpaceSize() /
1644           (StaticVisitorBase::kMinObjectSizeInWords * kPointerSize +
1645            AllocationMemento::kSize)) < MementoFoundCountBits::kMax);
1646   DCHECK(count < MementoFoundCountBits::kMax);
1647   set_pretenure_data(
1648       Smi::FromInt(MementoFoundCountBits::update(value, count)),
1649       SKIP_WRITE_BARRIER);
1650 }
1651
1652 inline bool AllocationSite::IncrementMementoFoundCount() {
1653   if (IsZombie()) return false;
1654
1655   int value = memento_found_count();
1656   set_memento_found_count(value + 1);
1657   return memento_found_count() == kPretenureMinimumCreated;
1658 }
1659
1660
1661 inline void AllocationSite::IncrementMementoCreateCount() {
1662   DCHECK(FLAG_allocation_site_pretenuring);
1663   int value = memento_create_count();
1664   set_memento_create_count(value + 1);
1665 }
1666
1667
1668 inline bool AllocationSite::MakePretenureDecision(
1669     PretenureDecision current_decision,
1670     double ratio,
1671     bool maximum_size_scavenge) {
1672   // Here we just allow state transitions from undecided or maybe tenure
1673   // to don't tenure, maybe tenure, or tenure.
1674   if ((current_decision == kUndecided || current_decision == kMaybeTenure)) {
1675     if (ratio >= kPretenureRatio) {
1676       // We just transition into tenure state when the semi-space was at
1677       // maximum capacity.
1678       if (maximum_size_scavenge) {
1679         set_deopt_dependent_code(true);
1680         set_pretenure_decision(kTenure);
1681         // Currently we just need to deopt when we make a state transition to
1682         // tenure.
1683         return true;
1684       }
1685       set_pretenure_decision(kMaybeTenure);
1686     } else {
1687       set_pretenure_decision(kDontTenure);
1688     }
1689   }
1690   return false;
1691 }
1692
1693
1694 inline bool AllocationSite::DigestPretenuringFeedback(
1695     bool maximum_size_scavenge) {
1696   bool deopt = false;
1697   int create_count = memento_create_count();
1698   int found_count = memento_found_count();
1699   bool minimum_mementos_created = create_count >= kPretenureMinimumCreated;
1700   double ratio =
1701       minimum_mementos_created || FLAG_trace_pretenuring_statistics ?
1702           static_cast<double>(found_count) / create_count : 0.0;
1703   PretenureDecision current_decision = pretenure_decision();
1704
1705   if (minimum_mementos_created) {
1706     deopt = MakePretenureDecision(
1707         current_decision, ratio, maximum_size_scavenge);
1708   }
1709
1710   if (FLAG_trace_pretenuring_statistics) {
1711     PrintF(
1712         "AllocationSite(%p): (created, found, ratio) (%d, %d, %f) %s => %s\n",
1713          static_cast<void*>(this), create_count, found_count, ratio,
1714          PretenureDecisionName(current_decision),
1715          PretenureDecisionName(pretenure_decision()));
1716   }
1717
1718   // Clear feedback calculation fields until the next gc.
1719   set_memento_found_count(0);
1720   set_memento_create_count(0);
1721   return deopt;
1722 }
1723
1724
1725 void JSObject::EnsureCanContainHeapObjectElements(Handle<JSObject> object) {
1726   JSObject::ValidateElements(object);
1727   ElementsKind elements_kind = object->map()->elements_kind();
1728   if (!IsFastObjectElementsKind(elements_kind)) {
1729     if (IsFastHoleyElementsKind(elements_kind)) {
1730       TransitionElementsKind(object, FAST_HOLEY_ELEMENTS);
1731     } else {
1732       TransitionElementsKind(object, FAST_ELEMENTS);
1733     }
1734   }
1735 }
1736
1737
1738 void JSObject::EnsureCanContainElements(Handle<JSObject> object,
1739                                         Object** objects,
1740                                         uint32_t count,
1741                                         EnsureElementsMode mode) {
1742   ElementsKind current_kind = object->map()->elements_kind();
1743   ElementsKind target_kind = current_kind;
1744   {
1745     DisallowHeapAllocation no_allocation;
1746     DCHECK(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1747     bool is_holey = IsFastHoleyElementsKind(current_kind);
1748     if (current_kind == FAST_HOLEY_ELEMENTS) return;
1749     Heap* heap = object->GetHeap();
1750     Object* the_hole = heap->the_hole_value();
1751     for (uint32_t i = 0; i < count; ++i) {
1752       Object* current = *objects++;
1753       if (current == the_hole) {
1754         is_holey = true;
1755         target_kind = GetHoleyElementsKind(target_kind);
1756       } else if (!current->IsSmi()) {
1757         if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && current->IsNumber()) {
1758           if (IsFastSmiElementsKind(target_kind)) {
1759             if (is_holey) {
1760               target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
1761             } else {
1762               target_kind = FAST_DOUBLE_ELEMENTS;
1763             }
1764           }
1765         } else if (is_holey) {
1766           target_kind = FAST_HOLEY_ELEMENTS;
1767           break;
1768         } else {
1769           target_kind = FAST_ELEMENTS;
1770         }
1771       }
1772     }
1773   }
1774   if (target_kind != current_kind) {
1775     TransitionElementsKind(object, target_kind);
1776   }
1777 }
1778
1779
1780 void JSObject::EnsureCanContainElements(Handle<JSObject> object,
1781                                         Handle<FixedArrayBase> elements,
1782                                         uint32_t length,
1783                                         EnsureElementsMode mode) {
1784   Heap* heap = object->GetHeap();
1785   if (elements->map() != heap->fixed_double_array_map()) {
1786     DCHECK(elements->map() == heap->fixed_array_map() ||
1787            elements->map() == heap->fixed_cow_array_map());
1788     if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1789       mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1790     }
1791     Object** objects =
1792         Handle<FixedArray>::cast(elements)->GetFirstElementAddress();
1793     EnsureCanContainElements(object, objects, length, mode);
1794     return;
1795   }
1796
1797   DCHECK(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1798   if (object->GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) {
1799     TransitionElementsKind(object, FAST_HOLEY_DOUBLE_ELEMENTS);
1800   } else if (object->GetElementsKind() == FAST_SMI_ELEMENTS) {
1801     Handle<FixedDoubleArray> double_array =
1802         Handle<FixedDoubleArray>::cast(elements);
1803     for (uint32_t i = 0; i < length; ++i) {
1804       if (double_array->is_the_hole(i)) {
1805         TransitionElementsKind(object, FAST_HOLEY_DOUBLE_ELEMENTS);
1806         return;
1807       }
1808     }
1809     TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS);
1810   }
1811 }
1812
1813
1814 void JSObject::SetMapAndElements(Handle<JSObject> object,
1815                                  Handle<Map> new_map,
1816                                  Handle<FixedArrayBase> value) {
1817   JSObject::MigrateToMap(object, new_map);
1818   DCHECK((object->map()->has_fast_smi_or_object_elements() ||
1819           (*value == object->GetHeap()->empty_fixed_array())) ==
1820          (value->map() == object->GetHeap()->fixed_array_map() ||
1821           value->map() == object->GetHeap()->fixed_cow_array_map()));
1822   DCHECK((*value == object->GetHeap()->empty_fixed_array()) ||
1823          (object->map()->has_fast_double_elements() ==
1824           value->IsFixedDoubleArray()));
1825   object->set_elements(*value);
1826 }
1827
1828
1829 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1830   WRITE_FIELD(this, kElementsOffset, value);
1831   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
1832 }
1833
1834
1835 void JSObject::initialize_properties() {
1836   DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1837   WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
1838 }
1839
1840
1841 void JSObject::initialize_elements() {
1842   FixedArrayBase* elements = map()->GetInitialElements();
1843   WRITE_FIELD(this, kElementsOffset, elements);
1844 }
1845
1846
1847 Handle<String> Map::ExpectedTransitionKey(Handle<Map> map) {
1848   DisallowHeapAllocation no_gc;
1849   if (!map->HasTransitionArray()) return Handle<String>::null();
1850   TransitionArray* transitions = map->transitions();
1851   if (!transitions->IsSimpleTransition()) return Handle<String>::null();
1852   int transition = TransitionArray::kSimpleTransitionIndex;
1853   PropertyDetails details = transitions->GetTargetDetails(transition);
1854   Name* name = transitions->GetKey(transition);
1855   if (details.type() != FIELD) return Handle<String>::null();
1856   if (details.attributes() != NONE) return Handle<String>::null();
1857   if (!name->IsString()) return Handle<String>::null();
1858   return Handle<String>(String::cast(name));
1859 }
1860
1861
1862 Handle<Map> Map::ExpectedTransitionTarget(Handle<Map> map) {
1863   DCHECK(!ExpectedTransitionKey(map).is_null());
1864   return Handle<Map>(map->transitions()->GetTarget(
1865       TransitionArray::kSimpleTransitionIndex));
1866 }
1867
1868
1869 Handle<Map> Map::FindTransitionToField(Handle<Map> map, Handle<Name> key) {
1870   DisallowHeapAllocation no_allocation;
1871   if (!map->HasTransitionArray()) return Handle<Map>::null();
1872   TransitionArray* transitions = map->transitions();
1873   int transition = transitions->Search(*key);
1874   if (transition == TransitionArray::kNotFound) return Handle<Map>::null();
1875   PropertyDetails target_details = transitions->GetTargetDetails(transition);
1876   if (target_details.type() != FIELD) return Handle<Map>::null();
1877   if (target_details.attributes() != NONE) return Handle<Map>::null();
1878   return Handle<Map>(transitions->GetTarget(transition));
1879 }
1880
1881
1882 ACCESSORS(Oddball, to_string, String, kToStringOffset)
1883 ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1884
1885
1886 byte Oddball::kind() const {
1887   return Smi::cast(READ_FIELD(this, kKindOffset))->value();
1888 }
1889
1890
1891 void Oddball::set_kind(byte value) {
1892   WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
1893 }
1894
1895
1896 Object* Cell::value() const {
1897   return READ_FIELD(this, kValueOffset);
1898 }
1899
1900
1901 void Cell::set_value(Object* val, WriteBarrierMode ignored) {
1902   // The write barrier is not used for global property cells.
1903   DCHECK(!val->IsPropertyCell() && !val->IsCell());
1904   WRITE_FIELD(this, kValueOffset, val);
1905 }
1906
1907 ACCESSORS(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset)
1908
1909 Object* PropertyCell::type_raw() const {
1910   return READ_FIELD(this, kTypeOffset);
1911 }
1912
1913
1914 void PropertyCell::set_type_raw(Object* val, WriteBarrierMode ignored) {
1915   WRITE_FIELD(this, kTypeOffset, val);
1916 }
1917
1918
1919 int JSObject::GetHeaderSize() {
1920   InstanceType type = map()->instance_type();
1921   // Check for the most common kind of JavaScript object before
1922   // falling into the generic switch. This speeds up the internal
1923   // field operations considerably on average.
1924   if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1925   switch (type) {
1926     case JS_GENERATOR_OBJECT_TYPE:
1927       return JSGeneratorObject::kSize;
1928     case JS_MODULE_TYPE:
1929       return JSModule::kSize;
1930     case JS_GLOBAL_PROXY_TYPE:
1931       return JSGlobalProxy::kSize;
1932     case JS_GLOBAL_OBJECT_TYPE:
1933       return JSGlobalObject::kSize;
1934     case JS_BUILTINS_OBJECT_TYPE:
1935       return JSBuiltinsObject::kSize;
1936     case JS_FUNCTION_TYPE:
1937       return JSFunction::kSize;
1938     case JS_VALUE_TYPE:
1939       return JSValue::kSize;
1940     case JS_DATE_TYPE:
1941       return JSDate::kSize;
1942     case JS_ARRAY_TYPE:
1943       return JSArray::kSize;
1944     case JS_ARRAY_BUFFER_TYPE:
1945       return JSArrayBuffer::kSize;
1946     case JS_TYPED_ARRAY_TYPE:
1947       return JSTypedArray::kSize;
1948     case JS_DATA_VIEW_TYPE:
1949       return JSDataView::kSize;
1950     case JS_SET_TYPE:
1951       return JSSet::kSize;
1952     case JS_MAP_TYPE:
1953       return JSMap::kSize;
1954     case JS_SET_ITERATOR_TYPE:
1955       return JSSetIterator::kSize;
1956     case JS_MAP_ITERATOR_TYPE:
1957       return JSMapIterator::kSize;
1958     case JS_WEAK_MAP_TYPE:
1959       return JSWeakMap::kSize;
1960     case JS_WEAK_SET_TYPE:
1961       return JSWeakSet::kSize;
1962     case JS_REGEXP_TYPE:
1963       return JSRegExp::kSize;
1964     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
1965       return JSObject::kHeaderSize;
1966     case JS_MESSAGE_OBJECT_TYPE:
1967       return JSMessageObject::kSize;
1968     default:
1969       // TODO(jkummerow): Re-enable this. Blink currently hits this
1970       // from its CustomElementConstructorBuilder.
1971       // UNREACHABLE();
1972       return 0;
1973   }
1974 }
1975
1976
1977 int JSObject::GetInternalFieldCount() {
1978   DCHECK(1 << kPointerSizeLog2 == kPointerSize);
1979   // Make sure to adjust for the number of in-object properties. These
1980   // properties do contribute to the size, but are not internal fields.
1981   return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1982          map()->inobject_properties();
1983 }
1984
1985
1986 int JSObject::GetInternalFieldOffset(int index) {
1987   DCHECK(index < GetInternalFieldCount() && index >= 0);
1988   return GetHeaderSize() + (kPointerSize * index);
1989 }
1990
1991
1992 Object* JSObject::GetInternalField(int index) {
1993   DCHECK(index < GetInternalFieldCount() && index >= 0);
1994   // Internal objects do follow immediately after the header, whereas in-object
1995   // properties are at the end of the object. Therefore there is no need
1996   // to adjust the index here.
1997   return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1998 }
1999
2000
2001 void JSObject::SetInternalField(int index, Object* value) {
2002   DCHECK(index < GetInternalFieldCount() && index >= 0);
2003   // Internal objects do follow immediately after the header, whereas in-object
2004   // properties are at the end of the object. Therefore there is no need
2005   // to adjust the index here.
2006   int offset = GetHeaderSize() + (kPointerSize * index);
2007   WRITE_FIELD(this, offset, value);
2008   WRITE_BARRIER(GetHeap(), this, offset, value);
2009 }
2010
2011
2012 void JSObject::SetInternalField(int index, Smi* value) {
2013   DCHECK(index < GetInternalFieldCount() && index >= 0);
2014   // Internal objects do follow immediately after the header, whereas in-object
2015   // properties are at the end of the object. Therefore there is no need
2016   // to adjust the index here.
2017   int offset = GetHeaderSize() + (kPointerSize * index);
2018   WRITE_FIELD(this, offset, value);
2019 }
2020
2021
2022 // Access fast-case object properties at index. The use of these routines
2023 // is needed to correctly distinguish between properties stored in-object and
2024 // properties stored in the properties array.
2025 Object* JSObject::RawFastPropertyAt(FieldIndex index) {
2026   if (index.is_inobject()) {
2027     return READ_FIELD(this, index.offset());
2028   } else {
2029     return properties()->get(index.outobject_array_index());
2030   }
2031 }
2032
2033
2034 void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
2035   if (index.is_inobject()) {
2036     int offset = index.offset();
2037     WRITE_FIELD(this, offset, value);
2038     WRITE_BARRIER(GetHeap(), this, offset, value);
2039   } else {
2040     properties()->set(index.outobject_array_index(), value);
2041   }
2042 }
2043
2044
2045 int JSObject::GetInObjectPropertyOffset(int index) {
2046   return map()->GetInObjectPropertyOffset(index);
2047 }
2048
2049
2050 Object* JSObject::InObjectPropertyAt(int index) {
2051   int offset = GetInObjectPropertyOffset(index);
2052   return READ_FIELD(this, offset);
2053 }
2054
2055
2056 Object* JSObject::InObjectPropertyAtPut(int index,
2057                                         Object* value,
2058                                         WriteBarrierMode mode) {
2059   // Adjust for the number of properties stored in the object.
2060   int offset = GetInObjectPropertyOffset(index);
2061   WRITE_FIELD(this, offset, value);
2062   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
2063   return value;
2064 }
2065
2066
2067
2068 void JSObject::InitializeBody(Map* map,
2069                               Object* pre_allocated_value,
2070                               Object* filler_value) {
2071   DCHECK(!filler_value->IsHeapObject() ||
2072          !GetHeap()->InNewSpace(filler_value));
2073   DCHECK(!pre_allocated_value->IsHeapObject() ||
2074          !GetHeap()->InNewSpace(pre_allocated_value));
2075   int size = map->instance_size();
2076   int offset = kHeaderSize;
2077   if (filler_value != pre_allocated_value) {
2078     int pre_allocated = map->pre_allocated_property_fields();
2079     DCHECK(pre_allocated * kPointerSize + kHeaderSize <= size);
2080     for (int i = 0; i < pre_allocated; i++) {
2081       WRITE_FIELD(this, offset, pre_allocated_value);
2082       offset += kPointerSize;
2083     }
2084   }
2085   while (offset < size) {
2086     WRITE_FIELD(this, offset, filler_value);
2087     offset += kPointerSize;
2088   }
2089 }
2090
2091
2092 bool JSObject::HasFastProperties() {
2093   DCHECK(properties()->IsDictionary() == map()->is_dictionary_map());
2094   return !properties()->IsDictionary();
2095 }
2096
2097
2098 bool Map::TooManyFastProperties(StoreFromKeyed store_mode) {
2099   if (unused_property_fields() != 0) return false;
2100   if (is_prototype_map()) return false;
2101   int minimum = store_mode == CERTAINLY_NOT_STORE_FROM_KEYED ? 128 : 12;
2102   int limit = Max(minimum, inobject_properties());
2103   int external = NumberOfFields() - inobject_properties();
2104   return external > limit;
2105 }
2106
2107
2108 void Struct::InitializeBody(int object_size) {
2109   Object* value = GetHeap()->undefined_value();
2110   for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
2111     WRITE_FIELD(this, offset, value);
2112   }
2113 }
2114
2115
2116 bool Object::ToArrayIndex(uint32_t* index) {
2117   if (IsSmi()) {
2118     int value = Smi::cast(this)->value();
2119     if (value < 0) return false;
2120     *index = value;
2121     return true;
2122   }
2123   if (IsHeapNumber()) {
2124     double value = HeapNumber::cast(this)->value();
2125     uint32_t uint_value = static_cast<uint32_t>(value);
2126     if (value == static_cast<double>(uint_value)) {
2127       *index = uint_value;
2128       return true;
2129     }
2130   }
2131   return false;
2132 }
2133
2134
2135 bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
2136   if (!this->IsJSValue()) return false;
2137
2138   JSValue* js_value = JSValue::cast(this);
2139   if (!js_value->value()->IsString()) return false;
2140
2141   String* str = String::cast(js_value->value());
2142   if (index >= static_cast<uint32_t>(str->length())) return false;
2143
2144   return true;
2145 }
2146
2147
2148 void Object::VerifyApiCallResultType() {
2149 #if ENABLE_EXTRA_CHECKS
2150   if (!(IsSmi() ||
2151         IsString() ||
2152         IsSymbol() ||
2153         IsSpecObject() ||
2154         IsHeapNumber() ||
2155         IsUndefined() ||
2156         IsTrue() ||
2157         IsFalse() ||
2158         IsNull())) {
2159     FATAL("API call returned invalid object");
2160   }
2161 #endif  // ENABLE_EXTRA_CHECKS
2162 }
2163
2164
2165 Object* FixedArray::get(int index) {
2166   SLOW_DCHECK(index >= 0 && index < this->length());
2167   return READ_FIELD(this, kHeaderSize + index * kPointerSize);
2168 }
2169
2170
2171 Handle<Object> FixedArray::get(Handle<FixedArray> array, int index) {
2172   return handle(array->get(index), array->GetIsolate());
2173 }
2174
2175
2176 bool FixedArray::is_the_hole(int index) {
2177   return get(index) == GetHeap()->the_hole_value();
2178 }
2179
2180
2181 void FixedArray::set(int index, Smi* value) {
2182   DCHECK(map() != GetHeap()->fixed_cow_array_map());
2183   DCHECK(index >= 0 && index < this->length());
2184   DCHECK(reinterpret_cast<Object*>(value)->IsSmi());
2185   int offset = kHeaderSize + index * kPointerSize;
2186   WRITE_FIELD(this, offset, value);
2187 }
2188
2189
2190 void FixedArray::set(int index, Object* value) {
2191   DCHECK_NE(GetHeap()->fixed_cow_array_map(), map());
2192   DCHECK_EQ(FIXED_ARRAY_TYPE, map()->instance_type());
2193   DCHECK(index >= 0 && index < this->length());
2194   int offset = kHeaderSize + index * kPointerSize;
2195   WRITE_FIELD(this, offset, value);
2196   WRITE_BARRIER(GetHeap(), this, offset, value);
2197 }
2198
2199
2200 inline bool FixedDoubleArray::is_the_hole_nan(double value) {
2201   return bit_cast<uint64_t, double>(value) == kHoleNanInt64;
2202 }
2203
2204
2205 inline double FixedDoubleArray::hole_nan_as_double() {
2206   return bit_cast<double, uint64_t>(kHoleNanInt64);
2207 }
2208
2209
2210 inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
2211   DCHECK(bit_cast<uint64_t>(base::OS::nan_value()) != kHoleNanInt64);
2212   DCHECK((bit_cast<uint64_t>(base::OS::nan_value()) >> 32) != kHoleNanUpper32);
2213   return base::OS::nan_value();
2214 }
2215
2216
2217 double FixedDoubleArray::get_scalar(int index) {
2218   DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2219          map() != GetHeap()->fixed_array_map());
2220   DCHECK(index >= 0 && index < this->length());
2221   double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
2222   DCHECK(!is_the_hole_nan(result));
2223   return result;
2224 }
2225
2226 int64_t FixedDoubleArray::get_representation(int index) {
2227   DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2228          map() != GetHeap()->fixed_array_map());
2229   DCHECK(index >= 0 && index < this->length());
2230   return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
2231 }
2232
2233
2234 Handle<Object> FixedDoubleArray::get(Handle<FixedDoubleArray> array,
2235                                      int index) {
2236   if (array->is_the_hole(index)) {
2237     return array->GetIsolate()->factory()->the_hole_value();
2238   } else {
2239     return array->GetIsolate()->factory()->NewNumber(array->get_scalar(index));
2240   }
2241 }
2242
2243
2244 void FixedDoubleArray::set(int index, double value) {
2245   DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2246          map() != GetHeap()->fixed_array_map());
2247   int offset = kHeaderSize + index * kDoubleSize;
2248   if (std::isnan(value)) value = canonical_not_the_hole_nan_as_double();
2249   WRITE_DOUBLE_FIELD(this, offset, value);
2250 }
2251
2252
2253 void FixedDoubleArray::set_the_hole(int index) {
2254   DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2255          map() != GetHeap()->fixed_array_map());
2256   int offset = kHeaderSize + index * kDoubleSize;
2257   WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
2258 }
2259
2260
2261 bool FixedDoubleArray::is_the_hole(int index) {
2262   int offset = kHeaderSize + index * kDoubleSize;
2263   return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
2264 }
2265
2266
2267 double* FixedDoubleArray::data_start() {
2268   return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
2269 }
2270
2271
2272 void FixedDoubleArray::FillWithHoles(int from, int to) {
2273   for (int i = from; i < to; i++) {
2274     set_the_hole(i);
2275   }
2276 }
2277
2278
2279 void ConstantPoolArray::NumberOfEntries::increment(Type type) {
2280   DCHECK(type < NUMBER_OF_TYPES);
2281   element_counts_[type]++;
2282 }
2283
2284
2285 int ConstantPoolArray::NumberOfEntries::equals(
2286     const ConstantPoolArray::NumberOfEntries& other) const {
2287   for (int i = 0; i < NUMBER_OF_TYPES; i++) {
2288     if (element_counts_[i] != other.element_counts_[i]) return false;
2289   }
2290   return true;
2291 }
2292
2293
2294 bool ConstantPoolArray::NumberOfEntries::is_empty() const {
2295   return total_count() == 0;
2296 }
2297
2298
2299 int ConstantPoolArray::NumberOfEntries::count_of(Type type) const {
2300   DCHECK(type < NUMBER_OF_TYPES);
2301   return element_counts_[type];
2302 }
2303
2304
2305 int ConstantPoolArray::NumberOfEntries::base_of(Type type) const {
2306   int base = 0;
2307   DCHECK(type < NUMBER_OF_TYPES);
2308   for (int i = 0; i < type; i++) {
2309     base += element_counts_[i];
2310   }
2311   return base;
2312 }
2313
2314
2315 int ConstantPoolArray::NumberOfEntries::total_count() const {
2316   int count = 0;
2317   for (int i = 0; i < NUMBER_OF_TYPES; i++) {
2318     count += element_counts_[i];
2319   }
2320   return count;
2321 }
2322
2323
2324 int ConstantPoolArray::NumberOfEntries::are_in_range(int min, int max) const {
2325   for (int i = FIRST_TYPE; i < NUMBER_OF_TYPES; i++) {
2326     if (element_counts_[i] < min || element_counts_[i] > max) {
2327       return false;
2328     }
2329   }
2330   return true;
2331 }
2332
2333
2334 int ConstantPoolArray::Iterator::next_index() {
2335   DCHECK(!is_finished());
2336   int ret = next_index_++;
2337   update_section();
2338   return ret;
2339 }
2340
2341
2342 bool ConstantPoolArray::Iterator::is_finished() {
2343   return next_index_ > array_->last_index(type_, final_section_);
2344 }
2345
2346
2347 void ConstantPoolArray::Iterator::update_section() {
2348   if (next_index_ > array_->last_index(type_, current_section_) &&
2349       current_section_ != final_section_) {
2350     DCHECK(final_section_ == EXTENDED_SECTION);
2351     current_section_ = EXTENDED_SECTION;
2352     next_index_ = array_->first_index(type_, EXTENDED_SECTION);
2353   }
2354 }
2355
2356
2357 bool ConstantPoolArray::is_extended_layout() {
2358   uint32_t small_layout_1 = READ_UINT32_FIELD(this, kSmallLayout1Offset);
2359   return IsExtendedField::decode(small_layout_1);
2360 }
2361
2362
2363 ConstantPoolArray::LayoutSection ConstantPoolArray::final_section() {
2364   return is_extended_layout() ? EXTENDED_SECTION : SMALL_SECTION;
2365 }
2366
2367
2368 int ConstantPoolArray::first_extended_section_index() {
2369   DCHECK(is_extended_layout());
2370   uint32_t small_layout_2 = READ_UINT32_FIELD(this, kSmallLayout2Offset);
2371   return TotalCountField::decode(small_layout_2);
2372 }
2373
2374
2375 int ConstantPoolArray::get_extended_section_header_offset() {
2376   return RoundUp(SizeFor(NumberOfEntries(this, SMALL_SECTION)), kInt64Size);
2377 }
2378
2379
2380 ConstantPoolArray::WeakObjectState ConstantPoolArray::get_weak_object_state() {
2381   uint32_t small_layout_2 = READ_UINT32_FIELD(this, kSmallLayout2Offset);
2382   return WeakObjectStateField::decode(small_layout_2);
2383 }
2384
2385
2386 void ConstantPoolArray::set_weak_object_state(
2387       ConstantPoolArray::WeakObjectState state) {
2388   uint32_t small_layout_2 = READ_UINT32_FIELD(this, kSmallLayout2Offset);
2389   small_layout_2 = WeakObjectStateField::update(small_layout_2, state);
2390   WRITE_INT32_FIELD(this, kSmallLayout2Offset, small_layout_2);
2391 }
2392
2393
2394 int ConstantPoolArray::first_index(Type type, LayoutSection section) {
2395   int index = 0;
2396   if (section == EXTENDED_SECTION) {
2397     DCHECK(is_extended_layout());
2398     index += first_extended_section_index();
2399   }
2400
2401   for (Type type_iter = FIRST_TYPE; type_iter < type;
2402        type_iter = next_type(type_iter)) {
2403     index += number_of_entries(type_iter, section);
2404   }
2405
2406   return index;
2407 }
2408
2409
2410 int ConstantPoolArray::last_index(Type type, LayoutSection section) {
2411   return first_index(type, section) + number_of_entries(type, section) - 1;
2412 }
2413
2414
2415 int ConstantPoolArray::number_of_entries(Type type, LayoutSection section) {
2416   if (section == SMALL_SECTION) {
2417     uint32_t small_layout_1 = READ_UINT32_FIELD(this, kSmallLayout1Offset);
2418     uint32_t small_layout_2 = READ_UINT32_FIELD(this, kSmallLayout2Offset);
2419     switch (type) {
2420       case INT64:
2421         return Int64CountField::decode(small_layout_1);
2422       case CODE_PTR:
2423         return CodePtrCountField::decode(small_layout_1);
2424       case HEAP_PTR:
2425         return HeapPtrCountField::decode(small_layout_1);
2426       case INT32:
2427         return Int32CountField::decode(small_layout_2);
2428       default:
2429         UNREACHABLE();
2430         return 0;
2431     }
2432   } else {
2433     DCHECK(section == EXTENDED_SECTION && is_extended_layout());
2434     int offset = get_extended_section_header_offset();
2435     switch (type) {
2436       case INT64:
2437         offset += kExtendedInt64CountOffset;
2438         break;
2439       case CODE_PTR:
2440         offset += kExtendedCodePtrCountOffset;
2441         break;
2442       case HEAP_PTR:
2443         offset += kExtendedHeapPtrCountOffset;
2444         break;
2445       case INT32:
2446         offset += kExtendedInt32CountOffset;
2447         break;
2448       default:
2449         UNREACHABLE();
2450     }
2451     return READ_INT_FIELD(this, offset);
2452   }
2453 }
2454
2455
2456 bool ConstantPoolArray::offset_is_type(int offset, Type type) {
2457   return (offset >= OffsetOfElementAt(first_index(type, SMALL_SECTION)) &&
2458           offset <= OffsetOfElementAt(last_index(type, SMALL_SECTION))) ||
2459          (is_extended_layout() &&
2460           offset >= OffsetOfElementAt(first_index(type, EXTENDED_SECTION)) &&
2461           offset <= OffsetOfElementAt(last_index(type, EXTENDED_SECTION)));
2462 }
2463
2464
2465 ConstantPoolArray::Type ConstantPoolArray::get_type(int index) {
2466   LayoutSection section;
2467   if (is_extended_layout() && index >= first_extended_section_index()) {
2468     section = EXTENDED_SECTION;
2469   } else {
2470     section = SMALL_SECTION;
2471   }
2472
2473   Type type = FIRST_TYPE;
2474   while (index > last_index(type, section)) {
2475     type = next_type(type);
2476   }
2477   DCHECK(type <= LAST_TYPE);
2478   return type;
2479 }
2480
2481
2482 int64_t ConstantPoolArray::get_int64_entry(int index) {
2483   DCHECK(map() == GetHeap()->constant_pool_array_map());
2484   DCHECK(get_type(index) == INT64);
2485   return READ_INT64_FIELD(this, OffsetOfElementAt(index));
2486 }
2487
2488
2489 double ConstantPoolArray::get_int64_entry_as_double(int index) {
2490   STATIC_ASSERT(kDoubleSize == kInt64Size);
2491   DCHECK(map() == GetHeap()->constant_pool_array_map());
2492   DCHECK(get_type(index) == INT64);
2493   return READ_DOUBLE_FIELD(this, OffsetOfElementAt(index));
2494 }
2495
2496
2497 Address ConstantPoolArray::get_code_ptr_entry(int index) {
2498   DCHECK(map() == GetHeap()->constant_pool_array_map());
2499   DCHECK(get_type(index) == CODE_PTR);
2500   return reinterpret_cast<Address>(READ_FIELD(this, OffsetOfElementAt(index)));
2501 }
2502
2503
2504 Object* ConstantPoolArray::get_heap_ptr_entry(int index) {
2505   DCHECK(map() == GetHeap()->constant_pool_array_map());
2506   DCHECK(get_type(index) == HEAP_PTR);
2507   return READ_FIELD(this, OffsetOfElementAt(index));
2508 }
2509
2510
2511 int32_t ConstantPoolArray::get_int32_entry(int index) {
2512   DCHECK(map() == GetHeap()->constant_pool_array_map());
2513   DCHECK(get_type(index) == INT32);
2514   return READ_INT32_FIELD(this, OffsetOfElementAt(index));
2515 }
2516
2517
2518 void ConstantPoolArray::set(int index, int64_t value) {
2519   DCHECK(map() == GetHeap()->constant_pool_array_map());
2520   DCHECK(get_type(index) == INT64);
2521   WRITE_INT64_FIELD(this, OffsetOfElementAt(index), value);
2522 }
2523
2524
2525 void ConstantPoolArray::set(int index, double value) {
2526   STATIC_ASSERT(kDoubleSize == kInt64Size);
2527   DCHECK(map() == GetHeap()->constant_pool_array_map());
2528   DCHECK(get_type(index) == INT64);
2529   WRITE_DOUBLE_FIELD(this, OffsetOfElementAt(index), value);
2530 }
2531
2532
2533 void ConstantPoolArray::set(int index, Address value) {
2534   DCHECK(map() == GetHeap()->constant_pool_array_map());
2535   DCHECK(get_type(index) == CODE_PTR);
2536   WRITE_FIELD(this, OffsetOfElementAt(index), reinterpret_cast<Object*>(value));
2537 }
2538
2539
2540 void ConstantPoolArray::set(int index, Object* value) {
2541   DCHECK(map() == GetHeap()->constant_pool_array_map());
2542   DCHECK(!GetHeap()->InNewSpace(value));
2543   DCHECK(get_type(index) == HEAP_PTR);
2544   WRITE_FIELD(this, OffsetOfElementAt(index), value);
2545   WRITE_BARRIER(GetHeap(), this, OffsetOfElementAt(index), value);
2546 }
2547
2548
2549 void ConstantPoolArray::set(int index, int32_t value) {
2550   DCHECK(map() == GetHeap()->constant_pool_array_map());
2551   DCHECK(get_type(index) == INT32);
2552   WRITE_INT32_FIELD(this, OffsetOfElementAt(index), value);
2553 }
2554
2555
2556 void ConstantPoolArray::set_at_offset(int offset, int32_t value) {
2557   DCHECK(map() == GetHeap()->constant_pool_array_map());
2558   DCHECK(offset_is_type(offset, INT32));
2559   WRITE_INT32_FIELD(this, offset, value);
2560 }
2561
2562
2563 void ConstantPoolArray::set_at_offset(int offset, int64_t value) {
2564   DCHECK(map() == GetHeap()->constant_pool_array_map());
2565   DCHECK(offset_is_type(offset, INT64));
2566   WRITE_INT64_FIELD(this, offset, value);
2567 }
2568
2569
2570 void ConstantPoolArray::set_at_offset(int offset, double value) {
2571   DCHECK(map() == GetHeap()->constant_pool_array_map());
2572   DCHECK(offset_is_type(offset, INT64));
2573   WRITE_DOUBLE_FIELD(this, offset, value);
2574 }
2575
2576
2577 void ConstantPoolArray::set_at_offset(int offset, Address value) {
2578   DCHECK(map() == GetHeap()->constant_pool_array_map());
2579   DCHECK(offset_is_type(offset, CODE_PTR));
2580   WRITE_FIELD(this, offset, reinterpret_cast<Object*>(value));
2581   WRITE_BARRIER(GetHeap(), this, offset, reinterpret_cast<Object*>(value));
2582 }
2583
2584
2585 void ConstantPoolArray::set_at_offset(int offset, Object* value) {
2586   DCHECK(map() == GetHeap()->constant_pool_array_map());
2587   DCHECK(!GetHeap()->InNewSpace(value));
2588   DCHECK(offset_is_type(offset, HEAP_PTR));
2589   WRITE_FIELD(this, offset, value);
2590   WRITE_BARRIER(GetHeap(), this, offset, value);
2591 }
2592
2593
2594 void ConstantPoolArray::Init(const NumberOfEntries& small) {
2595   uint32_t small_layout_1 =
2596       Int64CountField::encode(small.count_of(INT64)) |
2597       CodePtrCountField::encode(small.count_of(CODE_PTR)) |
2598       HeapPtrCountField::encode(small.count_of(HEAP_PTR)) |
2599       IsExtendedField::encode(false);
2600   uint32_t small_layout_2 =
2601       Int32CountField::encode(small.count_of(INT32)) |
2602       TotalCountField::encode(small.total_count()) |
2603       WeakObjectStateField::encode(NO_WEAK_OBJECTS);
2604   WRITE_UINT32_FIELD(this, kSmallLayout1Offset, small_layout_1);
2605   WRITE_UINT32_FIELD(this, kSmallLayout2Offset, small_layout_2);
2606   if (kHeaderSize != kFirstEntryOffset) {
2607     DCHECK(kFirstEntryOffset - kHeaderSize == kInt32Size);
2608     WRITE_UINT32_FIELD(this, kHeaderSize, 0);  // Zero out header padding.
2609   }
2610 }
2611
2612
2613 void ConstantPoolArray::InitExtended(const NumberOfEntries& small,
2614                                      const NumberOfEntries& extended) {
2615   // Initialize small layout fields first.
2616   Init(small);
2617
2618   // Set is_extended_layout field.
2619   uint32_t small_layout_1 = READ_UINT32_FIELD(this, kSmallLayout1Offset);
2620   small_layout_1 = IsExtendedField::update(small_layout_1, true);
2621   WRITE_INT32_FIELD(this, kSmallLayout1Offset, small_layout_1);
2622
2623   // Initialize the extended layout fields.
2624   int extended_header_offset = get_extended_section_header_offset();
2625   WRITE_INT_FIELD(this, extended_header_offset + kExtendedInt64CountOffset,
2626       extended.count_of(INT64));
2627   WRITE_INT_FIELD(this, extended_header_offset + kExtendedCodePtrCountOffset,
2628       extended.count_of(CODE_PTR));
2629   WRITE_INT_FIELD(this, extended_header_offset + kExtendedHeapPtrCountOffset,
2630       extended.count_of(HEAP_PTR));
2631   WRITE_INT_FIELD(this, extended_header_offset + kExtendedInt32CountOffset,
2632       extended.count_of(INT32));
2633 }
2634
2635
2636 int ConstantPoolArray::size() {
2637   NumberOfEntries small(this, SMALL_SECTION);
2638   if (!is_extended_layout()) {
2639     return SizeFor(small);
2640   } else {
2641     NumberOfEntries extended(this, EXTENDED_SECTION);
2642     return SizeForExtended(small, extended);
2643   }
2644 }
2645
2646
2647 int ConstantPoolArray::length() {
2648   uint32_t small_layout_2 = READ_UINT32_FIELD(this, kSmallLayout2Offset);
2649   int length = TotalCountField::decode(small_layout_2);
2650   if (is_extended_layout()) {
2651     length += number_of_entries(INT64, EXTENDED_SECTION) +
2652               number_of_entries(CODE_PTR, EXTENDED_SECTION) +
2653               number_of_entries(HEAP_PTR, EXTENDED_SECTION) +
2654               number_of_entries(INT32, EXTENDED_SECTION);
2655   }
2656   return length;
2657 }
2658
2659
2660 WriteBarrierMode HeapObject::GetWriteBarrierMode(
2661     const DisallowHeapAllocation& promise) {
2662   Heap* heap = GetHeap();
2663   if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
2664   if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
2665   return UPDATE_WRITE_BARRIER;
2666 }
2667
2668
2669 void FixedArray::set(int index,
2670                      Object* value,
2671                      WriteBarrierMode mode) {
2672   DCHECK(map() != GetHeap()->fixed_cow_array_map());
2673   DCHECK(index >= 0 && index < this->length());
2674   int offset = kHeaderSize + index * kPointerSize;
2675   WRITE_FIELD(this, offset, value);
2676   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
2677 }
2678
2679
2680 void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
2681                                               int index,
2682                                               Object* value) {
2683   DCHECK(array->map() != array->GetHeap()->fixed_cow_array_map());
2684   DCHECK(index >= 0 && index < array->length());
2685   int offset = kHeaderSize + index * kPointerSize;
2686   WRITE_FIELD(array, offset, value);
2687   Heap* heap = array->GetHeap();
2688   if (heap->InNewSpace(value)) {
2689     heap->RecordWrite(array->address(), offset);
2690   }
2691 }
2692
2693
2694 void FixedArray::NoWriteBarrierSet(FixedArray* array,
2695                                    int index,
2696                                    Object* value) {
2697   DCHECK(array->map() != array->GetHeap()->fixed_cow_array_map());
2698   DCHECK(index >= 0 && index < array->length());
2699   DCHECK(!array->GetHeap()->InNewSpace(value));
2700   WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
2701 }
2702
2703
2704 void FixedArray::set_undefined(int index) {
2705   DCHECK(map() != GetHeap()->fixed_cow_array_map());
2706   DCHECK(index >= 0 && index < this->length());
2707   DCHECK(!GetHeap()->InNewSpace(GetHeap()->undefined_value()));
2708   WRITE_FIELD(this,
2709               kHeaderSize + index * kPointerSize,
2710               GetHeap()->undefined_value());
2711 }
2712
2713
2714 void FixedArray::set_null(int index) {
2715   DCHECK(index >= 0 && index < this->length());
2716   DCHECK(!GetHeap()->InNewSpace(GetHeap()->null_value()));
2717   WRITE_FIELD(this,
2718               kHeaderSize + index * kPointerSize,
2719               GetHeap()->null_value());
2720 }
2721
2722
2723 void FixedArray::set_the_hole(int index) {
2724   DCHECK(map() != GetHeap()->fixed_cow_array_map());
2725   DCHECK(index >= 0 && index < this->length());
2726   DCHECK(!GetHeap()->InNewSpace(GetHeap()->the_hole_value()));
2727   WRITE_FIELD(this,
2728               kHeaderSize + index * kPointerSize,
2729               GetHeap()->the_hole_value());
2730 }
2731
2732
2733 void FixedArray::FillWithHoles(int from, int to) {
2734   for (int i = from; i < to; i++) {
2735     set_the_hole(i);
2736   }
2737 }
2738
2739
2740 Object** FixedArray::data_start() {
2741   return HeapObject::RawField(this, kHeaderSize);
2742 }
2743
2744
2745 bool DescriptorArray::IsEmpty() {
2746   DCHECK(length() >= kFirstIndex ||
2747          this == GetHeap()->empty_descriptor_array());
2748   return length() < kFirstIndex;
2749 }
2750
2751
2752 void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
2753   WRITE_FIELD(
2754       this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors));
2755 }
2756
2757
2758 // Perform a binary search in a fixed array. Low and high are entry indices. If
2759 // there are three entries in this array it should be called with low=0 and
2760 // high=2.
2761 template<SearchMode search_mode, typename T>
2762 int BinarySearch(T* array, Name* name, int low, int high, int valid_entries) {
2763   uint32_t hash = name->Hash();
2764   int limit = high;
2765
2766   DCHECK(low <= high);
2767
2768   while (low != high) {
2769     int mid = (low + high) / 2;
2770     Name* mid_name = array->GetSortedKey(mid);
2771     uint32_t mid_hash = mid_name->Hash();
2772
2773     if (mid_hash >= hash) {
2774       high = mid;
2775     } else {
2776       low = mid + 1;
2777     }
2778   }
2779
2780   for (; low <= limit; ++low) {
2781     int sort_index = array->GetSortedKeyIndex(low);
2782     Name* entry = array->GetKey(sort_index);
2783     if (entry->Hash() != hash) break;
2784     if (entry->Equals(name)) {
2785       if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
2786         return sort_index;
2787       }
2788       return T::kNotFound;
2789     }
2790   }
2791
2792   return T::kNotFound;
2793 }
2794
2795
2796 // Perform a linear search in this fixed array. len is the number of entry
2797 // indices that are valid.
2798 template<SearchMode search_mode, typename T>
2799 int LinearSearch(T* array, Name* name, int len, int valid_entries) {
2800   uint32_t hash = name->Hash();
2801   if (search_mode == ALL_ENTRIES) {
2802     for (int number = 0; number < len; number++) {
2803       int sorted_index = array->GetSortedKeyIndex(number);
2804       Name* entry = array->GetKey(sorted_index);
2805       uint32_t current_hash = entry->Hash();
2806       if (current_hash > hash) break;
2807       if (current_hash == hash && entry->Equals(name)) return sorted_index;
2808     }
2809   } else {
2810     DCHECK(len >= valid_entries);
2811     for (int number = 0; number < valid_entries; number++) {
2812       Name* entry = array->GetKey(number);
2813       uint32_t current_hash = entry->Hash();
2814       if (current_hash == hash && entry->Equals(name)) return number;
2815     }
2816   }
2817   return T::kNotFound;
2818 }
2819
2820
2821 template<SearchMode search_mode, typename T>
2822 int Search(T* array, Name* name, int valid_entries) {
2823   if (search_mode == VALID_ENTRIES) {
2824     SLOW_DCHECK(array->IsSortedNoDuplicates(valid_entries));
2825   } else {
2826     SLOW_DCHECK(array->IsSortedNoDuplicates());
2827   }
2828
2829   int nof = array->number_of_entries();
2830   if (nof == 0) return T::kNotFound;
2831
2832   // Fast case: do linear search for small arrays.
2833   const int kMaxElementsForLinearSearch = 8;
2834   if ((search_mode == ALL_ENTRIES &&
2835        nof <= kMaxElementsForLinearSearch) ||
2836       (search_mode == VALID_ENTRIES &&
2837        valid_entries <= (kMaxElementsForLinearSearch * 3))) {
2838     return LinearSearch<search_mode>(array, name, nof, valid_entries);
2839   }
2840
2841   // Slow case: perform binary search.
2842   return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries);
2843 }
2844
2845
2846 int DescriptorArray::Search(Name* name, int valid_descriptors) {
2847   return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors);
2848 }
2849
2850
2851 int DescriptorArray::SearchWithCache(Name* name, Map* map) {
2852   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
2853   if (number_of_own_descriptors == 0) return kNotFound;
2854
2855   DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
2856   int number = cache->Lookup(map, name);
2857
2858   if (number == DescriptorLookupCache::kAbsent) {
2859     number = Search(name, number_of_own_descriptors);
2860     cache->Update(map, name, number);
2861   }
2862
2863   return number;
2864 }
2865
2866
2867 PropertyDetails Map::GetLastDescriptorDetails() {
2868   return instance_descriptors()->GetDetails(LastAdded());
2869 }
2870
2871
2872 void Map::LookupDescriptor(JSObject* holder,
2873                            Name* name,
2874                            LookupResult* result) {
2875   DescriptorArray* descriptors = this->instance_descriptors();
2876   int number = descriptors->SearchWithCache(name, this);
2877   if (number == DescriptorArray::kNotFound) return result->NotFound();
2878   result->DescriptorResult(holder, descriptors->GetDetails(number), number);
2879 }
2880
2881
2882 void Map::LookupTransition(JSObject* holder,
2883                            Name* name,
2884                            LookupResult* result) {
2885   int transition_index = this->SearchTransition(name);
2886   if (transition_index == TransitionArray::kNotFound) return result->NotFound();
2887   result->TransitionResult(holder, this->GetTransition(transition_index));
2888 }
2889
2890
2891 FixedArrayBase* Map::GetInitialElements() {
2892   if (has_fast_smi_or_object_elements() ||
2893       has_fast_double_elements()) {
2894     DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
2895     return GetHeap()->empty_fixed_array();
2896   } else if (has_external_array_elements()) {
2897     ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(this);
2898     DCHECK(!GetHeap()->InNewSpace(empty_array));
2899     return empty_array;
2900   } else if (has_fixed_typed_array_elements()) {
2901     FixedTypedArrayBase* empty_array =
2902       GetHeap()->EmptyFixedTypedArrayForMap(this);
2903     DCHECK(!GetHeap()->InNewSpace(empty_array));
2904     return empty_array;
2905   } else {
2906     UNREACHABLE();
2907   }
2908   return NULL;
2909 }
2910
2911
2912 Object** DescriptorArray::GetKeySlot(int descriptor_number) {
2913   DCHECK(descriptor_number < number_of_descriptors());
2914   return RawFieldOfElementAt(ToKeyIndex(descriptor_number));
2915 }
2916
2917
2918 Object** DescriptorArray::GetDescriptorStartSlot(int descriptor_number) {
2919   return GetKeySlot(descriptor_number);
2920 }
2921
2922
2923 Object** DescriptorArray::GetDescriptorEndSlot(int descriptor_number) {
2924   return GetValueSlot(descriptor_number - 1) + 1;
2925 }
2926
2927
2928 Name* DescriptorArray::GetKey(int descriptor_number) {
2929   DCHECK(descriptor_number < number_of_descriptors());
2930   return Name::cast(get(ToKeyIndex(descriptor_number)));
2931 }
2932
2933
2934 int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
2935   return GetDetails(descriptor_number).pointer();
2936 }
2937
2938
2939 Name* DescriptorArray::GetSortedKey(int descriptor_number) {
2940   return GetKey(GetSortedKeyIndex(descriptor_number));
2941 }
2942
2943
2944 void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
2945   PropertyDetails details = GetDetails(descriptor_index);
2946   set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi());
2947 }
2948
2949
2950 void DescriptorArray::SetRepresentation(int descriptor_index,
2951                                         Representation representation) {
2952   DCHECK(!representation.IsNone());
2953   PropertyDetails details = GetDetails(descriptor_index);
2954   set(ToDetailsIndex(descriptor_index),
2955       details.CopyWithRepresentation(representation).AsSmi());
2956 }
2957
2958
2959 Object** DescriptorArray::GetValueSlot(int descriptor_number) {
2960   DCHECK(descriptor_number < number_of_descriptors());
2961   return RawFieldOfElementAt(ToValueIndex(descriptor_number));
2962 }
2963
2964
2965 int DescriptorArray::GetValueOffset(int descriptor_number) {
2966   return OffsetOfElementAt(ToValueIndex(descriptor_number));
2967 }
2968
2969
2970 Object* DescriptorArray::GetValue(int descriptor_number) {
2971   DCHECK(descriptor_number < number_of_descriptors());
2972   return get(ToValueIndex(descriptor_number));
2973 }
2974
2975
2976 void DescriptorArray::SetValue(int descriptor_index, Object* value) {
2977   set(ToValueIndex(descriptor_index), value);
2978 }
2979
2980
2981 PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
2982   DCHECK(descriptor_number < number_of_descriptors());
2983   Object* details = get(ToDetailsIndex(descriptor_number));
2984   return PropertyDetails(Smi::cast(details));
2985 }
2986
2987
2988 PropertyType DescriptorArray::GetType(int descriptor_number) {
2989   return GetDetails(descriptor_number).type();
2990 }
2991
2992
2993 int DescriptorArray::GetFieldIndex(int descriptor_number) {
2994   DCHECK(GetDetails(descriptor_number).type() == FIELD);
2995   return GetDetails(descriptor_number).field_index();
2996 }
2997
2998
2999 HeapType* DescriptorArray::GetFieldType(int descriptor_number) {
3000   DCHECK(GetDetails(descriptor_number).type() == FIELD);
3001   return HeapType::cast(GetValue(descriptor_number));
3002 }
3003
3004
3005 Object* DescriptorArray::GetConstant(int descriptor_number) {
3006   return GetValue(descriptor_number);
3007 }
3008
3009
3010 Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
3011   DCHECK(GetType(descriptor_number) == CALLBACKS);
3012   return GetValue(descriptor_number);
3013 }
3014
3015
3016 AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
3017   DCHECK(GetType(descriptor_number) == CALLBACKS);
3018   Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
3019   return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
3020 }
3021
3022
3023 void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
3024   desc->Init(handle(GetKey(descriptor_number), GetIsolate()),
3025              handle(GetValue(descriptor_number), GetIsolate()),
3026              GetDetails(descriptor_number));
3027 }
3028
3029
3030 void DescriptorArray::Set(int descriptor_number,
3031                           Descriptor* desc,
3032                           const WhitenessWitness&) {
3033   // Range check.
3034   DCHECK(descriptor_number < number_of_descriptors());
3035
3036   NoIncrementalWriteBarrierSet(this,
3037                                ToKeyIndex(descriptor_number),
3038                                *desc->GetKey());
3039   NoIncrementalWriteBarrierSet(this,
3040                                ToValueIndex(descriptor_number),
3041                                *desc->GetValue());
3042   NoIncrementalWriteBarrierSet(this,
3043                                ToDetailsIndex(descriptor_number),
3044                                desc->GetDetails().AsSmi());
3045 }
3046
3047
3048 void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
3049   // Range check.
3050   DCHECK(descriptor_number < number_of_descriptors());
3051
3052   set(ToKeyIndex(descriptor_number), *desc->GetKey());
3053   set(ToValueIndex(descriptor_number), *desc->GetValue());
3054   set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
3055 }
3056
3057
3058 void DescriptorArray::Append(Descriptor* desc) {
3059   DisallowHeapAllocation no_gc;
3060   int descriptor_number = number_of_descriptors();
3061   SetNumberOfDescriptors(descriptor_number + 1);
3062   Set(descriptor_number, desc);
3063
3064   uint32_t hash = desc->GetKey()->Hash();
3065
3066   int insertion;
3067
3068   for (insertion = descriptor_number; insertion > 0; --insertion) {
3069     Name* key = GetSortedKey(insertion - 1);
3070     if (key->Hash() <= hash) break;
3071     SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
3072   }
3073
3074   SetSortedKey(insertion, descriptor_number);
3075 }
3076
3077
3078 void DescriptorArray::SwapSortedKeys(int first, int second) {
3079   int first_key = GetSortedKeyIndex(first);
3080   SetSortedKey(first, GetSortedKeyIndex(second));
3081   SetSortedKey(second, first_key);
3082 }
3083
3084
3085 DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
3086     : marking_(array->GetHeap()->incremental_marking()) {
3087   marking_->EnterNoMarkingScope();
3088   DCHECK(!marking_->IsMarking() ||
3089          Marking::Color(array) == Marking::WHITE_OBJECT);
3090 }
3091
3092
3093 DescriptorArray::WhitenessWitness::~WhitenessWitness() {
3094   marking_->LeaveNoMarkingScope();
3095 }
3096
3097
3098 template<typename Derived, typename Shape, typename Key>
3099 int HashTable<Derived, Shape, Key>::ComputeCapacity(int at_least_space_for) {
3100   const int kMinCapacity = 32;
3101   int capacity = base::bits::RoundUpToPowerOfTwo32(at_least_space_for * 2);
3102   if (capacity < kMinCapacity) {
3103     capacity = kMinCapacity;  // Guarantee min capacity.
3104   }
3105   return capacity;
3106 }
3107
3108
3109 template<typename Derived, typename Shape, typename Key>
3110 int HashTable<Derived, Shape, Key>::FindEntry(Key key) {
3111   return FindEntry(GetIsolate(), key);
3112 }
3113
3114
3115 // Find entry for key otherwise return kNotFound.
3116 template<typename Derived, typename Shape, typename Key>
3117 int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key) {
3118   uint32_t capacity = Capacity();
3119   uint32_t entry = FirstProbe(HashTable::Hash(key), capacity);
3120   uint32_t count = 1;
3121   // EnsureCapacity will guarantee the hash table is never full.
3122   while (true) {
3123     Object* element = KeyAt(entry);
3124     // Empty entry. Uses raw unchecked accessors because it is called by the
3125     // string table during bootstrapping.
3126     if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
3127     if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
3128         Shape::IsMatch(key, element)) return entry;
3129     entry = NextProbe(entry, count++, capacity);
3130   }
3131   return kNotFound;
3132 }
3133
3134
3135 bool SeededNumberDictionary::requires_slow_elements() {
3136   Object* max_index_object = get(kMaxNumberKeyIndex);
3137   if (!max_index_object->IsSmi()) return false;
3138   return 0 !=
3139       (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
3140 }
3141
3142 uint32_t SeededNumberDictionary::max_number_key() {
3143   DCHECK(!requires_slow_elements());
3144   Object* max_index_object = get(kMaxNumberKeyIndex);
3145   if (!max_index_object->IsSmi()) return 0;
3146   uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
3147   return value >> kRequiresSlowElementsTagSize;
3148 }
3149
3150 void SeededNumberDictionary::set_requires_slow_elements() {
3151   set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
3152 }
3153
3154
3155 // ------------------------------------
3156 // Cast operations
3157
3158
3159 CAST_ACCESSOR(AccessorInfo)
3160 CAST_ACCESSOR(ByteArray)
3161 CAST_ACCESSOR(Cell)
3162 CAST_ACCESSOR(Code)
3163 CAST_ACCESSOR(CodeCacheHashTable)
3164 CAST_ACCESSOR(CompilationCacheTable)
3165 CAST_ACCESSOR(ConsString)
3166 CAST_ACCESSOR(ConstantPoolArray)
3167 CAST_ACCESSOR(DeoptimizationInputData)
3168 CAST_ACCESSOR(DeoptimizationOutputData)
3169 CAST_ACCESSOR(DependentCode)
3170 CAST_ACCESSOR(DescriptorArray)
3171 CAST_ACCESSOR(ExternalArray)
3172 CAST_ACCESSOR(ExternalOneByteString)
3173 CAST_ACCESSOR(ExternalFloat32Array)
3174 CAST_ACCESSOR(ExternalFloat64Array)
3175 CAST_ACCESSOR(ExternalInt16Array)
3176 CAST_ACCESSOR(ExternalInt32Array)
3177 CAST_ACCESSOR(ExternalInt8Array)
3178 CAST_ACCESSOR(ExternalString)
3179 CAST_ACCESSOR(ExternalTwoByteString)
3180 CAST_ACCESSOR(ExternalUint16Array)
3181 CAST_ACCESSOR(ExternalUint32Array)
3182 CAST_ACCESSOR(ExternalUint8Array)
3183 CAST_ACCESSOR(ExternalUint8ClampedArray)
3184 CAST_ACCESSOR(FixedArray)
3185 CAST_ACCESSOR(FixedArrayBase)
3186 CAST_ACCESSOR(FixedDoubleArray)
3187 CAST_ACCESSOR(FixedTypedArrayBase)
3188 CAST_ACCESSOR(Foreign)
3189 CAST_ACCESSOR(FreeSpace)
3190 CAST_ACCESSOR(GlobalObject)
3191 CAST_ACCESSOR(HeapObject)
3192 CAST_ACCESSOR(JSArray)
3193 CAST_ACCESSOR(JSArrayBuffer)
3194 CAST_ACCESSOR(JSArrayBufferView)
3195 CAST_ACCESSOR(JSBuiltinsObject)
3196 CAST_ACCESSOR(JSDataView)
3197 CAST_ACCESSOR(JSDate)
3198 CAST_ACCESSOR(JSFunction)
3199 CAST_ACCESSOR(JSFunctionProxy)
3200 CAST_ACCESSOR(JSFunctionResultCache)
3201 CAST_ACCESSOR(JSGeneratorObject)
3202 CAST_ACCESSOR(JSGlobalObject)
3203 CAST_ACCESSOR(JSGlobalProxy)
3204 CAST_ACCESSOR(JSMap)
3205 CAST_ACCESSOR(JSMapIterator)
3206 CAST_ACCESSOR(JSMessageObject)
3207 CAST_ACCESSOR(JSModule)
3208 CAST_ACCESSOR(JSObject)
3209 CAST_ACCESSOR(JSProxy)
3210 CAST_ACCESSOR(JSReceiver)
3211 CAST_ACCESSOR(JSRegExp)
3212 CAST_ACCESSOR(JSSet)
3213 CAST_ACCESSOR(JSSetIterator)
3214 CAST_ACCESSOR(JSTypedArray)
3215 CAST_ACCESSOR(JSValue)
3216 CAST_ACCESSOR(JSWeakMap)
3217 CAST_ACCESSOR(JSWeakSet)
3218 CAST_ACCESSOR(Map)
3219 CAST_ACCESSOR(MapCache)
3220 CAST_ACCESSOR(Name)
3221 CAST_ACCESSOR(NameDictionary)
3222 CAST_ACCESSOR(NormalizedMapCache)
3223 CAST_ACCESSOR(Object)
3224 CAST_ACCESSOR(ObjectHashTable)
3225 CAST_ACCESSOR(Oddball)
3226 CAST_ACCESSOR(OrderedHashMap)
3227 CAST_ACCESSOR(OrderedHashSet)
3228 CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
3229 CAST_ACCESSOR(PropertyCell)
3230 CAST_ACCESSOR(ScopeInfo)
3231 CAST_ACCESSOR(SeededNumberDictionary)
3232 CAST_ACCESSOR(SeqOneByteString)
3233 CAST_ACCESSOR(SeqString)
3234 CAST_ACCESSOR(SeqTwoByteString)
3235 CAST_ACCESSOR(SharedFunctionInfo)
3236 CAST_ACCESSOR(SlicedString)
3237 CAST_ACCESSOR(Smi)
3238 CAST_ACCESSOR(String)
3239 CAST_ACCESSOR(StringTable)
3240 CAST_ACCESSOR(Struct)
3241 CAST_ACCESSOR(Symbol)
3242 CAST_ACCESSOR(UnseededNumberDictionary)
3243 CAST_ACCESSOR(WeakHashTable)
3244
3245
3246 template <class Traits>
3247 FixedTypedArray<Traits>* FixedTypedArray<Traits>::cast(Object* object) {
3248   SLOW_DCHECK(object->IsHeapObject() &&
3249               HeapObject::cast(object)->map()->instance_type() ==
3250               Traits::kInstanceType);
3251   return reinterpret_cast<FixedTypedArray<Traits>*>(object);
3252 }
3253
3254
3255 template <class Traits>
3256 const FixedTypedArray<Traits>*
3257 FixedTypedArray<Traits>::cast(const Object* object) {
3258   SLOW_DCHECK(object->IsHeapObject() &&
3259               HeapObject::cast(object)->map()->instance_type() ==
3260               Traits::kInstanceType);
3261   return reinterpret_cast<FixedTypedArray<Traits>*>(object);
3262 }
3263
3264
3265 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
3266   STRUCT_LIST(MAKE_STRUCT_CAST)
3267 #undef MAKE_STRUCT_CAST
3268
3269
3270 template <typename Derived, typename Shape, typename Key>
3271 HashTable<Derived, Shape, Key>*
3272 HashTable<Derived, Shape, Key>::cast(Object* obj) {
3273   SLOW_DCHECK(obj->IsHashTable());
3274   return reinterpret_cast<HashTable*>(obj);
3275 }
3276
3277
3278 template <typename Derived, typename Shape, typename Key>
3279 const HashTable<Derived, Shape, Key>*
3280 HashTable<Derived, Shape, Key>::cast(const Object* obj) {
3281   SLOW_DCHECK(obj->IsHashTable());
3282   return reinterpret_cast<const HashTable*>(obj);
3283 }
3284
3285
3286 SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
3287 SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
3288
3289 SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
3290 NOBARRIER_SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
3291
3292 SMI_ACCESSORS(String, length, kLengthOffset)
3293 SYNCHRONIZED_SMI_ACCESSORS(String, length, kLengthOffset)
3294
3295
3296 uint32_t Name::hash_field() {
3297   return READ_UINT32_FIELD(this, kHashFieldOffset);
3298 }
3299
3300
3301 void Name::set_hash_field(uint32_t value) {
3302   WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
3303 #if V8_HOST_ARCH_64_BIT
3304   WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
3305 #endif
3306 }
3307
3308
3309 bool Name::Equals(Name* other) {
3310   if (other == this) return true;
3311   if ((this->IsInternalizedString() && other->IsInternalizedString()) ||
3312       this->IsSymbol() || other->IsSymbol()) {
3313     return false;
3314   }
3315   return String::cast(this)->SlowEquals(String::cast(other));
3316 }
3317
3318
3319 bool Name::Equals(Handle<Name> one, Handle<Name> two) {
3320   if (one.is_identical_to(two)) return true;
3321   if ((one->IsInternalizedString() && two->IsInternalizedString()) ||
3322       one->IsSymbol() || two->IsSymbol()) {
3323     return false;
3324   }
3325   return String::SlowEquals(Handle<String>::cast(one),
3326                             Handle<String>::cast(two));
3327 }
3328
3329
3330 ACCESSORS(Symbol, name, Object, kNameOffset)
3331 ACCESSORS(Symbol, flags, Smi, kFlagsOffset)
3332 BOOL_ACCESSORS(Symbol, flags, is_private, kPrivateBit)
3333 BOOL_ACCESSORS(Symbol, flags, is_own, kOwnBit)
3334
3335
3336 bool String::Equals(String* other) {
3337   if (other == this) return true;
3338   if (this->IsInternalizedString() && other->IsInternalizedString()) {
3339     return false;
3340   }
3341   return SlowEquals(other);
3342 }
3343
3344
3345 bool String::Equals(Handle<String> one, Handle<String> two) {
3346   if (one.is_identical_to(two)) return true;
3347   if (one->IsInternalizedString() && two->IsInternalizedString()) {
3348     return false;
3349   }
3350   return SlowEquals(one, two);
3351 }
3352
3353
3354 Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) {
3355   if (!string->IsConsString()) return string;
3356   Handle<ConsString> cons = Handle<ConsString>::cast(string);
3357   if (cons->IsFlat()) return handle(cons->first());
3358   return SlowFlatten(cons, pretenure);
3359 }
3360
3361
3362 uint16_t String::Get(int index) {
3363   DCHECK(index >= 0 && index < length());
3364   switch (StringShape(this).full_representation_tag()) {
3365     case kSeqStringTag | kOneByteStringTag:
3366       return SeqOneByteString::cast(this)->SeqOneByteStringGet(index);
3367     case kSeqStringTag | kTwoByteStringTag:
3368       return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
3369     case kConsStringTag | kOneByteStringTag:
3370     case kConsStringTag | kTwoByteStringTag:
3371       return ConsString::cast(this)->ConsStringGet(index);
3372     case kExternalStringTag | kOneByteStringTag:
3373       return ExternalOneByteString::cast(this)->ExternalOneByteStringGet(index);
3374     case kExternalStringTag | kTwoByteStringTag:
3375       return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
3376     case kSlicedStringTag | kOneByteStringTag:
3377     case kSlicedStringTag | kTwoByteStringTag:
3378       return SlicedString::cast(this)->SlicedStringGet(index);
3379     default:
3380       break;
3381   }
3382
3383   UNREACHABLE();
3384   return 0;
3385 }
3386
3387
3388 void String::Set(int index, uint16_t value) {
3389   DCHECK(index >= 0 && index < length());
3390   DCHECK(StringShape(this).IsSequential());
3391
3392   return this->IsOneByteRepresentation()
3393       ? SeqOneByteString::cast(this)->SeqOneByteStringSet(index, value)
3394       : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
3395 }
3396
3397
3398 bool String::IsFlat() {
3399   if (!StringShape(this).IsCons()) return true;
3400   return ConsString::cast(this)->second()->length() == 0;
3401 }
3402
3403
3404 String* String::GetUnderlying() {
3405   // Giving direct access to underlying string only makes sense if the
3406   // wrapping string is already flattened.
3407   DCHECK(this->IsFlat());
3408   DCHECK(StringShape(this).IsIndirect());
3409   STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
3410   const int kUnderlyingOffset = SlicedString::kParentOffset;
3411   return String::cast(READ_FIELD(this, kUnderlyingOffset));
3412 }
3413
3414
3415 template<class Visitor>
3416 ConsString* String::VisitFlat(Visitor* visitor,
3417                               String* string,
3418                               const int offset) {
3419   int slice_offset = offset;
3420   const int length = string->length();
3421   DCHECK(offset <= length);
3422   while (true) {
3423     int32_t type = string->map()->instance_type();
3424     switch (type & (kStringRepresentationMask | kStringEncodingMask)) {
3425       case kSeqStringTag | kOneByteStringTag:
3426         visitor->VisitOneByteString(
3427             SeqOneByteString::cast(string)->GetChars() + slice_offset,
3428             length - offset);
3429         return NULL;
3430
3431       case kSeqStringTag | kTwoByteStringTag:
3432         visitor->VisitTwoByteString(
3433             SeqTwoByteString::cast(string)->GetChars() + slice_offset,
3434             length - offset);
3435         return NULL;
3436
3437       case kExternalStringTag | kOneByteStringTag:
3438         visitor->VisitOneByteString(
3439             ExternalOneByteString::cast(string)->GetChars() + slice_offset,
3440             length - offset);
3441         return NULL;
3442
3443       case kExternalStringTag | kTwoByteStringTag:
3444         visitor->VisitTwoByteString(
3445             ExternalTwoByteString::cast(string)->GetChars() + slice_offset,
3446             length - offset);
3447         return NULL;
3448
3449       case kSlicedStringTag | kOneByteStringTag:
3450       case kSlicedStringTag | kTwoByteStringTag: {
3451         SlicedString* slicedString = SlicedString::cast(string);
3452         slice_offset += slicedString->offset();
3453         string = slicedString->parent();
3454         continue;
3455       }
3456
3457       case kConsStringTag | kOneByteStringTag:
3458       case kConsStringTag | kTwoByteStringTag:
3459         return ConsString::cast(string);
3460
3461       default:
3462         UNREACHABLE();
3463         return NULL;
3464     }
3465   }
3466 }
3467
3468
3469 uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
3470   DCHECK(index >= 0 && index < length());
3471   return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
3472 }
3473
3474
3475 void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) {
3476   DCHECK(index >= 0 && index < length() && value <= kMaxOneByteCharCode);
3477   WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
3478                    static_cast<byte>(value));
3479 }
3480
3481
3482 Address SeqOneByteString::GetCharsAddress() {
3483   return FIELD_ADDR(this, kHeaderSize);
3484 }
3485
3486
3487 uint8_t* SeqOneByteString::GetChars() {
3488   return reinterpret_cast<uint8_t*>(GetCharsAddress());
3489 }
3490
3491
3492 Address SeqTwoByteString::GetCharsAddress() {
3493   return FIELD_ADDR(this, kHeaderSize);
3494 }
3495
3496
3497 uc16* SeqTwoByteString::GetChars() {
3498   return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
3499 }
3500
3501
3502 uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
3503   DCHECK(index >= 0 && index < length());
3504   return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
3505 }
3506
3507
3508 void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
3509   DCHECK(index >= 0 && index < length());
3510   WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
3511 }
3512
3513
3514 int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
3515   return SizeFor(length());
3516 }
3517
3518
3519 int SeqOneByteString::SeqOneByteStringSize(InstanceType instance_type) {
3520   return SizeFor(length());
3521 }
3522
3523
3524 String* SlicedString::parent() {
3525   return String::cast(READ_FIELD(this, kParentOffset));
3526 }
3527
3528
3529 void SlicedString::set_parent(String* parent, WriteBarrierMode mode) {
3530   DCHECK(parent->IsSeqString() || parent->IsExternalString());
3531   WRITE_FIELD(this, kParentOffset, parent);
3532   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kParentOffset, parent, mode);
3533 }
3534
3535
3536 SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
3537
3538
3539 String* ConsString::first() {
3540   return String::cast(READ_FIELD(this, kFirstOffset));
3541 }
3542
3543
3544 Object* ConsString::unchecked_first() {
3545   return READ_FIELD(this, kFirstOffset);
3546 }
3547
3548
3549 void ConsString::set_first(String* value, WriteBarrierMode mode) {
3550   WRITE_FIELD(this, kFirstOffset, value);
3551   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
3552 }
3553
3554
3555 String* ConsString::second() {
3556   return String::cast(READ_FIELD(this, kSecondOffset));
3557 }
3558
3559
3560 Object* ConsString::unchecked_second() {
3561   return READ_FIELD(this, kSecondOffset);
3562 }
3563
3564
3565 void ConsString::set_second(String* value, WriteBarrierMode mode) {
3566   WRITE_FIELD(this, kSecondOffset, value);
3567   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
3568 }
3569
3570
3571 bool ExternalString::is_short() {
3572   InstanceType type = map()->instance_type();
3573   return (type & kShortExternalStringMask) == kShortExternalStringTag;
3574 }
3575
3576
3577 const ExternalOneByteString::Resource* ExternalOneByteString::resource() {
3578   return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
3579 }
3580
3581
3582 void ExternalOneByteString::update_data_cache() {
3583   if (is_short()) return;
3584   const char** data_field =
3585       reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
3586   *data_field = resource()->data();
3587 }
3588
3589
3590 void ExternalOneByteString::set_resource(
3591     const ExternalOneByteString::Resource* resource) {
3592   DCHECK(IsAligned(reinterpret_cast<intptr_t>(resource), kPointerSize));
3593   *reinterpret_cast<const Resource**>(
3594       FIELD_ADDR(this, kResourceOffset)) = resource;
3595   if (resource != NULL) update_data_cache();
3596 }
3597
3598
3599 const uint8_t* ExternalOneByteString::GetChars() {
3600   return reinterpret_cast<const uint8_t*>(resource()->data());
3601 }
3602
3603
3604 uint16_t ExternalOneByteString::ExternalOneByteStringGet(int index) {
3605   DCHECK(index >= 0 && index < length());
3606   return GetChars()[index];
3607 }
3608
3609
3610 const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
3611   return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
3612 }
3613
3614
3615 void ExternalTwoByteString::update_data_cache() {
3616   if (is_short()) return;
3617   const uint16_t** data_field =
3618       reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
3619   *data_field = resource()->data();
3620 }
3621
3622
3623 void ExternalTwoByteString::set_resource(
3624     const ExternalTwoByteString::Resource* resource) {
3625   *reinterpret_cast<const Resource**>(
3626       FIELD_ADDR(this, kResourceOffset)) = resource;
3627   if (resource != NULL) update_data_cache();
3628 }
3629
3630
3631 const uint16_t* ExternalTwoByteString::GetChars() {
3632   return resource()->data();
3633 }
3634
3635
3636 uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
3637   DCHECK(index >= 0 && index < length());
3638   return GetChars()[index];
3639 }
3640
3641
3642 const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
3643       unsigned start) {
3644   return GetChars() + start;
3645 }
3646
3647
3648 int ConsStringIteratorOp::OffsetForDepth(int depth) {
3649   return depth & kDepthMask;
3650 }
3651
3652
3653 void ConsStringIteratorOp::PushLeft(ConsString* string) {
3654   frames_[depth_++ & kDepthMask] = string;
3655 }
3656
3657
3658 void ConsStringIteratorOp::PushRight(ConsString* string) {
3659   // Inplace update.
3660   frames_[(depth_-1) & kDepthMask] = string;
3661 }
3662
3663
3664 void ConsStringIteratorOp::AdjustMaximumDepth() {
3665   if (depth_ > maximum_depth_) maximum_depth_ = depth_;
3666 }
3667
3668
3669 void ConsStringIteratorOp::Pop() {
3670   DCHECK(depth_ > 0);
3671   DCHECK(depth_ <= maximum_depth_);
3672   depth_--;
3673 }
3674
3675
3676 uint16_t StringCharacterStream::GetNext() {
3677   DCHECK(buffer8_ != NULL && end_ != NULL);
3678   // Advance cursor if needed.
3679   if (buffer8_ == end_) HasMore();
3680   DCHECK(buffer8_ < end_);
3681   return is_one_byte_ ? *buffer8_++ : *buffer16_++;
3682 }
3683
3684
3685 StringCharacterStream::StringCharacterStream(String* string,
3686                                              ConsStringIteratorOp* op,
3687                                              int offset)
3688   : is_one_byte_(false),
3689     op_(op) {
3690   Reset(string, offset);
3691 }
3692
3693
3694 void StringCharacterStream::Reset(String* string, int offset) {
3695   buffer8_ = NULL;
3696   end_ = NULL;
3697   ConsString* cons_string = String::VisitFlat(this, string, offset);
3698   op_->Reset(cons_string, offset);
3699   if (cons_string != NULL) {
3700     string = op_->Next(&offset);
3701     if (string != NULL) String::VisitFlat(this, string, offset);
3702   }
3703 }
3704
3705
3706 bool StringCharacterStream::HasMore() {
3707   if (buffer8_ != end_) return true;
3708   int offset;
3709   String* string = op_->Next(&offset);
3710   DCHECK_EQ(offset, 0);
3711   if (string == NULL) return false;
3712   String::VisitFlat(this, string);
3713   DCHECK(buffer8_ != end_);
3714   return true;
3715 }
3716
3717
3718 void StringCharacterStream::VisitOneByteString(
3719     const uint8_t* chars, int length) {
3720   is_one_byte_ = true;
3721   buffer8_ = chars;
3722   end_ = chars + length;
3723 }
3724
3725
3726 void StringCharacterStream::VisitTwoByteString(
3727     const uint16_t* chars, int length) {
3728   is_one_byte_ = false;
3729   buffer16_ = chars;
3730   end_ = reinterpret_cast<const uint8_t*>(chars + length);
3731 }
3732
3733
3734 void JSFunctionResultCache::MakeZeroSize() {
3735   set_finger_index(kEntriesIndex);
3736   set_size(kEntriesIndex);
3737 }
3738
3739
3740 void JSFunctionResultCache::Clear() {
3741   int cache_size = size();
3742   Object** entries_start = RawFieldOfElementAt(kEntriesIndex);
3743   MemsetPointer(entries_start,
3744                 GetHeap()->the_hole_value(),
3745                 cache_size - kEntriesIndex);
3746   MakeZeroSize();
3747 }
3748
3749
3750 int JSFunctionResultCache::size() {
3751   return Smi::cast(get(kCacheSizeIndex))->value();
3752 }
3753
3754
3755 void JSFunctionResultCache::set_size(int size) {
3756   set(kCacheSizeIndex, Smi::FromInt(size));
3757 }
3758
3759
3760 int JSFunctionResultCache::finger_index() {
3761   return Smi::cast(get(kFingerIndex))->value();
3762 }
3763
3764
3765 void JSFunctionResultCache::set_finger_index(int finger_index) {
3766   set(kFingerIndex, Smi::FromInt(finger_index));
3767 }
3768
3769
3770 byte ByteArray::get(int index) {
3771   DCHECK(index >= 0 && index < this->length());
3772   return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
3773 }
3774
3775
3776 void ByteArray::set(int index, byte value) {
3777   DCHECK(index >= 0 && index < this->length());
3778   WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
3779 }
3780
3781
3782 int ByteArray::get_int(int index) {
3783   DCHECK(index >= 0 && (index * kIntSize) < this->length());
3784   return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
3785 }
3786
3787
3788 ByteArray* ByteArray::FromDataStartAddress(Address address) {
3789   DCHECK_TAG_ALIGNED(address);
3790   return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
3791 }
3792
3793
3794 Address ByteArray::GetDataStartAddress() {
3795   return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
3796 }
3797
3798
3799 uint8_t* ExternalUint8ClampedArray::external_uint8_clamped_pointer() {
3800   return reinterpret_cast<uint8_t*>(external_pointer());
3801 }
3802
3803
3804 uint8_t ExternalUint8ClampedArray::get_scalar(int index) {
3805   DCHECK((index >= 0) && (index < this->length()));
3806   uint8_t* ptr = external_uint8_clamped_pointer();
3807   return ptr[index];
3808 }
3809
3810
3811 Handle<Object> ExternalUint8ClampedArray::get(
3812     Handle<ExternalUint8ClampedArray> array,
3813     int index) {
3814   return Handle<Smi>(Smi::FromInt(array->get_scalar(index)),
3815                      array->GetIsolate());
3816 }
3817
3818
3819 void ExternalUint8ClampedArray::set(int index, uint8_t value) {
3820   DCHECK((index >= 0) && (index < this->length()));
3821   uint8_t* ptr = external_uint8_clamped_pointer();
3822   ptr[index] = value;
3823 }
3824
3825
3826 void* ExternalArray::external_pointer() const {
3827   intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
3828   return reinterpret_cast<void*>(ptr);
3829 }
3830
3831
3832 void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
3833   intptr_t ptr = reinterpret_cast<intptr_t>(value);
3834   WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
3835 }
3836
3837
3838 int8_t ExternalInt8Array::get_scalar(int index) {
3839   DCHECK((index >= 0) && (index < this->length()));
3840   int8_t* ptr = static_cast<int8_t*>(external_pointer());
3841   return ptr[index];
3842 }
3843
3844
3845 Handle<Object> ExternalInt8Array::get(Handle<ExternalInt8Array> array,
3846                                       int index) {
3847   return Handle<Smi>(Smi::FromInt(array->get_scalar(index)),
3848                      array->GetIsolate());
3849 }
3850
3851
3852 void ExternalInt8Array::set(int index, int8_t value) {
3853   DCHECK((index >= 0) && (index < this->length()));
3854   int8_t* ptr = static_cast<int8_t*>(external_pointer());
3855   ptr[index] = value;
3856 }
3857
3858
3859 uint8_t ExternalUint8Array::get_scalar(int index) {
3860   DCHECK((index >= 0) && (index < this->length()));
3861   uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
3862   return ptr[index];
3863 }
3864
3865
3866 Handle<Object> ExternalUint8Array::get(Handle<ExternalUint8Array> array,
3867                                        int index) {
3868   return Handle<Smi>(Smi::FromInt(array->get_scalar(index)),
3869                      array->GetIsolate());
3870 }
3871
3872
3873 void ExternalUint8Array::set(int index, uint8_t value) {
3874   DCHECK((index >= 0) && (index < this->length()));
3875   uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
3876   ptr[index] = value;
3877 }
3878
3879
3880 int16_t ExternalInt16Array::get_scalar(int index) {
3881   DCHECK((index >= 0) && (index < this->length()));
3882   int16_t* ptr = static_cast<int16_t*>(external_pointer());
3883   return ptr[index];
3884 }
3885
3886
3887 Handle<Object> ExternalInt16Array::get(Handle<ExternalInt16Array> array,
3888                                        int index) {
3889   return Handle<Smi>(Smi::FromInt(array->get_scalar(index)),
3890                      array->GetIsolate());
3891 }
3892
3893
3894 void ExternalInt16Array::set(int index, int16_t value) {
3895   DCHECK((index >= 0) && (index < this->length()));
3896   int16_t* ptr = static_cast<int16_t*>(external_pointer());
3897   ptr[index] = value;
3898 }
3899
3900
3901 uint16_t ExternalUint16Array::get_scalar(int index) {
3902   DCHECK((index >= 0) && (index < this->length()));
3903   uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
3904   return ptr[index];
3905 }
3906
3907
3908 Handle<Object> ExternalUint16Array::get(Handle<ExternalUint16Array> array,
3909                                         int index) {
3910   return Handle<Smi>(Smi::FromInt(array->get_scalar(index)),
3911                      array->GetIsolate());
3912 }
3913
3914
3915 void ExternalUint16Array::set(int index, uint16_t value) {
3916   DCHECK((index >= 0) && (index < this->length()));
3917   uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
3918   ptr[index] = value;
3919 }
3920
3921
3922 int32_t ExternalInt32Array::get_scalar(int index) {
3923   DCHECK((index >= 0) && (index < this->length()));
3924   int32_t* ptr = static_cast<int32_t*>(external_pointer());
3925   return ptr[index];
3926 }
3927
3928
3929 Handle<Object> ExternalInt32Array::get(Handle<ExternalInt32Array> array,
3930                                        int index) {
3931   return array->GetIsolate()->factory()->
3932       NewNumberFromInt(array->get_scalar(index));
3933 }
3934
3935
3936 void ExternalInt32Array::set(int index, int32_t value) {
3937   DCHECK((index >= 0) && (index < this->length()));
3938   int32_t* ptr = static_cast<int32_t*>(external_pointer());
3939   ptr[index] = value;
3940 }
3941
3942
3943 uint32_t ExternalUint32Array::get_scalar(int index) {
3944   DCHECK((index >= 0) && (index < this->length()));
3945   uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
3946   return ptr[index];
3947 }
3948
3949
3950 Handle<Object> ExternalUint32Array::get(Handle<ExternalUint32Array> array,
3951                                         int index) {
3952   return array->GetIsolate()->factory()->
3953       NewNumberFromUint(array->get_scalar(index));
3954 }
3955
3956
3957 void ExternalUint32Array::set(int index, uint32_t value) {
3958   DCHECK((index >= 0) && (index < this->length()));
3959   uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
3960   ptr[index] = value;
3961 }
3962
3963
3964 float ExternalFloat32Array::get_scalar(int index) {
3965   DCHECK((index >= 0) && (index < this->length()));
3966   float* ptr = static_cast<float*>(external_pointer());
3967   return ptr[index];
3968 }
3969
3970
3971 Handle<Object> ExternalFloat32Array::get(Handle<ExternalFloat32Array> array,
3972                                          int index) {
3973   return array->GetIsolate()->factory()->NewNumber(array->get_scalar(index));
3974 }
3975
3976
3977 void ExternalFloat32Array::set(int index, float value) {
3978   DCHECK((index >= 0) && (index < this->length()));
3979   float* ptr = static_cast<float*>(external_pointer());
3980   ptr[index] = value;
3981 }
3982
3983
3984 double ExternalFloat64Array::get_scalar(int index) {
3985   DCHECK((index >= 0) && (index < this->length()));
3986   double* ptr = static_cast<double*>(external_pointer());
3987   return ptr[index];
3988 }
3989
3990
3991 Handle<Object> ExternalFloat64Array::get(Handle<ExternalFloat64Array> array,
3992                                          int index) {
3993   return array->GetIsolate()->factory()->NewNumber(array->get_scalar(index));
3994 }
3995
3996
3997 void ExternalFloat64Array::set(int index, double value) {
3998   DCHECK((index >= 0) && (index < this->length()));
3999   double* ptr = static_cast<double*>(external_pointer());
4000   ptr[index] = value;
4001 }
4002
4003
4004 void* FixedTypedArrayBase::DataPtr() {
4005   return FIELD_ADDR(this, kDataOffset);
4006 }
4007
4008
4009 int FixedTypedArrayBase::DataSize(InstanceType type) {
4010   int element_size;
4011   switch (type) {
4012 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                       \
4013     case FIXED_##TYPE##_ARRAY_TYPE:                                           \
4014       element_size = size;                                                    \
4015       break;
4016
4017     TYPED_ARRAYS(TYPED_ARRAY_CASE)
4018 #undef TYPED_ARRAY_CASE
4019     default:
4020       UNREACHABLE();
4021       return 0;
4022   }
4023   return length() * element_size;
4024 }
4025
4026
4027 int FixedTypedArrayBase::DataSize() {
4028   return DataSize(map()->instance_type());
4029 }
4030
4031
4032 int FixedTypedArrayBase::size() {
4033   return OBJECT_POINTER_ALIGN(kDataOffset + DataSize());
4034 }
4035
4036
4037 int FixedTypedArrayBase::TypedArraySize(InstanceType type) {
4038   return OBJECT_POINTER_ALIGN(kDataOffset + DataSize(type));
4039 }
4040
4041
4042 uint8_t Uint8ArrayTraits::defaultValue() { return 0; }
4043
4044
4045 uint8_t Uint8ClampedArrayTraits::defaultValue() { return 0; }
4046
4047
4048 int8_t Int8ArrayTraits::defaultValue() { return 0; }
4049
4050
4051 uint16_t Uint16ArrayTraits::defaultValue() { return 0; }
4052
4053
4054 int16_t Int16ArrayTraits::defaultValue() { return 0; }
4055
4056
4057 uint32_t Uint32ArrayTraits::defaultValue() { return 0; }
4058
4059
4060 int32_t Int32ArrayTraits::defaultValue() { return 0; }
4061
4062
4063 float Float32ArrayTraits::defaultValue() {
4064   return static_cast<float>(base::OS::nan_value());
4065 }
4066
4067
4068 double Float64ArrayTraits::defaultValue() { return base::OS::nan_value(); }
4069
4070
4071 template <class Traits>
4072 typename Traits::ElementType FixedTypedArray<Traits>::get_scalar(int index) {
4073   DCHECK((index >= 0) && (index < this->length()));
4074   ElementType* ptr = reinterpret_cast<ElementType*>(
4075       FIELD_ADDR(this, kDataOffset));
4076   return ptr[index];
4077 }
4078
4079
4080 template<> inline
4081 FixedTypedArray<Float64ArrayTraits>::ElementType
4082     FixedTypedArray<Float64ArrayTraits>::get_scalar(int index) {
4083   DCHECK((index >= 0) && (index < this->length()));
4084   return READ_DOUBLE_FIELD(this, ElementOffset(index));
4085 }
4086
4087
4088 template <class Traits>
4089 void FixedTypedArray<Traits>::set(int index, ElementType value) {
4090   DCHECK((index >= 0) && (index < this->length()));
4091   ElementType* ptr = reinterpret_cast<ElementType*>(
4092       FIELD_ADDR(this, kDataOffset));
4093   ptr[index] = value;
4094 }
4095
4096
4097 template<> inline
4098 void FixedTypedArray<Float64ArrayTraits>::set(
4099     int index, Float64ArrayTraits::ElementType value) {
4100   DCHECK((index >= 0) && (index < this->length()));
4101   WRITE_DOUBLE_FIELD(this, ElementOffset(index), value);
4102 }
4103
4104
4105 template <class Traits>
4106 typename Traits::ElementType FixedTypedArray<Traits>::from_int(int value) {
4107   return static_cast<ElementType>(value);
4108 }
4109
4110
4111 template <> inline
4112 uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from_int(int value) {
4113   if (value < 0) return 0;
4114   if (value > 0xFF) return 0xFF;
4115   return static_cast<uint8_t>(value);
4116 }
4117
4118
4119 template <class Traits>
4120 typename Traits::ElementType FixedTypedArray<Traits>::from_double(
4121     double value) {
4122   return static_cast<ElementType>(DoubleToInt32(value));
4123 }
4124
4125
4126 template<> inline
4127 uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from_double(double value) {
4128   if (value < 0) return 0;
4129   if (value > 0xFF) return 0xFF;
4130   return static_cast<uint8_t>(lrint(value));
4131 }
4132
4133
4134 template<> inline
4135 float FixedTypedArray<Float32ArrayTraits>::from_double(double value) {
4136   return static_cast<float>(value);
4137 }
4138
4139
4140 template<> inline
4141 double FixedTypedArray<Float64ArrayTraits>::from_double(double value) {
4142   return value;
4143 }
4144
4145
4146 template <class Traits>
4147 Handle<Object> FixedTypedArray<Traits>::get(
4148     Handle<FixedTypedArray<Traits> > array,
4149     int index) {
4150   return Traits::ToHandle(array->GetIsolate(), array->get_scalar(index));
4151 }
4152
4153
4154 template <class Traits>
4155 Handle<Object> FixedTypedArray<Traits>::SetValue(
4156     Handle<FixedTypedArray<Traits> > array,
4157     uint32_t index,
4158     Handle<Object> value) {
4159   ElementType cast_value = Traits::defaultValue();
4160   if (index < static_cast<uint32_t>(array->length())) {
4161     if (value->IsSmi()) {
4162       int int_value = Handle<Smi>::cast(value)->value();
4163       cast_value = from_int(int_value);
4164     } else if (value->IsHeapNumber()) {
4165       double double_value = Handle<HeapNumber>::cast(value)->value();
4166       cast_value = from_double(double_value);
4167     } else {
4168       // Clamp undefined to the default value. All other types have been
4169       // converted to a number type further up in the call chain.
4170       DCHECK(value->IsUndefined());
4171     }
4172     array->set(index, cast_value);
4173   }
4174   return Traits::ToHandle(array->GetIsolate(), cast_value);
4175 }
4176
4177
4178 Handle<Object> Uint8ArrayTraits::ToHandle(Isolate* isolate, uint8_t scalar) {
4179   return handle(Smi::FromInt(scalar), isolate);
4180 }
4181
4182
4183 Handle<Object> Uint8ClampedArrayTraits::ToHandle(Isolate* isolate,
4184                                                  uint8_t scalar) {
4185   return handle(Smi::FromInt(scalar), isolate);
4186 }
4187
4188
4189 Handle<Object> Int8ArrayTraits::ToHandle(Isolate* isolate, int8_t scalar) {
4190   return handle(Smi::FromInt(scalar), isolate);
4191 }
4192
4193
4194 Handle<Object> Uint16ArrayTraits::ToHandle(Isolate* isolate, uint16_t scalar) {
4195   return handle(Smi::FromInt(scalar), isolate);
4196 }
4197
4198
4199 Handle<Object> Int16ArrayTraits::ToHandle(Isolate* isolate, int16_t scalar) {
4200   return handle(Smi::FromInt(scalar), isolate);
4201 }
4202
4203
4204 Handle<Object> Uint32ArrayTraits::ToHandle(Isolate* isolate, uint32_t scalar) {
4205   return isolate->factory()->NewNumberFromUint(scalar);
4206 }
4207
4208
4209 Handle<Object> Int32ArrayTraits::ToHandle(Isolate* isolate, int32_t scalar) {
4210   return isolate->factory()->NewNumberFromInt(scalar);
4211 }
4212
4213
4214 Handle<Object> Float32ArrayTraits::ToHandle(Isolate* isolate, float scalar) {
4215   return isolate->factory()->NewNumber(scalar);
4216 }
4217
4218
4219 Handle<Object> Float64ArrayTraits::ToHandle(Isolate* isolate, double scalar) {
4220   return isolate->factory()->NewNumber(scalar);
4221 }
4222
4223
4224 int Map::visitor_id() {
4225   return READ_BYTE_FIELD(this, kVisitorIdOffset);
4226 }
4227
4228
4229 void Map::set_visitor_id(int id) {
4230   DCHECK(0 <= id && id < 256);
4231   WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
4232 }
4233
4234
4235 int Map::instance_size() {
4236   return NOBARRIER_READ_BYTE_FIELD(
4237       this, kInstanceSizeOffset) << kPointerSizeLog2;
4238 }
4239
4240
4241 int Map::inobject_properties() {
4242   return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
4243 }
4244
4245
4246 int Map::pre_allocated_property_fields() {
4247   return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
4248 }
4249
4250
4251 int Map::GetInObjectPropertyOffset(int index) {
4252   // Adjust for the number of properties stored in the object.
4253   index -= inobject_properties();
4254   DCHECK(index <= 0);
4255   return instance_size() + (index * kPointerSize);
4256 }
4257
4258
4259 int HeapObject::SizeFromMap(Map* map) {
4260   int instance_size = map->instance_size();
4261   if (instance_size != kVariableSizeSentinel) return instance_size;
4262   // Only inline the most frequent cases.
4263   InstanceType instance_type = map->instance_type();
4264   if (instance_type == FIXED_ARRAY_TYPE) {
4265     return FixedArray::BodyDescriptor::SizeOf(map, this);
4266   }
4267   if (instance_type == ONE_BYTE_STRING_TYPE ||
4268       instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) {
4269     return SeqOneByteString::SizeFor(
4270         reinterpret_cast<SeqOneByteString*>(this)->length());
4271   }
4272   if (instance_type == BYTE_ARRAY_TYPE) {
4273     return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
4274   }
4275   if (instance_type == FREE_SPACE_TYPE) {
4276     return reinterpret_cast<FreeSpace*>(this)->nobarrier_size();
4277   }
4278   if (instance_type == STRING_TYPE ||
4279       instance_type == INTERNALIZED_STRING_TYPE) {
4280     return SeqTwoByteString::SizeFor(
4281         reinterpret_cast<SeqTwoByteString*>(this)->length());
4282   }
4283   if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
4284     return FixedDoubleArray::SizeFor(
4285         reinterpret_cast<FixedDoubleArray*>(this)->length());
4286   }
4287   if (instance_type == CONSTANT_POOL_ARRAY_TYPE) {
4288     return reinterpret_cast<ConstantPoolArray*>(this)->size();
4289   }
4290   if (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE &&
4291       instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE) {
4292     return reinterpret_cast<FixedTypedArrayBase*>(
4293         this)->TypedArraySize(instance_type);
4294   }
4295   DCHECK(instance_type == CODE_TYPE);
4296   return reinterpret_cast<Code*>(this)->CodeSize();
4297 }
4298
4299
4300 void Map::set_instance_size(int value) {
4301   DCHECK_EQ(0, value & (kPointerSize - 1));
4302   value >>= kPointerSizeLog2;
4303   DCHECK(0 <= value && value < 256);
4304   NOBARRIER_WRITE_BYTE_FIELD(
4305       this, kInstanceSizeOffset, static_cast<byte>(value));
4306 }
4307
4308
4309 void Map::set_inobject_properties(int value) {
4310   DCHECK(0 <= value && value < 256);
4311   WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
4312 }
4313
4314
4315 void Map::set_pre_allocated_property_fields(int value) {
4316   DCHECK(0 <= value && value < 256);
4317   WRITE_BYTE_FIELD(this,
4318                    kPreAllocatedPropertyFieldsOffset,
4319                    static_cast<byte>(value));
4320 }
4321
4322
4323 InstanceType Map::instance_type() {
4324   return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
4325 }
4326
4327
4328 void Map::set_instance_type(InstanceType value) {
4329   WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
4330 }
4331
4332
4333 int Map::unused_property_fields() {
4334   return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
4335 }
4336
4337
4338 void Map::set_unused_property_fields(int value) {
4339   WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
4340 }
4341
4342
4343 byte Map::bit_field() {
4344   return READ_BYTE_FIELD(this, kBitFieldOffset);
4345 }
4346
4347
4348 void Map::set_bit_field(byte value) {
4349   WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
4350 }
4351
4352
4353 byte Map::bit_field2() {
4354   return READ_BYTE_FIELD(this, kBitField2Offset);
4355 }
4356
4357
4358 void Map::set_bit_field2(byte value) {
4359   WRITE_BYTE_FIELD(this, kBitField2Offset, value);
4360 }
4361
4362
4363 void Map::set_non_instance_prototype(bool value) {
4364   if (value) {
4365     set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
4366   } else {
4367     set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
4368   }
4369 }
4370
4371
4372 bool Map::has_non_instance_prototype() {
4373   return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
4374 }
4375
4376
4377 void Map::set_function_with_prototype(bool value) {
4378   set_bit_field(FunctionWithPrototype::update(bit_field(), value));
4379 }
4380
4381
4382 bool Map::function_with_prototype() {
4383   return FunctionWithPrototype::decode(bit_field());
4384 }
4385
4386
4387 void Map::set_is_access_check_needed(bool access_check_needed) {
4388   if (access_check_needed) {
4389     set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
4390   } else {
4391     set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
4392   }
4393 }
4394
4395
4396 bool Map::is_access_check_needed() {
4397   return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
4398 }
4399
4400
4401 void Map::set_is_extensible(bool value) {
4402   if (value) {
4403     set_bit_field2(bit_field2() | (1 << kIsExtensible));
4404   } else {
4405     set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
4406   }
4407 }
4408
4409 bool Map::is_extensible() {
4410   return ((1 << kIsExtensible) & bit_field2()) != 0;
4411 }
4412
4413
4414 void Map::set_is_prototype_map(bool value) {
4415   set_bit_field2(IsPrototypeMapBits::update(bit_field2(), value));
4416 }
4417
4418 bool Map::is_prototype_map() {
4419   return IsPrototypeMapBits::decode(bit_field2());
4420 }
4421
4422
4423 void Map::set_dictionary_map(bool value) {
4424   uint32_t new_bit_field3 = DictionaryMap::update(bit_field3(), value);
4425   new_bit_field3 = IsUnstable::update(new_bit_field3, value);
4426   set_bit_field3(new_bit_field3);
4427 }
4428
4429
4430 bool Map::is_dictionary_map() {
4431   return DictionaryMap::decode(bit_field3());
4432 }
4433
4434
4435 Code::Flags Code::flags() {
4436   return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
4437 }
4438
4439
4440 void Map::set_owns_descriptors(bool owns_descriptors) {
4441   set_bit_field3(OwnsDescriptors::update(bit_field3(), owns_descriptors));
4442 }
4443
4444
4445 bool Map::owns_descriptors() {
4446   return OwnsDescriptors::decode(bit_field3());
4447 }
4448
4449
4450 void Map::set_has_instance_call_handler() {
4451   set_bit_field3(HasInstanceCallHandler::update(bit_field3(), true));
4452 }
4453
4454
4455 bool Map::has_instance_call_handler() {
4456   return HasInstanceCallHandler::decode(bit_field3());
4457 }
4458
4459
4460 void Map::deprecate() {
4461   set_bit_field3(Deprecated::update(bit_field3(), true));
4462 }
4463
4464
4465 bool Map::is_deprecated() {
4466   return Deprecated::decode(bit_field3());
4467 }
4468
4469
4470 void Map::set_migration_target(bool value) {
4471   set_bit_field3(IsMigrationTarget::update(bit_field3(), value));
4472 }
4473
4474
4475 bool Map::is_migration_target() {
4476   return IsMigrationTarget::decode(bit_field3());
4477 }
4478
4479
4480 void Map::set_done_inobject_slack_tracking(bool value) {
4481   set_bit_field3(DoneInobjectSlackTracking::update(bit_field3(), value));
4482 }
4483
4484
4485 bool Map::done_inobject_slack_tracking() {
4486   return DoneInobjectSlackTracking::decode(bit_field3());
4487 }
4488
4489
4490 void Map::set_construction_count(int value) {
4491   set_bit_field3(ConstructionCount::update(bit_field3(), value));
4492 }
4493
4494
4495 int Map::construction_count() {
4496   return ConstructionCount::decode(bit_field3());
4497 }
4498
4499
4500 void Map::freeze() {
4501   set_bit_field3(IsFrozen::update(bit_field3(), true));
4502 }
4503
4504
4505 bool Map::is_frozen() {
4506   return IsFrozen::decode(bit_field3());
4507 }
4508
4509
4510 void Map::mark_unstable() {
4511   set_bit_field3(IsUnstable::update(bit_field3(), true));
4512 }
4513
4514
4515 bool Map::is_stable() {
4516   return !IsUnstable::decode(bit_field3());
4517 }
4518
4519
4520 bool Map::has_code_cache() {
4521   return code_cache() != GetIsolate()->heap()->empty_fixed_array();
4522 }
4523
4524
4525 bool Map::CanBeDeprecated() {
4526   int descriptor = LastAdded();
4527   for (int i = 0; i <= descriptor; i++) {
4528     PropertyDetails details = instance_descriptors()->GetDetails(i);
4529     if (details.representation().IsNone()) return true;
4530     if (details.representation().IsSmi()) return true;
4531     if (details.representation().IsDouble()) return true;
4532     if (details.representation().IsHeapObject()) return true;
4533     if (details.type() == CONSTANT) return true;
4534   }
4535   return false;
4536 }
4537
4538
4539 void Map::NotifyLeafMapLayoutChange() {
4540   if (is_stable()) {
4541     mark_unstable();
4542     dependent_code()->DeoptimizeDependentCodeGroup(
4543         GetIsolate(),
4544         DependentCode::kPrototypeCheckGroup);
4545   }
4546 }
4547
4548
4549 bool Map::CanOmitMapChecks() {
4550   return is_stable() && FLAG_omit_map_checks_for_leaf_maps;
4551 }
4552
4553
4554 int DependentCode::number_of_entries(DependencyGroup group) {
4555   if (length() == 0) return 0;
4556   return Smi::cast(get(group))->value();
4557 }
4558
4559
4560 void DependentCode::set_number_of_entries(DependencyGroup group, int value) {
4561   set(group, Smi::FromInt(value));
4562 }
4563
4564
4565 bool DependentCode::is_code_at(int i) {
4566   return get(kCodesStartIndex + i)->IsCode();
4567 }
4568
4569 Code* DependentCode::code_at(int i) {
4570   return Code::cast(get(kCodesStartIndex + i));
4571 }
4572
4573
4574 CompilationInfo* DependentCode::compilation_info_at(int i) {
4575   return reinterpret_cast<CompilationInfo*>(
4576       Foreign::cast(get(kCodesStartIndex + i))->foreign_address());
4577 }
4578
4579
4580 void DependentCode::set_object_at(int i, Object* object) {
4581   set(kCodesStartIndex + i, object);
4582 }
4583
4584
4585 Object* DependentCode::object_at(int i) {
4586   return get(kCodesStartIndex + i);
4587 }
4588
4589
4590 Object** DependentCode::slot_at(int i) {
4591   return RawFieldOfElementAt(kCodesStartIndex + i);
4592 }
4593
4594
4595 void DependentCode::clear_at(int i) {
4596   set_undefined(kCodesStartIndex + i);
4597 }
4598
4599
4600 void DependentCode::copy(int from, int to) {
4601   set(kCodesStartIndex + to, get(kCodesStartIndex + from));
4602 }
4603
4604
4605 void DependentCode::ExtendGroup(DependencyGroup group) {
4606   GroupStartIndexes starts(this);
4607   for (int g = kGroupCount - 1; g > group; g--) {
4608     if (starts.at(g) < starts.at(g + 1)) {
4609       copy(starts.at(g), starts.at(g + 1));
4610     }
4611   }
4612 }
4613
4614
4615 void Code::set_flags(Code::Flags flags) {
4616   STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
4617   WRITE_INT_FIELD(this, kFlagsOffset, flags);
4618 }
4619
4620
4621 Code::Kind Code::kind() {
4622   return ExtractKindFromFlags(flags());
4623 }
4624
4625
4626 bool Code::IsCodeStubOrIC() {
4627   return kind() == STUB || kind() == HANDLER || kind() == LOAD_IC ||
4628          kind() == KEYED_LOAD_IC || kind() == CALL_IC || kind() == STORE_IC ||
4629          kind() == KEYED_STORE_IC || kind() == BINARY_OP_IC ||
4630          kind() == COMPARE_IC || kind() == COMPARE_NIL_IC ||
4631          kind() == TO_BOOLEAN_IC;
4632 }
4633
4634
4635 InlineCacheState Code::ic_state() {
4636   InlineCacheState result = ExtractICStateFromFlags(flags());
4637   // Only allow uninitialized or debugger states for non-IC code
4638   // objects. This is used in the debugger to determine whether or not
4639   // a call to code object has been replaced with a debug break call.
4640   DCHECK(is_inline_cache_stub() ||
4641          result == UNINITIALIZED ||
4642          result == DEBUG_STUB);
4643   return result;
4644 }
4645
4646
4647 ExtraICState Code::extra_ic_state() {
4648   DCHECK(is_inline_cache_stub() || ic_state() == DEBUG_STUB);
4649   return ExtractExtraICStateFromFlags(flags());
4650 }
4651
4652
4653 Code::StubType Code::type() {
4654   return ExtractTypeFromFlags(flags());
4655 }
4656
4657
4658 // For initialization.
4659 void Code::set_raw_kind_specific_flags1(int value) {
4660   WRITE_INT_FIELD(this, kKindSpecificFlags1Offset, value);
4661 }
4662
4663
4664 void Code::set_raw_kind_specific_flags2(int value) {
4665   WRITE_INT_FIELD(this, kKindSpecificFlags2Offset, value);
4666 }
4667
4668
4669 inline bool Code::is_crankshafted() {
4670   return IsCrankshaftedField::decode(
4671       READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
4672 }
4673
4674
4675 inline bool Code::is_hydrogen_stub() {
4676   return is_crankshafted() && kind() != OPTIMIZED_FUNCTION;
4677 }
4678
4679
4680 inline void Code::set_is_crankshafted(bool value) {
4681   int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4682   int updated = IsCrankshaftedField::update(previous, value);
4683   WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
4684 }
4685
4686
4687 inline bool Code::is_turbofanned() {
4688   DCHECK(kind() == OPTIMIZED_FUNCTION || kind() == STUB);
4689   return IsTurbofannedField::decode(
4690       READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
4691 }
4692
4693
4694 inline void Code::set_is_turbofanned(bool value) {
4695   DCHECK(kind() == OPTIMIZED_FUNCTION || kind() == STUB);
4696   int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4697   int updated = IsTurbofannedField::update(previous, value);
4698   WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
4699 }
4700
4701
4702 bool Code::optimizable() {
4703   DCHECK_EQ(FUNCTION, kind());
4704   return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
4705 }
4706
4707
4708 void Code::set_optimizable(bool value) {
4709   DCHECK_EQ(FUNCTION, kind());
4710   WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
4711 }
4712
4713
4714 bool Code::has_deoptimization_support() {
4715   DCHECK_EQ(FUNCTION, kind());
4716   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
4717   return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
4718 }
4719
4720
4721 void Code::set_has_deoptimization_support(bool value) {
4722   DCHECK_EQ(FUNCTION, kind());
4723   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
4724   flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
4725   WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
4726 }
4727
4728
4729 bool Code::has_debug_break_slots() {
4730   DCHECK_EQ(FUNCTION, kind());
4731   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
4732   return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
4733 }
4734
4735
4736 void Code::set_has_debug_break_slots(bool value) {
4737   DCHECK_EQ(FUNCTION, kind());
4738   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
4739   flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
4740   WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
4741 }
4742
4743
4744 bool Code::is_compiled_optimizable() {
4745   DCHECK_EQ(FUNCTION, kind());
4746   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
4747   return FullCodeFlagsIsCompiledOptimizable::decode(flags);
4748 }
4749
4750
4751 void Code::set_compiled_optimizable(bool value) {
4752   DCHECK_EQ(FUNCTION, kind());
4753   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
4754   flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
4755   WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
4756 }
4757
4758
4759 int Code::allow_osr_at_loop_nesting_level() {
4760   DCHECK_EQ(FUNCTION, kind());
4761   int fields = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4762   return AllowOSRAtLoopNestingLevelField::decode(fields);
4763 }
4764
4765
4766 void Code::set_allow_osr_at_loop_nesting_level(int level) {
4767   DCHECK_EQ(FUNCTION, kind());
4768   DCHECK(level >= 0 && level <= kMaxLoopNestingMarker);
4769   int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4770   int updated = AllowOSRAtLoopNestingLevelField::update(previous, level);
4771   WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
4772 }
4773
4774
4775 int Code::profiler_ticks() {
4776   DCHECK_EQ(FUNCTION, kind());
4777   return READ_BYTE_FIELD(this, kProfilerTicksOffset);
4778 }
4779
4780
4781 void Code::set_profiler_ticks(int ticks) {
4782   DCHECK(ticks < 256);
4783   if (kind() == FUNCTION) {
4784     WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
4785   }
4786 }
4787
4788
4789 int Code::builtin_index() {
4790   DCHECK_EQ(BUILTIN, kind());
4791   return READ_INT32_FIELD(this, kKindSpecificFlags1Offset);
4792 }
4793
4794
4795 void Code::set_builtin_index(int index) {
4796   DCHECK_EQ(BUILTIN, kind());
4797   WRITE_INT32_FIELD(this, kKindSpecificFlags1Offset, index);
4798 }
4799
4800
4801 unsigned Code::stack_slots() {
4802   DCHECK(is_crankshafted());
4803   return StackSlotsField::decode(
4804       READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
4805 }
4806
4807
4808 void Code::set_stack_slots(unsigned slots) {
4809   CHECK(slots <= (1 << kStackSlotsBitCount));
4810   DCHECK(is_crankshafted());
4811   int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4812   int updated = StackSlotsField::update(previous, slots);
4813   WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
4814 }
4815
4816
4817 unsigned Code::safepoint_table_offset() {
4818   DCHECK(is_crankshafted());
4819   return SafepointTableOffsetField::decode(
4820       READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
4821 }
4822
4823
4824 void Code::set_safepoint_table_offset(unsigned offset) {
4825   CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
4826   DCHECK(is_crankshafted());
4827   DCHECK(IsAligned(offset, static_cast<unsigned>(kIntSize)));
4828   int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4829   int updated = SafepointTableOffsetField::update(previous, offset);
4830   WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
4831 }
4832
4833
4834 unsigned Code::back_edge_table_offset() {
4835   DCHECK_EQ(FUNCTION, kind());
4836   return BackEdgeTableOffsetField::decode(
4837       READ_UINT32_FIELD(this, kKindSpecificFlags2Offset)) << kPointerSizeLog2;
4838 }
4839
4840
4841 void Code::set_back_edge_table_offset(unsigned offset) {
4842   DCHECK_EQ(FUNCTION, kind());
4843   DCHECK(IsAligned(offset, static_cast<unsigned>(kPointerSize)));
4844   offset = offset >> kPointerSizeLog2;
4845   int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4846   int updated = BackEdgeTableOffsetField::update(previous, offset);
4847   WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
4848 }
4849
4850
4851 bool Code::back_edges_patched_for_osr() {
4852   DCHECK_EQ(FUNCTION, kind());
4853   return allow_osr_at_loop_nesting_level() > 0;
4854 }
4855
4856
4857 byte Code::to_boolean_state() {
4858   return extra_ic_state();
4859 }
4860
4861
4862 bool Code::has_function_cache() {
4863   DCHECK(kind() == STUB);
4864   return HasFunctionCacheField::decode(
4865       READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
4866 }
4867
4868
4869 void Code::set_has_function_cache(bool flag) {
4870   DCHECK(kind() == STUB);
4871   int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4872   int updated = HasFunctionCacheField::update(previous, flag);
4873   WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
4874 }
4875
4876
4877 bool Code::marked_for_deoptimization() {
4878   DCHECK(kind() == OPTIMIZED_FUNCTION);
4879   return MarkedForDeoptimizationField::decode(
4880       READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
4881 }
4882
4883
4884 void Code::set_marked_for_deoptimization(bool flag) {
4885   DCHECK(kind() == OPTIMIZED_FUNCTION);
4886   DCHECK(!flag || AllowDeoptimization::IsAllowed(GetIsolate()));
4887   int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4888   int updated = MarkedForDeoptimizationField::update(previous, flag);
4889   WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
4890 }
4891
4892
4893 bool Code::is_weak_stub() {
4894   return CanBeWeakStub() && WeakStubField::decode(
4895       READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
4896 }
4897
4898
4899 void Code::mark_as_weak_stub() {
4900   DCHECK(CanBeWeakStub());
4901   int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4902   int updated = WeakStubField::update(previous, true);
4903   WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
4904 }
4905
4906
4907 bool Code::is_invalidated_weak_stub() {
4908   return is_weak_stub() && InvalidatedWeakStubField::decode(
4909       READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
4910 }
4911
4912
4913 void Code::mark_as_invalidated_weak_stub() {
4914   DCHECK(is_inline_cache_stub());
4915   int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4916   int updated = InvalidatedWeakStubField::update(previous, true);
4917   WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
4918 }
4919
4920
4921 bool Code::is_inline_cache_stub() {
4922   Kind kind = this->kind();
4923   switch (kind) {
4924 #define CASE(name) case name: return true;
4925     IC_KIND_LIST(CASE)
4926 #undef CASE
4927     default: return false;
4928   }
4929 }
4930
4931
4932 bool Code::is_keyed_stub() {
4933   return is_keyed_load_stub() || is_keyed_store_stub();
4934 }
4935
4936
4937 bool Code::is_debug_stub() {
4938   return ic_state() == DEBUG_STUB;
4939 }
4940
4941
4942 ConstantPoolArray* Code::constant_pool() {
4943   return ConstantPoolArray::cast(READ_FIELD(this, kConstantPoolOffset));
4944 }
4945
4946
4947 void Code::set_constant_pool(Object* value) {
4948   DCHECK(value->IsConstantPoolArray());
4949   WRITE_FIELD(this, kConstantPoolOffset, value);
4950   WRITE_BARRIER(GetHeap(), this, kConstantPoolOffset, value);
4951 }
4952
4953
4954 Code::Flags Code::ComputeFlags(Kind kind, InlineCacheState ic_state,
4955                                ExtraICState extra_ic_state, StubType type,
4956                                CacheHolderFlag holder) {
4957   // Compute the bit mask.
4958   unsigned int bits = KindField::encode(kind)
4959       | ICStateField::encode(ic_state)
4960       | TypeField::encode(type)
4961       | ExtraICStateField::encode(extra_ic_state)
4962       | CacheHolderField::encode(holder);
4963   return static_cast<Flags>(bits);
4964 }
4965
4966
4967 Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
4968                                           ExtraICState extra_ic_state,
4969                                           CacheHolderFlag holder,
4970                                           StubType type) {
4971   return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, holder);
4972 }
4973
4974
4975 Code::Flags Code::ComputeHandlerFlags(Kind handler_kind, StubType type,
4976                                       CacheHolderFlag holder) {
4977   return ComputeFlags(Code::HANDLER, MONOMORPHIC, handler_kind, type, holder);
4978 }
4979
4980
4981 Code::Kind Code::ExtractKindFromFlags(Flags flags) {
4982   return KindField::decode(flags);
4983 }
4984
4985
4986 InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
4987   return ICStateField::decode(flags);
4988 }
4989
4990
4991 ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
4992   return ExtraICStateField::decode(flags);
4993 }
4994
4995
4996 Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
4997   return TypeField::decode(flags);
4998 }
4999
5000
5001 CacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
5002   return CacheHolderField::decode(flags);
5003 }
5004
5005
5006 Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
5007   int bits = flags & ~TypeField::kMask;
5008   return static_cast<Flags>(bits);
5009 }
5010
5011
5012 Code::Flags Code::RemoveTypeAndHolderFromFlags(Flags flags) {
5013   int bits = flags & ~TypeField::kMask & ~CacheHolderField::kMask;
5014   return static_cast<Flags>(bits);
5015 }
5016
5017
5018 Code* Code::GetCodeFromTargetAddress(Address address) {
5019   HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
5020   // GetCodeFromTargetAddress might be called when marking objects during mark
5021   // sweep. reinterpret_cast is therefore used instead of the more appropriate
5022   // Code::cast. Code::cast does not work when the object's map is
5023   // marked.
5024   Code* result = reinterpret_cast<Code*>(code);
5025   return result;
5026 }
5027
5028
5029 Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
5030   return HeapObject::
5031       FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
5032 }
5033
5034
5035 bool Code::IsWeakObjectInOptimizedCode(Object* object) {
5036   if (!FLAG_collect_maps) return false;
5037   if (object->IsMap()) {
5038     return Map::cast(object)->CanTransition() &&
5039            FLAG_weak_embedded_maps_in_optimized_code;
5040   }
5041   if (object->IsJSObject() ||
5042       (object->IsCell() && Cell::cast(object)->value()->IsJSObject())) {
5043     return FLAG_weak_embedded_objects_in_optimized_code;
5044   }
5045   return false;
5046 }
5047
5048
5049 class Code::FindAndReplacePattern {
5050  public:
5051   FindAndReplacePattern() : count_(0) { }
5052   void Add(Handle<Map> map_to_find, Handle<Object> obj_to_replace) {
5053     DCHECK(count_ < kMaxCount);
5054     find_[count_] = map_to_find;
5055     replace_[count_] = obj_to_replace;
5056     ++count_;
5057   }
5058  private:
5059   static const int kMaxCount = 4;
5060   int count_;
5061   Handle<Map> find_[kMaxCount];
5062   Handle<Object> replace_[kMaxCount];
5063   friend class Code;
5064 };
5065
5066
5067 bool Code::IsWeakObjectInIC(Object* object) {
5068   return object->IsMap() && Map::cast(object)->CanTransition() &&
5069          FLAG_collect_maps &&
5070          FLAG_weak_embedded_maps_in_ic;
5071 }
5072
5073
5074 Object* Map::prototype() const {
5075   return READ_FIELD(this, kPrototypeOffset);
5076 }
5077
5078
5079 void Map::set_prototype(Object* value, WriteBarrierMode mode) {
5080   DCHECK(value->IsNull() || value->IsJSReceiver());
5081   WRITE_FIELD(this, kPrototypeOffset, value);
5082   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
5083 }
5084
5085
5086 // If the descriptor is using the empty transition array, install a new empty
5087 // transition array that will have place for an element transition.
5088 static void EnsureHasTransitionArray(Handle<Map> map) {
5089   Handle<TransitionArray> transitions;
5090   if (!map->HasTransitionArray()) {
5091     transitions = TransitionArray::Allocate(map->GetIsolate(), 0);
5092     transitions->set_back_pointer_storage(map->GetBackPointer());
5093   } else if (!map->transitions()->IsFullTransitionArray()) {
5094     transitions = TransitionArray::ExtendToFullTransitionArray(map);
5095   } else {
5096     return;
5097   }
5098   map->set_transitions(*transitions);
5099 }
5100
5101
5102 void Map::InitializeDescriptors(DescriptorArray* descriptors) {
5103   int len = descriptors->number_of_descriptors();
5104   set_instance_descriptors(descriptors);
5105   SetNumberOfOwnDescriptors(len);
5106 }
5107
5108
5109 ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
5110
5111
5112 void Map::set_bit_field3(uint32_t bits) {
5113   if (kInt32Size != kPointerSize) {
5114     WRITE_UINT32_FIELD(this, kBitField3Offset + kInt32Size, 0);
5115   }
5116   WRITE_UINT32_FIELD(this, kBitField3Offset, bits);
5117 }
5118
5119
5120 uint32_t Map::bit_field3() {
5121   return READ_UINT32_FIELD(this, kBitField3Offset);
5122 }
5123
5124
5125 void Map::AppendDescriptor(Descriptor* desc) {
5126   DescriptorArray* descriptors = instance_descriptors();
5127   int number_of_own_descriptors = NumberOfOwnDescriptors();
5128   DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors);
5129   descriptors->Append(desc);
5130   SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
5131 }
5132
5133
5134 Object* Map::GetBackPointer() {
5135   Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
5136   if (object->IsDescriptorArray()) {
5137     return TransitionArray::cast(object)->back_pointer_storage();
5138   } else {
5139     DCHECK(object->IsMap() || object->IsUndefined());
5140     return object;
5141   }
5142 }
5143
5144
5145 bool Map::HasElementsTransition() {
5146   return HasTransitionArray() && transitions()->HasElementsTransition();
5147 }
5148
5149
5150 bool Map::HasTransitionArray() const {
5151   Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
5152   return object->IsTransitionArray();
5153 }
5154
5155
5156 Map* Map::elements_transition_map() {
5157   int index = transitions()->Search(GetHeap()->elements_transition_symbol());
5158   return transitions()->GetTarget(index);
5159 }
5160
5161
5162 bool Map::CanHaveMoreTransitions() {
5163   if (!HasTransitionArray()) return true;
5164   return FixedArray::SizeFor(transitions()->length() +
5165                              TransitionArray::kTransitionSize)
5166       <= Page::kMaxRegularHeapObjectSize;
5167 }
5168
5169
5170 Map* Map::GetTransition(int transition_index) {
5171   return transitions()->GetTarget(transition_index);
5172 }
5173
5174
5175 int Map::SearchTransition(Name* name) {
5176   if (HasTransitionArray()) return transitions()->Search(name);
5177   return TransitionArray::kNotFound;
5178 }
5179
5180
5181 FixedArray* Map::GetPrototypeTransitions() {
5182   if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
5183   if (!transitions()->HasPrototypeTransitions()) {
5184     return GetHeap()->empty_fixed_array();
5185   }
5186   return transitions()->GetPrototypeTransitions();
5187 }
5188
5189
5190 void Map::SetPrototypeTransitions(
5191     Handle<Map> map, Handle<FixedArray> proto_transitions) {
5192   EnsureHasTransitionArray(map);
5193   int old_number_of_transitions = map->NumberOfProtoTransitions();
5194 #ifdef DEBUG
5195   if (map->HasPrototypeTransitions()) {
5196     DCHECK(map->GetPrototypeTransitions() != *proto_transitions);
5197     map->ZapPrototypeTransitions();
5198   }
5199 #endif
5200   map->transitions()->SetPrototypeTransitions(*proto_transitions);
5201   map->SetNumberOfProtoTransitions(old_number_of_transitions);
5202 }
5203
5204
5205 bool Map::HasPrototypeTransitions() {
5206   return HasTransitionArray() && transitions()->HasPrototypeTransitions();
5207 }
5208
5209
5210 TransitionArray* Map::transitions() const {
5211   DCHECK(HasTransitionArray());
5212   Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
5213   return TransitionArray::cast(object);
5214 }
5215
5216
5217 void Map::set_transitions(TransitionArray* transition_array,
5218                           WriteBarrierMode mode) {
5219   // Transition arrays are not shared. When one is replaced, it should not
5220   // keep referenced objects alive, so we zap it.
5221   // When there is another reference to the array somewhere (e.g. a handle),
5222   // not zapping turns from a waste of memory into a source of crashes.
5223   if (HasTransitionArray()) {
5224 #ifdef DEBUG
5225     for (int i = 0; i < transitions()->number_of_transitions(); i++) {
5226       Map* target = transitions()->GetTarget(i);
5227       if (target->instance_descriptors() == instance_descriptors()) {
5228         Name* key = transitions()->GetKey(i);
5229         int new_target_index = transition_array->Search(key);
5230         DCHECK(new_target_index != TransitionArray::kNotFound);
5231         DCHECK(transition_array->GetTarget(new_target_index) == target);
5232       }
5233     }
5234 #endif
5235     DCHECK(transitions() != transition_array);
5236     ZapTransitions();
5237   }
5238
5239   WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array);
5240   CONDITIONAL_WRITE_BARRIER(
5241       GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode);
5242 }
5243
5244
5245 void Map::init_back_pointer(Object* undefined) {
5246   DCHECK(undefined->IsUndefined());
5247   WRITE_FIELD(this, kTransitionsOrBackPointerOffset, undefined);
5248 }
5249
5250
5251 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
5252   DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE);
5253   DCHECK((value->IsUndefined() && GetBackPointer()->IsMap()) ||
5254          (value->IsMap() && GetBackPointer()->IsUndefined()));
5255   Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
5256   if (object->IsTransitionArray()) {
5257     TransitionArray::cast(object)->set_back_pointer_storage(value);
5258   } else {
5259     WRITE_FIELD(this, kTransitionsOrBackPointerOffset, value);
5260     CONDITIONAL_WRITE_BARRIER(
5261         GetHeap(), this, kTransitionsOrBackPointerOffset, value, mode);
5262   }
5263 }
5264
5265
5266 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
5267 ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
5268 ACCESSORS(Map, constructor, Object, kConstructorOffset)
5269
5270 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
5271 ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
5272 ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
5273
5274 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
5275 ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset)
5276 ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
5277 ACCESSORS(GlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
5278
5279 ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
5280 ACCESSORS(JSGlobalProxy, hash, Object, kHashOffset)
5281
5282 ACCESSORS(AccessorInfo, name, Object, kNameOffset)
5283 ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
5284 ACCESSORS(AccessorInfo, expected_receiver_type, Object,
5285           kExpectedReceiverTypeOffset)
5286
5287 ACCESSORS(DeclaredAccessorDescriptor, serialized_data, ByteArray,
5288           kSerializedDataOffset)
5289
5290 ACCESSORS(DeclaredAccessorInfo, descriptor, DeclaredAccessorDescriptor,
5291           kDescriptorOffset)
5292
5293 ACCESSORS(ExecutableAccessorInfo, getter, Object, kGetterOffset)
5294 ACCESSORS(ExecutableAccessorInfo, setter, Object, kSetterOffset)
5295 ACCESSORS(ExecutableAccessorInfo, data, Object, kDataOffset)
5296
5297 ACCESSORS(Box, value, Object, kValueOffset)
5298
5299 ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
5300 ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
5301
5302 ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
5303 ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
5304 ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
5305
5306 ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
5307 ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
5308 ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
5309 ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
5310 ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
5311 ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
5312
5313 ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
5314 ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
5315
5316 ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
5317 ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
5318 ACCESSORS(TemplateInfo, property_accessors, Object, kPropertyAccessorsOffset)
5319
5320 ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
5321 ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
5322 ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
5323           kPrototypeTemplateOffset)
5324 ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
5325 ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
5326           kNamedPropertyHandlerOffset)
5327 ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
5328           kIndexedPropertyHandlerOffset)
5329 ACCESSORS(FunctionTemplateInfo, instance_template, Object,
5330           kInstanceTemplateOffset)
5331 ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
5332 ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
5333 ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
5334           kInstanceCallHandlerOffset)
5335 ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
5336           kAccessCheckInfoOffset)
5337 ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
5338
5339 ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
5340 ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
5341           kInternalFieldCountOffset)
5342
5343 ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
5344 ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
5345
5346 ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
5347
5348 ACCESSORS(AllocationSite, transition_info, Object, kTransitionInfoOffset)
5349 ACCESSORS(AllocationSite, nested_site, Object, kNestedSiteOffset)
5350 ACCESSORS_TO_SMI(AllocationSite, pretenure_data, kPretenureDataOffset)
5351 ACCESSORS_TO_SMI(AllocationSite, pretenure_create_count,
5352                  kPretenureCreateCountOffset)
5353 ACCESSORS(AllocationSite, dependent_code, DependentCode,
5354           kDependentCodeOffset)
5355 ACCESSORS(AllocationSite, weak_next, Object, kWeakNextOffset)
5356 ACCESSORS(AllocationMemento, allocation_site, Object, kAllocationSiteOffset)
5357
5358 ACCESSORS(Script, source, Object, kSourceOffset)
5359 ACCESSORS(Script, name, Object, kNameOffset)
5360 ACCESSORS(Script, id, Smi, kIdOffset)
5361 ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
5362 ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
5363 ACCESSORS(Script, context_data, Object, kContextOffset)
5364 ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
5365 ACCESSORS_TO_SMI(Script, type, kTypeOffset)
5366 ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
5367 ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
5368 ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
5369                  kEvalFrominstructionsOffsetOffset)
5370 ACCESSORS_TO_SMI(Script, flags, kFlagsOffset)
5371 BOOL_ACCESSORS(Script, flags, is_shared_cross_origin, kIsSharedCrossOriginBit)
5372 ACCESSORS(Script, source_url, Object, kSourceUrlOffset)
5373 ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset)
5374
5375 Script::CompilationType Script::compilation_type() {
5376   return BooleanBit::get(flags(), kCompilationTypeBit) ?
5377       COMPILATION_TYPE_EVAL : COMPILATION_TYPE_HOST;
5378 }
5379 void Script::set_compilation_type(CompilationType type) {
5380   set_flags(BooleanBit::set(flags(), kCompilationTypeBit,
5381       type == COMPILATION_TYPE_EVAL));
5382 }
5383 Script::CompilationState Script::compilation_state() {
5384   return BooleanBit::get(flags(), kCompilationStateBit) ?
5385       COMPILATION_STATE_COMPILED : COMPILATION_STATE_INITIAL;
5386 }
5387 void Script::set_compilation_state(CompilationState state) {
5388   set_flags(BooleanBit::set(flags(), kCompilationStateBit,
5389       state == COMPILATION_STATE_COMPILED));
5390 }
5391
5392
5393 ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
5394 ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
5395 ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
5396 ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
5397
5398 ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
5399 ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
5400 ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
5401 ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
5402
5403 ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
5404 ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
5405                  kOptimizedCodeMapOffset)
5406 ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
5407 ACCESSORS(SharedFunctionInfo, feedback_vector, TypeFeedbackVector,
5408           kFeedbackVectorOffset)
5409 ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
5410           kInstanceClassNameOffset)
5411 ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
5412 ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
5413 ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
5414 ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
5415
5416
5417 SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
5418 BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
5419                kHiddenPrototypeBit)
5420 BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
5421 BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
5422                kNeedsAccessCheckBit)
5423 BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
5424                kReadOnlyPrototypeBit)
5425 BOOL_ACCESSORS(FunctionTemplateInfo, flag, remove_prototype,
5426                kRemovePrototypeBit)
5427 BOOL_ACCESSORS(FunctionTemplateInfo, flag, do_not_cache,
5428                kDoNotCacheBit)
5429 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
5430                kIsExpressionBit)
5431 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
5432                kIsTopLevelBit)
5433
5434 BOOL_ACCESSORS(SharedFunctionInfo,
5435                compiler_hints,
5436                allows_lazy_compilation,
5437                kAllowLazyCompilation)
5438 BOOL_ACCESSORS(SharedFunctionInfo,
5439                compiler_hints,
5440                allows_lazy_compilation_without_context,
5441                kAllowLazyCompilationWithoutContext)
5442 BOOL_ACCESSORS(SharedFunctionInfo,
5443                compiler_hints,
5444                uses_arguments,
5445                kUsesArguments)
5446 BOOL_ACCESSORS(SharedFunctionInfo,
5447                compiler_hints,
5448                has_duplicate_parameters,
5449                kHasDuplicateParameters)
5450 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, asm_function, kIsAsmFunction)
5451
5452
5453 #if V8_HOST_ARCH_32_BIT
5454 SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
5455 SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
5456               kFormalParameterCountOffset)
5457 SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
5458               kExpectedNofPropertiesOffset)
5459 SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
5460 SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
5461               kStartPositionAndTypeOffset)
5462 SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
5463 SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
5464               kFunctionTokenPositionOffset)
5465 SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
5466               kCompilerHintsOffset)
5467 SMI_ACCESSORS(SharedFunctionInfo, opt_count_and_bailout_reason,
5468               kOptCountAndBailoutReasonOffset)
5469 SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
5470 SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
5471 SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
5472
5473 #else
5474
5475 #define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset)             \
5476   STATIC_ASSERT(holder::offset % kPointerSize == 0);              \
5477   int holder::name() const {                                      \
5478     int value = READ_INT_FIELD(this, offset);                     \
5479     DCHECK(kHeapObjectTag == 1);                                  \
5480     DCHECK((value & kHeapObjectTag) == 0);                        \
5481     return value >> 1;                                            \
5482   }                                                               \
5483   void holder::set_##name(int value) {                            \
5484     DCHECK(kHeapObjectTag == 1);                                  \
5485     DCHECK((value & 0xC0000000) == 0xC0000000 ||                  \
5486            (value & 0xC0000000) == 0x0);                          \
5487     WRITE_INT_FIELD(this,                                         \
5488                     offset,                                       \
5489                     (value << 1) & ~kHeapObjectTag);              \
5490   }
5491
5492 #define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset)             \
5493   STATIC_ASSERT(holder::offset % kPointerSize == kIntSize);       \
5494   INT_ACCESSORS(holder, name, offset)
5495
5496
5497 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
5498 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5499                         formal_parameter_count,
5500                         kFormalParameterCountOffset)
5501
5502 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5503                         expected_nof_properties,
5504                         kExpectedNofPropertiesOffset)
5505 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
5506
5507 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
5508 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5509                         start_position_and_type,
5510                         kStartPositionAndTypeOffset)
5511
5512 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5513                         function_token_position,
5514                         kFunctionTokenPositionOffset)
5515 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5516                         compiler_hints,
5517                         kCompilerHintsOffset)
5518
5519 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5520                         opt_count_and_bailout_reason,
5521                         kOptCountAndBailoutReasonOffset)
5522 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, counters, kCountersOffset)
5523
5524 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5525                         ast_node_count,
5526                         kAstNodeCountOffset)
5527 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5528                         profiler_ticks,
5529                         kProfilerTicksOffset)
5530
5531 #endif
5532
5533
5534 BOOL_GETTER(SharedFunctionInfo,
5535             compiler_hints,
5536             optimization_disabled,
5537             kOptimizationDisabled)
5538
5539
5540 void SharedFunctionInfo::set_optimization_disabled(bool disable) {
5541   set_compiler_hints(BooleanBit::set(compiler_hints(),
5542                                      kOptimizationDisabled,
5543                                      disable));
5544   // If disabling optimizations we reflect that in the code object so
5545   // it will not be counted as optimizable code.
5546   if ((code()->kind() == Code::FUNCTION) && disable) {
5547     code()->set_optimizable(false);
5548   }
5549 }
5550
5551
5552 StrictMode SharedFunctionInfo::strict_mode() {
5553   return BooleanBit::get(compiler_hints(), kStrictModeFunction)
5554       ? STRICT : SLOPPY;
5555 }
5556
5557
5558 void SharedFunctionInfo::set_strict_mode(StrictMode strict_mode) {
5559   // We only allow mode transitions from sloppy to strict.
5560   DCHECK(this->strict_mode() == SLOPPY || this->strict_mode() == strict_mode);
5561   int hints = compiler_hints();
5562   hints = BooleanBit::set(hints, kStrictModeFunction, strict_mode == STRICT);
5563   set_compiler_hints(hints);
5564 }
5565
5566
5567 FunctionKind SharedFunctionInfo::kind() {
5568   return FunctionKindBits::decode(compiler_hints());
5569 }
5570
5571
5572 void SharedFunctionInfo::set_kind(FunctionKind kind) {
5573   DCHECK(IsValidFunctionKind(kind));
5574   int hints = compiler_hints();
5575   hints = FunctionKindBits::update(hints, kind);
5576   set_compiler_hints(hints);
5577 }
5578
5579
5580 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
5581 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, inline_builtin,
5582                kInlineBuiltin)
5583 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
5584                name_should_print_as_anonymous,
5585                kNameShouldPrintAsAnonymous)
5586 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
5587 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
5588 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
5589 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
5590 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_flush, kDontFlush)
5591 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_arrow, kIsArrow)
5592 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator)
5593 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_concise_method,
5594                kIsConciseMethod)
5595
5596 ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
5597 ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
5598
5599 ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
5600
5601 bool Script::HasValidSource() {
5602   Object* src = this->source();
5603   if (!src->IsString()) return true;
5604   String* src_str = String::cast(src);
5605   if (!StringShape(src_str).IsExternal()) return true;
5606   if (src_str->IsOneByteRepresentation()) {
5607     return ExternalOneByteString::cast(src)->resource() != NULL;
5608   } else if (src_str->IsTwoByteRepresentation()) {
5609     return ExternalTwoByteString::cast(src)->resource() != NULL;
5610   }
5611   return true;
5612 }
5613
5614
5615 void SharedFunctionInfo::DontAdaptArguments() {
5616   DCHECK(code()->kind() == Code::BUILTIN);
5617   set_formal_parameter_count(kDontAdaptArgumentsSentinel);
5618 }
5619
5620
5621 int SharedFunctionInfo::start_position() const {
5622   return start_position_and_type() >> kStartPositionShift;
5623 }
5624
5625
5626 void SharedFunctionInfo::set_start_position(int start_position) {
5627   set_start_position_and_type((start_position << kStartPositionShift)
5628     | (start_position_and_type() & ~kStartPositionMask));
5629 }
5630
5631
5632 Code* SharedFunctionInfo::code() const {
5633   return Code::cast(READ_FIELD(this, kCodeOffset));
5634 }
5635
5636
5637 void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
5638   DCHECK(value->kind() != Code::OPTIMIZED_FUNCTION);
5639   WRITE_FIELD(this, kCodeOffset, value);
5640   CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
5641 }
5642
5643
5644 void SharedFunctionInfo::ReplaceCode(Code* value) {
5645   // If the GC metadata field is already used then the function was
5646   // enqueued as a code flushing candidate and we remove it now.
5647   if (code()->gc_metadata() != NULL) {
5648     CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
5649     flusher->EvictCandidate(this);
5650   }
5651
5652   DCHECK(code()->gc_metadata() == NULL && value->gc_metadata() == NULL);
5653
5654   set_code(value);
5655 }
5656
5657
5658 ScopeInfo* SharedFunctionInfo::scope_info() const {
5659   return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
5660 }
5661
5662
5663 void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
5664                                         WriteBarrierMode mode) {
5665   WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
5666   CONDITIONAL_WRITE_BARRIER(GetHeap(),
5667                             this,
5668                             kScopeInfoOffset,
5669                             reinterpret_cast<Object*>(value),
5670                             mode);
5671 }
5672
5673
5674 bool SharedFunctionInfo::is_compiled() {
5675   return code() != GetIsolate()->builtins()->builtin(Builtins::kCompileLazy);
5676 }
5677
5678
5679 bool SharedFunctionInfo::IsApiFunction() {
5680   return function_data()->IsFunctionTemplateInfo();
5681 }
5682
5683
5684 FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
5685   DCHECK(IsApiFunction());
5686   return FunctionTemplateInfo::cast(function_data());
5687 }
5688
5689
5690 bool SharedFunctionInfo::HasBuiltinFunctionId() {
5691   return function_data()->IsSmi();
5692 }
5693
5694
5695 BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
5696   DCHECK(HasBuiltinFunctionId());
5697   return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
5698 }
5699
5700
5701 int SharedFunctionInfo::ic_age() {
5702   return ICAgeBits::decode(counters());
5703 }
5704
5705
5706 void SharedFunctionInfo::set_ic_age(int ic_age) {
5707   set_counters(ICAgeBits::update(counters(), ic_age));
5708 }
5709
5710
5711 int SharedFunctionInfo::deopt_count() {
5712   return DeoptCountBits::decode(counters());
5713 }
5714
5715
5716 void SharedFunctionInfo::set_deopt_count(int deopt_count) {
5717   set_counters(DeoptCountBits::update(counters(), deopt_count));
5718 }
5719
5720
5721 void SharedFunctionInfo::increment_deopt_count() {
5722   int value = counters();
5723   int deopt_count = DeoptCountBits::decode(value);
5724   deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
5725   set_counters(DeoptCountBits::update(value, deopt_count));
5726 }
5727
5728
5729 int SharedFunctionInfo::opt_reenable_tries() {
5730   return OptReenableTriesBits::decode(counters());
5731 }
5732
5733
5734 void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
5735   set_counters(OptReenableTriesBits::update(counters(), tries));
5736 }
5737
5738
5739 int SharedFunctionInfo::opt_count() {
5740   return OptCountBits::decode(opt_count_and_bailout_reason());
5741 }
5742
5743
5744 void SharedFunctionInfo::set_opt_count(int opt_count) {
5745   set_opt_count_and_bailout_reason(
5746       OptCountBits::update(opt_count_and_bailout_reason(), opt_count));
5747 }
5748
5749
5750 BailoutReason SharedFunctionInfo::DisableOptimizationReason() {
5751   BailoutReason reason = static_cast<BailoutReason>(
5752       DisabledOptimizationReasonBits::decode(opt_count_and_bailout_reason()));
5753   return reason;
5754 }
5755
5756
5757 bool SharedFunctionInfo::has_deoptimization_support() {
5758   Code* code = this->code();
5759   return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
5760 }
5761
5762
5763 void SharedFunctionInfo::TryReenableOptimization() {
5764   int tries = opt_reenable_tries();
5765   set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
5766   // We reenable optimization whenever the number of tries is a large
5767   // enough power of 2.
5768   if (tries >= 16 && (((tries - 1) & tries) == 0)) {
5769     set_optimization_disabled(false);
5770     set_opt_count(0);
5771     set_deopt_count(0);
5772     code()->set_optimizable(true);
5773   }
5774 }
5775
5776
5777 bool JSFunction::IsBuiltin() {
5778   return context()->global_object()->IsJSBuiltinsObject();
5779 }
5780
5781
5782 bool JSFunction::IsFromNativeScript() {
5783   Object* script = shared()->script();
5784   bool native = script->IsScript() &&
5785                 Script::cast(script)->type()->value() == Script::TYPE_NATIVE;
5786   DCHECK(!IsBuiltin() || native);  // All builtins are also native.
5787   return native;
5788 }
5789
5790
5791 bool JSFunction::IsFromExtensionScript() {
5792   Object* script = shared()->script();
5793   return script->IsScript() &&
5794          Script::cast(script)->type()->value() == Script::TYPE_EXTENSION;
5795 }
5796
5797
5798 bool JSFunction::NeedsArgumentsAdaption() {
5799   return shared()->formal_parameter_count() !=
5800       SharedFunctionInfo::kDontAdaptArgumentsSentinel;
5801 }
5802
5803
5804 bool JSFunction::IsOptimized() {
5805   return code()->kind() == Code::OPTIMIZED_FUNCTION;
5806 }
5807
5808
5809 bool JSFunction::IsOptimizable() {
5810   return code()->kind() == Code::FUNCTION && code()->optimizable();
5811 }
5812
5813
5814 bool JSFunction::IsMarkedForOptimization() {
5815   return code() == GetIsolate()->builtins()->builtin(
5816       Builtins::kCompileOptimized);
5817 }
5818
5819
5820 bool JSFunction::IsMarkedForConcurrentOptimization() {
5821   return code() == GetIsolate()->builtins()->builtin(
5822       Builtins::kCompileOptimizedConcurrent);
5823 }
5824
5825
5826 bool JSFunction::IsInOptimizationQueue() {
5827   return code() == GetIsolate()->builtins()->builtin(
5828       Builtins::kInOptimizationQueue);
5829 }
5830
5831
5832 bool JSFunction::IsInobjectSlackTrackingInProgress() {
5833   return has_initial_map() &&
5834       initial_map()->construction_count() != JSFunction::kNoSlackTracking;
5835 }
5836
5837
5838 Code* JSFunction::code() {
5839   return Code::cast(
5840       Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
5841 }
5842
5843
5844 void JSFunction::set_code(Code* value) {
5845   DCHECK(!GetHeap()->InNewSpace(value));
5846   Address entry = value->entry();
5847   WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
5848   GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
5849       this,
5850       HeapObject::RawField(this, kCodeEntryOffset),
5851       value);
5852 }
5853
5854
5855 void JSFunction::set_code_no_write_barrier(Code* value) {
5856   DCHECK(!GetHeap()->InNewSpace(value));
5857   Address entry = value->entry();
5858   WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
5859 }
5860
5861
5862 void JSFunction::ReplaceCode(Code* code) {
5863   bool was_optimized = IsOptimized();
5864   bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
5865
5866   if (was_optimized && is_optimized) {
5867     shared()->EvictFromOptimizedCodeMap(this->code(),
5868         "Replacing with another optimized code");
5869   }
5870
5871   set_code(code);
5872
5873   // Add/remove the function from the list of optimized functions for this
5874   // context based on the state change.
5875   if (!was_optimized && is_optimized) {
5876     context()->native_context()->AddOptimizedFunction(this);
5877   }
5878   if (was_optimized && !is_optimized) {
5879     // TODO(titzer): linear in the number of optimized functions; fix!
5880     context()->native_context()->RemoveOptimizedFunction(this);
5881   }
5882 }
5883
5884
5885 Context* JSFunction::context() {
5886   return Context::cast(READ_FIELD(this, kContextOffset));
5887 }
5888
5889
5890 JSObject* JSFunction::global_proxy() {
5891   return context()->global_proxy();
5892 }
5893
5894
5895 void JSFunction::set_context(Object* value) {
5896   DCHECK(value->IsUndefined() || value->IsContext());
5897   WRITE_FIELD(this, kContextOffset, value);
5898   WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
5899 }
5900
5901 ACCESSORS(JSFunction, prototype_or_initial_map, Object,
5902           kPrototypeOrInitialMapOffset)
5903
5904
5905 Map* JSFunction::initial_map() {
5906   return Map::cast(prototype_or_initial_map());
5907 }
5908
5909
5910 bool JSFunction::has_initial_map() {
5911   return prototype_or_initial_map()->IsMap();
5912 }
5913
5914
5915 bool JSFunction::has_instance_prototype() {
5916   return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
5917 }
5918
5919
5920 bool JSFunction::has_prototype() {
5921   return map()->has_non_instance_prototype() || has_instance_prototype();
5922 }
5923
5924
5925 Object* JSFunction::instance_prototype() {
5926   DCHECK(has_instance_prototype());
5927   if (has_initial_map()) return initial_map()->prototype();
5928   // When there is no initial map and the prototype is a JSObject, the
5929   // initial map field is used for the prototype field.
5930   return prototype_or_initial_map();
5931 }
5932
5933
5934 Object* JSFunction::prototype() {
5935   DCHECK(has_prototype());
5936   // If the function's prototype property has been set to a non-JSObject
5937   // value, that value is stored in the constructor field of the map.
5938   if (map()->has_non_instance_prototype()) return map()->constructor();
5939   return instance_prototype();
5940 }
5941
5942
5943 bool JSFunction::should_have_prototype() {
5944   return map()->function_with_prototype();
5945 }
5946
5947
5948 bool JSFunction::is_compiled() {
5949   return code() != GetIsolate()->builtins()->builtin(Builtins::kCompileLazy);
5950 }
5951
5952
5953 FixedArray* JSFunction::literals() {
5954   DCHECK(!shared()->bound());
5955   return literals_or_bindings();
5956 }
5957
5958
5959 void JSFunction::set_literals(FixedArray* literals) {
5960   DCHECK(!shared()->bound());
5961   set_literals_or_bindings(literals);
5962 }
5963
5964
5965 FixedArray* JSFunction::function_bindings() {
5966   DCHECK(shared()->bound());
5967   return literals_or_bindings();
5968 }
5969
5970
5971 void JSFunction::set_function_bindings(FixedArray* bindings) {
5972   DCHECK(shared()->bound());
5973   // Bound function literal may be initialized to the empty fixed array
5974   // before the bindings are set.
5975   DCHECK(bindings == GetHeap()->empty_fixed_array() ||
5976          bindings->map() == GetHeap()->fixed_cow_array_map());
5977   set_literals_or_bindings(bindings);
5978 }
5979
5980
5981 int JSFunction::NumberOfLiterals() {
5982   DCHECK(!shared()->bound());
5983   return literals()->length();
5984 }
5985
5986
5987 Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
5988   DCHECK(id < kJSBuiltinsCount);  // id is unsigned.
5989   return READ_FIELD(this, OffsetOfFunctionWithId(id));
5990 }
5991
5992
5993 void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
5994                                               Object* value) {
5995   DCHECK(id < kJSBuiltinsCount);  // id is unsigned.
5996   WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
5997   WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
5998 }
5999
6000
6001 Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
6002   DCHECK(id < kJSBuiltinsCount);  // id is unsigned.
6003   return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
6004 }
6005
6006
6007 void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
6008                                                    Code* value) {
6009   DCHECK(id < kJSBuiltinsCount);  // id is unsigned.
6010   WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
6011   DCHECK(!GetHeap()->InNewSpace(value));
6012 }
6013
6014
6015 ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
6016 ACCESSORS(JSProxy, hash, Object, kHashOffset)
6017 ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
6018 ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
6019
6020
6021 void JSProxy::InitializeBody(int object_size, Object* value) {
6022   DCHECK(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
6023   for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
6024     WRITE_FIELD(this, offset, value);
6025   }
6026 }
6027
6028
6029 ACCESSORS(JSCollection, table, Object, kTableOffset)
6030
6031
6032 #define ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(name, type, offset)    \
6033   template<class Derived, class TableType>                           \
6034   type* OrderedHashTableIterator<Derived, TableType>::name() const { \
6035     return type::cast(READ_FIELD(this, offset));                     \
6036   }                                                                  \
6037   template<class Derived, class TableType>                           \
6038   void OrderedHashTableIterator<Derived, TableType>::set_##name(     \
6039       type* value, WriteBarrierMode mode) {                          \
6040     WRITE_FIELD(this, offset, value);                                \
6041     CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
6042   }
6043
6044 ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(table, Object, kTableOffset)
6045 ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(index, Object, kIndexOffset)
6046 ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(kind, Object, kKindOffset)
6047
6048 #undef ORDERED_HASH_TABLE_ITERATOR_ACCESSORS
6049
6050
6051 ACCESSORS(JSWeakCollection, table, Object, kTableOffset)
6052 ACCESSORS(JSWeakCollection, next, Object, kNextOffset)
6053
6054
6055 Address Foreign::foreign_address() {
6056   return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
6057 }
6058
6059
6060 void Foreign::set_foreign_address(Address value) {
6061   WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
6062 }
6063
6064
6065 ACCESSORS(JSGeneratorObject, function, JSFunction, kFunctionOffset)
6066 ACCESSORS(JSGeneratorObject, context, Context, kContextOffset)
6067 ACCESSORS(JSGeneratorObject, receiver, Object, kReceiverOffset)
6068 SMI_ACCESSORS(JSGeneratorObject, continuation, kContinuationOffset)
6069 ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset)
6070 SMI_ACCESSORS(JSGeneratorObject, stack_handler_index, kStackHandlerIndexOffset)
6071
6072 bool JSGeneratorObject::is_suspended() {
6073   DCHECK_LT(kGeneratorExecuting, kGeneratorClosed);
6074   DCHECK_EQ(kGeneratorClosed, 0);
6075   return continuation() > 0;
6076 }
6077
6078 bool JSGeneratorObject::is_closed() {
6079   return continuation() == kGeneratorClosed;
6080 }
6081
6082 bool JSGeneratorObject::is_executing() {
6083   return continuation() == kGeneratorExecuting;
6084 }
6085
6086 ACCESSORS(JSModule, context, Object, kContextOffset)
6087 ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
6088
6089
6090 ACCESSORS(JSValue, value, Object, kValueOffset)
6091
6092
6093 HeapNumber* HeapNumber::cast(Object* object) {
6094   SLOW_DCHECK(object->IsHeapNumber() || object->IsMutableHeapNumber());
6095   return reinterpret_cast<HeapNumber*>(object);
6096 }
6097
6098
6099 const HeapNumber* HeapNumber::cast(const Object* object) {
6100   SLOW_DCHECK(object->IsHeapNumber() || object->IsMutableHeapNumber());
6101   return reinterpret_cast<const HeapNumber*>(object);
6102 }
6103
6104
6105 ACCESSORS(JSDate, value, Object, kValueOffset)
6106 ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
6107 ACCESSORS(JSDate, year, Object, kYearOffset)
6108 ACCESSORS(JSDate, month, Object, kMonthOffset)
6109 ACCESSORS(JSDate, day, Object, kDayOffset)
6110 ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
6111 ACCESSORS(JSDate, hour, Object, kHourOffset)
6112 ACCESSORS(JSDate, min, Object, kMinOffset)
6113 ACCESSORS(JSDate, sec, Object, kSecOffset)
6114
6115
6116 ACCESSORS(JSMessageObject, type, String, kTypeOffset)
6117 ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
6118 ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
6119 ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
6120 SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
6121 SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
6122
6123
6124 INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
6125 INT_ACCESSORS(Code, prologue_offset, kPrologueOffset)
6126 ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
6127 ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
6128 ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
6129 ACCESSORS(Code, raw_type_feedback_info, Object, kTypeFeedbackInfoOffset)
6130 ACCESSORS(Code, next_code_link, Object, kNextCodeLinkOffset)
6131
6132
6133 void Code::WipeOutHeader() {
6134   WRITE_FIELD(this, kRelocationInfoOffset, NULL);
6135   WRITE_FIELD(this, kHandlerTableOffset, NULL);
6136   WRITE_FIELD(this, kDeoptimizationDataOffset, NULL);
6137   WRITE_FIELD(this, kConstantPoolOffset, NULL);
6138   // Do not wipe out major/minor keys on a code stub or IC
6139   if (!READ_FIELD(this, kTypeFeedbackInfoOffset)->IsSmi()) {
6140     WRITE_FIELD(this, kTypeFeedbackInfoOffset, NULL);
6141   }
6142 }
6143
6144
6145 Object* Code::type_feedback_info() {
6146   DCHECK(kind() == FUNCTION);
6147   return raw_type_feedback_info();
6148 }
6149
6150
6151 void Code::set_type_feedback_info(Object* value, WriteBarrierMode mode) {
6152   DCHECK(kind() == FUNCTION);
6153   set_raw_type_feedback_info(value, mode);
6154   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kTypeFeedbackInfoOffset,
6155                             value, mode);
6156 }
6157
6158
6159 uint32_t Code::stub_key() {
6160   DCHECK(IsCodeStubOrIC());
6161   Smi* smi_key = Smi::cast(raw_type_feedback_info());
6162   return static_cast<uint32_t>(smi_key->value());
6163 }
6164
6165
6166 void Code::set_stub_key(uint32_t key) {
6167   DCHECK(IsCodeStubOrIC());
6168   set_raw_type_feedback_info(Smi::FromInt(key));
6169 }
6170
6171
6172 ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
6173 INT_ACCESSORS(Code, ic_age, kICAgeOffset)
6174
6175
6176 byte* Code::instruction_start()  {
6177   return FIELD_ADDR(this, kHeaderSize);
6178 }
6179
6180
6181 byte* Code::instruction_end()  {
6182   return instruction_start() + instruction_size();
6183 }
6184
6185
6186 int Code::body_size() {
6187   return RoundUp(instruction_size(), kObjectAlignment);
6188 }
6189
6190
6191 ByteArray* Code::unchecked_relocation_info() {
6192   return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
6193 }
6194
6195
6196 byte* Code::relocation_start() {
6197   return unchecked_relocation_info()->GetDataStartAddress();
6198 }
6199
6200
6201 int Code::relocation_size() {
6202   return unchecked_relocation_info()->length();
6203 }
6204
6205
6206 byte* Code::entry() {
6207   return instruction_start();
6208 }
6209
6210
6211 bool Code::contains(byte* inner_pointer) {
6212   return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
6213 }
6214
6215
6216 ACCESSORS(JSArray, length, Object, kLengthOffset)
6217
6218
6219 void* JSArrayBuffer::backing_store() const {
6220   intptr_t ptr = READ_INTPTR_FIELD(this, kBackingStoreOffset);
6221   return reinterpret_cast<void*>(ptr);
6222 }
6223
6224
6225 void JSArrayBuffer::set_backing_store(void* value, WriteBarrierMode mode) {
6226   intptr_t ptr = reinterpret_cast<intptr_t>(value);
6227   WRITE_INTPTR_FIELD(this, kBackingStoreOffset, ptr);
6228 }
6229
6230
6231 ACCESSORS(JSArrayBuffer, byte_length, Object, kByteLengthOffset)
6232 ACCESSORS_TO_SMI(JSArrayBuffer, flag, kFlagOffset)
6233
6234
6235 bool JSArrayBuffer::is_external() {
6236   return BooleanBit::get(flag(), kIsExternalBit);
6237 }
6238
6239
6240 void JSArrayBuffer::set_is_external(bool value) {
6241   set_flag(BooleanBit::set(flag(), kIsExternalBit, value));
6242 }
6243
6244
6245 bool JSArrayBuffer::should_be_freed() {
6246   return BooleanBit::get(flag(), kShouldBeFreed);
6247 }
6248
6249
6250 void JSArrayBuffer::set_should_be_freed(bool value) {
6251   set_flag(BooleanBit::set(flag(), kShouldBeFreed, value));
6252 }
6253
6254
6255 ACCESSORS(JSArrayBuffer, weak_next, Object, kWeakNextOffset)
6256 ACCESSORS(JSArrayBuffer, weak_first_view, Object, kWeakFirstViewOffset)
6257
6258
6259 ACCESSORS(JSArrayBufferView, buffer, Object, kBufferOffset)
6260 ACCESSORS(JSArrayBufferView, byte_offset, Object, kByteOffsetOffset)
6261 ACCESSORS(JSArrayBufferView, byte_length, Object, kByteLengthOffset)
6262 ACCESSORS(JSArrayBufferView, weak_next, Object, kWeakNextOffset)
6263 ACCESSORS(JSTypedArray, length, Object, kLengthOffset)
6264
6265 ACCESSORS(JSRegExp, data, Object, kDataOffset)
6266
6267
6268 JSRegExp::Type JSRegExp::TypeTag() {
6269   Object* data = this->data();
6270   if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
6271   Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
6272   return static_cast<JSRegExp::Type>(smi->value());
6273 }
6274
6275
6276 int JSRegExp::CaptureCount() {
6277   switch (TypeTag()) {
6278     case ATOM:
6279       return 0;
6280     case IRREGEXP:
6281       return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
6282     default:
6283       UNREACHABLE();
6284       return -1;
6285   }
6286 }
6287
6288
6289 JSRegExp::Flags JSRegExp::GetFlags() {
6290   DCHECK(this->data()->IsFixedArray());
6291   Object* data = this->data();
6292   Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
6293   return Flags(smi->value());
6294 }
6295
6296
6297 String* JSRegExp::Pattern() {
6298   DCHECK(this->data()->IsFixedArray());
6299   Object* data = this->data();
6300   String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
6301   return pattern;
6302 }
6303
6304
6305 Object* JSRegExp::DataAt(int index) {
6306   DCHECK(TypeTag() != NOT_COMPILED);
6307   return FixedArray::cast(data())->get(index);
6308 }
6309
6310
6311 void JSRegExp::SetDataAt(int index, Object* value) {
6312   DCHECK(TypeTag() != NOT_COMPILED);
6313   DCHECK(index >= kDataIndex);  // Only implementation data can be set this way.
6314   FixedArray::cast(data())->set(index, value);
6315 }
6316
6317
6318 ElementsKind JSObject::GetElementsKind() {
6319   ElementsKind kind = map()->elements_kind();
6320 #if DEBUG
6321   FixedArrayBase* fixed_array =
6322       reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
6323
6324   // If a GC was caused while constructing this object, the elements
6325   // pointer may point to a one pointer filler map.
6326   if (ElementsAreSafeToExamine()) {
6327     Map* map = fixed_array->map();
6328     DCHECK((IsFastSmiOrObjectElementsKind(kind) &&
6329             (map == GetHeap()->fixed_array_map() ||
6330              map == GetHeap()->fixed_cow_array_map())) ||
6331            (IsFastDoubleElementsKind(kind) &&
6332             (fixed_array->IsFixedDoubleArray() ||
6333              fixed_array == GetHeap()->empty_fixed_array())) ||
6334            (kind == DICTIONARY_ELEMENTS &&
6335             fixed_array->IsFixedArray() &&
6336             fixed_array->IsDictionary()) ||
6337            (kind > DICTIONARY_ELEMENTS));
6338     DCHECK((kind != SLOPPY_ARGUMENTS_ELEMENTS) ||
6339            (elements()->IsFixedArray() && elements()->length() >= 2));
6340   }
6341 #endif
6342   return kind;
6343 }
6344
6345
6346 ElementsAccessor* JSObject::GetElementsAccessor() {
6347   return ElementsAccessor::ForKind(GetElementsKind());
6348 }
6349
6350
6351 bool JSObject::HasFastObjectElements() {
6352   return IsFastObjectElementsKind(GetElementsKind());
6353 }
6354
6355
6356 bool JSObject::HasFastSmiElements() {
6357   return IsFastSmiElementsKind(GetElementsKind());
6358 }
6359
6360
6361 bool JSObject::HasFastSmiOrObjectElements() {
6362   return IsFastSmiOrObjectElementsKind(GetElementsKind());
6363 }
6364
6365
6366 bool JSObject::HasFastDoubleElements() {
6367   return IsFastDoubleElementsKind(GetElementsKind());
6368 }
6369
6370
6371 bool JSObject::HasFastHoleyElements() {
6372   return IsFastHoleyElementsKind(GetElementsKind());
6373 }
6374
6375
6376 bool JSObject::HasFastElements() {
6377   return IsFastElementsKind(GetElementsKind());
6378 }
6379
6380
6381 bool JSObject::HasDictionaryElements() {
6382   return GetElementsKind() == DICTIONARY_ELEMENTS;
6383 }
6384
6385
6386 bool JSObject::HasSloppyArgumentsElements() {
6387   return GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS;
6388 }
6389
6390
6391 bool JSObject::HasExternalArrayElements() {
6392   HeapObject* array = elements();
6393   DCHECK(array != NULL);
6394   return array->IsExternalArray();
6395 }
6396
6397
6398 #define EXTERNAL_ELEMENTS_CHECK(Type, type, TYPE, ctype, size)          \
6399 bool JSObject::HasExternal##Type##Elements() {                          \
6400   HeapObject* array = elements();                                       \
6401   DCHECK(array != NULL);                                                \
6402   if (!array->IsHeapObject())                                           \
6403     return false;                                                       \
6404   return array->map()->instance_type() == EXTERNAL_##TYPE##_ARRAY_TYPE; \
6405 }
6406
6407 TYPED_ARRAYS(EXTERNAL_ELEMENTS_CHECK)
6408
6409 #undef EXTERNAL_ELEMENTS_CHECK
6410
6411
6412 bool JSObject::HasFixedTypedArrayElements() {
6413   HeapObject* array = elements();
6414   DCHECK(array != NULL);
6415   return array->IsFixedTypedArrayBase();
6416 }
6417
6418
6419 #define FIXED_TYPED_ELEMENTS_CHECK(Type, type, TYPE, ctype, size)         \
6420 bool JSObject::HasFixed##Type##Elements() {                               \
6421   HeapObject* array = elements();                                         \
6422   DCHECK(array != NULL);                                                  \
6423   if (!array->IsHeapObject())                                             \
6424     return false;                                                         \
6425   return array->map()->instance_type() == FIXED_##TYPE##_ARRAY_TYPE;      \
6426 }
6427
6428 TYPED_ARRAYS(FIXED_TYPED_ELEMENTS_CHECK)
6429
6430 #undef FIXED_TYPED_ELEMENTS_CHECK
6431
6432
6433 bool JSObject::HasNamedInterceptor() {
6434   return map()->has_named_interceptor();
6435 }
6436
6437
6438 bool JSObject::HasIndexedInterceptor() {
6439   return map()->has_indexed_interceptor();
6440 }
6441
6442
6443 NameDictionary* JSObject::property_dictionary() {
6444   DCHECK(!HasFastProperties());
6445   return NameDictionary::cast(properties());
6446 }
6447
6448
6449 SeededNumberDictionary* JSObject::element_dictionary() {
6450   DCHECK(HasDictionaryElements());
6451   return SeededNumberDictionary::cast(elements());
6452 }
6453
6454
6455 bool Name::IsHashFieldComputed(uint32_t field) {
6456   return (field & kHashNotComputedMask) == 0;
6457 }
6458
6459
6460 bool Name::HasHashCode() {
6461   return IsHashFieldComputed(hash_field());
6462 }
6463
6464
6465 uint32_t Name::Hash() {
6466   // Fast case: has hash code already been computed?
6467   uint32_t field = hash_field();
6468   if (IsHashFieldComputed(field)) return field >> kHashShift;
6469   // Slow case: compute hash code and set it. Has to be a string.
6470   return String::cast(this)->ComputeAndSetHash();
6471 }
6472
6473 bool Name::IsOwn() {
6474   return this->IsSymbol() && Symbol::cast(this)->is_own();
6475 }
6476
6477
6478 StringHasher::StringHasher(int length, uint32_t seed)
6479   : length_(length),
6480     raw_running_hash_(seed),
6481     array_index_(0),
6482     is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
6483     is_first_char_(true) {
6484   DCHECK(FLAG_randomize_hashes || raw_running_hash_ == 0);
6485 }
6486
6487
6488 bool StringHasher::has_trivial_hash() {
6489   return length_ > String::kMaxHashCalcLength;
6490 }
6491
6492
6493 uint32_t StringHasher::AddCharacterCore(uint32_t running_hash, uint16_t c) {
6494   running_hash += c;
6495   running_hash += (running_hash << 10);
6496   running_hash ^= (running_hash >> 6);
6497   return running_hash;
6498 }
6499
6500
6501 uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
6502   running_hash += (running_hash << 3);
6503   running_hash ^= (running_hash >> 11);
6504   running_hash += (running_hash << 15);
6505   if ((running_hash & String::kHashBitMask) == 0) {
6506     return kZeroHash;
6507   }
6508   return running_hash;
6509 }
6510
6511
6512 void StringHasher::AddCharacter(uint16_t c) {
6513   // Use the Jenkins one-at-a-time hash function to update the hash
6514   // for the given character.
6515   raw_running_hash_ = AddCharacterCore(raw_running_hash_, c);
6516 }
6517
6518
6519 bool StringHasher::UpdateIndex(uint16_t c) {
6520   DCHECK(is_array_index_);
6521   if (c < '0' || c > '9') {
6522     is_array_index_ = false;
6523     return false;
6524   }
6525   int d = c - '0';
6526   if (is_first_char_) {
6527     is_first_char_ = false;
6528     if (c == '0' && length_ > 1) {
6529       is_array_index_ = false;
6530       return false;
6531     }
6532   }
6533   if (array_index_ > 429496729U - ((d + 2) >> 3)) {
6534     is_array_index_ = false;
6535     return false;
6536   }
6537   array_index_ = array_index_ * 10 + d;
6538   return true;
6539 }
6540
6541
6542 template<typename Char>
6543 inline void StringHasher::AddCharacters(const Char* chars, int length) {
6544   DCHECK(sizeof(Char) == 1 || sizeof(Char) == 2);
6545   int i = 0;
6546   if (is_array_index_) {
6547     for (; i < length; i++) {
6548       AddCharacter(chars[i]);
6549       if (!UpdateIndex(chars[i])) {
6550         i++;
6551         break;
6552       }
6553     }
6554   }
6555   for (; i < length; i++) {
6556     DCHECK(!is_array_index_);
6557     AddCharacter(chars[i]);
6558   }
6559 }
6560
6561
6562 template <typename schar>
6563 uint32_t StringHasher::HashSequentialString(const schar* chars,
6564                                             int length,
6565                                             uint32_t seed) {
6566   StringHasher hasher(length, seed);
6567   if (!hasher.has_trivial_hash()) hasher.AddCharacters(chars, length);
6568   return hasher.GetHashField();
6569 }
6570
6571
6572 uint32_t IteratingStringHasher::Hash(String* string, uint32_t seed) {
6573   IteratingStringHasher hasher(string->length(), seed);
6574   // Nothing to do.
6575   if (hasher.has_trivial_hash()) return hasher.GetHashField();
6576   ConsString* cons_string = String::VisitFlat(&hasher, string);
6577   // The string was flat.
6578   if (cons_string == NULL) return hasher.GetHashField();
6579   // This is a ConsString, iterate across it.
6580   ConsStringIteratorOp op(cons_string);
6581   int offset;
6582   while (NULL != (string = op.Next(&offset))) {
6583     String::VisitFlat(&hasher, string, offset);
6584   }
6585   return hasher.GetHashField();
6586 }
6587
6588
6589 void IteratingStringHasher::VisitOneByteString(const uint8_t* chars,
6590                                                int length) {
6591   AddCharacters(chars, length);
6592 }
6593
6594
6595 void IteratingStringHasher::VisitTwoByteString(const uint16_t* chars,
6596                                                int length) {
6597   AddCharacters(chars, length);
6598 }
6599
6600
6601 bool Name::AsArrayIndex(uint32_t* index) {
6602   return IsString() && String::cast(this)->AsArrayIndex(index);
6603 }
6604
6605
6606 bool String::AsArrayIndex(uint32_t* index) {
6607   uint32_t field = hash_field();
6608   if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
6609     return false;
6610   }
6611   return SlowAsArrayIndex(index);
6612 }
6613
6614
6615 void String::SetForwardedInternalizedString(String* canonical) {
6616   DCHECK(IsInternalizedString());
6617   DCHECK(HasHashCode());
6618   if (canonical == this) return;  // No need to forward.
6619   DCHECK(SlowEquals(canonical));
6620   DCHECK(canonical->IsInternalizedString());
6621   DCHECK(canonical->HasHashCode());
6622   WRITE_FIELD(this, kHashFieldOffset, canonical);
6623   // Setting the hash field to a tagged value sets the LSB, causing the hash
6624   // code to be interpreted as uninitialized.  We use this fact to recognize
6625   // that we have a forwarded string.
6626   DCHECK(!HasHashCode());
6627 }
6628
6629
6630 String* String::GetForwardedInternalizedString() {
6631   DCHECK(IsInternalizedString());
6632   if (HasHashCode()) return this;
6633   String* canonical = String::cast(READ_FIELD(this, kHashFieldOffset));
6634   DCHECK(canonical->IsInternalizedString());
6635   DCHECK(SlowEquals(canonical));
6636   DCHECK(canonical->HasHashCode());
6637   return canonical;
6638 }
6639
6640
6641 Object* JSReceiver::GetConstructor() {
6642   return map()->constructor();
6643 }
6644
6645
6646 Maybe<bool> JSReceiver::HasProperty(Handle<JSReceiver> object,
6647                                     Handle<Name> name) {
6648   if (object->IsJSProxy()) {
6649     Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
6650     return JSProxy::HasPropertyWithHandler(proxy, name);
6651   }
6652   Maybe<PropertyAttributes> result = GetPropertyAttributes(object, name);
6653   if (!result.has_value) return Maybe<bool>();
6654   return maybe(result.value != ABSENT);
6655 }
6656
6657
6658 Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object,
6659                                        Handle<Name> name) {
6660   if (object->IsJSProxy()) {
6661     Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
6662     return JSProxy::HasPropertyWithHandler(proxy, name);
6663   }
6664   Maybe<PropertyAttributes> result = GetOwnPropertyAttributes(object, name);
6665   if (!result.has_value) return Maybe<bool>();
6666   return maybe(result.value != ABSENT);
6667 }
6668
6669
6670 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
6671     Handle<JSReceiver> object, Handle<Name> key) {
6672   uint32_t index;
6673   if (object->IsJSObject() && key->AsArrayIndex(&index)) {
6674     return GetElementAttribute(object, index);
6675   }
6676   LookupIterator it(object, key);
6677   return GetPropertyAttributes(&it);
6678 }
6679
6680
6681 Maybe<PropertyAttributes> JSReceiver::GetElementAttribute(
6682     Handle<JSReceiver> object, uint32_t index) {
6683   if (object->IsJSProxy()) {
6684     return JSProxy::GetElementAttributeWithHandler(
6685         Handle<JSProxy>::cast(object), object, index);
6686   }
6687   return JSObject::GetElementAttributeWithReceiver(
6688       Handle<JSObject>::cast(object), object, index, true);
6689 }
6690
6691
6692 bool JSGlobalObject::IsDetached() {
6693   return JSGlobalProxy::cast(global_proxy())->IsDetachedFrom(this);
6694 }
6695
6696
6697 bool JSGlobalProxy::IsDetachedFrom(GlobalObject* global) const {
6698   const PrototypeIterator iter(this->GetIsolate(),
6699                                const_cast<JSGlobalProxy*>(this));
6700   return iter.GetCurrent() != global;
6701 }
6702
6703
6704 Handle<Smi> JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver> object) {
6705   return object->IsJSProxy()
6706       ? JSProxy::GetOrCreateIdentityHash(Handle<JSProxy>::cast(object))
6707       : JSObject::GetOrCreateIdentityHash(Handle<JSObject>::cast(object));
6708 }
6709
6710
6711 Object* JSReceiver::GetIdentityHash() {
6712   return IsJSProxy()
6713       ? JSProxy::cast(this)->GetIdentityHash()
6714       : JSObject::cast(this)->GetIdentityHash();
6715 }
6716
6717
6718 Maybe<bool> JSReceiver::HasElement(Handle<JSReceiver> object, uint32_t index) {
6719   if (object->IsJSProxy()) {
6720     Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
6721     return JSProxy::HasElementWithHandler(proxy, index);
6722   }
6723   Maybe<PropertyAttributes> result = JSObject::GetElementAttributeWithReceiver(
6724       Handle<JSObject>::cast(object), object, index, true);
6725   if (!result.has_value) return Maybe<bool>();
6726   return maybe(result.value != ABSENT);
6727 }
6728
6729
6730 Maybe<bool> JSReceiver::HasOwnElement(Handle<JSReceiver> object,
6731                                       uint32_t index) {
6732   if (object->IsJSProxy()) {
6733     Handle<JSProxy> proxy = Handle<JSProxy>::cast(object);
6734     return JSProxy::HasElementWithHandler(proxy, index);
6735   }
6736   Maybe<PropertyAttributes> result = JSObject::GetElementAttributeWithReceiver(
6737       Handle<JSObject>::cast(object), object, index, false);
6738   if (!result.has_value) return Maybe<bool>();
6739   return maybe(result.value != ABSENT);
6740 }
6741
6742
6743 Maybe<PropertyAttributes> JSReceiver::GetOwnElementAttribute(
6744     Handle<JSReceiver> object, uint32_t index) {
6745   if (object->IsJSProxy()) {
6746     return JSProxy::GetElementAttributeWithHandler(
6747         Handle<JSProxy>::cast(object), object, index);
6748   }
6749   return JSObject::GetElementAttributeWithReceiver(
6750       Handle<JSObject>::cast(object), object, index, false);
6751 }
6752
6753
6754 bool AccessorInfo::all_can_read() {
6755   return BooleanBit::get(flag(), kAllCanReadBit);
6756 }
6757
6758
6759 void AccessorInfo::set_all_can_read(bool value) {
6760   set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
6761 }
6762
6763
6764 bool AccessorInfo::all_can_write() {
6765   return BooleanBit::get(flag(), kAllCanWriteBit);
6766 }
6767
6768
6769 void AccessorInfo::set_all_can_write(bool value) {
6770   set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
6771 }
6772
6773
6774 PropertyAttributes AccessorInfo::property_attributes() {
6775   return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
6776 }
6777
6778
6779 void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
6780   set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
6781 }
6782
6783
6784 bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
6785   if (!HasExpectedReceiverType()) return true;
6786   if (!receiver->IsJSObject()) return false;
6787   return FunctionTemplateInfo::cast(expected_receiver_type())
6788       ->IsTemplateFor(JSObject::cast(receiver)->map());
6789 }
6790
6791
6792 void ExecutableAccessorInfo::clear_setter() {
6793   set_setter(GetIsolate()->heap()->undefined_value(), SKIP_WRITE_BARRIER);
6794 }
6795
6796
6797 template<typename Derived, typename Shape, typename Key>
6798 void Dictionary<Derived, Shape, Key>::SetEntry(int entry,
6799                                                Handle<Object> key,
6800                                                Handle<Object> value) {
6801   SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
6802 }
6803
6804
6805 template<typename Derived, typename Shape, typename Key>
6806 void Dictionary<Derived, Shape, Key>::SetEntry(int entry,
6807                                                Handle<Object> key,
6808                                                Handle<Object> value,
6809                                                PropertyDetails details) {
6810   DCHECK(!key->IsName() ||
6811          details.IsDeleted() ||
6812          details.dictionary_index() > 0);
6813   int index = DerivedHashTable::EntryToIndex(entry);
6814   DisallowHeapAllocation no_gc;
6815   WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
6816   FixedArray::set(index, *key, mode);
6817   FixedArray::set(index+1, *value, mode);
6818   FixedArray::set(index+2, details.AsSmi());
6819 }
6820
6821
6822 bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
6823   DCHECK(other->IsNumber());
6824   return key == static_cast<uint32_t>(other->Number());
6825 }
6826
6827
6828 uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
6829   return ComputeIntegerHash(key, 0);
6830 }
6831
6832
6833 uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
6834                                                       Object* other) {
6835   DCHECK(other->IsNumber());
6836   return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
6837 }
6838
6839
6840 uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
6841   return ComputeIntegerHash(key, seed);
6842 }
6843
6844
6845 uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
6846                                                           uint32_t seed,
6847                                                           Object* other) {
6848   DCHECK(other->IsNumber());
6849   return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
6850 }
6851
6852
6853 Handle<Object> NumberDictionaryShape::AsHandle(Isolate* isolate, uint32_t key) {
6854   return isolate->factory()->NewNumberFromUint(key);
6855 }
6856
6857
6858 bool NameDictionaryShape::IsMatch(Handle<Name> key, Object* other) {
6859   // We know that all entries in a hash table had their hash keys created.
6860   // Use that knowledge to have fast failure.
6861   if (key->Hash() != Name::cast(other)->Hash()) return false;
6862   return key->Equals(Name::cast(other));
6863 }
6864
6865
6866 uint32_t NameDictionaryShape::Hash(Handle<Name> key) {
6867   return key->Hash();
6868 }
6869
6870
6871 uint32_t NameDictionaryShape::HashForObject(Handle<Name> key, Object* other) {
6872   return Name::cast(other)->Hash();
6873 }
6874
6875
6876 Handle<Object> NameDictionaryShape::AsHandle(Isolate* isolate,
6877                                              Handle<Name> key) {
6878   DCHECK(key->IsUniqueName());
6879   return key;
6880 }
6881
6882
6883 void NameDictionary::DoGenerateNewEnumerationIndices(
6884     Handle<NameDictionary> dictionary) {
6885   DerivedDictionary::GenerateNewEnumerationIndices(dictionary);
6886 }
6887
6888
6889 bool ObjectHashTableShape::IsMatch(Handle<Object> key, Object* other) {
6890   return key->SameValue(other);
6891 }
6892
6893
6894 uint32_t ObjectHashTableShape::Hash(Handle<Object> key) {
6895   return Smi::cast(key->GetHash())->value();
6896 }
6897
6898
6899 uint32_t ObjectHashTableShape::HashForObject(Handle<Object> key,
6900                                              Object* other) {
6901   return Smi::cast(other->GetHash())->value();
6902 }
6903
6904
6905 Handle<Object> ObjectHashTableShape::AsHandle(Isolate* isolate,
6906                                               Handle<Object> key) {
6907   return key;
6908 }
6909
6910
6911 Handle<ObjectHashTable> ObjectHashTable::Shrink(
6912     Handle<ObjectHashTable> table, Handle<Object> key) {
6913   return DerivedHashTable::Shrink(table, key);
6914 }
6915
6916
6917 template <int entrysize>
6918 bool WeakHashTableShape<entrysize>::IsMatch(Handle<Object> key, Object* other) {
6919   return key->SameValue(other);
6920 }
6921
6922
6923 template <int entrysize>
6924 uint32_t WeakHashTableShape<entrysize>::Hash(Handle<Object> key) {
6925   intptr_t hash = reinterpret_cast<intptr_t>(*key);
6926   return (uint32_t)(hash & 0xFFFFFFFF);
6927 }
6928
6929
6930 template <int entrysize>
6931 uint32_t WeakHashTableShape<entrysize>::HashForObject(Handle<Object> key,
6932                                                       Object* other) {
6933   intptr_t hash = reinterpret_cast<intptr_t>(other);
6934   return (uint32_t)(hash & 0xFFFFFFFF);
6935 }
6936
6937
6938 template <int entrysize>
6939 Handle<Object> WeakHashTableShape<entrysize>::AsHandle(Isolate* isolate,
6940                                                        Handle<Object> key) {
6941   return key;
6942 }
6943
6944
6945 void Map::ClearCodeCache(Heap* heap) {
6946   // No write barrier is needed since empty_fixed_array is not in new space.
6947   // Please note this function is used during marking:
6948   //  - MarkCompactCollector::MarkUnmarkedObject
6949   //  - IncrementalMarking::Step
6950   DCHECK(!heap->InNewSpace(heap->empty_fixed_array()));
6951   WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array());
6952 }
6953
6954
6955 void JSArray::EnsureSize(Handle<JSArray> array, int required_size) {
6956   DCHECK(array->HasFastSmiOrObjectElements());
6957   Handle<FixedArray> elts = handle(FixedArray::cast(array->elements()));
6958   const int kArraySizeThatFitsComfortablyInNewSpace = 128;
6959   if (elts->length() < required_size) {
6960     // Doubling in size would be overkill, but leave some slack to avoid
6961     // constantly growing.
6962     Expand(array, required_size + (required_size >> 3));
6963     // It's a performance benefit to keep a frequently used array in new-space.
6964   } else if (!array->GetHeap()->new_space()->Contains(*elts) &&
6965              required_size < kArraySizeThatFitsComfortablyInNewSpace) {
6966     // Expand will allocate a new backing store in new space even if the size
6967     // we asked for isn't larger than what we had before.
6968     Expand(array, required_size);
6969   }
6970 }
6971
6972
6973 void JSArray::set_length(Smi* length) {
6974   // Don't need a write barrier for a Smi.
6975   set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
6976 }
6977
6978
6979 bool JSArray::AllowsSetElementsLength() {
6980   bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
6981   DCHECK(result == !HasExternalArrayElements());
6982   return result;
6983 }
6984
6985
6986 void JSArray::SetContent(Handle<JSArray> array,
6987                          Handle<FixedArrayBase> storage) {
6988   EnsureCanContainElements(array, storage, storage->length(),
6989                            ALLOW_COPIED_DOUBLE_ELEMENTS);
6990
6991   DCHECK((storage->map() == array->GetHeap()->fixed_double_array_map() &&
6992           IsFastDoubleElementsKind(array->GetElementsKind())) ||
6993          ((storage->map() != array->GetHeap()->fixed_double_array_map()) &&
6994           (IsFastObjectElementsKind(array->GetElementsKind()) ||
6995            (IsFastSmiElementsKind(array->GetElementsKind()) &&
6996             Handle<FixedArray>::cast(storage)->ContainsOnlySmisOrHoles()))));
6997   array->set_elements(*storage);
6998   array->set_length(Smi::FromInt(storage->length()));
6999 }
7000
7001
7002 int TypeFeedbackInfo::ic_total_count() {
7003   int current = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7004   return ICTotalCountField::decode(current);
7005 }
7006
7007
7008 void TypeFeedbackInfo::set_ic_total_count(int count) {
7009   int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7010   value = ICTotalCountField::update(value,
7011                                     ICTotalCountField::decode(count));
7012   WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
7013 }
7014
7015
7016 int TypeFeedbackInfo::ic_with_type_info_count() {
7017   int current = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7018   return ICsWithTypeInfoCountField::decode(current);
7019 }
7020
7021
7022 void TypeFeedbackInfo::change_ic_with_type_info_count(int delta) {
7023   if (delta == 0) return;
7024   int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7025   int new_count = ICsWithTypeInfoCountField::decode(value) + delta;
7026   // We can get negative count here when the type-feedback info is
7027   // shared between two code objects. The can only happen when
7028   // the debugger made a shallow copy of code object (see Heap::CopyCode).
7029   // Since we do not optimize when the debugger is active, we can skip
7030   // this counter update.
7031   if (new_count >= 0) {
7032     new_count &= ICsWithTypeInfoCountField::kMask;
7033     value = ICsWithTypeInfoCountField::update(value, new_count);
7034     WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
7035   }
7036 }
7037
7038
7039 int TypeFeedbackInfo::ic_generic_count() {
7040   return Smi::cast(READ_FIELD(this, kStorage3Offset))->value();
7041 }
7042
7043
7044 void TypeFeedbackInfo::change_ic_generic_count(int delta) {
7045   if (delta == 0) return;
7046   int new_count = ic_generic_count() + delta;
7047   if (new_count >= 0) {
7048     new_count &= ~Smi::kMinValue;
7049     WRITE_FIELD(this, kStorage3Offset, Smi::FromInt(new_count));
7050   }
7051 }
7052
7053
7054 void TypeFeedbackInfo::initialize_storage() {
7055   WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(0));
7056   WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(0));
7057   WRITE_FIELD(this, kStorage3Offset, Smi::FromInt(0));
7058 }
7059
7060
7061 void TypeFeedbackInfo::change_own_type_change_checksum() {
7062   int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7063   int checksum = OwnTypeChangeChecksum::decode(value);
7064   checksum = (checksum + 1) % (1 << kTypeChangeChecksumBits);
7065   value = OwnTypeChangeChecksum::update(value, checksum);
7066   // Ensure packed bit field is in Smi range.
7067   if (value > Smi::kMaxValue) value |= Smi::kMinValue;
7068   if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
7069   WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
7070 }
7071
7072
7073 void TypeFeedbackInfo::set_inlined_type_change_checksum(int checksum) {
7074   int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7075   int mask = (1 << kTypeChangeChecksumBits) - 1;
7076   value = InlinedTypeChangeChecksum::update(value, checksum & mask);
7077   // Ensure packed bit field is in Smi range.
7078   if (value > Smi::kMaxValue) value |= Smi::kMinValue;
7079   if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
7080   WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
7081 }
7082
7083
7084 int TypeFeedbackInfo::own_type_change_checksum() {
7085   int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7086   return OwnTypeChangeChecksum::decode(value);
7087 }
7088
7089
7090 bool TypeFeedbackInfo::matches_inlined_type_change_checksum(int checksum) {
7091   int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7092   int mask = (1 << kTypeChangeChecksumBits) - 1;
7093   return InlinedTypeChangeChecksum::decode(value) == (checksum & mask);
7094 }
7095
7096
7097 SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
7098
7099
7100 Relocatable::Relocatable(Isolate* isolate) {
7101   isolate_ = isolate;
7102   prev_ = isolate->relocatable_top();
7103   isolate->set_relocatable_top(this);
7104 }
7105
7106
7107 Relocatable::~Relocatable() {
7108   DCHECK_EQ(isolate_->relocatable_top(), this);
7109   isolate_->set_relocatable_top(prev_);
7110 }
7111
7112
7113 int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
7114   return map->instance_size();
7115 }
7116
7117
7118 void Foreign::ForeignIterateBody(ObjectVisitor* v) {
7119   v->VisitExternalReference(
7120       reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
7121 }
7122
7123
7124 template<typename StaticVisitor>
7125 void Foreign::ForeignIterateBody() {
7126   StaticVisitor::VisitExternalReference(
7127       reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
7128 }
7129
7130
7131 void ExternalOneByteString::ExternalOneByteStringIterateBody(ObjectVisitor* v) {
7132   typedef v8::String::ExternalOneByteStringResource Resource;
7133   v->VisitExternalOneByteString(
7134       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
7135 }
7136
7137
7138 template <typename StaticVisitor>
7139 void ExternalOneByteString::ExternalOneByteStringIterateBody() {
7140   typedef v8::String::ExternalOneByteStringResource Resource;
7141   StaticVisitor::VisitExternalOneByteString(
7142       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
7143 }
7144
7145
7146 void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
7147   typedef v8::String::ExternalStringResource Resource;
7148   v->VisitExternalTwoByteString(
7149       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
7150 }
7151
7152
7153 template<typename StaticVisitor>
7154 void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
7155   typedef v8::String::ExternalStringResource Resource;
7156   StaticVisitor::VisitExternalTwoByteString(
7157       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
7158 }
7159
7160
7161 template<int start_offset, int end_offset, int size>
7162 void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
7163     HeapObject* obj,
7164     ObjectVisitor* v) {
7165     v->VisitPointers(HeapObject::RawField(obj, start_offset),
7166                      HeapObject::RawField(obj, end_offset));
7167 }
7168
7169
7170 template<int start_offset>
7171 void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
7172                                                        int object_size,
7173                                                        ObjectVisitor* v) {
7174   v->VisitPointers(HeapObject::RawField(obj, start_offset),
7175                    HeapObject::RawField(obj, object_size));
7176 }
7177
7178
7179 template<class Derived, class TableType>
7180 Object* OrderedHashTableIterator<Derived, TableType>::CurrentKey() {
7181   TableType* table(TableType::cast(this->table()));
7182   int index = Smi::cast(this->index())->value();
7183   Object* key = table->KeyAt(index);
7184   DCHECK(!key->IsTheHole());
7185   return key;
7186 }
7187
7188
7189 void JSSetIterator::PopulateValueArray(FixedArray* array) {
7190   array->set(0, CurrentKey());
7191 }
7192
7193
7194 void JSMapIterator::PopulateValueArray(FixedArray* array) {
7195   array->set(0, CurrentKey());
7196   array->set(1, CurrentValue());
7197 }
7198
7199
7200 Object* JSMapIterator::CurrentValue() {
7201   OrderedHashMap* table(OrderedHashMap::cast(this->table()));
7202   int index = Smi::cast(this->index())->value();
7203   Object* value = table->ValueAt(index);
7204   DCHECK(!value->IsTheHole());
7205   return value;
7206 }
7207
7208
7209 #undef TYPE_CHECKER
7210 #undef CAST_ACCESSOR
7211 #undef INT_ACCESSORS
7212 #undef ACCESSORS
7213 #undef ACCESSORS_TO_SMI
7214 #undef SMI_ACCESSORS
7215 #undef SYNCHRONIZED_SMI_ACCESSORS
7216 #undef NOBARRIER_SMI_ACCESSORS
7217 #undef BOOL_GETTER
7218 #undef BOOL_ACCESSORS
7219 #undef FIELD_ADDR
7220 #undef FIELD_ADDR_CONST
7221 #undef READ_FIELD
7222 #undef NOBARRIER_READ_FIELD
7223 #undef WRITE_FIELD
7224 #undef NOBARRIER_WRITE_FIELD
7225 #undef WRITE_BARRIER
7226 #undef CONDITIONAL_WRITE_BARRIER
7227 #undef READ_DOUBLE_FIELD
7228 #undef WRITE_DOUBLE_FIELD
7229 #undef READ_INT_FIELD
7230 #undef WRITE_INT_FIELD
7231 #undef READ_INTPTR_FIELD
7232 #undef WRITE_INTPTR_FIELD
7233 #undef READ_UINT32_FIELD
7234 #undef WRITE_UINT32_FIELD
7235 #undef READ_SHORT_FIELD
7236 #undef WRITE_SHORT_FIELD
7237 #undef READ_BYTE_FIELD
7238 #undef WRITE_BYTE_FIELD
7239 #undef NOBARRIER_READ_BYTE_FIELD
7240 #undef NOBARRIER_WRITE_BYTE_FIELD
7241
7242 } }  // namespace v8::internal
7243
7244 #endif  // V8_OBJECTS_INL_H_