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