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