Home | History | Annotate | Download | only in src
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 //
     28 // Review notes:
     29 //
     30 // - The use of macros in these inline functions may seem superfluous
     31 // but it is absolutely needed to make sure gcc generates optimal
     32 // code. gcc is not happy when attempting to inline too deep.
     33 //
     34 
     35 #ifndef V8_OBJECTS_INL_H_
     36 #define V8_OBJECTS_INL_H_
     37 
     38 #include "objects.h"
     39 #include "contexts.h"
     40 #include "conversions-inl.h"
     41 #include "heap.h"
     42 #include "isolate.h"
     43 #include "property.h"
     44 #include "spaces.h"
     45 #include "v8memory.h"
     46 
     47 namespace v8 {
     48 namespace internal {
     49 
     50 PropertyDetails::PropertyDetails(Smi* smi) {
     51   value_ = smi->value();
     52 }
     53 
     54 
     55 Smi* PropertyDetails::AsSmi() {
     56   return Smi::FromInt(value_);
     57 }
     58 
     59 
     60 PropertyDetails PropertyDetails::AsDeleted() {
     61   Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
     62   return PropertyDetails(smi);
     63 }
     64 
     65 
     66 #define CAST_ACCESSOR(type)                     \
     67   type* type::cast(Object* object) {            \
     68     ASSERT(object->Is##type());                 \
     69     return reinterpret_cast<type*>(object);     \
     70   }
     71 
     72 
     73 #define INT_ACCESSORS(holder, name, offset)                             \
     74   int holder::name() { return READ_INT_FIELD(this, offset); }           \
     75   void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
     76 
     77 
     78 #define ACCESSORS(holder, name, type, offset)                           \
     79   type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
     80   void holder::set_##name(type* value, WriteBarrierMode mode) {         \
     81     WRITE_FIELD(this, offset, value);                                   \
     82     CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);           \
     83   }
     84 
     85 
     86 // GC-safe accessors do not use HeapObject::GetHeap(), but access TLS instead.
     87 #define ACCESSORS_GCSAFE(holder, name, type, offset)                    \
     88   type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
     89   void holder::set_##name(type* value, WriteBarrierMode mode) {         \
     90     WRITE_FIELD(this, offset, value);                                   \
     91     CONDITIONAL_WRITE_BARRIER(HEAP, this, offset, mode);                \
     92   }
     93 
     94 
     95 #define SMI_ACCESSORS(holder, name, offset)             \
     96   int holder::name() {                                  \
     97     Object* value = READ_FIELD(this, offset);           \
     98     return Smi::cast(value)->value();                   \
     99   }                                                     \
    100   void holder::set_##name(int value) {                  \
    101     WRITE_FIELD(this, offset, Smi::FromInt(value));     \
    102   }
    103 
    104 
    105 #define BOOL_GETTER(holder, field, name, offset)           \
    106   bool holder::name() {                                    \
    107     return BooleanBit::get(field(), offset);               \
    108   }                                                        \
    109 
    110 
    111 #define BOOL_ACCESSORS(holder, field, name, offset)        \
    112   bool holder::name() {                                    \
    113     return BooleanBit::get(field(), offset);               \
    114   }                                                        \
    115   void holder::set_##name(bool value) {                    \
    116     set_##field(BooleanBit::set(field(), offset, value));  \
    117   }
    118 
    119 
    120 bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
    121   // There is a constraint on the object; check.
    122   if (!this->IsJSObject()) return false;
    123   // Fetch the constructor function of the object.
    124   Object* cons_obj = JSObject::cast(this)->map()->constructor();
    125   if (!cons_obj->IsJSFunction()) return false;
    126   JSFunction* fun = JSFunction::cast(cons_obj);
    127   // Iterate through the chain of inheriting function templates to
    128   // see if the required one occurs.
    129   for (Object* type = fun->shared()->function_data();
    130        type->IsFunctionTemplateInfo();
    131        type = FunctionTemplateInfo::cast(type)->parent_template()) {
    132     if (type == expected) return true;
    133   }
    134   // Didn't find the required type in the inheritance chain.
    135   return false;
    136 }
    137 
    138 
    139 bool Object::IsSmi() {
    140   return HAS_SMI_TAG(this);
    141 }
    142 
    143 
    144 bool Object::IsHeapObject() {
    145   return Internals::HasHeapObjectTag(this);
    146 }
    147 
    148 
    149 bool Object::IsHeapNumber() {
    150   return Object::IsHeapObject()
    151     && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
    152 }
    153 
    154 
    155 bool Object::IsString() {
    156   return Object::IsHeapObject()
    157     && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
    158 }
    159 
    160 
    161 bool Object::IsSymbol() {
    162   if (!this->IsHeapObject()) return false;
    163   uint32_t type = HeapObject::cast(this)->map()->instance_type();
    164   // Because the symbol tag is non-zero and no non-string types have the
    165   // symbol bit set we can test for symbols with a very simple test
    166   // operation.
    167   ASSERT(kSymbolTag != 0);
    168   ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
    169   return (type & kIsSymbolMask) != 0;
    170 }
    171 
    172 
    173 bool Object::IsConsString() {
    174   if (!this->IsHeapObject()) return false;
    175   uint32_t type = HeapObject::cast(this)->map()->instance_type();
    176   return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
    177          (kStringTag | kConsStringTag);
    178 }
    179 
    180 
    181 bool Object::IsSeqString() {
    182   if (!IsString()) return false;
    183   return StringShape(String::cast(this)).IsSequential();
    184 }
    185 
    186 
    187 bool Object::IsSeqAsciiString() {
    188   if (!IsString()) return false;
    189   return StringShape(String::cast(this)).IsSequential() &&
    190          String::cast(this)->IsAsciiRepresentation();
    191 }
    192 
    193 
    194 bool Object::IsSeqTwoByteString() {
    195   if (!IsString()) return false;
    196   return StringShape(String::cast(this)).IsSequential() &&
    197          String::cast(this)->IsTwoByteRepresentation();
    198 }
    199 
    200 
    201 bool Object::IsExternalString() {
    202   if (!IsString()) return false;
    203   return StringShape(String::cast(this)).IsExternal();
    204 }
    205 
    206 
    207 bool Object::IsExternalAsciiString() {
    208   if (!IsString()) return false;
    209   return StringShape(String::cast(this)).IsExternal() &&
    210          String::cast(this)->IsAsciiRepresentation();
    211 }
    212 
    213 
    214 bool Object::IsExternalTwoByteString() {
    215   if (!IsString()) return false;
    216   return StringShape(String::cast(this)).IsExternal() &&
    217          String::cast(this)->IsTwoByteRepresentation();
    218 }
    219 
    220 
    221 StringShape::StringShape(String* str)
    222   : type_(str->map()->instance_type()) {
    223   set_valid();
    224   ASSERT((type_ & kIsNotStringMask) == kStringTag);
    225 }
    226 
    227 
    228 StringShape::StringShape(Map* map)
    229   : type_(map->instance_type()) {
    230   set_valid();
    231   ASSERT((type_ & kIsNotStringMask) == kStringTag);
    232 }
    233 
    234 
    235 StringShape::StringShape(InstanceType t)
    236   : type_(static_cast<uint32_t>(t)) {
    237   set_valid();
    238   ASSERT((type_ & kIsNotStringMask) == kStringTag);
    239 }
    240 
    241 
    242 bool StringShape::IsSymbol() {
    243   ASSERT(valid());
    244   ASSERT(kSymbolTag != 0);
    245   return (type_ & kIsSymbolMask) != 0;
    246 }
    247 
    248 
    249 bool String::IsAsciiRepresentation() {
    250   uint32_t type = map()->instance_type();
    251   return (type & kStringEncodingMask) == kAsciiStringTag;
    252 }
    253 
    254 
    255 bool String::IsTwoByteRepresentation() {
    256   uint32_t type = map()->instance_type();
    257   return (type & kStringEncodingMask) == kTwoByteStringTag;
    258 }
    259 
    260 
    261 bool String::HasOnlyAsciiChars() {
    262   uint32_t type = map()->instance_type();
    263   return (type & kStringEncodingMask) == kAsciiStringTag ||
    264          (type & kAsciiDataHintMask) == kAsciiDataHintTag;
    265 }
    266 
    267 
    268 bool StringShape::IsCons() {
    269   return (type_ & kStringRepresentationMask) == kConsStringTag;
    270 }
    271 
    272 
    273 bool StringShape::IsExternal() {
    274   return (type_ & kStringRepresentationMask) == kExternalStringTag;
    275 }
    276 
    277 
    278 bool StringShape::IsSequential() {
    279   return (type_ & kStringRepresentationMask) == kSeqStringTag;
    280 }
    281 
    282 
    283 StringRepresentationTag StringShape::representation_tag() {
    284   uint32_t tag = (type_ & kStringRepresentationMask);
    285   return static_cast<StringRepresentationTag>(tag);
    286 }
    287 
    288 
    289 uint32_t StringShape::full_representation_tag() {
    290   return (type_ & (kStringRepresentationMask | kStringEncodingMask));
    291 }
    292 
    293 
    294 STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
    295              Internals::kFullStringRepresentationMask);
    296 
    297 
    298 bool StringShape::IsSequentialAscii() {
    299   return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
    300 }
    301 
    302 
    303 bool StringShape::IsSequentialTwoByte() {
    304   return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
    305 }
    306 
    307 
    308 bool StringShape::IsExternalAscii() {
    309   return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
    310 }
    311 
    312 
    313 bool StringShape::IsExternalTwoByte() {
    314   return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
    315 }
    316 
    317 
    318 STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
    319              Internals::kExternalTwoByteRepresentationTag);
    320 
    321 
    322 uc32 FlatStringReader::Get(int index) {
    323   ASSERT(0 <= index && index <= length_);
    324   if (is_ascii_) {
    325     return static_cast<const byte*>(start_)[index];
    326   } else {
    327     return static_cast<const uc16*>(start_)[index];
    328   }
    329 }
    330 
    331 
    332 bool Object::IsNumber() {
    333   return IsSmi() || IsHeapNumber();
    334 }
    335 
    336 
    337 bool Object::IsByteArray() {
    338   return Object::IsHeapObject()
    339     && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
    340 }
    341 
    342 
    343 bool Object::IsExternalPixelArray() {
    344   return Object::IsHeapObject() &&
    345       HeapObject::cast(this)->map()->instance_type() ==
    346           EXTERNAL_PIXEL_ARRAY_TYPE;
    347 }
    348 
    349 
    350 bool Object::IsExternalArray() {
    351   if (!Object::IsHeapObject())
    352     return false;
    353   InstanceType instance_type =
    354       HeapObject::cast(this)->map()->instance_type();
    355   return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
    356           instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
    357 }
    358 
    359 
    360 bool Object::IsExternalByteArray() {
    361   return Object::IsHeapObject() &&
    362       HeapObject::cast(this)->map()->instance_type() ==
    363       EXTERNAL_BYTE_ARRAY_TYPE;
    364 }
    365 
    366 
    367 bool Object::IsExternalUnsignedByteArray() {
    368   return Object::IsHeapObject() &&
    369       HeapObject::cast(this)->map()->instance_type() ==
    370       EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
    371 }
    372 
    373 
    374 bool Object::IsExternalShortArray() {
    375   return Object::IsHeapObject() &&
    376       HeapObject::cast(this)->map()->instance_type() ==
    377       EXTERNAL_SHORT_ARRAY_TYPE;
    378 }
    379 
    380 
    381 bool Object::IsExternalUnsignedShortArray() {
    382   return Object::IsHeapObject() &&
    383       HeapObject::cast(this)->map()->instance_type() ==
    384       EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
    385 }
    386 
    387 
    388 bool Object::IsExternalIntArray() {
    389   return Object::IsHeapObject() &&
    390       HeapObject::cast(this)->map()->instance_type() ==
    391       EXTERNAL_INT_ARRAY_TYPE;
    392 }
    393 
    394 
    395 bool Object::IsExternalUnsignedIntArray() {
    396   return Object::IsHeapObject() &&
    397       HeapObject::cast(this)->map()->instance_type() ==
    398       EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
    399 }
    400 
    401 
    402 bool Object::IsExternalFloatArray() {
    403   return Object::IsHeapObject() &&
    404       HeapObject::cast(this)->map()->instance_type() ==
    405       EXTERNAL_FLOAT_ARRAY_TYPE;
    406 }
    407 
    408 
    409 bool MaybeObject::IsFailure() {
    410   return HAS_FAILURE_TAG(this);
    411 }
    412 
    413 
    414 bool MaybeObject::IsRetryAfterGC() {
    415   return HAS_FAILURE_TAG(this)
    416     && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
    417 }
    418 
    419 
    420 bool MaybeObject::IsOutOfMemory() {
    421   return HAS_FAILURE_TAG(this)
    422       && Failure::cast(this)->IsOutOfMemoryException();
    423 }
    424 
    425 
    426 bool MaybeObject::IsException() {
    427   return this == Failure::Exception();
    428 }
    429 
    430 
    431 bool MaybeObject::IsTheHole() {
    432   return !IsFailure() && ToObjectUnchecked()->IsTheHole();
    433 }
    434 
    435 
    436 Failure* Failure::cast(MaybeObject* obj) {
    437   ASSERT(HAS_FAILURE_TAG(obj));
    438   return reinterpret_cast<Failure*>(obj);
    439 }
    440 
    441 
    442 bool Object::IsJSObject() {
    443   return IsHeapObject()
    444       && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
    445 }
    446 
    447 
    448 bool Object::IsJSContextExtensionObject() {
    449   return IsHeapObject()
    450       && (HeapObject::cast(this)->map()->instance_type() ==
    451           JS_CONTEXT_EXTENSION_OBJECT_TYPE);
    452 }
    453 
    454 
    455 bool Object::IsMap() {
    456   return Object::IsHeapObject()
    457       && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
    458 }
    459 
    460 
    461 bool Object::IsFixedArray() {
    462   return Object::IsHeapObject()
    463       && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
    464 }
    465 
    466 
    467 bool Object::IsDescriptorArray() {
    468   return IsFixedArray();
    469 }
    470 
    471 
    472 bool Object::IsDeoptimizationInputData() {
    473   // Must be a fixed array.
    474   if (!IsFixedArray()) return false;
    475 
    476   // There's no sure way to detect the difference between a fixed array and
    477   // a deoptimization data array.  Since this is used for asserts we can
    478   // check that the length is zero or else the fixed size plus a multiple of
    479   // the entry size.
    480   int length = FixedArray::cast(this)->length();
    481   if (length == 0) return true;
    482 
    483   length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
    484   return length >= 0 &&
    485       length % DeoptimizationInputData::kDeoptEntrySize == 0;
    486 }
    487 
    488 
    489 bool Object::IsDeoptimizationOutputData() {
    490   if (!IsFixedArray()) return false;
    491   // There's actually no way to see the difference between a fixed array and
    492   // a deoptimization data array.  Since this is used for asserts we can check
    493   // that the length is plausible though.
    494   if (FixedArray::cast(this)->length() % 2 != 0) return false;
    495   return true;
    496 }
    497 
    498 
    499 bool Object::IsContext() {
    500   if (Object::IsHeapObject()) {
    501     Heap* heap = HeapObject::cast(this)->GetHeap();
    502     return (HeapObject::cast(this)->map() == heap->context_map() ||
    503             HeapObject::cast(this)->map() == heap->catch_context_map() ||
    504             HeapObject::cast(this)->map() == heap->global_context_map());
    505   }
    506   return false;
    507 }
    508 
    509 
    510 bool Object::IsCatchContext() {
    511   return Object::IsHeapObject() &&
    512       HeapObject::cast(this)->map() ==
    513       HeapObject::cast(this)->GetHeap()->catch_context_map();
    514 }
    515 
    516 
    517 bool Object::IsGlobalContext() {
    518   return Object::IsHeapObject() &&
    519       HeapObject::cast(this)->map() ==
    520       HeapObject::cast(this)->GetHeap()->global_context_map();
    521 }
    522 
    523 
    524 bool Object::IsJSFunction() {
    525   return Object::IsHeapObject()
    526       && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
    527 }
    528 
    529 
    530 template <> inline bool Is<JSFunction>(Object* obj) {
    531   return obj->IsJSFunction();
    532 }
    533 
    534 
    535 bool Object::IsCode() {
    536   return Object::IsHeapObject()
    537       && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
    538 }
    539 
    540 
    541 bool Object::IsOddball() {
    542   ASSERT(HEAP->is_safe_to_read_maps());
    543   return Object::IsHeapObject()
    544     && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
    545 }
    546 
    547 
    548 bool Object::IsJSGlobalPropertyCell() {
    549   return Object::IsHeapObject()
    550       && HeapObject::cast(this)->map()->instance_type()
    551       == JS_GLOBAL_PROPERTY_CELL_TYPE;
    552 }
    553 
    554 
    555 bool Object::IsSharedFunctionInfo() {
    556   return Object::IsHeapObject() &&
    557       (HeapObject::cast(this)->map()->instance_type() ==
    558        SHARED_FUNCTION_INFO_TYPE);
    559 }
    560 
    561 
    562 bool Object::IsJSValue() {
    563   return Object::IsHeapObject()
    564       && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
    565 }
    566 
    567 
    568 bool Object::IsJSMessageObject() {
    569   return Object::IsHeapObject()
    570       && (HeapObject::cast(this)->map()->instance_type() ==
    571           JS_MESSAGE_OBJECT_TYPE);
    572 }
    573 
    574 
    575 bool Object::IsStringWrapper() {
    576   return IsJSValue() && JSValue::cast(this)->value()->IsString();
    577 }
    578 
    579 
    580 bool Object::IsProxy() {
    581   return Object::IsHeapObject()
    582       && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
    583 }
    584 
    585 
    586 bool Object::IsBoolean() {
    587   return IsOddball() &&
    588       ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
    589 }
    590 
    591 
    592 bool Object::IsJSArray() {
    593   return Object::IsHeapObject()
    594       && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
    595 }
    596 
    597 
    598 bool Object::IsJSRegExp() {
    599   return Object::IsHeapObject()
    600       && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
    601 }
    602 
    603 
    604 template <> inline bool Is<JSArray>(Object* obj) {
    605   return obj->IsJSArray();
    606 }
    607 
    608 
    609 bool Object::IsHashTable() {
    610   return Object::IsHeapObject() &&
    611       HeapObject::cast(this)->map() ==
    612       HeapObject::cast(this)->GetHeap()->hash_table_map();
    613 }
    614 
    615 
    616 bool Object::IsDictionary() {
    617   return IsHashTable() && this !=
    618          HeapObject::cast(this)->GetHeap()->symbol_table();
    619 }
    620 
    621 
    622 bool Object::IsSymbolTable() {
    623   return IsHashTable() && this ==
    624          HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
    625 }
    626 
    627 
    628 bool Object::IsJSFunctionResultCache() {
    629   if (!IsFixedArray()) return false;
    630   FixedArray* self = FixedArray::cast(this);
    631   int length = self->length();
    632   if (length < JSFunctionResultCache::kEntriesIndex) return false;
    633   if ((length - JSFunctionResultCache::kEntriesIndex)
    634       % JSFunctionResultCache::kEntrySize != 0) {
    635     return false;
    636   }
    637 #ifdef DEBUG
    638   reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
    639 #endif
    640   return true;
    641 }
    642 
    643 
    644 bool Object::IsNormalizedMapCache() {
    645   if (!IsFixedArray()) return false;
    646   if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
    647     return false;
    648   }
    649 #ifdef DEBUG
    650   reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
    651 #endif
    652   return true;
    653 }
    654 
    655 
    656 bool Object::IsCompilationCacheTable() {
    657   return IsHashTable();
    658 }
    659 
    660 
    661 bool Object::IsCodeCacheHashTable() {
    662   return IsHashTable();
    663 }
    664 
    665 
    666 bool Object::IsMapCache() {
    667   return IsHashTable();
    668 }
    669 
    670 
    671 bool Object::IsPrimitive() {
    672   return IsOddball() || IsNumber() || IsString();
    673 }
    674 
    675 
    676 bool Object::IsJSGlobalProxy() {
    677   bool result = IsHeapObject() &&
    678                 (HeapObject::cast(this)->map()->instance_type() ==
    679                  JS_GLOBAL_PROXY_TYPE);
    680   ASSERT(!result || IsAccessCheckNeeded());
    681   return result;
    682 }
    683 
    684 
    685 bool Object::IsGlobalObject() {
    686   if (!IsHeapObject()) return false;
    687 
    688   InstanceType type = HeapObject::cast(this)->map()->instance_type();
    689   return type == JS_GLOBAL_OBJECT_TYPE ||
    690          type == JS_BUILTINS_OBJECT_TYPE;
    691 }
    692 
    693 
    694 bool Object::IsJSGlobalObject() {
    695   return IsHeapObject() &&
    696       (HeapObject::cast(this)->map()->instance_type() ==
    697        JS_GLOBAL_OBJECT_TYPE);
    698 }
    699 
    700 
    701 bool Object::IsJSBuiltinsObject() {
    702   return IsHeapObject() &&
    703       (HeapObject::cast(this)->map()->instance_type() ==
    704        JS_BUILTINS_OBJECT_TYPE);
    705 }
    706 
    707 
    708 bool Object::IsUndetectableObject() {
    709   return IsHeapObject()
    710     && HeapObject::cast(this)->map()->is_undetectable();
    711 }
    712 
    713 
    714 bool Object::IsAccessCheckNeeded() {
    715   return IsHeapObject()
    716     && HeapObject::cast(this)->map()->is_access_check_needed();
    717 }
    718 
    719 
    720 bool Object::IsStruct() {
    721   if (!IsHeapObject()) return false;
    722   switch (HeapObject::cast(this)->map()->instance_type()) {
    723 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
    724   STRUCT_LIST(MAKE_STRUCT_CASE)
    725 #undef MAKE_STRUCT_CASE
    726     default: return false;
    727   }
    728 }
    729 
    730 
    731 #define MAKE_STRUCT_PREDICATE(NAME, Name, name)                  \
    732   bool Object::Is##Name() {                                      \
    733     return Object::IsHeapObject()                                \
    734       && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
    735   }
    736   STRUCT_LIST(MAKE_STRUCT_PREDICATE)
    737 #undef MAKE_STRUCT_PREDICATE
    738 
    739 
    740 bool Object::IsUndefined() {
    741   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
    742 }
    743 
    744 
    745 bool Object::IsNull() {
    746   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
    747 }
    748 
    749 
    750 bool Object::IsTheHole() {
    751   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
    752 }
    753 
    754 
    755 bool Object::IsTrue() {
    756   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
    757 }
    758 
    759 
    760 bool Object::IsFalse() {
    761   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
    762 }
    763 
    764 
    765 bool Object::IsArgumentsMarker() {
    766   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
    767 }
    768 
    769 
    770 double Object::Number() {
    771   ASSERT(IsNumber());
    772   return IsSmi()
    773     ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
    774     : reinterpret_cast<HeapNumber*>(this)->value();
    775 }
    776 
    777 
    778 MaybeObject* Object::ToSmi() {
    779   if (IsSmi()) return this;
    780   if (IsHeapNumber()) {
    781     double value = HeapNumber::cast(this)->value();
    782     int int_value = FastD2I(value);
    783     if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
    784       return Smi::FromInt(int_value);
    785     }
    786   }
    787   return Failure::Exception();
    788 }
    789 
    790 
    791 bool Object::HasSpecificClassOf(String* name) {
    792   return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
    793 }
    794 
    795 
    796 MaybeObject* Object::GetElement(uint32_t index) {
    797   // GetElement can trigger a getter which can cause allocation.
    798   // This was not always the case. This ASSERT is here to catch
    799   // leftover incorrect uses.
    800   ASSERT(HEAP->IsAllocationAllowed());
    801   return GetElementWithReceiver(this, index);
    802 }
    803 
    804 
    805 Object* Object::GetElementNoExceptionThrown(uint32_t index) {
    806   MaybeObject* maybe = GetElementWithReceiver(this, index);
    807   ASSERT(!maybe->IsFailure());
    808   Object* result = NULL;  // Initialization to please compiler.
    809   maybe->ToObject(&result);
    810   return result;
    811 }
    812 
    813 
    814 MaybeObject* Object::GetProperty(String* key) {
    815   PropertyAttributes attributes;
    816   return GetPropertyWithReceiver(this, key, &attributes);
    817 }
    818 
    819 
    820 MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
    821   return GetPropertyWithReceiver(this, key, attributes);
    822 }
    823 
    824 
    825 #define FIELD_ADDR(p, offset) \
    826   (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
    827 
    828 #define READ_FIELD(p, offset) \
    829   (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
    830 
    831 #define WRITE_FIELD(p, offset, value) \
    832   (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
    833 
    834 // TODO(isolates): Pass heap in to these macros.
    835 #define WRITE_BARRIER(object, offset) \
    836   object->GetHeap()->RecordWrite(object->address(), offset);
    837 
    838 // CONDITIONAL_WRITE_BARRIER must be issued after the actual
    839 // write due to the assert validating the written value.
    840 #define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
    841   if (mode == UPDATE_WRITE_BARRIER) { \
    842     heap->RecordWrite(object->address(), offset); \
    843   } else { \
    844     ASSERT(mode == SKIP_WRITE_BARRIER); \
    845     ASSERT(heap->InNewSpace(object) || \
    846            !heap->InNewSpace(READ_FIELD(object, offset)) || \
    847            Page::FromAddress(object->address())->           \
    848                IsRegionDirty(object->address() + offset));  \
    849   }
    850 
    851 #ifndef V8_TARGET_ARCH_MIPS
    852   #define READ_DOUBLE_FIELD(p, offset) \
    853     (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
    854 #else  // V8_TARGET_ARCH_MIPS
    855   // Prevent gcc from using load-double (mips ldc1) on (possibly)
    856   // non-64-bit aligned HeapNumber::value.
    857   static inline double read_double_field(HeapNumber* p, int offset) {
    858     union conversion {
    859       double d;
    860       uint32_t u[2];
    861     } c;
    862     c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
    863     c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
    864     return c.d;
    865   }
    866   #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
    867 #endif  // V8_TARGET_ARCH_MIPS
    868 
    869 
    870 #ifndef V8_TARGET_ARCH_MIPS
    871   #define WRITE_DOUBLE_FIELD(p, offset, value) \
    872     (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
    873 #else  // V8_TARGET_ARCH_MIPS
    874   // Prevent gcc from using store-double (mips sdc1) on (possibly)
    875   // non-64-bit aligned HeapNumber::value.
    876   static inline void write_double_field(HeapNumber* p, int offset,
    877                                         double value) {
    878     union conversion {
    879       double d;
    880       uint32_t u[2];
    881     } c;
    882     c.d = value;
    883     (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
    884     (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
    885   }
    886   #define WRITE_DOUBLE_FIELD(p, offset, value) \
    887     write_double_field(p, offset, value)
    888 #endif  // V8_TARGET_ARCH_MIPS
    889 
    890 
    891 #define READ_INT_FIELD(p, offset) \
    892   (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
    893 
    894 #define WRITE_INT_FIELD(p, offset, value) \
    895   (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
    896 
    897 #define READ_INTPTR_FIELD(p, offset) \
    898   (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
    899 
    900 #define WRITE_INTPTR_FIELD(p, offset, value) \
    901   (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
    902 
    903 #define READ_UINT32_FIELD(p, offset) \
    904   (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
    905 
    906 #define WRITE_UINT32_FIELD(p, offset, value) \
    907   (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
    908 
    909 #define READ_SHORT_FIELD(p, offset) \
    910   (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
    911 
    912 #define WRITE_SHORT_FIELD(p, offset, value) \
    913   (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
    914 
    915 #define READ_BYTE_FIELD(p, offset) \
    916   (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
    917 
    918 #define WRITE_BYTE_FIELD(p, offset, value) \
    919   (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
    920 
    921 
    922 Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
    923   return &READ_FIELD(obj, byte_offset);
    924 }
    925 
    926 
    927 int Smi::value() {
    928   return Internals::SmiValue(this);
    929 }
    930 
    931 
    932 Smi* Smi::FromInt(int value) {
    933   ASSERT(Smi::IsValid(value));
    934   int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
    935   intptr_t tagged_value =
    936       (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
    937   return reinterpret_cast<Smi*>(tagged_value);
    938 }
    939 
    940 
    941 Smi* Smi::FromIntptr(intptr_t value) {
    942   ASSERT(Smi::IsValid(value));
    943   int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
    944   return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
    945 }
    946 
    947 
    948 Failure::Type Failure::type() const {
    949   return static_cast<Type>(value() & kFailureTypeTagMask);
    950 }
    951 
    952 
    953 bool Failure::IsInternalError() const {
    954   return type() == INTERNAL_ERROR;
    955 }
    956 
    957 
    958 bool Failure::IsOutOfMemoryException() const {
    959   return type() == OUT_OF_MEMORY_EXCEPTION;
    960 }
    961 
    962 
    963 AllocationSpace Failure::allocation_space() const {
    964   ASSERT_EQ(RETRY_AFTER_GC, type());
    965   return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
    966                                       & kSpaceTagMask);
    967 }
    968 
    969 
    970 Failure* Failure::InternalError() {
    971   return Construct(INTERNAL_ERROR);
    972 }
    973 
    974 
    975 Failure* Failure::Exception() {
    976   return Construct(EXCEPTION);
    977 }
    978 
    979 
    980 Failure* Failure::OutOfMemoryException() {
    981   return Construct(OUT_OF_MEMORY_EXCEPTION);
    982 }
    983 
    984 
    985 intptr_t Failure::value() const {
    986   return static_cast<intptr_t>(
    987       reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
    988 }
    989 
    990 
    991 Failure* Failure::RetryAfterGC() {
    992   return RetryAfterGC(NEW_SPACE);
    993 }
    994 
    995 
    996 Failure* Failure::RetryAfterGC(AllocationSpace space) {
    997   ASSERT((space & ~kSpaceTagMask) == 0);
    998   return Construct(RETRY_AFTER_GC, space);
    999 }
   1000 
   1001 
   1002 Failure* Failure::Construct(Type type, intptr_t value) {
   1003   uintptr_t info =
   1004       (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
   1005   ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
   1006   return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
   1007 }
   1008 
   1009 
   1010 bool Smi::IsValid(intptr_t value) {
   1011 #ifdef DEBUG
   1012   bool in_range = (value >= kMinValue) && (value <= kMaxValue);
   1013 #endif
   1014 
   1015 #ifdef V8_TARGET_ARCH_X64
   1016   // To be representable as a long smi, the value must be a 32-bit integer.
   1017   bool result = (value == static_cast<int32_t>(value));
   1018 #else
   1019   // To be representable as an tagged small integer, the two
   1020   // most-significant bits of 'value' must be either 00 or 11 due to
   1021   // sign-extension. To check this we add 01 to the two
   1022   // most-significant bits, and check if the most-significant bit is 0
   1023   //
   1024   // CAUTION: The original code below:
   1025   // bool result = ((value + 0x40000000) & 0x80000000) == 0;
   1026   // may lead to incorrect results according to the C language spec, and
   1027   // in fact doesn't work correctly with gcc4.1.1 in some cases: The
   1028   // compiler may produce undefined results in case of signed integer
   1029   // overflow. The computation must be done w/ unsigned ints.
   1030   bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
   1031 #endif
   1032   ASSERT(result == in_range);
   1033   return result;
   1034 }
   1035 
   1036 
   1037 MapWord MapWord::FromMap(Map* map) {
   1038   return MapWord(reinterpret_cast<uintptr_t>(map));
   1039 }
   1040 
   1041 
   1042 Map* MapWord::ToMap() {
   1043   return reinterpret_cast<Map*>(value_);
   1044 }
   1045 
   1046 
   1047 bool MapWord::IsForwardingAddress() {
   1048   return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
   1049 }
   1050 
   1051 
   1052 MapWord MapWord::FromForwardingAddress(HeapObject* object) {
   1053   Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
   1054   return MapWord(reinterpret_cast<uintptr_t>(raw));
   1055 }
   1056 
   1057 
   1058 HeapObject* MapWord::ToForwardingAddress() {
   1059   ASSERT(IsForwardingAddress());
   1060   return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
   1061 }
   1062 
   1063 
   1064 bool MapWord::IsMarked() {
   1065   return (value_ & kMarkingMask) == 0;
   1066 }
   1067 
   1068 
   1069 void MapWord::SetMark() {
   1070   value_ &= ~kMarkingMask;
   1071 }
   1072 
   1073 
   1074 void MapWord::ClearMark() {
   1075   value_ |= kMarkingMask;
   1076 }
   1077 
   1078 
   1079 bool MapWord::IsOverflowed() {
   1080   return (value_ & kOverflowMask) != 0;
   1081 }
   1082 
   1083 
   1084 void MapWord::SetOverflow() {
   1085   value_ |= kOverflowMask;
   1086 }
   1087 
   1088 
   1089 void MapWord::ClearOverflow() {
   1090   value_ &= ~kOverflowMask;
   1091 }
   1092 
   1093 
   1094 MapWord MapWord::EncodeAddress(Address map_address, int offset) {
   1095   // Offset is the distance in live bytes from the first live object in the
   1096   // same page. The offset between two objects in the same page should not
   1097   // exceed the object area size of a page.
   1098   ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
   1099 
   1100   uintptr_t compact_offset = offset >> kObjectAlignmentBits;
   1101   ASSERT(compact_offset < (1 << kForwardingOffsetBits));
   1102 
   1103   Page* map_page = Page::FromAddress(map_address);
   1104   ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
   1105 
   1106   uintptr_t map_page_offset =
   1107       map_page->Offset(map_address) >> kMapAlignmentBits;
   1108 
   1109   uintptr_t encoding =
   1110       (compact_offset << kForwardingOffsetShift) |
   1111       (map_page_offset << kMapPageOffsetShift) |
   1112       (map_page->mc_page_index << kMapPageIndexShift);
   1113   return MapWord(encoding);
   1114 }
   1115 
   1116 
   1117 Address MapWord::DecodeMapAddress(MapSpace* map_space) {
   1118   int map_page_index =
   1119       static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
   1120   ASSERT_MAP_PAGE_INDEX(map_page_index);
   1121 
   1122   int map_page_offset = static_cast<int>(
   1123       ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
   1124       kMapAlignmentBits);
   1125 
   1126   return (map_space->PageAddress(map_page_index) + map_page_offset);
   1127 }
   1128 
   1129 
   1130 int MapWord::DecodeOffset() {
   1131   // The offset field is represented in the kForwardingOffsetBits
   1132   // most-significant bits.
   1133   uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
   1134   ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
   1135   return static_cast<int>(offset);
   1136 }
   1137 
   1138 
   1139 MapWord MapWord::FromEncodedAddress(Address address) {
   1140   return MapWord(reinterpret_cast<uintptr_t>(address));
   1141 }
   1142 
   1143 
   1144 Address MapWord::ToEncodedAddress() {
   1145   return reinterpret_cast<Address>(value_);
   1146 }
   1147 
   1148 
   1149 #ifdef DEBUG
   1150 void HeapObject::VerifyObjectField(int offset) {
   1151   VerifyPointer(READ_FIELD(this, offset));
   1152 }
   1153 
   1154 void HeapObject::VerifySmiField(int offset) {
   1155   ASSERT(READ_FIELD(this, offset)->IsSmi());
   1156 }
   1157 #endif
   1158 
   1159 
   1160 Heap* HeapObject::GetHeap() {
   1161   // During GC, the map pointer in HeapObject is used in various ways that
   1162   // prevent us from retrieving Heap from the map.
   1163   // Assert that we are not in GC, implement GC code in a way that it doesn't
   1164   // pull heap from the map.
   1165   ASSERT(HEAP->is_safe_to_read_maps());
   1166   return map()->heap();
   1167 }
   1168 
   1169 
   1170 Isolate* HeapObject::GetIsolate() {
   1171   return GetHeap()->isolate();
   1172 }
   1173 
   1174 
   1175 Map* HeapObject::map() {
   1176   return map_word().ToMap();
   1177 }
   1178 
   1179 
   1180 void HeapObject::set_map(Map* value) {
   1181   set_map_word(MapWord::FromMap(value));
   1182 }
   1183 
   1184 
   1185 MapWord HeapObject::map_word() {
   1186   return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
   1187 }
   1188 
   1189 
   1190 void HeapObject::set_map_word(MapWord map_word) {
   1191   // WRITE_FIELD does not invoke write barrier, but there is no need
   1192   // here.
   1193   WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
   1194 }
   1195 
   1196 
   1197 HeapObject* HeapObject::FromAddress(Address address) {
   1198   ASSERT_TAG_ALIGNED(address);
   1199   return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
   1200 }
   1201 
   1202 
   1203 Address HeapObject::address() {
   1204   return reinterpret_cast<Address>(this) - kHeapObjectTag;
   1205 }
   1206 
   1207 
   1208 int HeapObject::Size() {
   1209   return SizeFromMap(map());
   1210 }
   1211 
   1212 
   1213 void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
   1214   v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
   1215                    reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
   1216 }
   1217 
   1218 
   1219 void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
   1220   v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
   1221 }
   1222 
   1223 
   1224 bool HeapObject::IsMarked() {
   1225   return map_word().IsMarked();
   1226 }
   1227 
   1228 
   1229 void HeapObject::SetMark() {
   1230   ASSERT(!IsMarked());
   1231   MapWord first_word = map_word();
   1232   first_word.SetMark();
   1233   set_map_word(first_word);
   1234 }
   1235 
   1236 
   1237 void HeapObject::ClearMark() {
   1238   ASSERT(IsMarked());
   1239   MapWord first_word = map_word();
   1240   first_word.ClearMark();
   1241   set_map_word(first_word);
   1242 }
   1243 
   1244 
   1245 bool HeapObject::IsOverflowed() {
   1246   return map_word().IsOverflowed();
   1247 }
   1248 
   1249 
   1250 void HeapObject::SetOverflow() {
   1251   MapWord first_word = map_word();
   1252   first_word.SetOverflow();
   1253   set_map_word(first_word);
   1254 }
   1255 
   1256 
   1257 void HeapObject::ClearOverflow() {
   1258   ASSERT(IsOverflowed());
   1259   MapWord first_word = map_word();
   1260   first_word.ClearOverflow();
   1261   set_map_word(first_word);
   1262 }
   1263 
   1264 
   1265 double HeapNumber::value() {
   1266   return READ_DOUBLE_FIELD(this, kValueOffset);
   1267 }
   1268 
   1269 
   1270 void HeapNumber::set_value(double value) {
   1271   WRITE_DOUBLE_FIELD(this, kValueOffset, value);
   1272 }
   1273 
   1274 
   1275 int HeapNumber::get_exponent() {
   1276   return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
   1277           kExponentShift) - kExponentBias;
   1278 }
   1279 
   1280 
   1281 int HeapNumber::get_sign() {
   1282   return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
   1283 }
   1284 
   1285 
   1286 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
   1287 
   1288 
   1289 HeapObject* JSObject::elements() {
   1290   Object* array = READ_FIELD(this, kElementsOffset);
   1291   // In the assert below Dictionary is covered under FixedArray.
   1292   ASSERT(array->IsFixedArray() || array->IsExternalArray());
   1293   return reinterpret_cast<HeapObject*>(array);
   1294 }
   1295 
   1296 
   1297 void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
   1298   ASSERT(map()->has_fast_elements() ==
   1299          (value->map() == GetHeap()->fixed_array_map() ||
   1300           value->map() == GetHeap()->fixed_cow_array_map()));
   1301   // In the assert below Dictionary is covered under FixedArray.
   1302   ASSERT(value->IsFixedArray() || value->IsExternalArray());
   1303   WRITE_FIELD(this, kElementsOffset, value);
   1304   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
   1305 }
   1306 
   1307 
   1308 void JSObject::initialize_properties() {
   1309   ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
   1310   WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
   1311 }
   1312 
   1313 
   1314 void JSObject::initialize_elements() {
   1315   ASSERT(map()->has_fast_elements());
   1316   ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
   1317   WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
   1318 }
   1319 
   1320 
   1321 MaybeObject* JSObject::ResetElements() {
   1322   Object* obj;
   1323   { MaybeObject* maybe_obj = map()->GetFastElementsMap();
   1324     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   1325   }
   1326   set_map(Map::cast(obj));
   1327   initialize_elements();
   1328   return this;
   1329 }
   1330 
   1331 
   1332 ACCESSORS(Oddball, to_string, String, kToStringOffset)
   1333 ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
   1334 
   1335 
   1336 byte Oddball::kind() {
   1337   return READ_BYTE_FIELD(this, kKindOffset);
   1338 }
   1339 
   1340 
   1341 void Oddball::set_kind(byte value) {
   1342   WRITE_BYTE_FIELD(this, kKindOffset, value);
   1343 }
   1344 
   1345 
   1346 Object* JSGlobalPropertyCell::value() {
   1347   return READ_FIELD(this, kValueOffset);
   1348 }
   1349 
   1350 
   1351 void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
   1352   // The write barrier is not used for global property cells.
   1353   ASSERT(!val->IsJSGlobalPropertyCell());
   1354   WRITE_FIELD(this, kValueOffset, val);
   1355 }
   1356 
   1357 
   1358 int JSObject::GetHeaderSize() {
   1359   InstanceType type = map()->instance_type();
   1360   // Check for the most common kind of JavaScript object before
   1361   // falling into the generic switch. This speeds up the internal
   1362   // field operations considerably on average.
   1363   if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
   1364   switch (type) {
   1365     case JS_GLOBAL_PROXY_TYPE:
   1366       return JSGlobalProxy::kSize;
   1367     case JS_GLOBAL_OBJECT_TYPE:
   1368       return JSGlobalObject::kSize;
   1369     case JS_BUILTINS_OBJECT_TYPE:
   1370       return JSBuiltinsObject::kSize;
   1371     case JS_FUNCTION_TYPE:
   1372       return JSFunction::kSize;
   1373     case JS_VALUE_TYPE:
   1374       return JSValue::kSize;
   1375     case JS_ARRAY_TYPE:
   1376       return JSValue::kSize;
   1377     case JS_REGEXP_TYPE:
   1378       return JSValue::kSize;
   1379     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
   1380       return JSObject::kHeaderSize;
   1381     case JS_MESSAGE_OBJECT_TYPE:
   1382       return JSMessageObject::kSize;
   1383     default:
   1384       UNREACHABLE();
   1385       return 0;
   1386   }
   1387 }
   1388 
   1389 
   1390 int JSObject::GetInternalFieldCount() {
   1391   ASSERT(1 << kPointerSizeLog2 == kPointerSize);
   1392   // Make sure to adjust for the number of in-object properties. These
   1393   // properties do contribute to the size, but are not internal fields.
   1394   return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
   1395          map()->inobject_properties();
   1396 }
   1397 
   1398 
   1399 int JSObject::GetInternalFieldOffset(int index) {
   1400   ASSERT(index < GetInternalFieldCount() && index >= 0);
   1401   return GetHeaderSize() + (kPointerSize * index);
   1402 }
   1403 
   1404 
   1405 Object* JSObject::GetInternalField(int index) {
   1406   ASSERT(index < GetInternalFieldCount() && index >= 0);
   1407   // Internal objects do follow immediately after the header, whereas in-object
   1408   // properties are at the end of the object. Therefore there is no need
   1409   // to adjust the index here.
   1410   return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
   1411 }
   1412 
   1413 
   1414 void JSObject::SetInternalField(int index, Object* value) {
   1415   ASSERT(index < GetInternalFieldCount() && index >= 0);
   1416   // Internal objects do follow immediately after the header, whereas in-object
   1417   // properties are at the end of the object. Therefore there is no need
   1418   // to adjust the index here.
   1419   int offset = GetHeaderSize() + (kPointerSize * index);
   1420   WRITE_FIELD(this, offset, value);
   1421   WRITE_BARRIER(this, offset);
   1422 }
   1423 
   1424 
   1425 // Access fast-case object properties at index. The use of these routines
   1426 // is needed to correctly distinguish between properties stored in-object and
   1427 // properties stored in the properties array.
   1428 Object* JSObject::FastPropertyAt(int index) {
   1429   // Adjust for the number of properties stored in the object.
   1430   index -= map()->inobject_properties();
   1431   if (index < 0) {
   1432     int offset = map()->instance_size() + (index * kPointerSize);
   1433     return READ_FIELD(this, offset);
   1434   } else {
   1435     ASSERT(index < properties()->length());
   1436     return properties()->get(index);
   1437   }
   1438 }
   1439 
   1440 
   1441 Object* JSObject::FastPropertyAtPut(int index, Object* value) {
   1442   // Adjust for the number of properties stored in the object.
   1443   index -= map()->inobject_properties();
   1444   if (index < 0) {
   1445     int offset = map()->instance_size() + (index * kPointerSize);
   1446     WRITE_FIELD(this, offset, value);
   1447     WRITE_BARRIER(this, offset);
   1448   } else {
   1449     ASSERT(index < properties()->length());
   1450     properties()->set(index, value);
   1451   }
   1452   return value;
   1453 }
   1454 
   1455 
   1456 int JSObject::GetInObjectPropertyOffset(int index) {
   1457   // Adjust for the number of properties stored in the object.
   1458   index -= map()->inobject_properties();
   1459   ASSERT(index < 0);
   1460   return map()->instance_size() + (index * kPointerSize);
   1461 }
   1462 
   1463 
   1464 Object* JSObject::InObjectPropertyAt(int index) {
   1465   // Adjust for the number of properties stored in the object.
   1466   index -= map()->inobject_properties();
   1467   ASSERT(index < 0);
   1468   int offset = map()->instance_size() + (index * kPointerSize);
   1469   return READ_FIELD(this, offset);
   1470 }
   1471 
   1472 
   1473 Object* JSObject::InObjectPropertyAtPut(int index,
   1474                                         Object* value,
   1475                                         WriteBarrierMode mode) {
   1476   // Adjust for the number of properties stored in the object.
   1477   index -= map()->inobject_properties();
   1478   ASSERT(index < 0);
   1479   int offset = map()->instance_size() + (index * kPointerSize);
   1480   WRITE_FIELD(this, offset, value);
   1481   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
   1482   return value;
   1483 }
   1484 
   1485 
   1486 
   1487 void JSObject::InitializeBody(int object_size, Object* value) {
   1488   ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
   1489   for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
   1490     WRITE_FIELD(this, offset, value);
   1491   }
   1492 }
   1493 
   1494 
   1495 bool JSObject::HasFastProperties() {
   1496   return !properties()->IsDictionary();
   1497 }
   1498 
   1499 
   1500 int JSObject::MaxFastProperties() {
   1501   // Allow extra fast properties if the object has more than
   1502   // kMaxFastProperties in-object properties. When this is the case,
   1503   // it is very unlikely that the object is being used as a dictionary
   1504   // and there is a good chance that allowing more map transitions
   1505   // will be worth it.
   1506   return Max(map()->inobject_properties(), kMaxFastProperties);
   1507 }
   1508 
   1509 
   1510 void Struct::InitializeBody(int object_size) {
   1511   Object* value = GetHeap()->undefined_value();
   1512   for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
   1513     WRITE_FIELD(this, offset, value);
   1514   }
   1515 }
   1516 
   1517 
   1518 bool Object::ToArrayIndex(uint32_t* index) {
   1519   if (IsSmi()) {
   1520     int value = Smi::cast(this)->value();
   1521     if (value < 0) return false;
   1522     *index = value;
   1523     return true;
   1524   }
   1525   if (IsHeapNumber()) {
   1526     double value = HeapNumber::cast(this)->value();
   1527     uint32_t uint_value = static_cast<uint32_t>(value);
   1528     if (value == static_cast<double>(uint_value)) {
   1529       *index = uint_value;
   1530       return true;
   1531     }
   1532   }
   1533   return false;
   1534 }
   1535 
   1536 
   1537 bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
   1538   if (!this->IsJSValue()) return false;
   1539 
   1540   JSValue* js_value = JSValue::cast(this);
   1541   if (!js_value->value()->IsString()) return false;
   1542 
   1543   String* str = String::cast(js_value->value());
   1544   if (index >= (uint32_t)str->length()) return false;
   1545 
   1546   return true;
   1547 }
   1548 
   1549 
   1550 Object* FixedArray::get(int index) {
   1551   ASSERT(index >= 0 && index < this->length());
   1552   return READ_FIELD(this, kHeaderSize + index * kPointerSize);
   1553 }
   1554 
   1555 
   1556 void FixedArray::set(int index, Smi* value) {
   1557   ASSERT(map() != HEAP->fixed_cow_array_map());
   1558   ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
   1559   int offset = kHeaderSize + index * kPointerSize;
   1560   WRITE_FIELD(this, offset, value);
   1561 }
   1562 
   1563 
   1564 void FixedArray::set(int index, Object* value) {
   1565   ASSERT(map() != HEAP->fixed_cow_array_map());
   1566   ASSERT(index >= 0 && index < this->length());
   1567   int offset = kHeaderSize + index * kPointerSize;
   1568   WRITE_FIELD(this, offset, value);
   1569   WRITE_BARRIER(this, offset);
   1570 }
   1571 
   1572 
   1573 WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
   1574   if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
   1575   return UPDATE_WRITE_BARRIER;
   1576 }
   1577 
   1578 
   1579 void FixedArray::set(int index,
   1580                      Object* value,
   1581                      WriteBarrierMode mode) {
   1582   ASSERT(map() != HEAP->fixed_cow_array_map());
   1583   ASSERT(index >= 0 && index < this->length());
   1584   int offset = kHeaderSize + index * kPointerSize;
   1585   WRITE_FIELD(this, offset, value);
   1586   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
   1587 }
   1588 
   1589 
   1590 void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
   1591   ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
   1592   ASSERT(index >= 0 && index < array->length());
   1593   ASSERT(!HEAP->InNewSpace(value));
   1594   WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
   1595 }
   1596 
   1597 
   1598 void FixedArray::set_undefined(int index) {
   1599   ASSERT(map() != HEAP->fixed_cow_array_map());
   1600   set_undefined(GetHeap(), index);
   1601 }
   1602 
   1603 
   1604 void FixedArray::set_undefined(Heap* heap, int index) {
   1605   ASSERT(index >= 0 && index < this->length());
   1606   ASSERT(!heap->InNewSpace(heap->undefined_value()));
   1607   WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
   1608               heap->undefined_value());
   1609 }
   1610 
   1611 
   1612 void FixedArray::set_null(int index) {
   1613   set_null(GetHeap(), index);
   1614 }
   1615 
   1616 
   1617 void FixedArray::set_null(Heap* heap, int index) {
   1618   ASSERT(index >= 0 && index < this->length());
   1619   ASSERT(!heap->InNewSpace(heap->null_value()));
   1620   WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
   1621 }
   1622 
   1623 
   1624 void FixedArray::set_the_hole(int index) {
   1625   ASSERT(map() != HEAP->fixed_cow_array_map());
   1626   ASSERT(index >= 0 && index < this->length());
   1627   ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
   1628   WRITE_FIELD(this,
   1629               kHeaderSize + index * kPointerSize,
   1630               GetHeap()->the_hole_value());
   1631 }
   1632 
   1633 
   1634 void FixedArray::set_unchecked(int index, Smi* value) {
   1635   ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
   1636   int offset = kHeaderSize + index * kPointerSize;
   1637   WRITE_FIELD(this, offset, value);
   1638 }
   1639 
   1640 
   1641 void FixedArray::set_unchecked(Heap* heap,
   1642                                int index,
   1643                                Object* value,
   1644                                WriteBarrierMode mode) {
   1645   int offset = kHeaderSize + index * kPointerSize;
   1646   WRITE_FIELD(this, offset, value);
   1647   CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
   1648 }
   1649 
   1650 
   1651 void FixedArray::set_null_unchecked(Heap* heap, int index) {
   1652   ASSERT(index >= 0 && index < this->length());
   1653   ASSERT(!HEAP->InNewSpace(heap->null_value()));
   1654   WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
   1655 }
   1656 
   1657 
   1658 Object** FixedArray::data_start() {
   1659   return HeapObject::RawField(this, kHeaderSize);
   1660 }
   1661 
   1662 
   1663 bool DescriptorArray::IsEmpty() {
   1664   ASSERT(this->length() > kFirstIndex ||
   1665          this == HEAP->empty_descriptor_array());
   1666   return length() <= kFirstIndex;
   1667 }
   1668 
   1669 
   1670 void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
   1671   Object* tmp = array->get(first);
   1672   fast_set(array, first, array->get(second));
   1673   fast_set(array, second, tmp);
   1674 }
   1675 
   1676 
   1677 int DescriptorArray::Search(String* name) {
   1678   SLOW_ASSERT(IsSortedNoDuplicates());
   1679 
   1680   // Check for empty descriptor array.
   1681   int nof = number_of_descriptors();
   1682   if (nof == 0) return kNotFound;
   1683 
   1684   // Fast case: do linear search for small arrays.
   1685   const int kMaxElementsForLinearSearch = 8;
   1686   if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
   1687     return LinearSearch(name, nof);
   1688   }
   1689 
   1690   // Slow case: perform binary search.
   1691   return BinarySearch(name, 0, nof - 1);
   1692 }
   1693 
   1694 
   1695 int DescriptorArray::SearchWithCache(String* name) {
   1696   int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
   1697   if (number == DescriptorLookupCache::kAbsent) {
   1698     number = Search(name);
   1699     GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
   1700   }
   1701   return number;
   1702 }
   1703 
   1704 
   1705 String* DescriptorArray::GetKey(int descriptor_number) {
   1706   ASSERT(descriptor_number < number_of_descriptors());
   1707   return String::cast(get(ToKeyIndex(descriptor_number)));
   1708 }
   1709 
   1710 
   1711 Object* DescriptorArray::GetValue(int descriptor_number) {
   1712   ASSERT(descriptor_number < number_of_descriptors());
   1713   return GetContentArray()->get(ToValueIndex(descriptor_number));
   1714 }
   1715 
   1716 
   1717 Smi* DescriptorArray::GetDetails(int descriptor_number) {
   1718   ASSERT(descriptor_number < number_of_descriptors());
   1719   return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
   1720 }
   1721 
   1722 
   1723 PropertyType DescriptorArray::GetType(int descriptor_number) {
   1724   ASSERT(descriptor_number < number_of_descriptors());
   1725   return PropertyDetails(GetDetails(descriptor_number)).type();
   1726 }
   1727 
   1728 
   1729 int DescriptorArray::GetFieldIndex(int descriptor_number) {
   1730   return Descriptor::IndexFromValue(GetValue(descriptor_number));
   1731 }
   1732 
   1733 
   1734 JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
   1735   return JSFunction::cast(GetValue(descriptor_number));
   1736 }
   1737 
   1738 
   1739 Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
   1740   ASSERT(GetType(descriptor_number) == CALLBACKS);
   1741   return GetValue(descriptor_number);
   1742 }
   1743 
   1744 
   1745 AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
   1746   ASSERT(GetType(descriptor_number) == CALLBACKS);
   1747   Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
   1748   return reinterpret_cast<AccessorDescriptor*>(p->proxy());
   1749 }
   1750 
   1751 
   1752 bool DescriptorArray::IsProperty(int descriptor_number) {
   1753   return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
   1754 }
   1755 
   1756 
   1757 bool DescriptorArray::IsTransition(int descriptor_number) {
   1758   PropertyType t = GetType(descriptor_number);
   1759   return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
   1760       t == EXTERNAL_ARRAY_TRANSITION;
   1761 }
   1762 
   1763 
   1764 bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
   1765   return GetType(descriptor_number) == NULL_DESCRIPTOR;
   1766 }
   1767 
   1768 
   1769 bool DescriptorArray::IsDontEnum(int descriptor_number) {
   1770   return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
   1771 }
   1772 
   1773 
   1774 void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
   1775   desc->Init(GetKey(descriptor_number),
   1776              GetValue(descriptor_number),
   1777              PropertyDetails(GetDetails(descriptor_number)));
   1778 }
   1779 
   1780 
   1781 void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
   1782   // Range check.
   1783   ASSERT(descriptor_number < number_of_descriptors());
   1784 
   1785   // Make sure none of the elements in desc are in new space.
   1786   ASSERT(!HEAP->InNewSpace(desc->GetKey()));
   1787   ASSERT(!HEAP->InNewSpace(desc->GetValue()));
   1788 
   1789   fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
   1790   FixedArray* content_array = GetContentArray();
   1791   fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
   1792   fast_set(content_array, ToDetailsIndex(descriptor_number),
   1793            desc->GetDetails().AsSmi());
   1794 }
   1795 
   1796 
   1797 void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
   1798   Descriptor desc;
   1799   src->Get(src_index, &desc);
   1800   Set(index, &desc);
   1801 }
   1802 
   1803 
   1804 void DescriptorArray::Swap(int first, int second) {
   1805   fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
   1806   FixedArray* content_array = GetContentArray();
   1807   fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
   1808   fast_swap(content_array, ToDetailsIndex(first),  ToDetailsIndex(second));
   1809 }
   1810 
   1811 
   1812 template<typename Shape, typename Key>
   1813 int HashTable<Shape, Key>::FindEntry(Key key) {
   1814   return FindEntry(GetIsolate(), key);
   1815 }
   1816 
   1817 
   1818 // Find entry for key otherwise return kNotFound.
   1819 template<typename Shape, typename Key>
   1820 int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
   1821   uint32_t capacity = Capacity();
   1822   uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
   1823   uint32_t count = 1;
   1824   // EnsureCapacity will guarantee the hash table is never full.
   1825   while (true) {
   1826     Object* element = KeyAt(entry);
   1827     if (element == isolate->heap()->undefined_value()) break;  // Empty entry.
   1828     if (element != isolate->heap()->null_value() &&
   1829         Shape::IsMatch(key, element)) return entry;
   1830     entry = NextProbe(entry, count++, capacity);
   1831   }
   1832   return kNotFound;
   1833 }
   1834 
   1835 
   1836 bool NumberDictionary::requires_slow_elements() {
   1837   Object* max_index_object = get(kMaxNumberKeyIndex);
   1838   if (!max_index_object->IsSmi()) return false;
   1839   return 0 !=
   1840       (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
   1841 }
   1842 
   1843 uint32_t NumberDictionary::max_number_key() {
   1844   ASSERT(!requires_slow_elements());
   1845   Object* max_index_object = get(kMaxNumberKeyIndex);
   1846   if (!max_index_object->IsSmi()) return 0;
   1847   uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
   1848   return value >> kRequiresSlowElementsTagSize;
   1849 }
   1850 
   1851 void NumberDictionary::set_requires_slow_elements() {
   1852   set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
   1853 }
   1854 
   1855 
   1856 // ------------------------------------
   1857 // Cast operations
   1858 
   1859 
   1860 CAST_ACCESSOR(FixedArray)
   1861 CAST_ACCESSOR(DescriptorArray)
   1862 CAST_ACCESSOR(DeoptimizationInputData)
   1863 CAST_ACCESSOR(DeoptimizationOutputData)
   1864 CAST_ACCESSOR(SymbolTable)
   1865 CAST_ACCESSOR(JSFunctionResultCache)
   1866 CAST_ACCESSOR(NormalizedMapCache)
   1867 CAST_ACCESSOR(CompilationCacheTable)
   1868 CAST_ACCESSOR(CodeCacheHashTable)
   1869 CAST_ACCESSOR(MapCache)
   1870 CAST_ACCESSOR(String)
   1871 CAST_ACCESSOR(SeqString)
   1872 CAST_ACCESSOR(SeqAsciiString)
   1873 CAST_ACCESSOR(SeqTwoByteString)
   1874 CAST_ACCESSOR(ConsString)
   1875 CAST_ACCESSOR(ExternalString)
   1876 CAST_ACCESSOR(ExternalAsciiString)
   1877 CAST_ACCESSOR(ExternalTwoByteString)
   1878 CAST_ACCESSOR(JSObject)
   1879 CAST_ACCESSOR(Smi)
   1880 CAST_ACCESSOR(HeapObject)
   1881 CAST_ACCESSOR(HeapNumber)
   1882 CAST_ACCESSOR(Oddball)
   1883 CAST_ACCESSOR(JSGlobalPropertyCell)
   1884 CAST_ACCESSOR(SharedFunctionInfo)
   1885 CAST_ACCESSOR(Map)
   1886 CAST_ACCESSOR(JSFunction)
   1887 CAST_ACCESSOR(GlobalObject)
   1888 CAST_ACCESSOR(JSGlobalProxy)
   1889 CAST_ACCESSOR(JSGlobalObject)
   1890 CAST_ACCESSOR(JSBuiltinsObject)
   1891 CAST_ACCESSOR(Code)
   1892 CAST_ACCESSOR(JSArray)
   1893 CAST_ACCESSOR(JSRegExp)
   1894 CAST_ACCESSOR(Proxy)
   1895 CAST_ACCESSOR(ByteArray)
   1896 CAST_ACCESSOR(ExternalArray)
   1897 CAST_ACCESSOR(ExternalByteArray)
   1898 CAST_ACCESSOR(ExternalUnsignedByteArray)
   1899 CAST_ACCESSOR(ExternalShortArray)
   1900 CAST_ACCESSOR(ExternalUnsignedShortArray)
   1901 CAST_ACCESSOR(ExternalIntArray)
   1902 CAST_ACCESSOR(ExternalUnsignedIntArray)
   1903 CAST_ACCESSOR(ExternalFloatArray)
   1904 CAST_ACCESSOR(ExternalPixelArray)
   1905 CAST_ACCESSOR(Struct)
   1906 
   1907 
   1908 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
   1909   STRUCT_LIST(MAKE_STRUCT_CAST)
   1910 #undef MAKE_STRUCT_CAST
   1911 
   1912 
   1913 template <typename Shape, typename Key>
   1914 HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
   1915   ASSERT(obj->IsHashTable());
   1916   return reinterpret_cast<HashTable*>(obj);
   1917 }
   1918 
   1919 
   1920 SMI_ACCESSORS(FixedArray, length, kLengthOffset)
   1921 SMI_ACCESSORS(ByteArray, length, kLengthOffset)
   1922 
   1923 INT_ACCESSORS(ExternalArray, length, kLengthOffset)
   1924 
   1925 
   1926 SMI_ACCESSORS(String, length, kLengthOffset)
   1927 
   1928 
   1929 uint32_t String::hash_field() {
   1930   return READ_UINT32_FIELD(this, kHashFieldOffset);
   1931 }
   1932 
   1933 
   1934 void String::set_hash_field(uint32_t value) {
   1935   WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
   1936 #if V8_HOST_ARCH_64_BIT
   1937   WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
   1938 #endif
   1939 }
   1940 
   1941 
   1942 bool String::Equals(String* other) {
   1943   if (other == this) return true;
   1944   if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
   1945     return false;
   1946   }
   1947   return SlowEquals(other);
   1948 }
   1949 
   1950 
   1951 MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
   1952   if (!StringShape(this).IsCons()) return this;
   1953   ConsString* cons = ConsString::cast(this);
   1954   if (cons->second()->length() == 0) return cons->first();
   1955   return SlowTryFlatten(pretenure);
   1956 }
   1957 
   1958 
   1959 String* String::TryFlattenGetString(PretenureFlag pretenure) {
   1960   MaybeObject* flat = TryFlatten(pretenure);
   1961   Object* successfully_flattened;
   1962   if (flat->ToObject(&successfully_flattened)) {
   1963     return String::cast(successfully_flattened);
   1964   }
   1965   return this;
   1966 }
   1967 
   1968 
   1969 uint16_t String::Get(int index) {
   1970   ASSERT(index >= 0 && index < length());
   1971   switch (StringShape(this).full_representation_tag()) {
   1972     case kSeqStringTag | kAsciiStringTag:
   1973       return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
   1974     case kSeqStringTag | kTwoByteStringTag:
   1975       return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
   1976     case kConsStringTag | kAsciiStringTag:
   1977     case kConsStringTag | kTwoByteStringTag:
   1978       return ConsString::cast(this)->ConsStringGet(index);
   1979     case kExternalStringTag | kAsciiStringTag:
   1980       return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
   1981     case kExternalStringTag | kTwoByteStringTag:
   1982       return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
   1983     default:
   1984       break;
   1985   }
   1986 
   1987   UNREACHABLE();
   1988   return 0;
   1989 }
   1990 
   1991 
   1992 void String::Set(int index, uint16_t value) {
   1993   ASSERT(index >= 0 && index < length());
   1994   ASSERT(StringShape(this).IsSequential());
   1995 
   1996   return this->IsAsciiRepresentation()
   1997       ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
   1998       : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
   1999 }
   2000 
   2001 
   2002 bool String::IsFlat() {
   2003   switch (StringShape(this).representation_tag()) {
   2004     case kConsStringTag: {
   2005       String* second = ConsString::cast(this)->second();
   2006       // Only flattened strings have second part empty.
   2007       return second->length() == 0;
   2008     }
   2009     default:
   2010       return true;
   2011   }
   2012 }
   2013 
   2014 
   2015 uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
   2016   ASSERT(index >= 0 && index < length());
   2017   return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
   2018 }
   2019 
   2020 
   2021 void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
   2022   ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
   2023   WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
   2024                    static_cast<byte>(value));
   2025 }
   2026 
   2027 
   2028 Address SeqAsciiString::GetCharsAddress() {
   2029   return FIELD_ADDR(this, kHeaderSize);
   2030 }
   2031 
   2032 
   2033 char* SeqAsciiString::GetChars() {
   2034   return reinterpret_cast<char*>(GetCharsAddress());
   2035 }
   2036 
   2037 
   2038 Address SeqTwoByteString::GetCharsAddress() {
   2039   return FIELD_ADDR(this, kHeaderSize);
   2040 }
   2041 
   2042 
   2043 uc16* SeqTwoByteString::GetChars() {
   2044   return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
   2045 }
   2046 
   2047 
   2048 uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
   2049   ASSERT(index >= 0 && index < length());
   2050   return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
   2051 }
   2052 
   2053 
   2054 void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
   2055   ASSERT(index >= 0 && index < length());
   2056   WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
   2057 }
   2058 
   2059 
   2060 int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
   2061   return SizeFor(length());
   2062 }
   2063 
   2064 
   2065 int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
   2066   return SizeFor(length());
   2067 }
   2068 
   2069 
   2070 String* ConsString::first() {
   2071   return String::cast(READ_FIELD(this, kFirstOffset));
   2072 }
   2073 
   2074 
   2075 Object* ConsString::unchecked_first() {
   2076   return READ_FIELD(this, kFirstOffset);
   2077 }
   2078 
   2079 
   2080 void ConsString::set_first(String* value, WriteBarrierMode mode) {
   2081   WRITE_FIELD(this, kFirstOffset, value);
   2082   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
   2083 }
   2084 
   2085 
   2086 String* ConsString::second() {
   2087   return String::cast(READ_FIELD(this, kSecondOffset));
   2088 }
   2089 
   2090 
   2091 Object* ConsString::unchecked_second() {
   2092   return READ_FIELD(this, kSecondOffset);
   2093 }
   2094 
   2095 
   2096 void ConsString::set_second(String* value, WriteBarrierMode mode) {
   2097   WRITE_FIELD(this, kSecondOffset, value);
   2098   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
   2099 }
   2100 
   2101 
   2102 ExternalAsciiString::Resource* ExternalAsciiString::resource() {
   2103   return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
   2104 }
   2105 
   2106 
   2107 void ExternalAsciiString::set_resource(
   2108     ExternalAsciiString::Resource* resource) {
   2109   *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
   2110 }
   2111 
   2112 
   2113 ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
   2114   return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
   2115 }
   2116 
   2117 
   2118 void ExternalTwoByteString::set_resource(
   2119     ExternalTwoByteString::Resource* resource) {
   2120   *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
   2121 }
   2122 
   2123 
   2124 void JSFunctionResultCache::MakeZeroSize() {
   2125   set_finger_index(kEntriesIndex);
   2126   set_size(kEntriesIndex);
   2127 }
   2128 
   2129 
   2130 void JSFunctionResultCache::Clear() {
   2131   int cache_size = size();
   2132   Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
   2133   MemsetPointer(entries_start,
   2134                 GetHeap()->the_hole_value(),
   2135                 cache_size - kEntriesIndex);
   2136   MakeZeroSize();
   2137 }
   2138 
   2139 
   2140 int JSFunctionResultCache::size() {
   2141   return Smi::cast(get(kCacheSizeIndex))->value();
   2142 }
   2143 
   2144 
   2145 void JSFunctionResultCache::set_size(int size) {
   2146   set(kCacheSizeIndex, Smi::FromInt(size));
   2147 }
   2148 
   2149 
   2150 int JSFunctionResultCache::finger_index() {
   2151   return Smi::cast(get(kFingerIndex))->value();
   2152 }
   2153 
   2154 
   2155 void JSFunctionResultCache::set_finger_index(int finger_index) {
   2156   set(kFingerIndex, Smi::FromInt(finger_index));
   2157 }
   2158 
   2159 
   2160 byte ByteArray::get(int index) {
   2161   ASSERT(index >= 0 && index < this->length());
   2162   return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
   2163 }
   2164 
   2165 
   2166 void ByteArray::set(int index, byte value) {
   2167   ASSERT(index >= 0 && index < this->length());
   2168   WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
   2169 }
   2170 
   2171 
   2172 int ByteArray::get_int(int index) {
   2173   ASSERT(index >= 0 && (index * kIntSize) < this->length());
   2174   return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
   2175 }
   2176 
   2177 
   2178 ByteArray* ByteArray::FromDataStartAddress(Address address) {
   2179   ASSERT_TAG_ALIGNED(address);
   2180   return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
   2181 }
   2182 
   2183 
   2184 Address ByteArray::GetDataStartAddress() {
   2185   return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
   2186 }
   2187 
   2188 
   2189 uint8_t* ExternalPixelArray::external_pixel_pointer() {
   2190   return reinterpret_cast<uint8_t*>(external_pointer());
   2191 }
   2192 
   2193 
   2194 uint8_t ExternalPixelArray::get(int index) {
   2195   ASSERT((index >= 0) && (index < this->length()));
   2196   uint8_t* ptr = external_pixel_pointer();
   2197   return ptr[index];
   2198 }
   2199 
   2200 
   2201 void ExternalPixelArray::set(int index, uint8_t value) {
   2202   ASSERT((index >= 0) && (index < this->length()));
   2203   uint8_t* ptr = external_pixel_pointer();
   2204   ptr[index] = value;
   2205 }
   2206 
   2207 
   2208 void* ExternalArray::external_pointer() {
   2209   intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
   2210   return reinterpret_cast<void*>(ptr);
   2211 }
   2212 
   2213 
   2214 void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
   2215   intptr_t ptr = reinterpret_cast<intptr_t>(value);
   2216   WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
   2217 }
   2218 
   2219 
   2220 int8_t ExternalByteArray::get(int index) {
   2221   ASSERT((index >= 0) && (index < this->length()));
   2222   int8_t* ptr = static_cast<int8_t*>(external_pointer());
   2223   return ptr[index];
   2224 }
   2225 
   2226 
   2227 void ExternalByteArray::set(int index, int8_t value) {
   2228   ASSERT((index >= 0) && (index < this->length()));
   2229   int8_t* ptr = static_cast<int8_t*>(external_pointer());
   2230   ptr[index] = value;
   2231 }
   2232 
   2233 
   2234 uint8_t ExternalUnsignedByteArray::get(int index) {
   2235   ASSERT((index >= 0) && (index < this->length()));
   2236   uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
   2237   return ptr[index];
   2238 }
   2239 
   2240 
   2241 void ExternalUnsignedByteArray::set(int index, uint8_t value) {
   2242   ASSERT((index >= 0) && (index < this->length()));
   2243   uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
   2244   ptr[index] = value;
   2245 }
   2246 
   2247 
   2248 int16_t ExternalShortArray::get(int index) {
   2249   ASSERT((index >= 0) && (index < this->length()));
   2250   int16_t* ptr = static_cast<int16_t*>(external_pointer());
   2251   return ptr[index];
   2252 }
   2253 
   2254 
   2255 void ExternalShortArray::set(int index, int16_t value) {
   2256   ASSERT((index >= 0) && (index < this->length()));
   2257   int16_t* ptr = static_cast<int16_t*>(external_pointer());
   2258   ptr[index] = value;
   2259 }
   2260 
   2261 
   2262 uint16_t ExternalUnsignedShortArray::get(int index) {
   2263   ASSERT((index >= 0) && (index < this->length()));
   2264   uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
   2265   return ptr[index];
   2266 }
   2267 
   2268 
   2269 void ExternalUnsignedShortArray::set(int index, uint16_t value) {
   2270   ASSERT((index >= 0) && (index < this->length()));
   2271   uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
   2272   ptr[index] = value;
   2273 }
   2274 
   2275 
   2276 int32_t ExternalIntArray::get(int index) {
   2277   ASSERT((index >= 0) && (index < this->length()));
   2278   int32_t* ptr = static_cast<int32_t*>(external_pointer());
   2279   return ptr[index];
   2280 }
   2281 
   2282 
   2283 void ExternalIntArray::set(int index, int32_t value) {
   2284   ASSERT((index >= 0) && (index < this->length()));
   2285   int32_t* ptr = static_cast<int32_t*>(external_pointer());
   2286   ptr[index] = value;
   2287 }
   2288 
   2289 
   2290 uint32_t ExternalUnsignedIntArray::get(int index) {
   2291   ASSERT((index >= 0) && (index < this->length()));
   2292   uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
   2293   return ptr[index];
   2294 }
   2295 
   2296 
   2297 void ExternalUnsignedIntArray::set(int index, uint32_t value) {
   2298   ASSERT((index >= 0) && (index < this->length()));
   2299   uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
   2300   ptr[index] = value;
   2301 }
   2302 
   2303 
   2304 float ExternalFloatArray::get(int index) {
   2305   ASSERT((index >= 0) && (index < this->length()));
   2306   float* ptr = static_cast<float*>(external_pointer());
   2307   return ptr[index];
   2308 }
   2309 
   2310 
   2311 void ExternalFloatArray::set(int index, float value) {
   2312   ASSERT((index >= 0) && (index < this->length()));
   2313   float* ptr = static_cast<float*>(external_pointer());
   2314   ptr[index] = value;
   2315 }
   2316 
   2317 
   2318 int Map::visitor_id() {
   2319   return READ_BYTE_FIELD(this, kVisitorIdOffset);
   2320 }
   2321 
   2322 
   2323 void Map::set_visitor_id(int id) {
   2324   ASSERT(0 <= id && id < 256);
   2325   WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
   2326 }
   2327 
   2328 
   2329 int Map::instance_size() {
   2330   return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
   2331 }
   2332 
   2333 
   2334 int Map::inobject_properties() {
   2335   return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
   2336 }
   2337 
   2338 
   2339 int Map::pre_allocated_property_fields() {
   2340   return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
   2341 }
   2342 
   2343 
   2344 int HeapObject::SizeFromMap(Map* map) {
   2345   int instance_size = map->instance_size();
   2346   if (instance_size != kVariableSizeSentinel) return instance_size;
   2347   // We can ignore the "symbol" bit becase it is only set for symbols
   2348   // and implies a string type.
   2349   int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
   2350   // Only inline the most frequent cases.
   2351   if (instance_type == FIXED_ARRAY_TYPE) {
   2352     return FixedArray::BodyDescriptor::SizeOf(map, this);
   2353   }
   2354   if (instance_type == ASCII_STRING_TYPE) {
   2355     return SeqAsciiString::SizeFor(
   2356         reinterpret_cast<SeqAsciiString*>(this)->length());
   2357   }
   2358   if (instance_type == BYTE_ARRAY_TYPE) {
   2359     return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
   2360   }
   2361   if (instance_type == STRING_TYPE) {
   2362     return SeqTwoByteString::SizeFor(
   2363         reinterpret_cast<SeqTwoByteString*>(this)->length());
   2364   }
   2365   ASSERT(instance_type == CODE_TYPE);
   2366   return reinterpret_cast<Code*>(this)->CodeSize();
   2367 }
   2368 
   2369 
   2370 void Map::set_instance_size(int value) {
   2371   ASSERT_EQ(0, value & (kPointerSize - 1));
   2372   value >>= kPointerSizeLog2;
   2373   ASSERT(0 <= value && value < 256);
   2374   WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
   2375 }
   2376 
   2377 
   2378 void Map::set_inobject_properties(int value) {
   2379   ASSERT(0 <= value && value < 256);
   2380   WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
   2381 }
   2382 
   2383 
   2384 void Map::set_pre_allocated_property_fields(int value) {
   2385   ASSERT(0 <= value && value < 256);
   2386   WRITE_BYTE_FIELD(this,
   2387                    kPreAllocatedPropertyFieldsOffset,
   2388                    static_cast<byte>(value));
   2389 }
   2390 
   2391 
   2392 InstanceType Map::instance_type() {
   2393   return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
   2394 }
   2395 
   2396 
   2397 void Map::set_instance_type(InstanceType value) {
   2398   WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
   2399 }
   2400 
   2401 
   2402 int Map::unused_property_fields() {
   2403   return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
   2404 }
   2405 
   2406 
   2407 void Map::set_unused_property_fields(int value) {
   2408   WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
   2409 }
   2410 
   2411 
   2412 byte Map::bit_field() {
   2413   return READ_BYTE_FIELD(this, kBitFieldOffset);
   2414 }
   2415 
   2416 
   2417 void Map::set_bit_field(byte value) {
   2418   WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
   2419 }
   2420 
   2421 
   2422 byte Map::bit_field2() {
   2423   return READ_BYTE_FIELD(this, kBitField2Offset);
   2424 }
   2425 
   2426 
   2427 void Map::set_bit_field2(byte value) {
   2428   WRITE_BYTE_FIELD(this, kBitField2Offset, value);
   2429 }
   2430 
   2431 
   2432 void Map::set_non_instance_prototype(bool value) {
   2433   if (value) {
   2434     set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
   2435   } else {
   2436     set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
   2437   }
   2438 }
   2439 
   2440 
   2441 bool Map::has_non_instance_prototype() {
   2442   return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
   2443 }
   2444 
   2445 
   2446 void Map::set_function_with_prototype(bool value) {
   2447   if (value) {
   2448     set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
   2449   } else {
   2450     set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
   2451   }
   2452 }
   2453 
   2454 
   2455 bool Map::function_with_prototype() {
   2456   return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
   2457 }
   2458 
   2459 
   2460 void Map::set_is_access_check_needed(bool access_check_needed) {
   2461   if (access_check_needed) {
   2462     set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
   2463   } else {
   2464     set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
   2465   }
   2466 }
   2467 
   2468 
   2469 bool Map::is_access_check_needed() {
   2470   return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
   2471 }
   2472 
   2473 
   2474 void Map::set_is_extensible(bool value) {
   2475   if (value) {
   2476     set_bit_field2(bit_field2() | (1 << kIsExtensible));
   2477   } else {
   2478     set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
   2479   }
   2480 }
   2481 
   2482 bool Map::is_extensible() {
   2483   return ((1 << kIsExtensible) & bit_field2()) != 0;
   2484 }
   2485 
   2486 
   2487 void Map::set_attached_to_shared_function_info(bool value) {
   2488   if (value) {
   2489     set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
   2490   } else {
   2491     set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
   2492   }
   2493 }
   2494 
   2495 bool Map::attached_to_shared_function_info() {
   2496   return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
   2497 }
   2498 
   2499 
   2500 void Map::set_is_shared(bool value) {
   2501   if (value) {
   2502     set_bit_field2(bit_field2() | (1 << kIsShared));
   2503   } else {
   2504     set_bit_field2(bit_field2() & ~(1 << kIsShared));
   2505   }
   2506 }
   2507 
   2508 bool Map::is_shared() {
   2509   return ((1 << kIsShared) & bit_field2()) != 0;
   2510 }
   2511 
   2512 
   2513 JSFunction* Map::unchecked_constructor() {
   2514   return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
   2515 }
   2516 
   2517 
   2518 FixedArray* Map::unchecked_prototype_transitions() {
   2519   return reinterpret_cast<FixedArray*>(
   2520       READ_FIELD(this, kPrototypeTransitionsOffset));
   2521 }
   2522 
   2523 
   2524 Code::Flags Code::flags() {
   2525   return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
   2526 }
   2527 
   2528 
   2529 void Code::set_flags(Code::Flags flags) {
   2530   STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
   2531   // Make sure that all call stubs have an arguments count.
   2532   ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
   2533           ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
   2534          ExtractArgumentsCountFromFlags(flags) >= 0);
   2535   WRITE_INT_FIELD(this, kFlagsOffset, flags);
   2536 }
   2537 
   2538 
   2539 Code::Kind Code::kind() {
   2540   return ExtractKindFromFlags(flags());
   2541 }
   2542 
   2543 
   2544 InLoopFlag Code::ic_in_loop() {
   2545   return ExtractICInLoopFromFlags(flags());
   2546 }
   2547 
   2548 
   2549 InlineCacheState Code::ic_state() {
   2550   InlineCacheState result = ExtractICStateFromFlags(flags());
   2551   // Only allow uninitialized or debugger states for non-IC code
   2552   // objects. This is used in the debugger to determine whether or not
   2553   // a call to code object has been replaced with a debug break call.
   2554   ASSERT(is_inline_cache_stub() ||
   2555          result == UNINITIALIZED ||
   2556          result == DEBUG_BREAK ||
   2557          result == DEBUG_PREPARE_STEP_IN);
   2558   return result;
   2559 }
   2560 
   2561 
   2562 Code::ExtraICState Code::extra_ic_state() {
   2563   ASSERT(is_inline_cache_stub());
   2564   return ExtractExtraICStateFromFlags(flags());
   2565 }
   2566 
   2567 
   2568 PropertyType Code::type() {
   2569   ASSERT(ic_state() == MONOMORPHIC);
   2570   return ExtractTypeFromFlags(flags());
   2571 }
   2572 
   2573 
   2574 int Code::arguments_count() {
   2575   ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
   2576   return ExtractArgumentsCountFromFlags(flags());
   2577 }
   2578 
   2579 
   2580 int Code::major_key() {
   2581   ASSERT(kind() == STUB ||
   2582          kind() == TYPE_RECORDING_BINARY_OP_IC ||
   2583          kind() == COMPARE_IC);
   2584   return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
   2585 }
   2586 
   2587 
   2588 void Code::set_major_key(int major) {
   2589   ASSERT(kind() == STUB ||
   2590          kind() == TYPE_RECORDING_BINARY_OP_IC ||
   2591          kind() == COMPARE_IC);
   2592   ASSERT(0 <= major && major < 256);
   2593   WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
   2594 }
   2595 
   2596 
   2597 bool Code::optimizable() {
   2598   ASSERT(kind() == FUNCTION);
   2599   return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
   2600 }
   2601 
   2602 
   2603 void Code::set_optimizable(bool value) {
   2604   ASSERT(kind() == FUNCTION);
   2605   WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
   2606 }
   2607 
   2608 
   2609 bool Code::has_deoptimization_support() {
   2610   ASSERT(kind() == FUNCTION);
   2611   return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
   2612 }
   2613 
   2614 
   2615 void Code::set_has_deoptimization_support(bool value) {
   2616   ASSERT(kind() == FUNCTION);
   2617   WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
   2618 }
   2619 
   2620 
   2621 int Code::allow_osr_at_loop_nesting_level() {
   2622   ASSERT(kind() == FUNCTION);
   2623   return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
   2624 }
   2625 
   2626 
   2627 void Code::set_allow_osr_at_loop_nesting_level(int level) {
   2628   ASSERT(kind() == FUNCTION);
   2629   ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
   2630   WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
   2631 }
   2632 
   2633 
   2634 unsigned Code::stack_slots() {
   2635   ASSERT(kind() == OPTIMIZED_FUNCTION);
   2636   return READ_UINT32_FIELD(this, kStackSlotsOffset);
   2637 }
   2638 
   2639 
   2640 void Code::set_stack_slots(unsigned slots) {
   2641   ASSERT(kind() == OPTIMIZED_FUNCTION);
   2642   WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
   2643 }
   2644 
   2645 
   2646 unsigned Code::safepoint_table_offset() {
   2647   ASSERT(kind() == OPTIMIZED_FUNCTION);
   2648   return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
   2649 }
   2650 
   2651 
   2652 void Code::set_safepoint_table_offset(unsigned offset) {
   2653   ASSERT(kind() == OPTIMIZED_FUNCTION);
   2654   ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
   2655   WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
   2656 }
   2657 
   2658 
   2659 unsigned Code::stack_check_table_offset() {
   2660   ASSERT(kind() == FUNCTION);
   2661   return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
   2662 }
   2663 
   2664 
   2665 void Code::set_stack_check_table_offset(unsigned offset) {
   2666   ASSERT(kind() == FUNCTION);
   2667   ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
   2668   WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
   2669 }
   2670 
   2671 
   2672 CheckType Code::check_type() {
   2673   ASSERT(is_call_stub() || is_keyed_call_stub());
   2674   byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
   2675   return static_cast<CheckType>(type);
   2676 }
   2677 
   2678 
   2679 void Code::set_check_type(CheckType value) {
   2680   ASSERT(is_call_stub() || is_keyed_call_stub());
   2681   WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
   2682 }
   2683 
   2684 
   2685 ExternalArrayType Code::external_array_type() {
   2686   ASSERT(is_external_array_load_stub() || is_external_array_store_stub());
   2687   byte type = READ_BYTE_FIELD(this, kExternalArrayTypeOffset);
   2688   return static_cast<ExternalArrayType>(type);
   2689 }
   2690 
   2691 
   2692 void Code::set_external_array_type(ExternalArrayType value) {
   2693   ASSERT(is_external_array_load_stub() || is_external_array_store_stub());
   2694   WRITE_BYTE_FIELD(this, kExternalArrayTypeOffset, value);
   2695 }
   2696 
   2697 
   2698 byte Code::type_recording_binary_op_type() {
   2699   ASSERT(is_type_recording_binary_op_stub());
   2700   return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
   2701 }
   2702 
   2703 
   2704 void Code::set_type_recording_binary_op_type(byte value) {
   2705   ASSERT(is_type_recording_binary_op_stub());
   2706   WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
   2707 }
   2708 
   2709 
   2710 byte Code::type_recording_binary_op_result_type() {
   2711   ASSERT(is_type_recording_binary_op_stub());
   2712   return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
   2713 }
   2714 
   2715 
   2716 void Code::set_type_recording_binary_op_result_type(byte value) {
   2717   ASSERT(is_type_recording_binary_op_stub());
   2718   WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
   2719 }
   2720 
   2721 
   2722 byte Code::compare_state() {
   2723   ASSERT(is_compare_ic_stub());
   2724   return READ_BYTE_FIELD(this, kCompareStateOffset);
   2725 }
   2726 
   2727 
   2728 void Code::set_compare_state(byte value) {
   2729   ASSERT(is_compare_ic_stub());
   2730   WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
   2731 }
   2732 
   2733 
   2734 bool Code::is_inline_cache_stub() {
   2735   Kind kind = this->kind();
   2736   return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
   2737 }
   2738 
   2739 
   2740 Code::Flags Code::ComputeFlags(Kind kind,
   2741                                InLoopFlag in_loop,
   2742                                InlineCacheState ic_state,
   2743                                ExtraICState extra_ic_state,
   2744                                PropertyType type,
   2745                                int argc,
   2746                                InlineCacheHolderFlag holder) {
   2747   // Extra IC state is only allowed for monomorphic call IC stubs
   2748   // or for store IC stubs.
   2749   ASSERT(extra_ic_state == kNoExtraICState ||
   2750          (kind == CALL_IC && (ic_state == MONOMORPHIC ||
   2751                               ic_state == MONOMORPHIC_PROTOTYPE_FAILURE)) ||
   2752          (kind == STORE_IC) ||
   2753          (kind == KEYED_STORE_IC));
   2754   // Compute the bit mask.
   2755   int bits = kind << kFlagsKindShift;
   2756   if (in_loop) bits |= kFlagsICInLoopMask;
   2757   bits |= ic_state << kFlagsICStateShift;
   2758   bits |= type << kFlagsTypeShift;
   2759   bits |= extra_ic_state << kFlagsExtraICStateShift;
   2760   bits |= argc << kFlagsArgumentsCountShift;
   2761   if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
   2762   // Cast to flags and validate result before returning it.
   2763   Flags result = static_cast<Flags>(bits);
   2764   ASSERT(ExtractKindFromFlags(result) == kind);
   2765   ASSERT(ExtractICStateFromFlags(result) == ic_state);
   2766   ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
   2767   ASSERT(ExtractTypeFromFlags(result) == type);
   2768   ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
   2769   ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
   2770   return result;
   2771 }
   2772 
   2773 
   2774 Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
   2775                                           PropertyType type,
   2776                                           ExtraICState extra_ic_state,
   2777                                           InlineCacheHolderFlag holder,
   2778                                           InLoopFlag in_loop,
   2779                                           int argc) {
   2780   return ComputeFlags(
   2781       kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
   2782 }
   2783 
   2784 
   2785 Code::Kind Code::ExtractKindFromFlags(Flags flags) {
   2786   int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
   2787   return static_cast<Kind>(bits);
   2788 }
   2789 
   2790 
   2791 InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
   2792   int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
   2793   return static_cast<InlineCacheState>(bits);
   2794 }
   2795 
   2796 
   2797 Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
   2798   int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
   2799   return static_cast<ExtraICState>(bits);
   2800 }
   2801 
   2802 
   2803 InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
   2804   int bits = (flags & kFlagsICInLoopMask);
   2805   return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
   2806 }
   2807 
   2808 
   2809 PropertyType Code::ExtractTypeFromFlags(Flags flags) {
   2810   int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
   2811   return static_cast<PropertyType>(bits);
   2812 }
   2813 
   2814 
   2815 int Code::ExtractArgumentsCountFromFlags(Flags flags) {
   2816   return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
   2817 }
   2818 
   2819 
   2820 InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
   2821   int bits = (flags & kFlagsCacheInPrototypeMapMask);
   2822   return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
   2823 }
   2824 
   2825 
   2826 Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
   2827   int bits = flags & ~kFlagsTypeMask;
   2828   return static_cast<Flags>(bits);
   2829 }
   2830 
   2831 
   2832 Code* Code::GetCodeFromTargetAddress(Address address) {
   2833   HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
   2834   // GetCodeFromTargetAddress might be called when marking objects during mark
   2835   // sweep. reinterpret_cast is therefore used instead of the more appropriate
   2836   // Code::cast. Code::cast does not work when the object's map is
   2837   // marked.
   2838   Code* result = reinterpret_cast<Code*>(code);
   2839   return result;
   2840 }
   2841 
   2842 
   2843 Isolate* Map::isolate() {
   2844   return heap()->isolate();
   2845 }
   2846 
   2847 
   2848 Heap* Map::heap() {
   2849   // NOTE: address() helper is not used to save one instruction.
   2850   Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
   2851   ASSERT(heap != NULL);
   2852   ASSERT(heap->isolate() == Isolate::Current());
   2853   return heap;
   2854 }
   2855 
   2856 
   2857 Heap* Code::heap() {
   2858   // NOTE: address() helper is not used to save one instruction.
   2859   Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
   2860   ASSERT(heap != NULL);
   2861   ASSERT(heap->isolate() == Isolate::Current());
   2862   return heap;
   2863 }
   2864 
   2865 
   2866 Isolate* Code::isolate() {
   2867   return heap()->isolate();
   2868 }
   2869 
   2870 
   2871 Heap* JSGlobalPropertyCell::heap() {
   2872   // NOTE: address() helper is not used to save one instruction.
   2873   Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
   2874   ASSERT(heap != NULL);
   2875   ASSERT(heap->isolate() == Isolate::Current());
   2876   return heap;
   2877 }
   2878 
   2879 
   2880 Isolate* JSGlobalPropertyCell::isolate() {
   2881   return heap()->isolate();
   2882 }
   2883 
   2884 
   2885 Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
   2886   return HeapObject::
   2887       FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
   2888 }
   2889 
   2890 
   2891 Object* Map::prototype() {
   2892   return READ_FIELD(this, kPrototypeOffset);
   2893 }
   2894 
   2895 
   2896 void Map::set_prototype(Object* value, WriteBarrierMode mode) {
   2897   ASSERT(value->IsNull() || value->IsJSObject());
   2898   WRITE_FIELD(this, kPrototypeOffset, value);
   2899   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
   2900 }
   2901 
   2902 
   2903 MaybeObject* Map::GetFastElementsMap() {
   2904   if (has_fast_elements()) return this;
   2905   Object* obj;
   2906   { MaybeObject* maybe_obj = CopyDropTransitions();
   2907     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   2908   }
   2909   Map* new_map = Map::cast(obj);
   2910   new_map->set_has_fast_elements(true);
   2911   isolate()->counters()->map_slow_to_fast_elements()->Increment();
   2912   return new_map;
   2913 }
   2914 
   2915 
   2916 MaybeObject* Map::GetSlowElementsMap() {
   2917   if (!has_fast_elements()) return this;
   2918   Object* obj;
   2919   { MaybeObject* maybe_obj = CopyDropTransitions();
   2920     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   2921   }
   2922   Map* new_map = Map::cast(obj);
   2923   new_map->set_has_fast_elements(false);
   2924   isolate()->counters()->map_fast_to_slow_elements()->Increment();
   2925   return new_map;
   2926 }
   2927 
   2928 
   2929 ACCESSORS(Map, instance_descriptors, DescriptorArray,
   2930           kInstanceDescriptorsOffset)
   2931 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
   2932 ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
   2933 ACCESSORS(Map, constructor, Object, kConstructorOffset)
   2934 
   2935 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
   2936 ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
   2937 ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
   2938                  kNextFunctionLinkOffset)
   2939 
   2940 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
   2941 ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
   2942 ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
   2943 
   2944 ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
   2945 
   2946 ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
   2947 ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
   2948 ACCESSORS(AccessorInfo, data, Object, kDataOffset)
   2949 ACCESSORS(AccessorInfo, name, Object, kNameOffset)
   2950 ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
   2951 
   2952 ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
   2953 ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
   2954 ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
   2955 
   2956 ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
   2957 ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
   2958 ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
   2959 ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
   2960 ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
   2961 ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
   2962 
   2963 ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
   2964 ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
   2965 
   2966 ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
   2967 ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
   2968 
   2969 ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
   2970 ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
   2971 ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
   2972           kPropertyAccessorsOffset)
   2973 ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
   2974           kPrototypeTemplateOffset)
   2975 ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
   2976 ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
   2977           kNamedPropertyHandlerOffset)
   2978 ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
   2979           kIndexedPropertyHandlerOffset)
   2980 ACCESSORS(FunctionTemplateInfo, instance_template, Object,
   2981           kInstanceTemplateOffset)
   2982 ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
   2983 ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
   2984 ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
   2985           kInstanceCallHandlerOffset)
   2986 ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
   2987           kAccessCheckInfoOffset)
   2988 ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
   2989 
   2990 ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
   2991 ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
   2992           kInternalFieldCountOffset)
   2993 
   2994 ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
   2995 ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
   2996 
   2997 ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
   2998 
   2999 ACCESSORS(Script, source, Object, kSourceOffset)
   3000 ACCESSORS(Script, name, Object, kNameOffset)
   3001 ACCESSORS(Script, id, Object, kIdOffset)
   3002 ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
   3003 ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
   3004 ACCESSORS(Script, data, Object, kDataOffset)
   3005 ACCESSORS(Script, context_data, Object, kContextOffset)
   3006 ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
   3007 ACCESSORS(Script, type, Smi, kTypeOffset)
   3008 ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
   3009 ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
   3010 ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
   3011 ACCESSORS(Script, eval_from_instructions_offset, Smi,
   3012           kEvalFrominstructionsOffsetOffset)
   3013 
   3014 #ifdef ENABLE_DEBUGGER_SUPPORT
   3015 ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
   3016 ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
   3017 ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
   3018 ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
   3019 
   3020 ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
   3021 ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
   3022 ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
   3023 ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
   3024 #endif
   3025 
   3026 ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
   3027 ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
   3028 ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
   3029 ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
   3030           kInstanceClassNameOffset)
   3031 ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
   3032 ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
   3033 ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
   3034 ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
   3035 ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
   3036           kThisPropertyAssignmentsOffset)
   3037 
   3038 BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
   3039                kHiddenPrototypeBit)
   3040 BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
   3041 BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
   3042                kNeedsAccessCheckBit)
   3043 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
   3044                kIsExpressionBit)
   3045 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
   3046                kIsTopLevelBit)
   3047 BOOL_GETTER(SharedFunctionInfo, compiler_hints,
   3048             has_only_simple_this_property_assignments,
   3049             kHasOnlySimpleThisPropertyAssignments)
   3050 BOOL_ACCESSORS(SharedFunctionInfo,
   3051                compiler_hints,
   3052                allows_lazy_compilation,
   3053                kAllowLazyCompilation)
   3054 
   3055 
   3056 #if V8_HOST_ARCH_32_BIT
   3057 SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
   3058 SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
   3059               kFormalParameterCountOffset)
   3060 SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
   3061               kExpectedNofPropertiesOffset)
   3062 SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
   3063 SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
   3064               kStartPositionAndTypeOffset)
   3065 SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
   3066 SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
   3067               kFunctionTokenPositionOffset)
   3068 SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
   3069               kCompilerHintsOffset)
   3070 SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
   3071               kThisPropertyAssignmentsCountOffset)
   3072 SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
   3073 #else
   3074 
   3075 #define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset)             \
   3076   STATIC_ASSERT(holder::offset % kPointerSize == 0);              \
   3077   int holder::name() {                                            \
   3078     int value = READ_INT_FIELD(this, offset);                     \
   3079     ASSERT(kHeapObjectTag == 1);                                  \
   3080     ASSERT((value & kHeapObjectTag) == 0);                        \
   3081     return value >> 1;                                            \
   3082   }                                                               \
   3083   void holder::set_##name(int value) {                            \
   3084     ASSERT(kHeapObjectTag == 1);                                  \
   3085     ASSERT((value & 0xC0000000) == 0xC0000000 ||                  \
   3086            (value & 0xC0000000) == 0x000000000);                  \
   3087     WRITE_INT_FIELD(this,                                         \
   3088                     offset,                                       \
   3089                     (value << 1) & ~kHeapObjectTag);              \
   3090   }
   3091 
   3092 #define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset)             \
   3093   STATIC_ASSERT(holder::offset % kPointerSize == kIntSize);       \
   3094   INT_ACCESSORS(holder, name, offset)
   3095 
   3096 
   3097 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
   3098 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
   3099                         formal_parameter_count,
   3100                         kFormalParameterCountOffset)
   3101 
   3102 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
   3103                         expected_nof_properties,
   3104                         kExpectedNofPropertiesOffset)
   3105 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
   3106 
   3107 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
   3108 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
   3109                         start_position_and_type,
   3110                         kStartPositionAndTypeOffset)
   3111 
   3112 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
   3113                         function_token_position,
   3114                         kFunctionTokenPositionOffset)
   3115 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
   3116                         compiler_hints,
   3117                         kCompilerHintsOffset)
   3118 
   3119 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
   3120                         this_property_assignments_count,
   3121                         kThisPropertyAssignmentsCountOffset)
   3122 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
   3123 #endif
   3124 
   3125 
   3126 int SharedFunctionInfo::construction_count() {
   3127   return READ_BYTE_FIELD(this, kConstructionCountOffset);
   3128 }
   3129 
   3130 
   3131 void SharedFunctionInfo::set_construction_count(int value) {
   3132   ASSERT(0 <= value && value < 256);
   3133   WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
   3134 }
   3135 
   3136 
   3137 bool SharedFunctionInfo::live_objects_may_exist() {
   3138   return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
   3139 }
   3140 
   3141 
   3142 void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
   3143   if (value) {
   3144     set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
   3145   } else {
   3146     set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
   3147   }
   3148 }
   3149 
   3150 
   3151 bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
   3152   return initial_map() != HEAP->undefined_value();
   3153 }
   3154 
   3155 
   3156 bool SharedFunctionInfo::optimization_disabled() {
   3157   return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
   3158 }
   3159 
   3160 
   3161 void SharedFunctionInfo::set_optimization_disabled(bool disable) {
   3162   set_compiler_hints(BooleanBit::set(compiler_hints(),
   3163                                      kOptimizationDisabled,
   3164                                      disable));
   3165   // If disabling optimizations we reflect that in the code object so
   3166   // it will not be counted as optimizable code.
   3167   if ((code()->kind() == Code::FUNCTION) && disable) {
   3168     code()->set_optimizable(false);
   3169   }
   3170 }
   3171 
   3172 
   3173 bool SharedFunctionInfo::strict_mode() {
   3174   return BooleanBit::get(compiler_hints(), kStrictModeFunction);
   3175 }
   3176 
   3177 
   3178 void SharedFunctionInfo::set_strict_mode(bool value) {
   3179   set_compiler_hints(BooleanBit::set(compiler_hints(),
   3180                                      kStrictModeFunction,
   3181                                      value));
   3182 }
   3183 
   3184 
   3185 ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
   3186 ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
   3187 
   3188 bool Script::HasValidSource() {
   3189   Object* src = this->source();
   3190   if (!src->IsString()) return true;
   3191   String* src_str = String::cast(src);
   3192   if (!StringShape(src_str).IsExternal()) return true;
   3193   if (src_str->IsAsciiRepresentation()) {
   3194     return ExternalAsciiString::cast(src)->resource() != NULL;
   3195   } else if (src_str->IsTwoByteRepresentation()) {
   3196     return ExternalTwoByteString::cast(src)->resource() != NULL;
   3197   }
   3198   return true;
   3199 }
   3200 
   3201 
   3202 void SharedFunctionInfo::DontAdaptArguments() {
   3203   ASSERT(code()->kind() == Code::BUILTIN);
   3204   set_formal_parameter_count(kDontAdaptArgumentsSentinel);
   3205 }
   3206 
   3207 
   3208 int SharedFunctionInfo::start_position() {
   3209   return start_position_and_type() >> kStartPositionShift;
   3210 }
   3211 
   3212 
   3213 void SharedFunctionInfo::set_start_position(int start_position) {
   3214   set_start_position_and_type((start_position << kStartPositionShift)
   3215     | (start_position_and_type() & ~kStartPositionMask));
   3216 }
   3217 
   3218 
   3219 Code* SharedFunctionInfo::code() {
   3220   return Code::cast(READ_FIELD(this, kCodeOffset));
   3221 }
   3222 
   3223 
   3224 Code* SharedFunctionInfo::unchecked_code() {
   3225   return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
   3226 }
   3227 
   3228 
   3229 void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
   3230   WRITE_FIELD(this, kCodeOffset, value);
   3231   ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
   3232 }
   3233 
   3234 
   3235 SerializedScopeInfo* SharedFunctionInfo::scope_info() {
   3236   return reinterpret_cast<SerializedScopeInfo*>(
   3237       READ_FIELD(this, kScopeInfoOffset));
   3238 }
   3239 
   3240 
   3241 void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
   3242                                         WriteBarrierMode mode) {
   3243   WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
   3244   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
   3245 }
   3246 
   3247 
   3248 Smi* SharedFunctionInfo::deopt_counter() {
   3249   return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
   3250 }
   3251 
   3252 
   3253 void SharedFunctionInfo::set_deopt_counter(Smi* value) {
   3254   WRITE_FIELD(this, kDeoptCounterOffset, value);
   3255 }
   3256 
   3257 
   3258 bool SharedFunctionInfo::is_compiled() {
   3259   return code() !=
   3260       Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
   3261 }
   3262 
   3263 
   3264 bool SharedFunctionInfo::IsApiFunction() {
   3265   return function_data()->IsFunctionTemplateInfo();
   3266 }
   3267 
   3268 
   3269 FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
   3270   ASSERT(IsApiFunction());
   3271   return FunctionTemplateInfo::cast(function_data());
   3272 }
   3273 
   3274 
   3275 bool SharedFunctionInfo::HasBuiltinFunctionId() {
   3276   return function_data()->IsSmi();
   3277 }
   3278 
   3279 
   3280 BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
   3281   ASSERT(HasBuiltinFunctionId());
   3282   return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
   3283 }
   3284 
   3285 
   3286 int SharedFunctionInfo::code_age() {
   3287   return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
   3288 }
   3289 
   3290 
   3291 void SharedFunctionInfo::set_code_age(int code_age) {
   3292   set_compiler_hints(compiler_hints() |
   3293                      ((code_age & kCodeAgeMask) << kCodeAgeShift));
   3294 }
   3295 
   3296 
   3297 bool SharedFunctionInfo::has_deoptimization_support() {
   3298   Code* code = this->code();
   3299   return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
   3300 }
   3301 
   3302 
   3303 bool JSFunction::IsBuiltin() {
   3304   return context()->global()->IsJSBuiltinsObject();
   3305 }
   3306 
   3307 
   3308 bool JSFunction::NeedsArgumentsAdaption() {
   3309   return shared()->formal_parameter_count() !=
   3310       SharedFunctionInfo::kDontAdaptArgumentsSentinel;
   3311 }
   3312 
   3313 
   3314 bool JSFunction::IsOptimized() {
   3315   return code()->kind() == Code::OPTIMIZED_FUNCTION;
   3316 }
   3317 
   3318 
   3319 bool JSFunction::IsOptimizable() {
   3320   return code()->kind() == Code::FUNCTION && code()->optimizable();
   3321 }
   3322 
   3323 
   3324 bool JSFunction::IsMarkedForLazyRecompilation() {
   3325   return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
   3326 }
   3327 
   3328 
   3329 Code* JSFunction::code() {
   3330   return Code::cast(unchecked_code());
   3331 }
   3332 
   3333 
   3334 Code* JSFunction::unchecked_code() {
   3335   return reinterpret_cast<Code*>(
   3336       Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
   3337 }
   3338 
   3339 
   3340 void JSFunction::set_code(Code* value) {
   3341   // Skip the write barrier because code is never in new space.
   3342   ASSERT(!HEAP->InNewSpace(value));
   3343   Address entry = value->entry();
   3344   WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
   3345 }
   3346 
   3347 
   3348 void JSFunction::ReplaceCode(Code* code) {
   3349   bool was_optimized = IsOptimized();
   3350   bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
   3351 
   3352   set_code(code);
   3353 
   3354   // Add/remove the function from the list of optimized functions for this
   3355   // context based on the state change.
   3356   if (!was_optimized && is_optimized) {
   3357     context()->global_context()->AddOptimizedFunction(this);
   3358   }
   3359   if (was_optimized && !is_optimized) {
   3360     context()->global_context()->RemoveOptimizedFunction(this);
   3361   }
   3362 }
   3363 
   3364 
   3365 Context* JSFunction::context() {
   3366   return Context::cast(READ_FIELD(this, kContextOffset));
   3367 }
   3368 
   3369 
   3370 Object* JSFunction::unchecked_context() {
   3371   return READ_FIELD(this, kContextOffset);
   3372 }
   3373 
   3374 
   3375 SharedFunctionInfo* JSFunction::unchecked_shared() {
   3376   return reinterpret_cast<SharedFunctionInfo*>(
   3377       READ_FIELD(this, kSharedFunctionInfoOffset));
   3378 }
   3379 
   3380 
   3381 void JSFunction::set_context(Object* value) {
   3382   ASSERT(value->IsUndefined() || value->IsContext());
   3383   WRITE_FIELD(this, kContextOffset, value);
   3384   WRITE_BARRIER(this, kContextOffset);
   3385 }
   3386 
   3387 ACCESSORS(JSFunction, prototype_or_initial_map, Object,
   3388           kPrototypeOrInitialMapOffset)
   3389 
   3390 
   3391 Map* JSFunction::initial_map() {
   3392   return Map::cast(prototype_or_initial_map());
   3393 }
   3394 
   3395 
   3396 void JSFunction::set_initial_map(Map* value) {
   3397   set_prototype_or_initial_map(value);
   3398 }
   3399 
   3400 
   3401 bool JSFunction::has_initial_map() {
   3402   return prototype_or_initial_map()->IsMap();
   3403 }
   3404 
   3405 
   3406 bool JSFunction::has_instance_prototype() {
   3407   return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
   3408 }
   3409 
   3410 
   3411 bool JSFunction::has_prototype() {
   3412   return map()->has_non_instance_prototype() || has_instance_prototype();
   3413 }
   3414 
   3415 
   3416 Object* JSFunction::instance_prototype() {
   3417   ASSERT(has_instance_prototype());
   3418   if (has_initial_map()) return initial_map()->prototype();
   3419   // When there is no initial map and the prototype is a JSObject, the
   3420   // initial map field is used for the prototype field.
   3421   return prototype_or_initial_map();
   3422 }
   3423 
   3424 
   3425 Object* JSFunction::prototype() {
   3426   ASSERT(has_prototype());
   3427   // If the function's prototype property has been set to a non-JSObject
   3428   // value, that value is stored in the constructor field of the map.
   3429   if (map()->has_non_instance_prototype()) return map()->constructor();
   3430   return instance_prototype();
   3431 }
   3432 
   3433 bool JSFunction::should_have_prototype() {
   3434   return map()->function_with_prototype();
   3435 }
   3436 
   3437 
   3438 bool JSFunction::is_compiled() {
   3439   return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
   3440 }
   3441 
   3442 
   3443 int JSFunction::NumberOfLiterals() {
   3444   return literals()->length();
   3445 }
   3446 
   3447 
   3448 Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
   3449   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
   3450   return READ_FIELD(this, OffsetOfFunctionWithId(id));
   3451 }
   3452 
   3453 
   3454 void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
   3455                                               Object* value) {
   3456   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
   3457   WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
   3458   WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
   3459 }
   3460 
   3461 
   3462 Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
   3463   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
   3464   return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
   3465 }
   3466 
   3467 
   3468 void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
   3469                                                    Code* value) {
   3470   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
   3471   WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
   3472   ASSERT(!HEAP->InNewSpace(value));
   3473 }
   3474 
   3475 
   3476 Address Proxy::proxy() {
   3477   return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
   3478 }
   3479 
   3480 
   3481 void Proxy::set_proxy(Address value) {
   3482   WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
   3483 }
   3484 
   3485 
   3486 ACCESSORS(JSValue, value, Object, kValueOffset)
   3487 
   3488 
   3489 JSValue* JSValue::cast(Object* obj) {
   3490   ASSERT(obj->IsJSValue());
   3491   ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
   3492   return reinterpret_cast<JSValue*>(obj);
   3493 }
   3494 
   3495 
   3496 ACCESSORS(JSMessageObject, type, String, kTypeOffset)
   3497 ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
   3498 ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
   3499 ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
   3500 ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
   3501 SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
   3502 SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
   3503 
   3504 
   3505 JSMessageObject* JSMessageObject::cast(Object* obj) {
   3506   ASSERT(obj->IsJSMessageObject());
   3507   ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
   3508   return reinterpret_cast<JSMessageObject*>(obj);
   3509 }
   3510 
   3511 
   3512 INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
   3513 ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
   3514 ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
   3515 
   3516 
   3517 byte* Code::instruction_start()  {
   3518   return FIELD_ADDR(this, kHeaderSize);
   3519 }
   3520 
   3521 
   3522 byte* Code::instruction_end()  {
   3523   return instruction_start() + instruction_size();
   3524 }
   3525 
   3526 
   3527 int Code::body_size() {
   3528   return RoundUp(instruction_size(), kObjectAlignment);
   3529 }
   3530 
   3531 
   3532 FixedArray* Code::unchecked_deoptimization_data() {
   3533   return reinterpret_cast<FixedArray*>(
   3534       READ_FIELD(this, kDeoptimizationDataOffset));
   3535 }
   3536 
   3537 
   3538 ByteArray* Code::unchecked_relocation_info() {
   3539   return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
   3540 }
   3541 
   3542 
   3543 byte* Code::relocation_start() {
   3544   return unchecked_relocation_info()->GetDataStartAddress();
   3545 }
   3546 
   3547 
   3548 int Code::relocation_size() {
   3549   return unchecked_relocation_info()->length();
   3550 }
   3551 
   3552 
   3553 byte* Code::entry() {
   3554   return instruction_start();
   3555 }
   3556 
   3557 
   3558 bool Code::contains(byte* pc) {
   3559   return (instruction_start() <= pc) &&
   3560       (pc <= instruction_start() + instruction_size());
   3561 }
   3562 
   3563 
   3564 ACCESSORS(JSArray, length, Object, kLengthOffset)
   3565 
   3566 
   3567 ACCESSORS(JSRegExp, data, Object, kDataOffset)
   3568 
   3569 
   3570 JSRegExp::Type JSRegExp::TypeTag() {
   3571   Object* data = this->data();
   3572   if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
   3573   Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
   3574   return static_cast<JSRegExp::Type>(smi->value());
   3575 }
   3576 
   3577 
   3578 int JSRegExp::CaptureCount() {
   3579   switch (TypeTag()) {
   3580     case ATOM:
   3581       return 0;
   3582     case IRREGEXP:
   3583       return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
   3584     default:
   3585       UNREACHABLE();
   3586       return -1;
   3587   }
   3588 }
   3589 
   3590 
   3591 JSRegExp::Flags JSRegExp::GetFlags() {
   3592   ASSERT(this->data()->IsFixedArray());
   3593   Object* data = this->data();
   3594   Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
   3595   return Flags(smi->value());
   3596 }
   3597 
   3598 
   3599 String* JSRegExp::Pattern() {
   3600   ASSERT(this->data()->IsFixedArray());
   3601   Object* data = this->data();
   3602   String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
   3603   return pattern;
   3604 }
   3605 
   3606 
   3607 Object* JSRegExp::DataAt(int index) {
   3608   ASSERT(TypeTag() != NOT_COMPILED);
   3609   return FixedArray::cast(data())->get(index);
   3610 }
   3611 
   3612 
   3613 void JSRegExp::SetDataAt(int index, Object* value) {
   3614   ASSERT(TypeTag() != NOT_COMPILED);
   3615   ASSERT(index >= kDataIndex);  // Only implementation data can be set this way.
   3616   FixedArray::cast(data())->set(index, value);
   3617 }
   3618 
   3619 
   3620 JSObject::ElementsKind JSObject::GetElementsKind() {
   3621   if (map()->has_fast_elements()) {
   3622     ASSERT(elements()->map() == GetHeap()->fixed_array_map() ||
   3623            elements()->map() == GetHeap()->fixed_cow_array_map());
   3624     return FAST_ELEMENTS;
   3625   }
   3626   HeapObject* array = elements();
   3627   if (array->IsFixedArray()) {
   3628     // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
   3629     // FixedArray, but FAST_ELEMENTS is already handled above.
   3630     ASSERT(array->IsDictionary());
   3631     return DICTIONARY_ELEMENTS;
   3632   }
   3633   ASSERT(!map()->has_fast_elements());
   3634   if (array->IsExternalArray()) {
   3635     switch (array->map()->instance_type()) {
   3636       case EXTERNAL_BYTE_ARRAY_TYPE:
   3637         return EXTERNAL_BYTE_ELEMENTS;
   3638       case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
   3639         return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
   3640       case EXTERNAL_SHORT_ARRAY_TYPE:
   3641         return EXTERNAL_SHORT_ELEMENTS;
   3642       case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
   3643         return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
   3644       case EXTERNAL_INT_ARRAY_TYPE:
   3645         return EXTERNAL_INT_ELEMENTS;
   3646       case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
   3647         return EXTERNAL_UNSIGNED_INT_ELEMENTS;
   3648       case EXTERNAL_PIXEL_ARRAY_TYPE:
   3649         return EXTERNAL_PIXEL_ELEMENTS;
   3650       default:
   3651         break;
   3652     }
   3653   }
   3654   ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
   3655   return EXTERNAL_FLOAT_ELEMENTS;
   3656 }
   3657 
   3658 
   3659 bool JSObject::HasFastElements() {
   3660   return GetElementsKind() == FAST_ELEMENTS;
   3661 }
   3662 
   3663 
   3664 bool JSObject::HasDictionaryElements() {
   3665   return GetElementsKind() == DICTIONARY_ELEMENTS;
   3666 }
   3667 
   3668 
   3669 bool JSObject::HasExternalArrayElements() {
   3670   HeapObject* array = elements();
   3671   ASSERT(array != NULL);
   3672   return array->IsExternalArray();
   3673 }
   3674 
   3675 
   3676 #define EXTERNAL_ELEMENTS_CHECK(name, type)          \
   3677 bool JSObject::HasExternal##name##Elements() {       \
   3678   HeapObject* array = elements();                    \
   3679   ASSERT(array != NULL);                             \
   3680   if (!array->IsHeapObject())                        \
   3681     return false;                                    \
   3682   return array->map()->instance_type() == type;      \
   3683 }
   3684 
   3685 
   3686 EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
   3687 EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
   3688 EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
   3689 EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
   3690                         EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
   3691 EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
   3692 EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
   3693                         EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
   3694 EXTERNAL_ELEMENTS_CHECK(Float,
   3695                         EXTERNAL_FLOAT_ARRAY_TYPE)
   3696 EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
   3697 
   3698 
   3699 bool JSObject::HasNamedInterceptor() {
   3700   return map()->has_named_interceptor();
   3701 }
   3702 
   3703 
   3704 bool JSObject::HasIndexedInterceptor() {
   3705   return map()->has_indexed_interceptor();
   3706 }
   3707 
   3708 
   3709 bool JSObject::AllowsSetElementsLength() {
   3710   bool result = elements()->IsFixedArray();
   3711   ASSERT(result == !HasExternalArrayElements());
   3712   return result;
   3713 }
   3714 
   3715 
   3716 MaybeObject* JSObject::EnsureWritableFastElements() {
   3717   ASSERT(HasFastElements());
   3718   FixedArray* elems = FixedArray::cast(elements());
   3719   Isolate* isolate = GetIsolate();
   3720   if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
   3721   Object* writable_elems;
   3722   { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
   3723       elems, isolate->heap()->fixed_array_map());
   3724     if (!maybe_writable_elems->ToObject(&writable_elems)) {
   3725       return maybe_writable_elems;
   3726     }
   3727   }
   3728   set_elements(FixedArray::cast(writable_elems));
   3729   isolate->counters()->cow_arrays_converted()->Increment();
   3730   return writable_elems;
   3731 }
   3732 
   3733 
   3734 StringDictionary* JSObject::property_dictionary() {
   3735   ASSERT(!HasFastProperties());
   3736   return StringDictionary::cast(properties());
   3737 }
   3738 
   3739 
   3740 NumberDictionary* JSObject::element_dictionary() {
   3741   ASSERT(HasDictionaryElements());
   3742   return NumberDictionary::cast(elements());
   3743 }
   3744 
   3745 
   3746 bool String::IsHashFieldComputed(uint32_t field) {
   3747   return (field & kHashNotComputedMask) == 0;
   3748 }
   3749 
   3750 
   3751 bool String::HasHashCode() {
   3752   return IsHashFieldComputed(hash_field());
   3753 }
   3754 
   3755 
   3756 uint32_t String::Hash() {
   3757   // Fast case: has hash code already been computed?
   3758   uint32_t field = hash_field();
   3759   if (IsHashFieldComputed(field)) return field >> kHashShift;
   3760   // Slow case: compute hash code and set it.
   3761   return ComputeAndSetHash();
   3762 }
   3763 
   3764 
   3765 StringHasher::StringHasher(int length)
   3766   : length_(length),
   3767     raw_running_hash_(0),
   3768     array_index_(0),
   3769     is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
   3770     is_first_char_(true),
   3771     is_valid_(true) { }
   3772 
   3773 
   3774 bool StringHasher::has_trivial_hash() {
   3775   return length_ > String::kMaxHashCalcLength;
   3776 }
   3777 
   3778 
   3779 void StringHasher::AddCharacter(uc32 c) {
   3780   // Use the Jenkins one-at-a-time hash function to update the hash
   3781   // for the given character.
   3782   raw_running_hash_ += c;
   3783   raw_running_hash_ += (raw_running_hash_ << 10);
   3784   raw_running_hash_ ^= (raw_running_hash_ >> 6);
   3785   // Incremental array index computation.
   3786   if (is_array_index_) {
   3787     if (c < '0' || c > '9') {
   3788       is_array_index_ = false;
   3789     } else {
   3790       int d = c - '0';
   3791       if (is_first_char_) {
   3792         is_first_char_ = false;
   3793         if (c == '0' && length_ > 1) {
   3794           is_array_index_ = false;
   3795           return;
   3796         }
   3797       }
   3798       if (array_index_ > 429496729U - ((d + 2) >> 3)) {
   3799         is_array_index_ = false;
   3800       } else {
   3801         array_index_ = array_index_ * 10 + d;
   3802       }
   3803     }
   3804   }
   3805 }
   3806 
   3807 
   3808 void StringHasher::AddCharacterNoIndex(uc32 c) {
   3809   ASSERT(!is_array_index());
   3810   raw_running_hash_ += c;
   3811   raw_running_hash_ += (raw_running_hash_ << 10);
   3812   raw_running_hash_ ^= (raw_running_hash_ >> 6);
   3813 }
   3814 
   3815 
   3816 uint32_t StringHasher::GetHash() {
   3817   // Get the calculated raw hash value and do some more bit ops to distribute
   3818   // the hash further. Ensure that we never return zero as the hash value.
   3819   uint32_t result = raw_running_hash_;
   3820   result += (result << 3);
   3821   result ^= (result >> 11);
   3822   result += (result << 15);
   3823   if (result == 0) {
   3824     result = 27;
   3825   }
   3826   return result;
   3827 }
   3828 
   3829 
   3830 template <typename schar>
   3831 uint32_t HashSequentialString(const schar* chars, int length) {
   3832   StringHasher hasher(length);
   3833   if (!hasher.has_trivial_hash()) {
   3834     int i;
   3835     for (i = 0; hasher.is_array_index() && (i < length); i++) {
   3836       hasher.AddCharacter(chars[i]);
   3837     }
   3838     for (; i < length; i++) {
   3839       hasher.AddCharacterNoIndex(chars[i]);
   3840     }
   3841   }
   3842   return hasher.GetHashField();
   3843 }
   3844 
   3845 
   3846 bool String::AsArrayIndex(uint32_t* index) {
   3847   uint32_t field = hash_field();
   3848   if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
   3849     return false;
   3850   }
   3851   return SlowAsArrayIndex(index);
   3852 }
   3853 
   3854 
   3855 Object* JSObject::GetPrototype() {
   3856   return JSObject::cast(this)->map()->prototype();
   3857 }
   3858 
   3859 
   3860 PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
   3861   return GetPropertyAttributeWithReceiver(this, key);
   3862 }
   3863 
   3864 // TODO(504): this may be useful in other places too where JSGlobalProxy
   3865 // is used.
   3866 Object* JSObject::BypassGlobalProxy() {
   3867   if (IsJSGlobalProxy()) {
   3868     Object* proto = GetPrototype();
   3869     if (proto->IsNull()) return GetHeap()->undefined_value();
   3870     ASSERT(proto->IsJSGlobalObject());
   3871     return proto;
   3872   }
   3873   return this;
   3874 }
   3875 
   3876 
   3877 bool JSObject::HasHiddenPropertiesObject() {
   3878   ASSERT(!IsJSGlobalProxy());
   3879   return GetPropertyAttributePostInterceptor(this,
   3880                                              GetHeap()->hidden_symbol(),
   3881                                              false) != ABSENT;
   3882 }
   3883 
   3884 
   3885 Object* JSObject::GetHiddenPropertiesObject() {
   3886   ASSERT(!IsJSGlobalProxy());
   3887   PropertyAttributes attributes;
   3888   // You can't install a getter on a property indexed by the hidden symbol,
   3889   // so we can be sure that GetLocalPropertyPostInterceptor returns a real
   3890   // object.
   3891   Object* result =
   3892       GetLocalPropertyPostInterceptor(this,
   3893                                       GetHeap()->hidden_symbol(),
   3894                                       &attributes)->ToObjectUnchecked();
   3895   return result;
   3896 }
   3897 
   3898 
   3899 MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
   3900   ASSERT(!IsJSGlobalProxy());
   3901   return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
   3902                                     hidden_obj,
   3903                                     DONT_ENUM,
   3904                                     kNonStrictMode);
   3905 }
   3906 
   3907 
   3908 bool JSObject::HasElement(uint32_t index) {
   3909   return HasElementWithReceiver(this, index);
   3910 }
   3911 
   3912 
   3913 bool AccessorInfo::all_can_read() {
   3914   return BooleanBit::get(flag(), kAllCanReadBit);
   3915 }
   3916 
   3917 
   3918 void AccessorInfo::set_all_can_read(bool value) {
   3919   set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
   3920 }
   3921 
   3922 
   3923 bool AccessorInfo::all_can_write() {
   3924   return BooleanBit::get(flag(), kAllCanWriteBit);
   3925 }
   3926 
   3927 
   3928 void AccessorInfo::set_all_can_write(bool value) {
   3929   set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
   3930 }
   3931 
   3932 
   3933 bool AccessorInfo::prohibits_overwriting() {
   3934   return BooleanBit::get(flag(), kProhibitsOverwritingBit);
   3935 }
   3936 
   3937 
   3938 void AccessorInfo::set_prohibits_overwriting(bool value) {
   3939   set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
   3940 }
   3941 
   3942 
   3943 PropertyAttributes AccessorInfo::property_attributes() {
   3944   return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
   3945 }
   3946 
   3947 
   3948 void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
   3949   ASSERT(AttributesField::is_valid(attributes));
   3950   int rest_value = flag()->value() & ~AttributesField::mask();
   3951   set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
   3952 }
   3953 
   3954 
   3955 template<typename Shape, typename Key>
   3956 void Dictionary<Shape, Key>::SetEntry(int entry,
   3957                                       Object* key,
   3958                                       Object* value) {
   3959   SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
   3960 }
   3961 
   3962 
   3963 template<typename Shape, typename Key>
   3964 void Dictionary<Shape, Key>::SetEntry(int entry,
   3965                                       Object* key,
   3966                                       Object* value,
   3967                                       PropertyDetails details) {
   3968   ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
   3969   int index = HashTable<Shape, Key>::EntryToIndex(entry);
   3970   AssertNoAllocation no_gc;
   3971   WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
   3972   FixedArray::set(index, key, mode);
   3973   FixedArray::set(index+1, value, mode);
   3974   FixedArray::fast_set(this, index+2, details.AsSmi());
   3975 }
   3976 
   3977 
   3978 bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
   3979   ASSERT(other->IsNumber());
   3980   return key == static_cast<uint32_t>(other->Number());
   3981 }
   3982 
   3983 
   3984 uint32_t NumberDictionaryShape::Hash(uint32_t key) {
   3985   return ComputeIntegerHash(key);
   3986 }
   3987 
   3988 
   3989 uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
   3990   ASSERT(other->IsNumber());
   3991   return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
   3992 }
   3993 
   3994 
   3995 MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
   3996   return Isolate::Current()->heap()->NumberFromUint32(key);
   3997 }
   3998 
   3999 
   4000 bool StringDictionaryShape::IsMatch(String* key, Object* other) {
   4001   // We know that all entries in a hash table had their hash keys created.
   4002   // Use that knowledge to have fast failure.
   4003   if (key->Hash() != String::cast(other)->Hash()) return false;
   4004   return key->Equals(String::cast(other));
   4005 }
   4006 
   4007 
   4008 uint32_t StringDictionaryShape::Hash(String* key) {
   4009   return key->Hash();
   4010 }
   4011 
   4012 
   4013 uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
   4014   return String::cast(other)->Hash();
   4015 }
   4016 
   4017 
   4018 MaybeObject* StringDictionaryShape::AsObject(String* key) {
   4019   return key;
   4020 }
   4021 
   4022 
   4023 void Map::ClearCodeCache(Heap* heap) {
   4024   // No write barrier is needed since empty_fixed_array is not in new space.
   4025   // Please note this function is used during marking:
   4026   //  - MarkCompactCollector::MarkUnmarkedObject
   4027   ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
   4028   WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
   4029 }
   4030 
   4031 
   4032 void JSArray::EnsureSize(int required_size) {
   4033   ASSERT(HasFastElements());
   4034   FixedArray* elts = FixedArray::cast(elements());
   4035   const int kArraySizeThatFitsComfortablyInNewSpace = 128;
   4036   if (elts->length() < required_size) {
   4037     // Doubling in size would be overkill, but leave some slack to avoid
   4038     // constantly growing.
   4039     Expand(required_size + (required_size >> 3));
   4040     // It's a performance benefit to keep a frequently used array in new-space.
   4041   } else if (!GetHeap()->new_space()->Contains(elts) &&
   4042              required_size < kArraySizeThatFitsComfortablyInNewSpace) {
   4043     // Expand will allocate a new backing store in new space even if the size
   4044     // we asked for isn't larger than what we had before.
   4045     Expand(required_size);
   4046   }
   4047 }
   4048 
   4049 
   4050 void JSArray::set_length(Smi* length) {
   4051   set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
   4052 }
   4053 
   4054 
   4055 void JSArray::SetContent(FixedArray* storage) {
   4056   set_length(Smi::FromInt(storage->length()));
   4057   set_elements(storage);
   4058 }
   4059 
   4060 
   4061 MaybeObject* FixedArray::Copy() {
   4062   if (length() == 0) return this;
   4063   return GetHeap()->CopyFixedArray(this);
   4064 }
   4065 
   4066 
   4067 Relocatable::Relocatable(Isolate* isolate) {
   4068   ASSERT(isolate == Isolate::Current());
   4069   isolate_ = isolate;
   4070   prev_ = isolate->relocatable_top();
   4071   isolate->set_relocatable_top(this);
   4072 }
   4073 
   4074 
   4075 Relocatable::~Relocatable() {
   4076   ASSERT(isolate_ == Isolate::Current());
   4077   ASSERT_EQ(isolate_->relocatable_top(), this);
   4078   isolate_->set_relocatable_top(prev_);
   4079 }
   4080 
   4081 
   4082 int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
   4083   return map->instance_size();
   4084 }
   4085 
   4086 
   4087 void Proxy::ProxyIterateBody(ObjectVisitor* v) {
   4088   v->VisitExternalReference(
   4089       reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
   4090 }
   4091 
   4092 
   4093 template<typename StaticVisitor>
   4094 void Proxy::ProxyIterateBody() {
   4095   StaticVisitor::VisitExternalReference(
   4096       reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
   4097 }
   4098 
   4099 
   4100 void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
   4101   typedef v8::String::ExternalAsciiStringResource Resource;
   4102   v->VisitExternalAsciiString(
   4103       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
   4104 }
   4105 
   4106 
   4107 template<typename StaticVisitor>
   4108 void ExternalAsciiString::ExternalAsciiStringIterateBody() {
   4109   typedef v8::String::ExternalAsciiStringResource Resource;
   4110   StaticVisitor::VisitExternalAsciiString(
   4111       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
   4112 }
   4113 
   4114 
   4115 void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
   4116   typedef v8::String::ExternalStringResource Resource;
   4117   v->VisitExternalTwoByteString(
   4118       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
   4119 }
   4120 
   4121 
   4122 template<typename StaticVisitor>
   4123 void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
   4124   typedef v8::String::ExternalStringResource Resource;
   4125   StaticVisitor::VisitExternalTwoByteString(
   4126       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
   4127 }
   4128 
   4129 #define SLOT_ADDR(obj, offset) \
   4130   reinterpret_cast<Object**>((obj)->address() + offset)
   4131 
   4132 template<int start_offset, int end_offset, int size>
   4133 void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
   4134     HeapObject* obj,
   4135     ObjectVisitor* v) {
   4136     v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
   4137 }
   4138 
   4139 
   4140 template<int start_offset>
   4141 void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
   4142                                                        int object_size,
   4143                                                        ObjectVisitor* v) {
   4144   v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
   4145 }
   4146 
   4147 #undef SLOT_ADDR
   4148 
   4149 
   4150 #undef CAST_ACCESSOR
   4151 #undef INT_ACCESSORS
   4152 #undef SMI_ACCESSORS
   4153 #undef ACCESSORS
   4154 #undef FIELD_ADDR
   4155 #undef READ_FIELD
   4156 #undef WRITE_FIELD
   4157 #undef WRITE_BARRIER
   4158 #undef CONDITIONAL_WRITE_BARRIER
   4159 #undef READ_MEMADDR_FIELD
   4160 #undef WRITE_MEMADDR_FIELD
   4161 #undef READ_DOUBLE_FIELD
   4162 #undef WRITE_DOUBLE_FIELD
   4163 #undef READ_INT_FIELD
   4164 #undef WRITE_INT_FIELD
   4165 #undef READ_SHORT_FIELD
   4166 #undef WRITE_SHORT_FIELD
   4167 #undef READ_BYTE_FIELD
   4168 #undef WRITE_BYTE_FIELD
   4169 
   4170 
   4171 } }  // namespace v8::internal
   4172 
   4173 #endif  // V8_OBJECTS_INL_H_
   4174