Home | History | Annotate | Download | only in src
      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_
   7245