[V8] Introduce a QML compilation mode
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / src / objects-inl.h
1 // Copyright 2012 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 "elements.h"
39 #include "objects.h"
40 #include "contexts.h"
41 #include "conversions-inl.h"
42 #include "heap.h"
43 #include "isolate.h"
44 #include "property.h"
45 #include "spaces.h"
46 #include "store-buffer.h"
47 #include "v8memory.h"
48 #include "factory.h"
49 #include "incremental-marking.h"
50
51 namespace v8 {
52 namespace internal {
53
54 PropertyDetails::PropertyDetails(Smi* smi) {
55   value_ = smi->value();
56 }
57
58
59 Smi* PropertyDetails::AsSmi() {
60   return Smi::FromInt(value_);
61 }
62
63
64 PropertyDetails PropertyDetails::AsDeleted() {
65   Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
66   return PropertyDetails(smi);
67 }
68
69
70 #define TYPE_CHECKER(type, instancetype)                                \
71   bool Object::Is##type() {                                             \
72   return Object::IsHeapObject() &&                                      \
73       HeapObject::cast(this)->map()->instance_type() == instancetype;   \
74   }
75
76
77 #define CAST_ACCESSOR(type)                     \
78   type* type::cast(Object* object) {            \
79     ASSERT(object->Is##type());                 \
80     return reinterpret_cast<type*>(object);     \
81   }
82
83
84 #define INT_ACCESSORS(holder, name, offset)                             \
85   int holder::name() { return READ_INT_FIELD(this, offset); }           \
86   void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
87
88
89 #define ACCESSORS(holder, name, type, offset)                           \
90   type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
91   void holder::set_##name(type* value, WriteBarrierMode mode) {         \
92     WRITE_FIELD(this, offset, value);                                   \
93     CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);    \
94   }
95
96
97 // Getter that returns a tagged Smi and setter that writes a tagged Smi.
98 #define ACCESSORS_TO_SMI(holder, name, offset)                          \
99   Smi* holder::name() { return Smi::cast(READ_FIELD(this, offset)); }   \
100   void holder::set_##name(Smi* value, WriteBarrierMode mode) {          \
101     WRITE_FIELD(this, offset, value);                                   \
102   }
103
104
105 // Getter that returns a Smi as an int and writes an int as a Smi.
106 #define SMI_ACCESSORS(holder, name, offset)             \
107   int holder::name() {                                  \
108     Object* value = READ_FIELD(this, offset);           \
109     return Smi::cast(value)->value();                   \
110   }                                                     \
111   void holder::set_##name(int value) {                  \
112     WRITE_FIELD(this, offset, Smi::FromInt(value));     \
113   }
114
115
116 #define BOOL_GETTER(holder, field, name, offset)           \
117   bool holder::name() {                                    \
118     return BooleanBit::get(field(), offset);               \
119   }                                                        \
120
121
122 #define BOOL_ACCESSORS(holder, field, name, offset)        \
123   bool holder::name() {                                    \
124     return BooleanBit::get(field(), offset);               \
125   }                                                        \
126   void holder::set_##name(bool value) {                    \
127     set_##field(BooleanBit::set(field(), offset, value));  \
128   }
129
130
131 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
132                                          ElementsKind to_kind) {
133   if (to_kind == FAST_ELEMENTS) {
134     return from_kind == FAST_SMI_ONLY_ELEMENTS ||
135         from_kind == FAST_DOUBLE_ELEMENTS;
136   } else {
137     return to_kind == FAST_DOUBLE_ELEMENTS &&
138         from_kind == FAST_SMI_ONLY_ELEMENTS;
139   }
140 }
141
142
143 bool Object::IsFixedArrayBase() {
144   return IsFixedArray() || IsFixedDoubleArray();
145 }
146
147
148 bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
149   // There is a constraint on the object; check.
150   if (!this->IsJSObject()) return false;
151   // Fetch the constructor function of the object.
152   Object* cons_obj = JSObject::cast(this)->map()->constructor();
153   if (!cons_obj->IsJSFunction()) return false;
154   JSFunction* fun = JSFunction::cast(cons_obj);
155   // Iterate through the chain of inheriting function templates to
156   // see if the required one occurs.
157   for (Object* type = fun->shared()->function_data();
158        type->IsFunctionTemplateInfo();
159        type = FunctionTemplateInfo::cast(type)->parent_template()) {
160     if (type == expected) return true;
161   }
162   // Didn't find the required type in the inheritance chain.
163   return false;
164 }
165
166
167 bool Object::IsSmi() {
168   return HAS_SMI_TAG(this);
169 }
170
171
172 bool Object::IsHeapObject() {
173   return Internals::HasHeapObjectTag(this);
174 }
175
176
177 bool Object::NonFailureIsHeapObject() {
178   ASSERT(!this->IsFailure());
179   return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
180 }
181
182
183 TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
184
185
186 bool Object::IsString() {
187   return Object::IsHeapObject()
188     && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
189 }
190
191
192 bool Object::IsSpecObject() {
193   return Object::IsHeapObject()
194     && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
195 }
196
197
198 bool Object::IsSpecFunction() {
199   if (!Object::IsHeapObject()) return false;
200   InstanceType type = HeapObject::cast(this)->map()->instance_type();
201   return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
202 }
203
204
205 bool Object::IsSymbol() {
206   if (!this->IsHeapObject()) return false;
207   uint32_t type = HeapObject::cast(this)->map()->instance_type();
208   // Because the symbol tag is non-zero and no non-string types have the
209   // symbol bit set we can test for symbols with a very simple test
210   // operation.
211   STATIC_ASSERT(kSymbolTag != 0);
212   ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
213   return (type & kIsSymbolMask) != 0;
214 }
215
216
217 bool Object::IsConsString() {
218   if (!IsString()) return false;
219   return StringShape(String::cast(this)).IsCons();
220 }
221
222
223 bool Object::IsSlicedString() {
224   if (!IsString()) return false;
225   return StringShape(String::cast(this)).IsSliced();
226 }
227
228
229 bool Object::IsSeqString() {
230   if (!IsString()) return false;
231   return StringShape(String::cast(this)).IsSequential();
232 }
233
234
235 bool Object::IsSeqAsciiString() {
236   if (!IsString()) return false;
237   return StringShape(String::cast(this)).IsSequential() &&
238          String::cast(this)->IsAsciiRepresentation();
239 }
240
241
242 bool Object::IsSeqTwoByteString() {
243   if (!IsString()) return false;
244   return StringShape(String::cast(this)).IsSequential() &&
245          String::cast(this)->IsTwoByteRepresentation();
246 }
247
248
249 bool Object::IsExternalString() {
250   if (!IsString()) return false;
251   return StringShape(String::cast(this)).IsExternal();
252 }
253
254
255 bool Object::IsExternalAsciiString() {
256   if (!IsString()) return false;
257   return StringShape(String::cast(this)).IsExternal() &&
258          String::cast(this)->IsAsciiRepresentation();
259 }
260
261
262 bool Object::IsExternalTwoByteString() {
263   if (!IsString()) return false;
264   return StringShape(String::cast(this)).IsExternal() &&
265          String::cast(this)->IsTwoByteRepresentation();
266 }
267
268 bool Object::HasValidElements() {
269   // Dictionary is covered under FixedArray.
270   return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
271 }
272
273 StringShape::StringShape(String* str)
274   : type_(str->map()->instance_type()) {
275   set_valid();
276   ASSERT((type_ & kIsNotStringMask) == kStringTag);
277 }
278
279
280 StringShape::StringShape(Map* map)
281   : type_(map->instance_type()) {
282   set_valid();
283   ASSERT((type_ & kIsNotStringMask) == kStringTag);
284 }
285
286
287 StringShape::StringShape(InstanceType t)
288   : type_(static_cast<uint32_t>(t)) {
289   set_valid();
290   ASSERT((type_ & kIsNotStringMask) == kStringTag);
291 }
292
293
294 bool StringShape::IsSymbol() {
295   ASSERT(valid());
296   STATIC_ASSERT(kSymbolTag != 0);
297   return (type_ & kIsSymbolMask) != 0;
298 }
299
300
301 bool String::IsAsciiRepresentation() {
302   uint32_t type = map()->instance_type();
303   return (type & kStringEncodingMask) == kAsciiStringTag;
304 }
305
306
307 bool String::IsTwoByteRepresentation() {
308   uint32_t type = map()->instance_type();
309   return (type & kStringEncodingMask) == kTwoByteStringTag;
310 }
311
312
313 bool String::IsAsciiRepresentationUnderneath() {
314   uint32_t type = map()->instance_type();
315   STATIC_ASSERT(kIsIndirectStringTag != 0);
316   STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
317   ASSERT(IsFlat());
318   switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
319     case kAsciiStringTag:
320       return true;
321     case kTwoByteStringTag:
322       return false;
323     default:  // Cons or sliced string.  Need to go deeper.
324       return GetUnderlying()->IsAsciiRepresentation();
325   }
326 }
327
328
329 bool String::IsTwoByteRepresentationUnderneath() {
330   uint32_t type = map()->instance_type();
331   STATIC_ASSERT(kIsIndirectStringTag != 0);
332   STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
333   ASSERT(IsFlat());
334   switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
335     case kAsciiStringTag:
336       return false;
337     case kTwoByteStringTag:
338       return true;
339     default:  // Cons or sliced string.  Need to go deeper.
340       return GetUnderlying()->IsTwoByteRepresentation();
341   }
342 }
343
344
345 bool String::HasOnlyAsciiChars() {
346   uint32_t type = map()->instance_type();
347   return (type & kStringEncodingMask) == kAsciiStringTag ||
348          (type & kAsciiDataHintMask) == kAsciiDataHintTag;
349 }
350
351
352 bool StringShape::IsCons() {
353   return (type_ & kStringRepresentationMask) == kConsStringTag;
354 }
355
356
357 bool StringShape::IsSliced() {
358   return (type_ & kStringRepresentationMask) == kSlicedStringTag;
359 }
360
361
362 bool StringShape::IsIndirect() {
363   return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
364 }
365
366
367 bool StringShape::IsExternal() {
368   return (type_ & kStringRepresentationMask) == kExternalStringTag;
369 }
370
371
372 bool StringShape::IsSequential() {
373   return (type_ & kStringRepresentationMask) == kSeqStringTag;
374 }
375
376
377 StringRepresentationTag StringShape::representation_tag() {
378   uint32_t tag = (type_ & kStringRepresentationMask);
379   return static_cast<StringRepresentationTag>(tag);
380 }
381
382
383 uint32_t StringShape::encoding_tag() {
384   return type_ & kStringEncodingMask;
385 }
386
387
388 uint32_t StringShape::full_representation_tag() {
389   return (type_ & (kStringRepresentationMask | kStringEncodingMask));
390 }
391
392
393 STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
394              Internals::kFullStringRepresentationMask);
395
396
397 bool StringShape::IsSequentialAscii() {
398   return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
399 }
400
401
402 bool StringShape::IsSequentialTwoByte() {
403   return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
404 }
405
406
407 bool StringShape::IsExternalAscii() {
408   return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
409 }
410
411
412 bool StringShape::IsExternalTwoByte() {
413   return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
414 }
415
416
417 STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
418              Internals::kExternalTwoByteRepresentationTag);
419
420
421 uc32 FlatStringReader::Get(int index) {
422   ASSERT(0 <= index && index <= length_);
423   if (is_ascii_) {
424     return static_cast<const byte*>(start_)[index];
425   } else {
426     return static_cast<const uc16*>(start_)[index];
427   }
428 }
429
430
431 bool Object::IsNumber() {
432   return IsSmi() || IsHeapNumber();
433 }
434
435
436 TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
437 TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
438
439
440 bool Object::IsFiller() {
441   if (!Object::IsHeapObject()) return false;
442   InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
443   return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
444 }
445
446
447 TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
448
449
450 bool Object::IsExternalArray() {
451   if (!Object::IsHeapObject())
452     return false;
453   InstanceType instance_type =
454       HeapObject::cast(this)->map()->instance_type();
455   return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
456           instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
457 }
458
459
460 TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
461 TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
462 TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
463 TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
464 TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
465 TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
466 TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
467 TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
468
469
470 bool MaybeObject::IsFailure() {
471   return HAS_FAILURE_TAG(this);
472 }
473
474
475 bool MaybeObject::IsRetryAfterGC() {
476   return HAS_FAILURE_TAG(this)
477     && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
478 }
479
480
481 bool MaybeObject::IsOutOfMemory() {
482   return HAS_FAILURE_TAG(this)
483       && Failure::cast(this)->IsOutOfMemoryException();
484 }
485
486
487 bool MaybeObject::IsException() {
488   return this == Failure::Exception();
489 }
490
491
492 bool MaybeObject::IsTheHole() {
493   return !IsFailure() && ToObjectUnchecked()->IsTheHole();
494 }
495
496
497 Failure* Failure::cast(MaybeObject* obj) {
498   ASSERT(HAS_FAILURE_TAG(obj));
499   return reinterpret_cast<Failure*>(obj);
500 }
501
502
503 bool Object::IsJSReceiver() {
504   STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
505   return IsHeapObject() &&
506       HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
507 }
508
509
510 bool Object::IsJSObject() {
511   STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
512   return IsHeapObject() &&
513       HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
514 }
515
516
517 bool Object::IsJSProxy() {
518   if (!Object::IsHeapObject()) return false;
519   InstanceType type = HeapObject::cast(this)->map()->instance_type();
520   return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
521 }
522
523
524 TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
525 TYPE_CHECKER(JSSet, JS_SET_TYPE)
526 TYPE_CHECKER(JSMap, JS_MAP_TYPE)
527 TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
528 TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
529 TYPE_CHECKER(Map, MAP_TYPE)
530 TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
531 TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
532
533
534 bool Object::IsDescriptorArray() {
535   return IsFixedArray();
536 }
537
538
539 bool Object::IsDeoptimizationInputData() {
540   // Must be a fixed array.
541   if (!IsFixedArray()) return false;
542
543   // There's no sure way to detect the difference between a fixed array and
544   // a deoptimization data array.  Since this is used for asserts we can
545   // check that the length is zero or else the fixed size plus a multiple of
546   // the entry size.
547   int length = FixedArray::cast(this)->length();
548   if (length == 0) return true;
549
550   length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
551   return length >= 0 &&
552       length % DeoptimizationInputData::kDeoptEntrySize == 0;
553 }
554
555
556 bool Object::IsDeoptimizationOutputData() {
557   if (!IsFixedArray()) return false;
558   // There's actually no way to see the difference between a fixed array and
559   // a deoptimization data array.  Since this is used for asserts we can check
560   // that the length is plausible though.
561   if (FixedArray::cast(this)->length() % 2 != 0) return false;
562   return true;
563 }
564
565
566 bool Object::IsTypeFeedbackCells() {
567   if (!IsFixedArray()) return false;
568   // There's actually no way to see the difference between a fixed array and
569   // a cache cells array.  Since this is used for asserts we can check that
570   // the length is plausible though.
571   if (FixedArray::cast(this)->length() % 2 != 0) return false;
572   return true;
573 }
574
575
576 bool Object::IsContext() {
577   if (Object::IsHeapObject()) {
578     Map* map = HeapObject::cast(this)->map();
579     Heap* heap = map->GetHeap();
580     return (map == heap->function_context_map() ||
581             map == heap->catch_context_map() ||
582             map == heap->with_context_map() ||
583             map == heap->global_context_map() ||
584             map == heap->block_context_map() ||
585             map == heap->module_context_map());
586   }
587   return false;
588 }
589
590
591 bool Object::IsGlobalContext() {
592   return Object::IsHeapObject() &&
593       HeapObject::cast(this)->map() ==
594       HeapObject::cast(this)->GetHeap()->global_context_map();
595 }
596
597
598 bool Object::IsModuleContext() {
599   return Object::IsHeapObject() &&
600       HeapObject::cast(this)->map() ==
601       HeapObject::cast(this)->GetHeap()->module_context_map();
602 }
603
604
605 bool Object::IsScopeInfo() {
606   return Object::IsHeapObject() &&
607       HeapObject::cast(this)->map() ==
608       HeapObject::cast(this)->GetHeap()->scope_info_map();
609 }
610
611
612 TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
613
614
615 template <> inline bool Is<JSFunction>(Object* obj) {
616   return obj->IsJSFunction();
617 }
618
619
620 TYPE_CHECKER(Code, CODE_TYPE)
621 TYPE_CHECKER(Oddball, ODDBALL_TYPE)
622 TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
623 TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
624 TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
625 TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
626 TYPE_CHECKER(JSDate, JS_DATE_TYPE)
627 TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
628
629
630 bool Object::IsStringWrapper() {
631   return IsJSValue() && JSValue::cast(this)->value()->IsString();
632 }
633
634
635 TYPE_CHECKER(Foreign, FOREIGN_TYPE)
636
637
638 bool Object::IsBoolean() {
639   return IsOddball() &&
640       ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
641 }
642
643
644 TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
645 TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
646
647
648 template <> inline bool Is<JSArray>(Object* obj) {
649   return obj->IsJSArray();
650 }
651
652
653 bool Object::IsHashTable() {
654   return Object::IsHeapObject() &&
655       HeapObject::cast(this)->map() ==
656       HeapObject::cast(this)->GetHeap()->hash_table_map();
657 }
658
659
660 bool Object::IsDictionary() {
661   return IsHashTable() &&
662       this != HeapObject::cast(this)->GetHeap()->symbol_table();
663 }
664
665
666 bool Object::IsSymbolTable() {
667   return IsHashTable() && this ==
668          HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
669 }
670
671
672 bool Object::IsJSFunctionResultCache() {
673   if (!IsFixedArray()) return false;
674   FixedArray* self = FixedArray::cast(this);
675   int length = self->length();
676   if (length < JSFunctionResultCache::kEntriesIndex) return false;
677   if ((length - JSFunctionResultCache::kEntriesIndex)
678       % JSFunctionResultCache::kEntrySize != 0) {
679     return false;
680   }
681 #ifdef DEBUG
682   if (FLAG_verify_heap) {
683     reinterpret_cast<JSFunctionResultCache*>(this)->
684         JSFunctionResultCacheVerify();
685   }
686 #endif
687   return true;
688 }
689
690
691 bool Object::IsNormalizedMapCache() {
692   if (!IsFixedArray()) return false;
693   if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
694     return false;
695   }
696 #ifdef DEBUG
697   if (FLAG_verify_heap) {
698     reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
699   }
700 #endif
701   return true;
702 }
703
704
705 bool Object::IsCompilationCacheTable() {
706   return IsHashTable();
707 }
708
709
710 bool Object::IsCodeCacheHashTable() {
711   return IsHashTable();
712 }
713
714
715 bool Object::IsPolymorphicCodeCacheHashTable() {
716   return IsHashTable();
717 }
718
719
720 bool Object::IsMapCache() {
721   return IsHashTable();
722 }
723
724
725 bool Object::IsPrimitive() {
726   return IsOddball() || IsNumber() || IsString();
727 }
728
729
730 bool Object::IsJSGlobalProxy() {
731   bool result = IsHeapObject() &&
732                 (HeapObject::cast(this)->map()->instance_type() ==
733                  JS_GLOBAL_PROXY_TYPE);
734   ASSERT(!result || IsAccessCheckNeeded());
735   return result;
736 }
737
738
739 bool Object::IsGlobalObject() {
740   if (!IsHeapObject()) return false;
741
742   InstanceType type = HeapObject::cast(this)->map()->instance_type();
743   return type == JS_GLOBAL_OBJECT_TYPE ||
744          type == JS_BUILTINS_OBJECT_TYPE;
745 }
746
747
748 TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
749 TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
750
751
752 bool Object::IsUndetectableObject() {
753   return IsHeapObject()
754     && HeapObject::cast(this)->map()->is_undetectable();
755 }
756
757
758 bool Object::IsAccessCheckNeeded() {
759   return IsHeapObject()
760     && HeapObject::cast(this)->map()->is_access_check_needed();
761 }
762
763
764 bool Object::IsStruct() {
765   if (!IsHeapObject()) return false;
766   switch (HeapObject::cast(this)->map()->instance_type()) {
767 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
768   STRUCT_LIST(MAKE_STRUCT_CASE)
769 #undef MAKE_STRUCT_CASE
770     default: return false;
771   }
772 }
773
774
775 #define MAKE_STRUCT_PREDICATE(NAME, Name, name)                  \
776   bool Object::Is##Name() {                                      \
777     return Object::IsHeapObject()                                \
778       && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
779   }
780   STRUCT_LIST(MAKE_STRUCT_PREDICATE)
781 #undef MAKE_STRUCT_PREDICATE
782
783
784 bool Object::IsUndefined() {
785   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
786 }
787
788
789 bool Object::IsNull() {
790   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
791 }
792
793
794 bool Object::IsTheHole() {
795   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
796 }
797
798
799 bool Object::IsTrue() {
800   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
801 }
802
803
804 bool Object::IsFalse() {
805   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
806 }
807
808
809 bool Object::IsArgumentsMarker() {
810   return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
811 }
812
813
814 double Object::Number() {
815   ASSERT(IsNumber());
816   return IsSmi()
817     ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
818     : reinterpret_cast<HeapNumber*>(this)->value();
819 }
820
821
822 bool Object::IsNaN() {
823   return this->IsHeapNumber() && isnan(HeapNumber::cast(this)->value());
824 }
825
826
827 MaybeObject* Object::ToSmi() {
828   if (IsSmi()) return this;
829   if (IsHeapNumber()) {
830     double value = HeapNumber::cast(this)->value();
831     int int_value = FastD2I(value);
832     if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
833       return Smi::FromInt(int_value);
834     }
835   }
836   return Failure::Exception();
837 }
838
839
840 bool Object::HasSpecificClassOf(String* name) {
841   return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
842 }
843
844
845 MaybeObject* Object::GetElement(uint32_t index) {
846   // GetElement can trigger a getter which can cause allocation.
847   // This was not always the case. This ASSERT is here to catch
848   // leftover incorrect uses.
849   ASSERT(HEAP->IsAllocationAllowed());
850   return GetElementWithReceiver(this, index);
851 }
852
853
854 Object* Object::GetElementNoExceptionThrown(uint32_t index) {
855   MaybeObject* maybe = GetElementWithReceiver(this, index);
856   ASSERT(!maybe->IsFailure());
857   Object* result = NULL;  // Initialization to please compiler.
858   maybe->ToObject(&result);
859   return result;
860 }
861
862
863 MaybeObject* Object::GetProperty(String* key) {
864   PropertyAttributes attributes;
865   return GetPropertyWithReceiver(this, key, &attributes);
866 }
867
868
869 MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
870   return GetPropertyWithReceiver(this, key, attributes);
871 }
872
873
874 #define FIELD_ADDR(p, offset) \
875   (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
876
877 #define READ_FIELD(p, offset) \
878   (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
879
880 #define WRITE_FIELD(p, offset, value) \
881   (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
882
883 #define WRITE_BARRIER(heap, object, offset, value)                      \
884   heap->incremental_marking()->RecordWrite(                             \
885       object, HeapObject::RawField(object, offset), value);             \
886   if (heap->InNewSpace(value)) {                                        \
887     heap->RecordWrite(object->address(), offset);                       \
888   }
889
890 #define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode)    \
891   if (mode == UPDATE_WRITE_BARRIER) {                                   \
892     heap->incremental_marking()->RecordWrite(                           \
893       object, HeapObject::RawField(object, offset), value);             \
894     if (heap->InNewSpace(value)) {                                      \
895       heap->RecordWrite(object->address(), offset);                     \
896     }                                                                   \
897   }
898
899 #ifndef V8_TARGET_ARCH_MIPS
900   #define READ_DOUBLE_FIELD(p, offset) \
901     (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
902 #else  // V8_TARGET_ARCH_MIPS
903   // Prevent gcc from using load-double (mips ldc1) on (possibly)
904   // non-64-bit aligned HeapNumber::value.
905   static inline double read_double_field(void* p, int offset) {
906     union conversion {
907       double d;
908       uint32_t u[2];
909     } c;
910     c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
911     c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
912     return c.d;
913   }
914   #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
915 #endif  // V8_TARGET_ARCH_MIPS
916
917 #ifndef V8_TARGET_ARCH_MIPS
918   #define WRITE_DOUBLE_FIELD(p, offset, value) \
919     (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
920 #else  // V8_TARGET_ARCH_MIPS
921   // Prevent gcc from using store-double (mips sdc1) on (possibly)
922   // non-64-bit aligned HeapNumber::value.
923   static inline void write_double_field(void* p, int offset,
924                                         double value) {
925     union conversion {
926       double d;
927       uint32_t u[2];
928     } c;
929     c.d = value;
930     (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
931     (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
932   }
933   #define WRITE_DOUBLE_FIELD(p, offset, value) \
934     write_double_field(p, offset, value)
935 #endif  // V8_TARGET_ARCH_MIPS
936
937
938 #define READ_INT_FIELD(p, offset) \
939   (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
940
941 #define WRITE_INT_FIELD(p, offset, value) \
942   (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
943
944 #define READ_INTPTR_FIELD(p, offset) \
945   (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
946
947 #define WRITE_INTPTR_FIELD(p, offset, value) \
948   (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
949
950 #define READ_UINT32_FIELD(p, offset) \
951   (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
952
953 #define WRITE_UINT32_FIELD(p, offset, value) \
954   (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
955
956 #define READ_INT64_FIELD(p, offset) \
957   (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
958
959 #define WRITE_INT64_FIELD(p, offset, value) \
960   (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
961
962 #define READ_SHORT_FIELD(p, offset) \
963   (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
964
965 #define WRITE_SHORT_FIELD(p, offset, value) \
966   (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
967
968 #define READ_BYTE_FIELD(p, offset) \
969   (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
970
971 #define WRITE_BYTE_FIELD(p, offset, value) \
972   (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
973
974
975 Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
976   return &READ_FIELD(obj, byte_offset);
977 }
978
979
980 int Smi::value() {
981   return Internals::SmiValue(this);
982 }
983
984
985 Smi* Smi::FromInt(int value) {
986   ASSERT(Smi::IsValid(value));
987   int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
988   intptr_t tagged_value =
989       (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
990   return reinterpret_cast<Smi*>(tagged_value);
991 }
992
993
994 Smi* Smi::FromIntptr(intptr_t value) {
995   ASSERT(Smi::IsValid(value));
996   int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
997   return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
998 }
999
1000
1001 Failure::Type Failure::type() const {
1002   return static_cast<Type>(value() & kFailureTypeTagMask);
1003 }
1004
1005
1006 bool Failure::IsInternalError() const {
1007   return type() == INTERNAL_ERROR;
1008 }
1009
1010
1011 bool Failure::IsOutOfMemoryException() const {
1012   return type() == OUT_OF_MEMORY_EXCEPTION;
1013 }
1014
1015
1016 AllocationSpace Failure::allocation_space() const {
1017   ASSERT_EQ(RETRY_AFTER_GC, type());
1018   return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1019                                       & kSpaceTagMask);
1020 }
1021
1022
1023 Failure* Failure::InternalError() {
1024   return Construct(INTERNAL_ERROR);
1025 }
1026
1027
1028 Failure* Failure::Exception() {
1029   return Construct(EXCEPTION);
1030 }
1031
1032
1033 Failure* Failure::OutOfMemoryException() {
1034   return Construct(OUT_OF_MEMORY_EXCEPTION);
1035 }
1036
1037
1038 intptr_t Failure::value() const {
1039   return static_cast<intptr_t>(
1040       reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
1041 }
1042
1043
1044 Failure* Failure::RetryAfterGC() {
1045   return RetryAfterGC(NEW_SPACE);
1046 }
1047
1048
1049 Failure* Failure::RetryAfterGC(AllocationSpace space) {
1050   ASSERT((space & ~kSpaceTagMask) == 0);
1051   return Construct(RETRY_AFTER_GC, space);
1052 }
1053
1054
1055 Failure* Failure::Construct(Type type, intptr_t value) {
1056   uintptr_t info =
1057       (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
1058   ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
1059   return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
1060 }
1061
1062
1063 bool Smi::IsValid(intptr_t value) {
1064 #ifdef DEBUG
1065   bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1066 #endif
1067
1068 #ifdef V8_TARGET_ARCH_X64
1069   // To be representable as a long smi, the value must be a 32-bit integer.
1070   bool result = (value == static_cast<int32_t>(value));
1071 #else
1072   // To be representable as an tagged small integer, the two
1073   // most-significant bits of 'value' must be either 00 or 11 due to
1074   // sign-extension. To check this we add 01 to the two
1075   // most-significant bits, and check if the most-significant bit is 0
1076   //
1077   // CAUTION: The original code below:
1078   // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1079   // may lead to incorrect results according to the C language spec, and
1080   // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1081   // compiler may produce undefined results in case of signed integer
1082   // overflow. The computation must be done w/ unsigned ints.
1083   bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
1084 #endif
1085   ASSERT(result == in_range);
1086   return result;
1087 }
1088
1089
1090 MapWord MapWord::FromMap(Map* map) {
1091   return MapWord(reinterpret_cast<uintptr_t>(map));
1092 }
1093
1094
1095 Map* MapWord::ToMap() {
1096   return reinterpret_cast<Map*>(value_);
1097 }
1098
1099
1100 bool MapWord::IsForwardingAddress() {
1101   return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
1102 }
1103
1104
1105 MapWord MapWord::FromForwardingAddress(HeapObject* object) {
1106   Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1107   return MapWord(reinterpret_cast<uintptr_t>(raw));
1108 }
1109
1110
1111 HeapObject* MapWord::ToForwardingAddress() {
1112   ASSERT(IsForwardingAddress());
1113   return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
1114 }
1115
1116
1117 #ifdef DEBUG
1118 void HeapObject::VerifyObjectField(int offset) {
1119   VerifyPointer(READ_FIELD(this, offset));
1120 }
1121
1122 void HeapObject::VerifySmiField(int offset) {
1123   ASSERT(READ_FIELD(this, offset)->IsSmi());
1124 }
1125 #endif
1126
1127
1128 Heap* HeapObject::GetHeap() {
1129   Heap* heap =
1130       MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1131   ASSERT(heap != NULL);
1132   ASSERT(heap->isolate() == Isolate::Current());
1133   return heap;
1134 }
1135
1136
1137 Isolate* HeapObject::GetIsolate() {
1138   return GetHeap()->isolate();
1139 }
1140
1141
1142 Map* HeapObject::map() {
1143   return map_word().ToMap();
1144 }
1145
1146
1147 void HeapObject::set_map(Map* value) {
1148   set_map_word(MapWord::FromMap(value));
1149   if (value != NULL) {
1150     // TODO(1600) We are passing NULL as a slot because maps can never be on
1151     // evacuation candidate.
1152     value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1153   }
1154 }
1155
1156
1157 // Unsafe accessor omitting write barrier.
1158 void HeapObject::set_map_no_write_barrier(Map* value) {
1159   set_map_word(MapWord::FromMap(value));
1160 }
1161
1162
1163 MapWord HeapObject::map_word() {
1164   return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1165 }
1166
1167
1168 void HeapObject::set_map_word(MapWord map_word) {
1169   // WRITE_FIELD does not invoke write barrier, but there is no need
1170   // here.
1171   WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1172 }
1173
1174
1175 HeapObject* HeapObject::FromAddress(Address address) {
1176   ASSERT_TAG_ALIGNED(address);
1177   return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1178 }
1179
1180
1181 Address HeapObject::address() {
1182   return reinterpret_cast<Address>(this) - kHeapObjectTag;
1183 }
1184
1185
1186 int HeapObject::Size() {
1187   return SizeFromMap(map());
1188 }
1189
1190
1191 void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1192   v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1193                    reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1194 }
1195
1196
1197 void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1198   v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1199 }
1200
1201
1202 double HeapNumber::value() {
1203   return READ_DOUBLE_FIELD(this, kValueOffset);
1204 }
1205
1206
1207 void HeapNumber::set_value(double value) {
1208   WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1209 }
1210
1211
1212 int HeapNumber::get_exponent() {
1213   return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1214           kExponentShift) - kExponentBias;
1215 }
1216
1217
1218 int HeapNumber::get_sign() {
1219   return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1220 }
1221
1222
1223 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
1224
1225
1226 Object** FixedArray::GetFirstElementAddress() {
1227   return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1228 }
1229
1230
1231 bool FixedArray::ContainsOnlySmisOrHoles() {
1232   Object* the_hole = GetHeap()->the_hole_value();
1233   Object** current = GetFirstElementAddress();
1234   for (int i = 0; i < length(); ++i) {
1235     Object* candidate = *current++;
1236     if (!candidate->IsSmi() && candidate != the_hole) return false;
1237   }
1238   return true;
1239 }
1240
1241
1242 FixedArrayBase* JSObject::elements() {
1243   Object* array = READ_FIELD(this, kElementsOffset);
1244   return static_cast<FixedArrayBase*>(array);
1245 }
1246
1247 void JSObject::ValidateSmiOnlyElements() {
1248 #if DEBUG
1249   if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
1250     Heap* heap = GetHeap();
1251     // Don't use elements, since integrity checks will fail if there
1252     // are filler pointers in the array.
1253     FixedArray* fixed_array =
1254         reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1255     Map* map = fixed_array->map();
1256     // Arrays that have been shifted in place can't be verified.
1257     if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1258         map != heap->raw_unchecked_two_pointer_filler_map() &&
1259         map != heap->free_space_map()) {
1260       for (int i = 0; i < fixed_array->length(); i++) {
1261         Object* current = fixed_array->get(i);
1262         ASSERT(current->IsSmi() || current->IsTheHole());
1263       }
1264     }
1265   }
1266 #endif
1267 }
1268
1269
1270 MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
1271 #if DEBUG
1272   ValidateSmiOnlyElements();
1273 #endif
1274   if ((map()->elements_kind() != FAST_ELEMENTS)) {
1275     return TransitionElementsKind(FAST_ELEMENTS);
1276   }
1277   return this;
1278 }
1279
1280
1281 MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
1282                                                 uint32_t count,
1283                                                 EnsureElementsMode mode) {
1284   ElementsKind current_kind = map()->elements_kind();
1285   ElementsKind target_kind = current_kind;
1286   ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1287   if (current_kind == FAST_ELEMENTS) return this;
1288
1289   Heap* heap = GetHeap();
1290   Object* the_hole = heap->the_hole_value();
1291   Object* heap_number_map = heap->heap_number_map();
1292   for (uint32_t i = 0; i < count; ++i) {
1293     Object* current = *objects++;
1294     if (!current->IsSmi() && current != the_hole) {
1295       if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
1296           HeapObject::cast(current)->map() == heap_number_map) {
1297         target_kind = FAST_DOUBLE_ELEMENTS;
1298       } else {
1299         target_kind = FAST_ELEMENTS;
1300         break;
1301       }
1302     }
1303   }
1304
1305   if (target_kind != current_kind) {
1306     return TransitionElementsKind(target_kind);
1307   }
1308   return this;
1309 }
1310
1311
1312 MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
1313                                                 EnsureElementsMode mode) {
1314   if (elements->map() != GetHeap()->fixed_double_array_map()) {
1315     ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1316            elements->map() == GetHeap()->fixed_cow_array_map());
1317     if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1318       mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1319     }
1320     Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
1321     return EnsureCanContainElements(objects, elements->length(), mode);
1322   }
1323
1324   ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1325   if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1326     return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1327   }
1328
1329   return this;
1330 }
1331
1332
1333 MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1334                                                 ElementsKind to_kind) {
1335   Map* current_map = map();
1336   ElementsKind from_kind = current_map->elements_kind();
1337
1338   if (from_kind == to_kind) return current_map;
1339
1340   Context* global_context = isolate->context()->global_context();
1341   if (current_map == global_context->smi_js_array_map()) {
1342     if (to_kind == FAST_ELEMENTS) {
1343       return global_context->object_js_array_map();
1344     } else {
1345       if (to_kind == FAST_DOUBLE_ELEMENTS) {
1346         return global_context->double_js_array_map();
1347       } else {
1348         ASSERT(to_kind == DICTIONARY_ELEMENTS);
1349       }
1350     }
1351   }
1352   return GetElementsTransitionMapSlow(to_kind);
1353 }
1354
1355
1356 void JSObject::set_map_and_elements(Map* new_map,
1357                                     FixedArrayBase* value,
1358                                     WriteBarrierMode mode) {
1359   ASSERT(value->HasValidElements());
1360 #ifdef DEBUG
1361   ValidateSmiOnlyElements();
1362 #endif
1363   if (new_map != NULL) {
1364     if (mode == UPDATE_WRITE_BARRIER) {
1365       set_map(new_map);
1366     } else {
1367       ASSERT(mode == SKIP_WRITE_BARRIER);
1368       set_map_no_write_barrier(new_map);
1369     }
1370   }
1371   ASSERT((map()->has_fast_elements() ||
1372           map()->has_fast_smi_only_elements() ||
1373           (value == GetHeap()->empty_fixed_array())) ==
1374          (value->map() == GetHeap()->fixed_array_map() ||
1375           value->map() == GetHeap()->fixed_cow_array_map()));
1376   ASSERT((value == GetHeap()->empty_fixed_array()) ||
1377          (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
1378   WRITE_FIELD(this, kElementsOffset, value);
1379   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
1380 }
1381
1382
1383 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1384   set_map_and_elements(NULL, value, mode);
1385 }
1386
1387
1388 void JSObject::initialize_properties() {
1389   ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1390   WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
1391 }
1392
1393
1394 void JSObject::initialize_elements() {
1395   ASSERT(map()->has_fast_elements() ||
1396          map()->has_fast_smi_only_elements() ||
1397          map()->has_fast_double_elements());
1398   ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1399   WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
1400 }
1401
1402
1403 MaybeObject* JSObject::ResetElements() {
1404   Object* obj;
1405   ElementsKind elements_kind = FLAG_smi_only_arrays
1406       ? FAST_SMI_ONLY_ELEMENTS
1407       : FAST_ELEMENTS;
1408   MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1409                                                     elements_kind);
1410   if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1411   set_map(Map::cast(obj));
1412   initialize_elements();
1413   return this;
1414 }
1415
1416
1417 ACCESSORS(Oddball, to_string, String, kToStringOffset)
1418 ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1419
1420
1421 byte Oddball::kind() {
1422   return Smi::cast(READ_FIELD(this, kKindOffset))->value();
1423 }
1424
1425
1426 void Oddball::set_kind(byte value) {
1427   WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
1428 }
1429
1430
1431 Object* JSGlobalPropertyCell::value() {
1432   return READ_FIELD(this, kValueOffset);
1433 }
1434
1435
1436 void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1437   // The write barrier is not used for global property cells.
1438   ASSERT(!val->IsJSGlobalPropertyCell());
1439   WRITE_FIELD(this, kValueOffset, val);
1440 }
1441
1442
1443 int JSObject::GetHeaderSize() {
1444   InstanceType type = map()->instance_type();
1445   // Check for the most common kind of JavaScript object before
1446   // falling into the generic switch. This speeds up the internal
1447   // field operations considerably on average.
1448   if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1449   switch (type) {
1450     case JS_MODULE_TYPE:
1451       return JSModule::kSize;
1452     case JS_GLOBAL_PROXY_TYPE:
1453       return JSGlobalProxy::kSize;
1454     case JS_GLOBAL_OBJECT_TYPE:
1455       return JSGlobalObject::kSize;
1456     case JS_BUILTINS_OBJECT_TYPE:
1457       return JSBuiltinsObject::kSize;
1458     case JS_FUNCTION_TYPE:
1459       return JSFunction::kSize;
1460     case JS_VALUE_TYPE:
1461       return JSValue::kSize;
1462     case JS_DATE_TYPE:
1463       return JSDate::kSize;
1464     case JS_ARRAY_TYPE:
1465       return JSArray::kSize;
1466     case JS_WEAK_MAP_TYPE:
1467       return JSWeakMap::kSize;
1468     case JS_REGEXP_TYPE:
1469       return JSRegExp::kSize;
1470     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
1471       return JSObject::kHeaderSize;
1472     case JS_MESSAGE_OBJECT_TYPE:
1473       return JSMessageObject::kSize;
1474     default:
1475       UNREACHABLE();
1476       return 0;
1477   }
1478 }
1479
1480
1481 int JSObject::GetInternalFieldCount() {
1482   ASSERT(1 << kPointerSizeLog2 == kPointerSize);
1483   // Make sure to adjust for the number of in-object properties. These
1484   // properties do contribute to the size, but are not internal fields.
1485   return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1486          map()->inobject_properties() - (map()->has_external_resource()?1:0);
1487 }
1488
1489
1490 int JSObject::GetInternalFieldOffset(int index) {
1491   ASSERT(index < GetInternalFieldCount() && index >= 0);
1492   return GetHeaderSize() + (kPointerSize * index);
1493 }
1494
1495
1496 Object* JSObject::GetInternalField(int index) {
1497   ASSERT(index < GetInternalFieldCount() && index >= 0);
1498   // Internal objects do follow immediately after the header, whereas in-object
1499   // properties are at the end of the object. Therefore there is no need
1500   // to adjust the index here.
1501   return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1502 }
1503
1504
1505 void JSObject::SetInternalField(int index, Object* value) {
1506   ASSERT(index < GetInternalFieldCount() && index >= 0);
1507   // Internal objects do follow immediately after the header, whereas in-object
1508   // properties are at the end of the object. Therefore there is no need
1509   // to adjust the index here.
1510   int offset = GetHeaderSize() + (kPointerSize * index);
1511   WRITE_FIELD(this, offset, value);
1512   WRITE_BARRIER(GetHeap(), this, offset, value);
1513 }
1514
1515
1516 void JSObject::SetInternalField(int index, Smi* value) {
1517   ASSERT(index < GetInternalFieldCount() && index >= 0);
1518   // Internal objects do follow immediately after the header, whereas in-object
1519   // properties are at the end of the object. Therefore there is no need
1520   // to adjust the index here.
1521   int offset = GetHeaderSize() + (kPointerSize * index);
1522   WRITE_FIELD(this, offset, value);
1523 }
1524
1525
1526 void JSObject::SetExternalResourceObject(Object *value) {
1527   ASSERT(map()->has_external_resource());
1528   int offset = GetHeaderSize() + kPointerSize * GetInternalFieldCount();
1529   WRITE_FIELD(this, offset, value);
1530   WRITE_BARRIER(GetHeap(), this, offset, value);
1531 }
1532
1533
1534 Object *JSObject::GetExternalResourceObject() {
1535   if (map()->has_external_resource()) {
1536     return READ_FIELD(this, GetHeaderSize() + kPointerSize * GetInternalFieldCount());
1537   } else {
1538     return GetHeap()->undefined_value();
1539   }
1540 }
1541
1542
1543 // Access fast-case object properties at index. The use of these routines
1544 // is needed to correctly distinguish between properties stored in-object and
1545 // properties stored in the properties array.
1546 Object* JSObject::FastPropertyAt(int index) {
1547   // Adjust for the number of properties stored in the object.
1548   index -= map()->inobject_properties();
1549   if (index < 0) {
1550     int offset = map()->instance_size() + (index * kPointerSize);
1551     return READ_FIELD(this, offset);
1552   } else {
1553     ASSERT(index < properties()->length());
1554     return properties()->get(index);
1555   }
1556 }
1557
1558
1559 Object* JSObject::FastPropertyAtPut(int index, Object* value) {
1560   // Adjust for the number of properties stored in the object.
1561   index -= map()->inobject_properties();
1562   if (index < 0) {
1563     int offset = map()->instance_size() + (index * kPointerSize);
1564     WRITE_FIELD(this, offset, value);
1565     WRITE_BARRIER(GetHeap(), this, offset, value);
1566   } else {
1567     ASSERT(index < properties()->length());
1568     properties()->set(index, value);
1569   }
1570   return value;
1571 }
1572
1573
1574 int JSObject::GetInObjectPropertyOffset(int index) {
1575   // Adjust for the number of properties stored in the object.
1576   index -= map()->inobject_properties();
1577   ASSERT(index < 0);
1578   return map()->instance_size() + (index * kPointerSize);
1579 }
1580
1581
1582 Object* JSObject::InObjectPropertyAt(int index) {
1583   // Adjust for the number of properties stored in the object.
1584   index -= map()->inobject_properties();
1585   ASSERT(index < 0);
1586   int offset = map()->instance_size() + (index * kPointerSize);
1587   return READ_FIELD(this, offset);
1588 }
1589
1590
1591 Object* JSObject::InObjectPropertyAtPut(int index,
1592                                         Object* value,
1593                                         WriteBarrierMode mode) {
1594   // Adjust for the number of properties stored in the object.
1595   index -= map()->inobject_properties();
1596   ASSERT(index < 0);
1597   int offset = map()->instance_size() + (index * kPointerSize);
1598   WRITE_FIELD(this, offset, value);
1599   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
1600   return value;
1601 }
1602
1603
1604
1605 void JSObject::InitializeBody(Map* map,
1606                               Object* pre_allocated_value,
1607                               Object* filler_value) {
1608   ASSERT(!filler_value->IsHeapObject() ||
1609          !GetHeap()->InNewSpace(filler_value));
1610   ASSERT(!pre_allocated_value->IsHeapObject() ||
1611          !GetHeap()->InNewSpace(pre_allocated_value));
1612   int size = map->instance_size();
1613   int offset = kHeaderSize;
1614   if (filler_value != pre_allocated_value) {
1615     int pre_allocated = map->pre_allocated_property_fields();
1616     ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1617     for (int i = 0; i < pre_allocated; i++) {
1618       WRITE_FIELD(this, offset, pre_allocated_value);
1619       offset += kPointerSize;
1620     }
1621   }
1622   while (offset < size) {
1623     WRITE_FIELD(this, offset, filler_value);
1624     offset += kPointerSize;
1625   }
1626 }
1627
1628
1629 bool JSObject::HasFastProperties() {
1630   return !properties()->IsDictionary();
1631 }
1632
1633
1634 int JSObject::MaxFastProperties() {
1635   // Allow extra fast properties if the object has more than
1636   // kMaxFastProperties in-object properties. When this is the case,
1637   // it is very unlikely that the object is being used as a dictionary
1638   // and there is a good chance that allowing more map transitions
1639   // will be worth it.
1640   return Max(map()->inobject_properties(), kMaxFastProperties);
1641 }
1642
1643
1644 void Struct::InitializeBody(int object_size) {
1645   Object* value = GetHeap()->undefined_value();
1646   for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
1647     WRITE_FIELD(this, offset, value);
1648   }
1649 }
1650
1651
1652 bool Object::ToArrayIndex(uint32_t* index) {
1653   if (IsSmi()) {
1654     int value = Smi::cast(this)->value();
1655     if (value < 0) return false;
1656     *index = value;
1657     return true;
1658   }
1659   if (IsHeapNumber()) {
1660     double value = HeapNumber::cast(this)->value();
1661     uint32_t uint_value = static_cast<uint32_t>(value);
1662     if (value == static_cast<double>(uint_value)) {
1663       *index = uint_value;
1664       return true;
1665     }
1666   }
1667   return false;
1668 }
1669
1670
1671 bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1672   if (!this->IsJSValue()) return false;
1673
1674   JSValue* js_value = JSValue::cast(this);
1675   if (!js_value->value()->IsString()) return false;
1676
1677   String* str = String::cast(js_value->value());
1678   if (index >= (uint32_t)str->length()) return false;
1679
1680   return true;
1681 }
1682
1683
1684 FixedArrayBase* FixedArrayBase::cast(Object* object) {
1685   ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1686   return reinterpret_cast<FixedArrayBase*>(object);
1687 }
1688
1689
1690 Object* FixedArray::get(int index) {
1691   ASSERT(index >= 0 && index < this->length());
1692   return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1693 }
1694
1695
1696 void FixedArray::set(int index, Smi* value) {
1697   ASSERT(map() != HEAP->fixed_cow_array_map());
1698   ASSERT(index >= 0 && index < this->length());
1699   ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1700   int offset = kHeaderSize + index * kPointerSize;
1701   WRITE_FIELD(this, offset, value);
1702 }
1703
1704
1705 void FixedArray::set(int index, Object* value) {
1706   ASSERT(map() != HEAP->fixed_cow_array_map());
1707   ASSERT(index >= 0 && index < this->length());
1708   int offset = kHeaderSize + index * kPointerSize;
1709   WRITE_FIELD(this, offset, value);
1710   WRITE_BARRIER(GetHeap(), this, offset, value);
1711 }
1712
1713
1714 inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1715   return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1716 }
1717
1718
1719 inline double FixedDoubleArray::hole_nan_as_double() {
1720   return BitCast<double, uint64_t>(kHoleNanInt64);
1721 }
1722
1723
1724 inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1725   ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1726   ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1727   return OS::nan_value();
1728 }
1729
1730
1731 double FixedDoubleArray::get_scalar(int index) {
1732   ASSERT(map() != HEAP->fixed_cow_array_map() &&
1733          map() != HEAP->fixed_array_map());
1734   ASSERT(index >= 0 && index < this->length());
1735   double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1736   ASSERT(!is_the_hole_nan(result));
1737   return result;
1738 }
1739
1740 int64_t FixedDoubleArray::get_representation(int index) {
1741   ASSERT(map() != HEAP->fixed_cow_array_map() &&
1742          map() != HEAP->fixed_array_map());
1743   ASSERT(index >= 0 && index < this->length());
1744   return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1745 }
1746
1747 MaybeObject* FixedDoubleArray::get(int index) {
1748   if (is_the_hole(index)) {
1749     return GetHeap()->the_hole_value();
1750   } else {
1751     return GetHeap()->NumberFromDouble(get_scalar(index));
1752   }
1753 }
1754
1755
1756 void FixedDoubleArray::set(int index, double value) {
1757   ASSERT(map() != HEAP->fixed_cow_array_map() &&
1758          map() != HEAP->fixed_array_map());
1759   int offset = kHeaderSize + index * kDoubleSize;
1760   if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1761   WRITE_DOUBLE_FIELD(this, offset, value);
1762 }
1763
1764
1765 void FixedDoubleArray::set_the_hole(int index) {
1766   ASSERT(map() != HEAP->fixed_cow_array_map() &&
1767          map() != HEAP->fixed_array_map());
1768   int offset = kHeaderSize + index * kDoubleSize;
1769   WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1770 }
1771
1772
1773 bool FixedDoubleArray::is_the_hole(int index) {
1774   int offset = kHeaderSize + index * kDoubleSize;
1775   return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1776 }
1777
1778
1779 WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
1780   Heap* heap = GetHeap();
1781   if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1782   if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
1783   return UPDATE_WRITE_BARRIER;
1784 }
1785
1786
1787 void FixedArray::set(int index,
1788                      Object* value,
1789                      WriteBarrierMode mode) {
1790   ASSERT(map() != HEAP->fixed_cow_array_map());
1791   ASSERT(index >= 0 && index < this->length());
1792   int offset = kHeaderSize + index * kPointerSize;
1793   WRITE_FIELD(this, offset, value);
1794   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
1795 }
1796
1797
1798 void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1799                                               int index,
1800                                               Object* value) {
1801   ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1802   ASSERT(index >= 0 && index < array->length());
1803   int offset = kHeaderSize + index * kPointerSize;
1804   WRITE_FIELD(array, offset, value);
1805   Heap* heap = array->GetHeap();
1806   if (heap->InNewSpace(value)) {
1807     heap->RecordWrite(array->address(), offset);
1808   }
1809 }
1810
1811
1812 void FixedArray::NoWriteBarrierSet(FixedArray* array,
1813                                    int index,
1814                                    Object* value) {
1815   ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1816   ASSERT(index >= 0 && index < array->length());
1817   ASSERT(!HEAP->InNewSpace(value));
1818   WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1819 }
1820
1821
1822 void FixedArray::set_undefined(int index) {
1823   ASSERT(map() != HEAP->fixed_cow_array_map());
1824   set_undefined(GetHeap(), index);
1825 }
1826
1827
1828 void FixedArray::set_undefined(Heap* heap, int index) {
1829   ASSERT(index >= 0 && index < this->length());
1830   ASSERT(!heap->InNewSpace(heap->undefined_value()));
1831   WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1832               heap->undefined_value());
1833 }
1834
1835
1836 void FixedArray::set_null(int index) {
1837   set_null(GetHeap(), index);
1838 }
1839
1840
1841 void FixedArray::set_null(Heap* heap, int index) {
1842   ASSERT(index >= 0 && index < this->length());
1843   ASSERT(!heap->InNewSpace(heap->null_value()));
1844   WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
1845 }
1846
1847
1848 void FixedArray::set_the_hole(int index) {
1849   ASSERT(map() != HEAP->fixed_cow_array_map());
1850   ASSERT(index >= 0 && index < this->length());
1851   ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1852   WRITE_FIELD(this,
1853               kHeaderSize + index * kPointerSize,
1854               GetHeap()->the_hole_value());
1855 }
1856
1857
1858 void FixedArray::set_unchecked(int index, Smi* value) {
1859   ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1860   int offset = kHeaderSize + index * kPointerSize;
1861   WRITE_FIELD(this, offset, value);
1862 }
1863
1864
1865 void FixedArray::set_unchecked(Heap* heap,
1866                                int index,
1867                                Object* value,
1868                                WriteBarrierMode mode) {
1869   int offset = kHeaderSize + index * kPointerSize;
1870   WRITE_FIELD(this, offset, value);
1871   CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
1872 }
1873
1874
1875 void FixedArray::set_null_unchecked(Heap* heap, int index) {
1876   ASSERT(index >= 0 && index < this->length());
1877   ASSERT(!HEAP->InNewSpace(heap->null_value()));
1878   WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
1879 }
1880
1881
1882 Object** FixedArray::data_start() {
1883   return HeapObject::RawField(this, kHeaderSize);
1884 }
1885
1886
1887 bool DescriptorArray::IsEmpty() {
1888   ASSERT(this->IsSmi() ||
1889          this->length() > kFirstIndex ||
1890          this == HEAP->empty_descriptor_array());
1891   return this->IsSmi() || length() <= kFirstIndex;
1892 }
1893
1894
1895 int DescriptorArray::bit_field3_storage() {
1896   Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1897   return Smi::cast(storage)->value();
1898 }
1899
1900 void DescriptorArray::set_bit_field3_storage(int value) {
1901   ASSERT(!IsEmpty());
1902   WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
1903 }
1904
1905
1906 void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1907                                                     int first,
1908                                                     int second) {
1909   Object* tmp = array->get(first);
1910   NoIncrementalWriteBarrierSet(array, first, array->get(second));
1911   NoIncrementalWriteBarrierSet(array, second, tmp);
1912 }
1913
1914
1915 int DescriptorArray::Search(String* name) {
1916   SLOW_ASSERT(IsSortedNoDuplicates());
1917
1918   // Check for empty descriptor array.
1919   int nof = number_of_descriptors();
1920   if (nof == 0) return kNotFound;
1921
1922   // Fast case: do linear search for small arrays.
1923   const int kMaxElementsForLinearSearch = 8;
1924   if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
1925     return LinearSearch(name, nof);
1926   }
1927
1928   // Slow case: perform binary search.
1929   return BinarySearch(name, 0, nof - 1);
1930 }
1931
1932
1933 int DescriptorArray::SearchWithCache(String* name) {
1934   int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
1935   if (number == DescriptorLookupCache::kAbsent) {
1936     number = Search(name);
1937     GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
1938   }
1939   return number;
1940 }
1941
1942
1943 String* DescriptorArray::GetKey(int descriptor_number) {
1944   ASSERT(descriptor_number < number_of_descriptors());
1945   return String::cast(get(ToKeyIndex(descriptor_number)));
1946 }
1947
1948
1949 Object* DescriptorArray::GetValue(int descriptor_number) {
1950   ASSERT(descriptor_number < number_of_descriptors());
1951   return GetContentArray()->get(ToValueIndex(descriptor_number));
1952 }
1953
1954
1955 PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
1956   ASSERT(descriptor_number < number_of_descriptors());
1957   Object* details = GetContentArray()->get(ToDetailsIndex(descriptor_number));
1958   return PropertyDetails(Smi::cast(details));
1959 }
1960
1961
1962 PropertyType DescriptorArray::GetType(int descriptor_number) {
1963   return GetDetails(descriptor_number).type();
1964 }
1965
1966
1967 int DescriptorArray::GetFieldIndex(int descriptor_number) {
1968   return Descriptor::IndexFromValue(GetValue(descriptor_number));
1969 }
1970
1971
1972 JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1973   return JSFunction::cast(GetValue(descriptor_number));
1974 }
1975
1976
1977 Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1978   ASSERT(GetType(descriptor_number) == CALLBACKS);
1979   return GetValue(descriptor_number);
1980 }
1981
1982
1983 AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1984   ASSERT(GetType(descriptor_number) == CALLBACKS);
1985   Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1986   return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
1987 }
1988
1989
1990 bool DescriptorArray::IsProperty(int descriptor_number) {
1991   Entry entry(this, descriptor_number);
1992   return IsPropertyDescriptor(&entry);
1993 }
1994
1995
1996 bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
1997   switch (GetType(descriptor_number)) {
1998     case MAP_TRANSITION:
1999     case CONSTANT_TRANSITION:
2000     case ELEMENTS_TRANSITION:
2001       return true;
2002     case CALLBACKS: {
2003       Object* value = GetValue(descriptor_number);
2004       if (!value->IsAccessorPair()) return false;
2005       AccessorPair* accessors = AccessorPair::cast(value);
2006       return accessors->getter()->IsMap() && accessors->setter()->IsMap();
2007     }
2008     case NORMAL:
2009     case FIELD:
2010     case CONSTANT_FUNCTION:
2011     case HANDLER:
2012     case INTERCEPTOR:
2013     case NULL_DESCRIPTOR:
2014       return false;
2015   }
2016   UNREACHABLE();  // Keep the compiler happy.
2017   return false;
2018 }
2019
2020
2021 bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2022   return GetType(descriptor_number) == NULL_DESCRIPTOR;
2023 }
2024
2025
2026 void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2027   desc->Init(GetKey(descriptor_number),
2028              GetValue(descriptor_number),
2029              GetDetails(descriptor_number));
2030 }
2031
2032
2033 void DescriptorArray::Set(int descriptor_number,
2034                           Descriptor* desc,
2035                           const WhitenessWitness&) {
2036   // Range check.
2037   ASSERT(descriptor_number < number_of_descriptors());
2038
2039   NoIncrementalWriteBarrierSet(this,
2040                                ToKeyIndex(descriptor_number),
2041                                desc->GetKey());
2042   FixedArray* content_array = GetContentArray();
2043   NoIncrementalWriteBarrierSet(content_array,
2044                                ToValueIndex(descriptor_number),
2045                                desc->GetValue());
2046   NoIncrementalWriteBarrierSet(content_array,
2047                                ToDetailsIndex(descriptor_number),
2048                                desc->GetDetails().AsSmi());
2049 }
2050
2051
2052 void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2053     int first, int second) {
2054   NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
2055   FixedArray* content_array = GetContentArray();
2056   NoIncrementalWriteBarrierSwap(content_array,
2057                                 ToValueIndex(first),
2058                                 ToValueIndex(second));
2059   NoIncrementalWriteBarrierSwap(content_array,
2060                                 ToDetailsIndex(first),
2061                                 ToDetailsIndex(second));
2062 }
2063
2064
2065 DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2066     : marking_(array->GetHeap()->incremental_marking()) {
2067   marking_->EnterNoMarkingScope();
2068   if (array->number_of_descriptors() > 0) {
2069     ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2070     ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2071   }
2072 }
2073
2074
2075 DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2076   marking_->LeaveNoMarkingScope();
2077 }
2078
2079
2080 template<typename Shape, typename Key>
2081 int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2082   const int kMinCapacity = 32;
2083   int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2084   if (capacity < kMinCapacity) {
2085     capacity = kMinCapacity;  // Guarantee min capacity.
2086   }
2087   return capacity;
2088 }
2089
2090
2091 template<typename Shape, typename Key>
2092 int HashTable<Shape, Key>::FindEntry(Key key) {
2093   return FindEntry(GetIsolate(), key);
2094 }
2095
2096
2097 // Find entry for key otherwise return kNotFound.
2098 template<typename Shape, typename Key>
2099 int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2100   uint32_t capacity = Capacity();
2101   uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
2102   uint32_t count = 1;
2103   // EnsureCapacity will guarantee the hash table is never full.
2104   while (true) {
2105     Object* element = KeyAt(entry);
2106     // Empty entry.
2107     if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2108     if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
2109         Shape::IsMatch(key, element)) return entry;
2110     entry = NextProbe(entry, count++, capacity);
2111   }
2112   return kNotFound;
2113 }
2114
2115
2116 bool SeededNumberDictionary::requires_slow_elements() {
2117   Object* max_index_object = get(kMaxNumberKeyIndex);
2118   if (!max_index_object->IsSmi()) return false;
2119   return 0 !=
2120       (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2121 }
2122
2123 uint32_t SeededNumberDictionary::max_number_key() {
2124   ASSERT(!requires_slow_elements());
2125   Object* max_index_object = get(kMaxNumberKeyIndex);
2126   if (!max_index_object->IsSmi()) return 0;
2127   uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2128   return value >> kRequiresSlowElementsTagSize;
2129 }
2130
2131 void SeededNumberDictionary::set_requires_slow_elements() {
2132   set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
2133 }
2134
2135
2136 // ------------------------------------
2137 // Cast operations
2138
2139
2140 CAST_ACCESSOR(FixedArray)
2141 CAST_ACCESSOR(FixedDoubleArray)
2142 CAST_ACCESSOR(DescriptorArray)
2143 CAST_ACCESSOR(DeoptimizationInputData)
2144 CAST_ACCESSOR(DeoptimizationOutputData)
2145 CAST_ACCESSOR(TypeFeedbackCells)
2146 CAST_ACCESSOR(SymbolTable)
2147 CAST_ACCESSOR(JSFunctionResultCache)
2148 CAST_ACCESSOR(NormalizedMapCache)
2149 CAST_ACCESSOR(ScopeInfo)
2150 CAST_ACCESSOR(CompilationCacheTable)
2151 CAST_ACCESSOR(CodeCacheHashTable)
2152 CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
2153 CAST_ACCESSOR(MapCache)
2154 CAST_ACCESSOR(String)
2155 CAST_ACCESSOR(SeqString)
2156 CAST_ACCESSOR(SeqAsciiString)
2157 CAST_ACCESSOR(SeqTwoByteString)
2158 CAST_ACCESSOR(SlicedString)
2159 CAST_ACCESSOR(ConsString)
2160 CAST_ACCESSOR(ExternalString)
2161 CAST_ACCESSOR(ExternalAsciiString)
2162 CAST_ACCESSOR(ExternalTwoByteString)
2163 CAST_ACCESSOR(JSReceiver)
2164 CAST_ACCESSOR(JSObject)
2165 CAST_ACCESSOR(Smi)
2166 CAST_ACCESSOR(HeapObject)
2167 CAST_ACCESSOR(HeapNumber)
2168 CAST_ACCESSOR(Oddball)
2169 CAST_ACCESSOR(JSGlobalPropertyCell)
2170 CAST_ACCESSOR(SharedFunctionInfo)
2171 CAST_ACCESSOR(Map)
2172 CAST_ACCESSOR(JSFunction)
2173 CAST_ACCESSOR(GlobalObject)
2174 CAST_ACCESSOR(JSGlobalProxy)
2175 CAST_ACCESSOR(JSGlobalObject)
2176 CAST_ACCESSOR(JSBuiltinsObject)
2177 CAST_ACCESSOR(Code)
2178 CAST_ACCESSOR(JSArray)
2179 CAST_ACCESSOR(JSRegExp)
2180 CAST_ACCESSOR(JSProxy)
2181 CAST_ACCESSOR(JSFunctionProxy)
2182 CAST_ACCESSOR(JSSet)
2183 CAST_ACCESSOR(JSMap)
2184 CAST_ACCESSOR(JSWeakMap)
2185 CAST_ACCESSOR(Foreign)
2186 CAST_ACCESSOR(ByteArray)
2187 CAST_ACCESSOR(FreeSpace)
2188 CAST_ACCESSOR(ExternalArray)
2189 CAST_ACCESSOR(ExternalByteArray)
2190 CAST_ACCESSOR(ExternalUnsignedByteArray)
2191 CAST_ACCESSOR(ExternalShortArray)
2192 CAST_ACCESSOR(ExternalUnsignedShortArray)
2193 CAST_ACCESSOR(ExternalIntArray)
2194 CAST_ACCESSOR(ExternalUnsignedIntArray)
2195 CAST_ACCESSOR(ExternalFloatArray)
2196 CAST_ACCESSOR(ExternalDoubleArray)
2197 CAST_ACCESSOR(ExternalPixelArray)
2198 CAST_ACCESSOR(Struct)
2199
2200
2201 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2202   STRUCT_LIST(MAKE_STRUCT_CAST)
2203 #undef MAKE_STRUCT_CAST
2204
2205
2206 template <typename Shape, typename Key>
2207 HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
2208   ASSERT(obj->IsHashTable());
2209   return reinterpret_cast<HashTable*>(obj);
2210 }
2211
2212
2213 SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
2214 SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
2215
2216 SMI_ACCESSORS(String, length, kLengthOffset)
2217 SMI_ACCESSORS(SeqString, symbol_id, kSymbolIdOffset)
2218
2219
2220 uint32_t String::hash_field() {
2221   return READ_UINT32_FIELD(this, kHashFieldOffset);
2222 }
2223
2224
2225 void String::set_hash_field(uint32_t value) {
2226   WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
2227 #if V8_HOST_ARCH_64_BIT
2228   WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2229 #endif
2230 }
2231
2232
2233 bool String::Equals(String* other) {
2234   if (other == this) return true;
2235   if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2236     return false;
2237   }
2238   return SlowEquals(other);
2239 }
2240
2241
2242 MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
2243   if (!StringShape(this).IsCons()) return this;
2244   ConsString* cons = ConsString::cast(this);
2245   if (cons->IsFlat()) return cons->first();
2246   return SlowTryFlatten(pretenure);
2247 }
2248
2249
2250 String* String::TryFlattenGetString(PretenureFlag pretenure) {
2251   MaybeObject* flat = TryFlatten(pretenure);
2252   Object* successfully_flattened;
2253   if (!flat->ToObject(&successfully_flattened)) return this;
2254   return String::cast(successfully_flattened);
2255 }
2256
2257
2258 uint16_t String::Get(int index) {
2259   ASSERT(index >= 0 && index < length());
2260   switch (StringShape(this).full_representation_tag()) {
2261     case kSeqStringTag | kAsciiStringTag:
2262       return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2263     case kSeqStringTag | kTwoByteStringTag:
2264       return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2265     case kConsStringTag | kAsciiStringTag:
2266     case kConsStringTag | kTwoByteStringTag:
2267       return ConsString::cast(this)->ConsStringGet(index);
2268     case kExternalStringTag | kAsciiStringTag:
2269       return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2270     case kExternalStringTag | kTwoByteStringTag:
2271       return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
2272     case kSlicedStringTag | kAsciiStringTag:
2273     case kSlicedStringTag | kTwoByteStringTag:
2274       return SlicedString::cast(this)->SlicedStringGet(index);
2275     default:
2276       break;
2277   }
2278
2279   UNREACHABLE();
2280   return 0;
2281 }
2282
2283
2284 void String::Set(int index, uint16_t value) {
2285   ASSERT(index >= 0 && index < length());
2286   ASSERT(StringShape(this).IsSequential());
2287
2288   return this->IsAsciiRepresentation()
2289       ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2290       : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
2291 }
2292
2293
2294 bool String::IsFlat() {
2295   if (!StringShape(this).IsCons()) return true;
2296   return ConsString::cast(this)->second()->length() == 0;
2297 }
2298
2299
2300 String* String::GetUnderlying() {
2301   // Giving direct access to underlying string only makes sense if the
2302   // wrapping string is already flattened.
2303   ASSERT(this->IsFlat());
2304   ASSERT(StringShape(this).IsIndirect());
2305   STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2306   const int kUnderlyingOffset = SlicedString::kParentOffset;
2307   return String::cast(READ_FIELD(this, kUnderlyingOffset));
2308 }
2309
2310
2311 uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
2312   ASSERT(index >= 0 && index < length());
2313   return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2314 }
2315
2316
2317 void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
2318   ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2319   WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2320                    static_cast<byte>(value));
2321 }
2322
2323
2324 Address SeqAsciiString::GetCharsAddress() {
2325   return FIELD_ADDR(this, kHeaderSize);
2326 }
2327
2328
2329 char* SeqAsciiString::GetChars() {
2330   return reinterpret_cast<char*>(GetCharsAddress());
2331 }
2332
2333
2334 Address SeqTwoByteString::GetCharsAddress() {
2335   return FIELD_ADDR(this, kHeaderSize);
2336 }
2337
2338
2339 uc16* SeqTwoByteString::GetChars() {
2340   return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2341 }
2342
2343
2344 uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
2345   ASSERT(index >= 0 && index < length());
2346   return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2347 }
2348
2349
2350 void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
2351   ASSERT(index >= 0 && index < length());
2352   WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2353 }
2354
2355
2356 int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
2357   return SizeFor(length());
2358 }
2359
2360
2361 int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
2362   return SizeFor(length());
2363 }
2364
2365
2366 String* SlicedString::parent() {
2367   return String::cast(READ_FIELD(this, kParentOffset));
2368 }
2369
2370
2371 void SlicedString::set_parent(String* parent) {
2372   ASSERT(parent->IsSeqString() || parent->IsExternalString());
2373   WRITE_FIELD(this, kParentOffset, parent);
2374 }
2375
2376
2377 SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2378
2379
2380 String* ConsString::first() {
2381   return String::cast(READ_FIELD(this, kFirstOffset));
2382 }
2383
2384
2385 Object* ConsString::unchecked_first() {
2386   return READ_FIELD(this, kFirstOffset);
2387 }
2388
2389
2390 void ConsString::set_first(String* value, WriteBarrierMode mode) {
2391   WRITE_FIELD(this, kFirstOffset, value);
2392   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
2393 }
2394
2395
2396 String* ConsString::second() {
2397   return String::cast(READ_FIELD(this, kSecondOffset));
2398 }
2399
2400
2401 Object* ConsString::unchecked_second() {
2402   return READ_FIELD(this, kSecondOffset);
2403 }
2404
2405
2406 void ConsString::set_second(String* value, WriteBarrierMode mode) {
2407   WRITE_FIELD(this, kSecondOffset, value);
2408   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
2409 }
2410
2411
2412 bool ExternalString::is_short() {
2413   InstanceType type = map()->instance_type();
2414   return (type & kShortExternalStringMask) == kShortExternalStringTag;
2415 }
2416
2417
2418 const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2419   return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2420 }
2421
2422
2423 void ExternalAsciiString::update_data_cache() {
2424   if (is_short()) return;
2425   const char** data_field =
2426       reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2427   *data_field = resource()->data();
2428 }
2429
2430
2431 void ExternalAsciiString::set_resource(
2432     const ExternalAsciiString::Resource* resource) {
2433   *reinterpret_cast<const Resource**>(
2434       FIELD_ADDR(this, kResourceOffset)) = resource;
2435   if (resource != NULL) update_data_cache();
2436 }
2437
2438
2439 const char* ExternalAsciiString::GetChars() {
2440   return resource()->data();
2441 }
2442
2443
2444 uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2445   ASSERT(index >= 0 && index < length());
2446   return GetChars()[index];
2447 }
2448
2449
2450 const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2451   return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2452 }
2453
2454
2455 void ExternalTwoByteString::update_data_cache() {
2456   if (is_short()) return;
2457   const uint16_t** data_field =
2458       reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2459   *data_field = resource()->data();
2460 }
2461
2462
2463 void ExternalTwoByteString::set_resource(
2464     const ExternalTwoByteString::Resource* resource) {
2465   *reinterpret_cast<const Resource**>(
2466       FIELD_ADDR(this, kResourceOffset)) = resource;
2467   if (resource != NULL) update_data_cache();
2468 }
2469
2470
2471 const uint16_t* ExternalTwoByteString::GetChars() {
2472   return resource()->data();
2473 }
2474
2475
2476 uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2477   ASSERT(index >= 0 && index < length());
2478   return GetChars()[index];
2479 }
2480
2481
2482 const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2483       unsigned start) {
2484   return GetChars() + start;
2485 }
2486
2487
2488 void JSFunctionResultCache::MakeZeroSize() {
2489   set_finger_index(kEntriesIndex);
2490   set_size(kEntriesIndex);
2491 }
2492
2493
2494 void JSFunctionResultCache::Clear() {
2495   int cache_size = size();
2496   Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
2497   MemsetPointer(entries_start,
2498                 GetHeap()->the_hole_value(),
2499                 cache_size - kEntriesIndex);
2500   MakeZeroSize();
2501 }
2502
2503
2504 int JSFunctionResultCache::size() {
2505   return Smi::cast(get(kCacheSizeIndex))->value();
2506 }
2507
2508
2509 void JSFunctionResultCache::set_size(int size) {
2510   set(kCacheSizeIndex, Smi::FromInt(size));
2511 }
2512
2513
2514 int JSFunctionResultCache::finger_index() {
2515   return Smi::cast(get(kFingerIndex))->value();
2516 }
2517
2518
2519 void JSFunctionResultCache::set_finger_index(int finger_index) {
2520   set(kFingerIndex, Smi::FromInt(finger_index));
2521 }
2522
2523
2524 byte ByteArray::get(int index) {
2525   ASSERT(index >= 0 && index < this->length());
2526   return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2527 }
2528
2529
2530 void ByteArray::set(int index, byte value) {
2531   ASSERT(index >= 0 && index < this->length());
2532   WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2533 }
2534
2535
2536 int ByteArray::get_int(int index) {
2537   ASSERT(index >= 0 && (index * kIntSize) < this->length());
2538   return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2539 }
2540
2541
2542 ByteArray* ByteArray::FromDataStartAddress(Address address) {
2543   ASSERT_TAG_ALIGNED(address);
2544   return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2545 }
2546
2547
2548 Address ByteArray::GetDataStartAddress() {
2549   return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2550 }
2551
2552
2553 uint8_t* ExternalPixelArray::external_pixel_pointer() {
2554   return reinterpret_cast<uint8_t*>(external_pointer());
2555 }
2556
2557
2558 uint8_t ExternalPixelArray::get_scalar(int index) {
2559   ASSERT((index >= 0) && (index < this->length()));
2560   uint8_t* ptr = external_pixel_pointer();
2561   return ptr[index];
2562 }
2563
2564
2565 MaybeObject* ExternalPixelArray::get(int index) {
2566   return Smi::FromInt(static_cast<int>(get_scalar(index)));
2567 }
2568
2569
2570 void ExternalPixelArray::set(int index, uint8_t value) {
2571   ASSERT((index >= 0) && (index < this->length()));
2572   uint8_t* ptr = external_pixel_pointer();
2573   ptr[index] = value;
2574 }
2575
2576
2577 void* ExternalArray::external_pointer() {
2578   intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2579   return reinterpret_cast<void*>(ptr);
2580 }
2581
2582
2583 void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2584   intptr_t ptr = reinterpret_cast<intptr_t>(value);
2585   WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2586 }
2587
2588
2589 int8_t ExternalByteArray::get_scalar(int index) {
2590   ASSERT((index >= 0) && (index < this->length()));
2591   int8_t* ptr = static_cast<int8_t*>(external_pointer());
2592   return ptr[index];
2593 }
2594
2595
2596 MaybeObject* ExternalByteArray::get(int index) {
2597   return Smi::FromInt(static_cast<int>(get_scalar(index)));
2598 }
2599
2600
2601 void ExternalByteArray::set(int index, int8_t value) {
2602   ASSERT((index >= 0) && (index < this->length()));
2603   int8_t* ptr = static_cast<int8_t*>(external_pointer());
2604   ptr[index] = value;
2605 }
2606
2607
2608 uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
2609   ASSERT((index >= 0) && (index < this->length()));
2610   uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2611   return ptr[index];
2612 }
2613
2614
2615 MaybeObject* ExternalUnsignedByteArray::get(int index) {
2616   return Smi::FromInt(static_cast<int>(get_scalar(index)));
2617 }
2618
2619
2620 void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2621   ASSERT((index >= 0) && (index < this->length()));
2622   uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2623   ptr[index] = value;
2624 }
2625
2626
2627 int16_t ExternalShortArray::get_scalar(int index) {
2628   ASSERT((index >= 0) && (index < this->length()));
2629   int16_t* ptr = static_cast<int16_t*>(external_pointer());
2630   return ptr[index];
2631 }
2632
2633
2634 MaybeObject* ExternalShortArray::get(int index) {
2635   return Smi::FromInt(static_cast<int>(get_scalar(index)));
2636 }
2637
2638
2639 void ExternalShortArray::set(int index, int16_t value) {
2640   ASSERT((index >= 0) && (index < this->length()));
2641   int16_t* ptr = static_cast<int16_t*>(external_pointer());
2642   ptr[index] = value;
2643 }
2644
2645
2646 uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
2647   ASSERT((index >= 0) && (index < this->length()));
2648   uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2649   return ptr[index];
2650 }
2651
2652
2653 MaybeObject* ExternalUnsignedShortArray::get(int index) {
2654   return Smi::FromInt(static_cast<int>(get_scalar(index)));
2655 }
2656
2657
2658 void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2659   ASSERT((index >= 0) && (index < this->length()));
2660   uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2661   ptr[index] = value;
2662 }
2663
2664
2665 int32_t ExternalIntArray::get_scalar(int index) {
2666   ASSERT((index >= 0) && (index < this->length()));
2667   int32_t* ptr = static_cast<int32_t*>(external_pointer());
2668   return ptr[index];
2669 }
2670
2671
2672 MaybeObject* ExternalIntArray::get(int index) {
2673     return GetHeap()->NumberFromInt32(get_scalar(index));
2674 }
2675
2676
2677 void ExternalIntArray::set(int index, int32_t value) {
2678   ASSERT((index >= 0) && (index < this->length()));
2679   int32_t* ptr = static_cast<int32_t*>(external_pointer());
2680   ptr[index] = value;
2681 }
2682
2683
2684 uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
2685   ASSERT((index >= 0) && (index < this->length()));
2686   uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2687   return ptr[index];
2688 }
2689
2690
2691 MaybeObject* ExternalUnsignedIntArray::get(int index) {
2692     return GetHeap()->NumberFromUint32(get_scalar(index));
2693 }
2694
2695
2696 void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2697   ASSERT((index >= 0) && (index < this->length()));
2698   uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2699   ptr[index] = value;
2700 }
2701
2702
2703 float ExternalFloatArray::get_scalar(int index) {
2704   ASSERT((index >= 0) && (index < this->length()));
2705   float* ptr = static_cast<float*>(external_pointer());
2706   return ptr[index];
2707 }
2708
2709
2710 MaybeObject* ExternalFloatArray::get(int index) {
2711     return GetHeap()->NumberFromDouble(get_scalar(index));
2712 }
2713
2714
2715 void ExternalFloatArray::set(int index, float value) {
2716   ASSERT((index >= 0) && (index < this->length()));
2717   float* ptr = static_cast<float*>(external_pointer());
2718   ptr[index] = value;
2719 }
2720
2721
2722 double ExternalDoubleArray::get_scalar(int index) {
2723   ASSERT((index >= 0) && (index < this->length()));
2724   double* ptr = static_cast<double*>(external_pointer());
2725   return ptr[index];
2726 }
2727
2728
2729 MaybeObject* ExternalDoubleArray::get(int index) {
2730     return GetHeap()->NumberFromDouble(get_scalar(index));
2731 }
2732
2733
2734 void ExternalDoubleArray::set(int index, double value) {
2735   ASSERT((index >= 0) && (index < this->length()));
2736   double* ptr = static_cast<double*>(external_pointer());
2737   ptr[index] = value;
2738 }
2739
2740
2741 int Map::visitor_id() {
2742   return READ_BYTE_FIELD(this, kVisitorIdOffset);
2743 }
2744
2745
2746 void Map::set_visitor_id(int id) {
2747   ASSERT(0 <= id && id < 256);
2748   WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2749 }
2750
2751
2752 int Map::instance_size() {
2753   return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2754 }
2755
2756
2757 int Map::inobject_properties() {
2758   return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
2759 }
2760
2761
2762 int Map::pre_allocated_property_fields() {
2763   return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2764 }
2765
2766
2767 int HeapObject::SizeFromMap(Map* map) {
2768   int instance_size = map->instance_size();
2769   if (instance_size != kVariableSizeSentinel) return instance_size;
2770   // We can ignore the "symbol" bit becase it is only set for symbols
2771   // and implies a string type.
2772   int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
2773   // Only inline the most frequent cases.
2774   if (instance_type == FIXED_ARRAY_TYPE) {
2775     return FixedArray::BodyDescriptor::SizeOf(map, this);
2776   }
2777   if (instance_type == ASCII_STRING_TYPE) {
2778     return SeqAsciiString::SizeFor(
2779         reinterpret_cast<SeqAsciiString*>(this)->length());
2780   }
2781   if (instance_type == BYTE_ARRAY_TYPE) {
2782     return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2783   }
2784   if (instance_type == FREE_SPACE_TYPE) {
2785     return reinterpret_cast<FreeSpace*>(this)->size();
2786   }
2787   if (instance_type == STRING_TYPE) {
2788     return SeqTwoByteString::SizeFor(
2789         reinterpret_cast<SeqTwoByteString*>(this)->length());
2790   }
2791   if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2792     return FixedDoubleArray::SizeFor(
2793         reinterpret_cast<FixedDoubleArray*>(this)->length());
2794   }
2795   ASSERT(instance_type == CODE_TYPE);
2796   return reinterpret_cast<Code*>(this)->CodeSize();
2797 }
2798
2799
2800 void Map::set_instance_size(int value) {
2801   ASSERT_EQ(0, value & (kPointerSize - 1));
2802   value >>= kPointerSizeLog2;
2803   ASSERT(0 <= value && value < 256);
2804   WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2805 }
2806
2807
2808 void Map::set_inobject_properties(int value) {
2809   ASSERT(0 <= value && value < 256);
2810   WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2811 }
2812
2813
2814 void Map::set_pre_allocated_property_fields(int value) {
2815   ASSERT(0 <= value && value < 256);
2816   WRITE_BYTE_FIELD(this,
2817                    kPreAllocatedPropertyFieldsOffset,
2818                    static_cast<byte>(value));
2819 }
2820
2821
2822 InstanceType Map::instance_type() {
2823   return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2824 }
2825
2826
2827 void Map::set_instance_type(InstanceType value) {
2828   WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2829 }
2830
2831
2832 int Map::unused_property_fields() {
2833   return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2834 }
2835
2836
2837 void Map::set_unused_property_fields(int value) {
2838   WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2839 }
2840
2841
2842 byte Map::bit_field() {
2843   return READ_BYTE_FIELD(this, kBitFieldOffset);
2844 }
2845
2846
2847 void Map::set_bit_field(byte value) {
2848   WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2849 }
2850
2851
2852 byte Map::bit_field2() {
2853   return READ_BYTE_FIELD(this, kBitField2Offset);
2854 }
2855
2856
2857 void Map::set_bit_field2(byte value) {
2858   WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2859 }
2860
2861
2862 void Map::set_non_instance_prototype(bool value) {
2863   if (value) {
2864     set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2865   } else {
2866     set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2867   }
2868 }
2869
2870
2871 bool Map::has_non_instance_prototype() {
2872   return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2873 }
2874
2875
2876 void Map::set_function_with_prototype(bool value) {
2877   if (value) {
2878     set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2879   } else {
2880     set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2881   }
2882 }
2883
2884
2885 bool Map::function_with_prototype() {
2886   return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2887 }
2888
2889
2890 void Map::set_is_access_check_needed(bool access_check_needed) {
2891   if (access_check_needed) {
2892     set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2893   } else {
2894     set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2895   }
2896 }
2897
2898
2899 bool Map::is_access_check_needed() {
2900   return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2901 }
2902
2903
2904 void Map::set_is_extensible(bool value) {
2905   if (value) {
2906     set_bit_field2(bit_field2() | (1 << kIsExtensible));
2907   } else {
2908     set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2909   }
2910 }
2911
2912 bool Map::is_extensible() {
2913   return ((1 << kIsExtensible) & bit_field2()) != 0;
2914 }
2915
2916
2917 void Map::set_attached_to_shared_function_info(bool value) {
2918   if (value) {
2919     set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2920   } else {
2921     set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2922   }
2923 }
2924
2925 bool Map::attached_to_shared_function_info() {
2926   return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2927 }
2928
2929
2930 void Map::set_is_shared(bool value) {
2931   if (value) {
2932     set_bit_field3(bit_field3() | (1 << kIsShared));
2933   } else {
2934     set_bit_field3(bit_field3() & ~(1 << kIsShared));
2935   }
2936 }
2937
2938 bool Map::is_shared() {
2939   return ((1 << kIsShared) & bit_field3()) != 0;
2940 }
2941
2942 void Map::set_has_external_resource(bool value) {
2943   if (value) {
2944     set_bit_field(bit_field() | (1 << kHasExternalResource));
2945   } else {
2946     set_bit_field(bit_field() & ~(1 << kHasExternalResource));
2947   }
2948 }
2949
2950 bool Map::has_external_resource()
2951 {
2952     return ((1 << kHasExternalResource) & bit_field()) != 0;
2953 }
2954
2955
2956 void Map::set_named_interceptor_is_fallback(bool value) {
2957   if (value) {
2958     set_bit_field3(bit_field3() | (1 << kNamedInterceptorIsFallback));
2959   } else {
2960     set_bit_field3(bit_field3() & ~(1 << kNamedInterceptorIsFallback));
2961   }
2962 }
2963
2964 bool Map::named_interceptor_is_fallback() {
2965   return ((1 << kNamedInterceptorIsFallback) & bit_field3()) != 0;
2966 }
2967
2968
2969 JSFunction* Map::unchecked_constructor() {
2970   return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2971 }
2972
2973
2974 Code::Flags Code::flags() {
2975   return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2976 }
2977
2978
2979 void Code::set_flags(Code::Flags flags) {
2980   STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
2981   // Make sure that all call stubs have an arguments count.
2982   ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2983           ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
2984          ExtractArgumentsCountFromFlags(flags) >= 0);
2985   WRITE_INT_FIELD(this, kFlagsOffset, flags);
2986 }
2987
2988
2989 Code::Kind Code::kind() {
2990   return ExtractKindFromFlags(flags());
2991 }
2992
2993
2994 InlineCacheState Code::ic_state() {
2995   InlineCacheState result = ExtractICStateFromFlags(flags());
2996   // Only allow uninitialized or debugger states for non-IC code
2997   // objects. This is used in the debugger to determine whether or not
2998   // a call to code object has been replaced with a debug break call.
2999   ASSERT(is_inline_cache_stub() ||
3000          result == UNINITIALIZED ||
3001          result == DEBUG_BREAK ||
3002          result == DEBUG_PREPARE_STEP_IN);
3003   return result;
3004 }
3005
3006
3007 Code::ExtraICState Code::extra_ic_state() {
3008   ASSERT(is_inline_cache_stub());
3009   return ExtractExtraICStateFromFlags(flags());
3010 }
3011
3012
3013 PropertyType Code::type() {
3014   return ExtractTypeFromFlags(flags());
3015 }
3016
3017
3018 int Code::arguments_count() {
3019   ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
3020   return ExtractArgumentsCountFromFlags(flags());
3021 }
3022
3023
3024 int Code::major_key() {
3025   ASSERT(kind() == STUB ||
3026          kind() == UNARY_OP_IC ||
3027          kind() == BINARY_OP_IC ||
3028          kind() == COMPARE_IC ||
3029          kind() == TO_BOOLEAN_IC);
3030   return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
3031 }
3032
3033
3034 void Code::set_major_key(int major) {
3035   ASSERT(kind() == STUB ||
3036          kind() == UNARY_OP_IC ||
3037          kind() == BINARY_OP_IC ||
3038          kind() == COMPARE_IC ||
3039          kind() == TO_BOOLEAN_IC);
3040   ASSERT(0 <= major && major < 256);
3041   WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
3042 }
3043
3044
3045 bool Code::is_pregenerated() {
3046   return kind() == STUB && IsPregeneratedField::decode(flags());
3047 }
3048
3049
3050 void Code::set_is_pregenerated(bool value) {
3051   ASSERT(kind() == STUB);
3052   Flags f = flags();
3053   f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3054   set_flags(f);
3055 }
3056
3057
3058 bool Code::optimizable() {
3059   ASSERT_EQ(FUNCTION, kind());
3060   return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3061 }
3062
3063
3064 void Code::set_optimizable(bool value) {
3065   ASSERT_EQ(FUNCTION, kind());
3066   WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3067 }
3068
3069
3070 bool Code::has_deoptimization_support() {
3071   ASSERT_EQ(FUNCTION, kind());
3072   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3073   return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
3074 }
3075
3076
3077 void Code::set_has_deoptimization_support(bool value) {
3078   ASSERT_EQ(FUNCTION, kind());
3079   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3080   flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3081   WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3082 }
3083
3084
3085 bool Code::has_debug_break_slots() {
3086   ASSERT_EQ(FUNCTION, kind());
3087   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3088   return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3089 }
3090
3091
3092 void Code::set_has_debug_break_slots(bool value) {
3093   ASSERT_EQ(FUNCTION, kind());
3094   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3095   flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3096   WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3097 }
3098
3099
3100 bool Code::is_compiled_optimizable() {
3101   ASSERT_EQ(FUNCTION, kind());
3102   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3103   return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3104 }
3105
3106
3107 void Code::set_compiled_optimizable(bool value) {
3108   ASSERT_EQ(FUNCTION, kind());
3109   byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3110   flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3111   WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3112 }
3113
3114
3115 int Code::allow_osr_at_loop_nesting_level() {
3116   ASSERT_EQ(FUNCTION, kind());
3117   return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3118 }
3119
3120
3121 void Code::set_allow_osr_at_loop_nesting_level(int level) {
3122   ASSERT_EQ(FUNCTION, kind());
3123   ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3124   WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3125 }
3126
3127
3128 int Code::profiler_ticks() {
3129   ASSERT_EQ(FUNCTION, kind());
3130   return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3131 }
3132
3133
3134 void Code::set_profiler_ticks(int ticks) {
3135   ASSERT_EQ(FUNCTION, kind());
3136   ASSERT(ticks < 256);
3137   WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3138 }
3139
3140
3141 unsigned Code::stack_slots() {
3142   ASSERT(kind() == OPTIMIZED_FUNCTION);
3143   return READ_UINT32_FIELD(this, kStackSlotsOffset);
3144 }
3145
3146
3147 void Code::set_stack_slots(unsigned slots) {
3148   ASSERT(kind() == OPTIMIZED_FUNCTION);
3149   WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3150 }
3151
3152
3153 unsigned Code::safepoint_table_offset() {
3154   ASSERT(kind() == OPTIMIZED_FUNCTION);
3155   return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
3156 }
3157
3158
3159 void Code::set_safepoint_table_offset(unsigned offset) {
3160   ASSERT(kind() == OPTIMIZED_FUNCTION);
3161   ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
3162   WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
3163 }
3164
3165
3166 unsigned Code::stack_check_table_offset() {
3167   ASSERT_EQ(FUNCTION, kind());
3168   return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
3169 }
3170
3171
3172 void Code::set_stack_check_table_offset(unsigned offset) {
3173   ASSERT_EQ(FUNCTION, kind());
3174   ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
3175   WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
3176 }
3177
3178
3179 CheckType Code::check_type() {
3180   ASSERT(is_call_stub() || is_keyed_call_stub());
3181   byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3182   return static_cast<CheckType>(type);
3183 }
3184
3185
3186 void Code::set_check_type(CheckType value) {
3187   ASSERT(is_call_stub() || is_keyed_call_stub());
3188   WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3189 }
3190
3191
3192 byte Code::unary_op_type() {
3193   ASSERT(is_unary_op_stub());
3194   return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3195 }
3196
3197
3198 void Code::set_unary_op_type(byte value) {
3199   ASSERT(is_unary_op_stub());
3200   WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3201 }
3202
3203
3204 byte Code::binary_op_type() {
3205   ASSERT(is_binary_op_stub());
3206   return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3207 }
3208
3209
3210 void Code::set_binary_op_type(byte value) {
3211   ASSERT(is_binary_op_stub());
3212   WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3213 }
3214
3215
3216 byte Code::binary_op_result_type() {
3217   ASSERT(is_binary_op_stub());
3218   return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3219 }
3220
3221
3222 void Code::set_binary_op_result_type(byte value) {
3223   ASSERT(is_binary_op_stub());
3224   WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3225 }
3226
3227
3228 byte Code::compare_state() {
3229   ASSERT(is_compare_ic_stub());
3230   return READ_BYTE_FIELD(this, kCompareStateOffset);
3231 }
3232
3233
3234 void Code::set_compare_state(byte value) {
3235   ASSERT(is_compare_ic_stub());
3236   WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3237 }
3238
3239
3240 byte Code::compare_operation() {
3241   ASSERT(is_compare_ic_stub());
3242   return READ_BYTE_FIELD(this, kCompareOperationOffset);
3243 }
3244
3245
3246 void Code::set_compare_operation(byte value) {
3247   ASSERT(is_compare_ic_stub());
3248   WRITE_BYTE_FIELD(this, kCompareOperationOffset, value);
3249 }
3250
3251
3252 byte Code::to_boolean_state() {
3253   ASSERT(is_to_boolean_ic_stub());
3254   return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3255 }
3256
3257
3258 void Code::set_to_boolean_state(byte value) {
3259   ASSERT(is_to_boolean_ic_stub());
3260   WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3261 }
3262
3263
3264 bool Code::has_function_cache() {
3265   ASSERT(kind() == STUB);
3266   return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3267 }
3268
3269
3270 void Code::set_has_function_cache(bool flag) {
3271   ASSERT(kind() == STUB);
3272   WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3273 }
3274
3275
3276 bool Code::is_inline_cache_stub() {
3277   Kind kind = this->kind();
3278   return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3279 }
3280
3281
3282 Code::Flags Code::ComputeFlags(Kind kind,
3283                                InlineCacheState ic_state,
3284                                ExtraICState extra_ic_state,
3285                                PropertyType type,
3286                                int argc,
3287                                InlineCacheHolderFlag holder) {
3288   // Extra IC state is only allowed for call IC stubs or for store IC
3289   // stubs.
3290   ASSERT(extra_ic_state == kNoExtraICState ||
3291          kind == CALL_IC ||
3292          kind == STORE_IC ||
3293          kind == KEYED_STORE_IC);
3294   // Compute the bit mask.
3295   int bits = KindField::encode(kind)
3296       | ICStateField::encode(ic_state)
3297       | TypeField::encode(type)
3298       | ExtraICStateField::encode(extra_ic_state)
3299       | (argc << kArgumentsCountShift)
3300       | CacheHolderField::encode(holder);
3301   return static_cast<Flags>(bits);
3302 }
3303
3304
3305 Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3306                                           PropertyType type,
3307                                           ExtraICState extra_ic_state,
3308                                           InlineCacheHolderFlag holder,
3309                                           int argc) {
3310   return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
3311 }
3312
3313
3314 Code::Kind Code::ExtractKindFromFlags(Flags flags) {
3315   return KindField::decode(flags);
3316 }
3317
3318
3319 InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
3320   return ICStateField::decode(flags);
3321 }
3322
3323
3324 Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
3325   return ExtraICStateField::decode(flags);
3326 }
3327
3328
3329 PropertyType Code::ExtractTypeFromFlags(Flags flags) {
3330   return TypeField::decode(flags);
3331 }
3332
3333
3334 int Code::ExtractArgumentsCountFromFlags(Flags flags) {
3335   return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
3336 }
3337
3338
3339 InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
3340   return CacheHolderField::decode(flags);
3341 }
3342
3343
3344 Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
3345   int bits = flags & ~TypeField::kMask;
3346   return static_cast<Flags>(bits);
3347 }
3348
3349
3350 Code* Code::GetCodeFromTargetAddress(Address address) {
3351   HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3352   // GetCodeFromTargetAddress might be called when marking objects during mark
3353   // sweep. reinterpret_cast is therefore used instead of the more appropriate
3354   // Code::cast. Code::cast does not work when the object's map is
3355   // marked.
3356   Code* result = reinterpret_cast<Code*>(code);
3357   return result;
3358 }
3359
3360
3361 Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3362   return HeapObject::
3363       FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3364 }
3365
3366
3367 Object* Map::prototype() {
3368   return READ_FIELD(this, kPrototypeOffset);
3369 }
3370
3371
3372 void Map::set_prototype(Object* value, WriteBarrierMode mode) {
3373   ASSERT(value->IsNull() || value->IsJSReceiver());
3374   WRITE_FIELD(this, kPrototypeOffset, value);
3375   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
3376 }
3377
3378
3379 DescriptorArray* Map::instance_descriptors() {
3380   Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3381   if (object->IsSmi()) {
3382     return GetHeap()->empty_descriptor_array();
3383   } else {
3384     return DescriptorArray::cast(object);
3385   }
3386 }
3387
3388
3389 void Map::init_instance_descriptors() {
3390   WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3391 }
3392
3393
3394 void Map::clear_instance_descriptors() {
3395   Object* object = READ_FIELD(this,
3396                               kInstanceDescriptorsOrBitField3Offset);
3397   if (!object->IsSmi()) {
3398 #ifdef DEBUG
3399     ZapInstanceDescriptors();
3400 #endif
3401     WRITE_FIELD(
3402         this,
3403         kInstanceDescriptorsOrBitField3Offset,
3404         Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3405   }
3406 }
3407
3408
3409 void Map::set_instance_descriptors(DescriptorArray* value,
3410                                    WriteBarrierMode mode) {
3411   Object* object = READ_FIELD(this,
3412                               kInstanceDescriptorsOrBitField3Offset);
3413   Heap* heap = GetHeap();
3414   if (value == heap->empty_descriptor_array()) {
3415     clear_instance_descriptors();
3416     return;
3417   } else {
3418     if (object->IsSmi()) {
3419       value->set_bit_field3_storage(Smi::cast(object)->value());
3420     } else {
3421       value->set_bit_field3_storage(
3422           DescriptorArray::cast(object)->bit_field3_storage());
3423     }
3424   }
3425   ASSERT(!is_shared());
3426 #ifdef DEBUG
3427   if (value != instance_descriptors()) {
3428     ZapInstanceDescriptors();
3429   }
3430 #endif
3431   WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3432   CONDITIONAL_WRITE_BARRIER(
3433       heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
3434 }
3435
3436
3437 int Map::bit_field3() {
3438   Object* object = READ_FIELD(this,
3439                               kInstanceDescriptorsOrBitField3Offset);
3440   if (object->IsSmi()) {
3441     return Smi::cast(object)->value();
3442   } else {
3443     return DescriptorArray::cast(object)->bit_field3_storage();
3444   }
3445 }
3446
3447
3448 void Map::set_bit_field3(int value) {
3449   ASSERT(Smi::IsValid(value));
3450   Object* object = READ_FIELD(this,
3451                               kInstanceDescriptorsOrBitField3Offset);
3452   if (object->IsSmi()) {
3453     WRITE_FIELD(this,
3454                 kInstanceDescriptorsOrBitField3Offset,
3455                 Smi::FromInt(value));
3456   } else {
3457     DescriptorArray::cast(object)->set_bit_field3_storage(value);
3458   }
3459 }
3460
3461
3462 Object* Map::GetBackPointer() {
3463   Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3464   if (object->IsFixedArray()) {
3465     return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset);
3466   } else {
3467     return object;
3468   }
3469 }
3470
3471
3472 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
3473   Heap* heap = GetHeap();
3474   ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3475   ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3476          (value->IsMap() && GetBackPointer()->IsUndefined()));
3477   Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3478   if (object->IsFixedArray()) {
3479     FixedArray::cast(object)->set(
3480         kProtoTransitionBackPointerOffset, value, mode);
3481   } else {
3482     WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3483     CONDITIONAL_WRITE_BARRIER(
3484         heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3485   }
3486 }
3487
3488
3489 FixedArray* Map::prototype_transitions() {
3490   Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3491   if (object->IsFixedArray()) {
3492     return FixedArray::cast(object);
3493   } else {
3494     return GetHeap()->empty_fixed_array();
3495   }
3496 }
3497
3498
3499 void Map::set_prototype_transitions(FixedArray* value, WriteBarrierMode mode) {
3500   Heap* heap = GetHeap();
3501   ASSERT(value != heap->empty_fixed_array());
3502   value->set(kProtoTransitionBackPointerOffset, GetBackPointer());
3503 #ifdef DEBUG
3504   if (value != prototype_transitions()) {
3505     ZapPrototypeTransitions();
3506   }
3507 #endif
3508   WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3509   CONDITIONAL_WRITE_BARRIER(
3510       heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3511 }
3512
3513
3514 void Map::init_prototype_transitions(Object* undefined) {
3515   ASSERT(undefined->IsUndefined());
3516   WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, undefined);
3517 }
3518
3519
3520 HeapObject* Map::unchecked_prototype_transitions() {
3521   Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3522   return reinterpret_cast<HeapObject*>(object);
3523 }
3524
3525
3526 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
3527 ACCESSORS(Map, constructor, Object, kConstructorOffset)
3528
3529 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3530 ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
3531 ACCESSORS(JSFunction,
3532           next_function_link,
3533           Object,
3534           kNextFunctionLinkOffset)
3535
3536 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3537 ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
3538 ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
3539
3540 ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
3541
3542 ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3543 ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3544 ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3545 ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3546 ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
3547
3548 ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3549 ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3550
3551 ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3552 ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3553 ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3554
3555 ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3556 ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3557 ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3558 ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3559 ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3560 ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3561 ACCESSORS(InterceptorInfo, is_fallback, Smi, kFallbackOffset)
3562
3563 ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3564 ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3565
3566 ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3567 ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3568
3569 ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3570 ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
3571 ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3572           kPropertyAccessorsOffset)
3573 ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3574           kPrototypeTemplateOffset)
3575 ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3576 ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3577           kNamedPropertyHandlerOffset)
3578 ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3579           kIndexedPropertyHandlerOffset)
3580 ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3581           kInstanceTemplateOffset)
3582 ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3583 ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
3584 ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3585           kInstanceCallHandlerOffset)
3586 ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3587           kAccessCheckInfoOffset)
3588 ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
3589
3590 ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
3591 ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3592           kInternalFieldCountOffset)
3593 ACCESSORS(ObjectTemplateInfo, has_external_resource, Object,
3594           kHasExternalResourceOffset)
3595
3596 ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3597 ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3598
3599 ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3600
3601 ACCESSORS(Script, source, Object, kSourceOffset)
3602 ACCESSORS(Script, name, Object, kNameOffset)
3603 ACCESSORS(Script, id, Object, kIdOffset)
3604 ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3605 ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
3606 ACCESSORS(Script, data, Object, kDataOffset)
3607 ACCESSORS(Script, context_data, Object, kContextOffset)
3608 ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
3609 ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3610 ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3611 ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
3612 ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
3613 ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
3614 ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3615                  kEvalFrominstructionsOffsetOffset)
3616
3617 #ifdef ENABLE_DEBUGGER_SUPPORT
3618 ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3619 ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3620 ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3621 ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3622
3623 ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3624 ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3625 ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
3626 ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
3627 #endif
3628
3629 ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
3630 ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3631 ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
3632 ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3633           kInstanceClassNameOffset)
3634 ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
3635 ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3636 ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
3637 ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
3638 ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3639           kThisPropertyAssignmentsOffset)
3640 SMI_ACCESSORS(SharedFunctionInfo, ic_age, kICAgeOffset)
3641
3642
3643 BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3644                kHiddenPrototypeBit)
3645 BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3646 BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3647                kNeedsAccessCheckBit)
3648 BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3649                kReadOnlyPrototypeBit)
3650 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3651                kIsExpressionBit)
3652 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3653                kIsTopLevelBit)
3654 BOOL_GETTER(SharedFunctionInfo,
3655             compiler_hints,
3656             has_only_simple_this_property_assignments,
3657             kHasOnlySimpleThisPropertyAssignments)
3658 BOOL_ACCESSORS(SharedFunctionInfo,
3659                compiler_hints,
3660                allows_lazy_compilation,
3661                kAllowLazyCompilation)
3662 BOOL_ACCESSORS(SharedFunctionInfo,
3663                compiler_hints,
3664                uses_arguments,
3665                kUsesArguments)
3666 BOOL_ACCESSORS(SharedFunctionInfo,
3667                compiler_hints,
3668                has_duplicate_parameters,
3669                kHasDuplicateParameters)
3670
3671
3672 #if V8_HOST_ARCH_32_BIT
3673 SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3674 SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
3675               kFormalParameterCountOffset)
3676 SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
3677               kExpectedNofPropertiesOffset)
3678 SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3679 SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
3680               kStartPositionAndTypeOffset)
3681 SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3682 SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
3683               kFunctionTokenPositionOffset)
3684 SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
3685               kCompilerHintsOffset)
3686 SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
3687               kThisPropertyAssignmentsCountOffset)
3688 SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
3689 SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3690 SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
3691 #else
3692
3693 #define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset)             \
3694   STATIC_ASSERT(holder::offset % kPointerSize == 0);              \
3695   int holder::name() {                                            \
3696     int value = READ_INT_FIELD(this, offset);                     \
3697     ASSERT(kHeapObjectTag == 1);                                  \
3698     ASSERT((value & kHeapObjectTag) == 0);                        \
3699     return value >> 1;                                            \
3700   }                                                               \
3701   void holder::set_##name(int value) {                            \
3702     ASSERT(kHeapObjectTag == 1);                                  \
3703     ASSERT((value & 0xC0000000) == 0xC0000000 ||                  \
3704            (value & 0xC0000000) == 0x000000000);                  \
3705     WRITE_INT_FIELD(this,                                         \
3706                     offset,                                       \
3707                     (value << 1) & ~kHeapObjectTag);              \
3708   }
3709
3710 #define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset)             \
3711   STATIC_ASSERT(holder::offset % kPointerSize == kIntSize);       \
3712   INT_ACCESSORS(holder, name, offset)
3713
3714
3715 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
3716 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3717                         formal_parameter_count,
3718                         kFormalParameterCountOffset)
3719
3720 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3721                         expected_nof_properties,
3722                         kExpectedNofPropertiesOffset)
3723 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3724
3725 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3726 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3727                         start_position_and_type,
3728                         kStartPositionAndTypeOffset)
3729
3730 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3731                         function_token_position,
3732                         kFunctionTokenPositionOffset)
3733 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3734                         compiler_hints,
3735                         kCompilerHintsOffset)
3736
3737 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3738                         this_property_assignments_count,
3739                         kThisPropertyAssignmentsCountOffset)
3740 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
3741
3742 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3743 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
3744 #endif
3745
3746
3747 int SharedFunctionInfo::construction_count() {
3748   return READ_BYTE_FIELD(this, kConstructionCountOffset);
3749 }
3750
3751
3752 void SharedFunctionInfo::set_construction_count(int value) {
3753   ASSERT(0 <= value && value < 256);
3754   WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3755 }
3756
3757
3758 BOOL_ACCESSORS(SharedFunctionInfo,
3759                compiler_hints,
3760                live_objects_may_exist,
3761                kLiveObjectsMayExist)
3762
3763
3764 bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
3765   return initial_map() != GetHeap()->undefined_value();
3766 }
3767
3768
3769 BOOL_GETTER(SharedFunctionInfo,
3770             compiler_hints,
3771             optimization_disabled,
3772             kOptimizationDisabled)
3773
3774
3775 void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3776   set_compiler_hints(BooleanBit::set(compiler_hints(),
3777                                      kOptimizationDisabled,
3778                                      disable));
3779   // If disabling optimizations we reflect that in the code object so
3780   // it will not be counted as optimizable code.
3781   if ((code()->kind() == Code::FUNCTION) && disable) {
3782     code()->set_optimizable(false);
3783   }
3784 }
3785
3786
3787 int SharedFunctionInfo::profiler_ticks() {
3788   if (code()->kind() != Code::FUNCTION) return 0;
3789   return code()->profiler_ticks();
3790 }
3791
3792
3793 LanguageMode SharedFunctionInfo::language_mode() {
3794   int hints = compiler_hints();
3795   if (BooleanBit::get(hints, kExtendedModeFunction)) {
3796     ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3797     return EXTENDED_MODE;
3798   }
3799   return BooleanBit::get(hints, kStrictModeFunction)
3800       ? STRICT_MODE : CLASSIC_MODE;
3801 }
3802
3803
3804 void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3805   // We only allow language mode transitions that go set the same language mode
3806   // again or go up in the chain:
3807   //   CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3808   ASSERT(this->language_mode() == CLASSIC_MODE ||
3809          this->language_mode() == language_mode ||
3810          language_mode == EXTENDED_MODE);
3811   int hints = compiler_hints();
3812   hints = BooleanBit::set(
3813       hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3814   hints = BooleanBit::set(
3815       hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3816   set_compiler_hints(hints);
3817 }
3818
3819
3820 bool SharedFunctionInfo::is_classic_mode() {
3821   return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3822 }
3823
3824 BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3825             kExtendedModeFunction)
3826 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, qml_mode,
3827                kQmlModeFunction)
3828 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3829 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3830                name_should_print_as_anonymous,
3831                kNameShouldPrintAsAnonymous)
3832 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3833 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
3834 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3835 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3836                kDontOptimize)
3837 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
3838
3839 ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3840 ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3841
3842 ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3843
3844 bool Script::HasValidSource() {
3845   Object* src = this->source();
3846   if (!src->IsString()) return true;
3847   String* src_str = String::cast(src);
3848   if (!StringShape(src_str).IsExternal()) return true;
3849   if (src_str->IsAsciiRepresentation()) {
3850     return ExternalAsciiString::cast(src)->resource() != NULL;
3851   } else if (src_str->IsTwoByteRepresentation()) {
3852     return ExternalTwoByteString::cast(src)->resource() != NULL;
3853   }
3854   return true;
3855 }
3856
3857
3858 void SharedFunctionInfo::DontAdaptArguments() {
3859   ASSERT(code()->kind() == Code::BUILTIN);
3860   set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3861 }
3862
3863
3864 int SharedFunctionInfo::start_position() {
3865   return start_position_and_type() >> kStartPositionShift;
3866 }
3867
3868
3869 void SharedFunctionInfo::set_start_position(int start_position) {
3870   set_start_position_and_type((start_position << kStartPositionShift)
3871     | (start_position_and_type() & ~kStartPositionMask));
3872 }
3873
3874
3875 Code* SharedFunctionInfo::code() {
3876   return Code::cast(READ_FIELD(this, kCodeOffset));
3877 }
3878
3879
3880 Code* SharedFunctionInfo::unchecked_code() {
3881   return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3882 }
3883
3884
3885 void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
3886   WRITE_FIELD(this, kCodeOffset, value);
3887   CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
3888 }
3889
3890
3891 ScopeInfo* SharedFunctionInfo::scope_info() {
3892   return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
3893 }
3894
3895
3896 void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
3897                                         WriteBarrierMode mode) {
3898   WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
3899   CONDITIONAL_WRITE_BARRIER(GetHeap(),
3900                             this,
3901                             kScopeInfoOffset,
3902                             reinterpret_cast<Object*>(value),
3903                             mode);
3904 }
3905
3906
3907 bool SharedFunctionInfo::is_compiled() {
3908   return code() !=
3909       Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
3910 }
3911
3912
3913 bool SharedFunctionInfo::IsApiFunction() {
3914   return function_data()->IsFunctionTemplateInfo();
3915 }
3916
3917
3918 FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3919   ASSERT(IsApiFunction());
3920   return FunctionTemplateInfo::cast(function_data());
3921 }
3922
3923
3924 bool SharedFunctionInfo::HasBuiltinFunctionId() {
3925   return function_data()->IsSmi();
3926 }
3927
3928
3929 BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3930   ASSERT(HasBuiltinFunctionId());
3931   return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
3932 }
3933
3934
3935 int SharedFunctionInfo::code_age() {
3936   return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3937 }
3938
3939
3940 void SharedFunctionInfo::set_code_age(int code_age) {
3941   int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3942   set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
3943 }
3944
3945
3946 bool SharedFunctionInfo::has_deoptimization_support() {
3947   Code* code = this->code();
3948   return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3949 }
3950
3951
3952 bool JSFunction::IsBuiltin() {
3953   return context()->global()->IsJSBuiltinsObject();
3954 }
3955
3956
3957 bool JSFunction::NeedsArgumentsAdaption() {
3958   return shared()->formal_parameter_count() !=
3959       SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3960 }
3961
3962
3963 bool JSFunction::IsOptimized() {
3964   return code()->kind() == Code::OPTIMIZED_FUNCTION;
3965 }
3966
3967
3968 bool JSFunction::IsOptimizable() {
3969   return code()->kind() == Code::FUNCTION && code()->optimizable();
3970 }
3971
3972
3973 bool JSFunction::IsMarkedForLazyRecompilation() {
3974   return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
3975 }
3976
3977
3978 Code* JSFunction::code() {
3979   return Code::cast(unchecked_code());
3980 }
3981
3982
3983 Code* JSFunction::unchecked_code() {
3984   return reinterpret_cast<Code*>(
3985       Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
3986 }
3987
3988
3989 void JSFunction::set_code(Code* value) {
3990   ASSERT(!HEAP->InNewSpace(value));
3991   Address entry = value->entry();
3992   WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
3993   GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3994       this,
3995       HeapObject::RawField(this, kCodeEntryOffset),
3996       value);
3997 }
3998
3999
4000 void JSFunction::ReplaceCode(Code* code) {
4001   bool was_optimized = IsOptimized();
4002   bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4003
4004   set_code(code);
4005
4006   // Add/remove the function from the list of optimized functions for this
4007   // context based on the state change.
4008   if (!was_optimized && is_optimized) {
4009     context()->global_context()->AddOptimizedFunction(this);
4010   }
4011   if (was_optimized && !is_optimized) {
4012     context()->global_context()->RemoveOptimizedFunction(this);
4013   }
4014 }
4015
4016
4017 Context* JSFunction::context() {
4018   return Context::cast(READ_FIELD(this, kContextOffset));
4019 }
4020
4021
4022 Object* JSFunction::unchecked_context() {
4023   return READ_FIELD(this, kContextOffset);
4024 }
4025
4026
4027 SharedFunctionInfo* JSFunction::unchecked_shared() {
4028   return reinterpret_cast<SharedFunctionInfo*>(
4029       READ_FIELD(this, kSharedFunctionInfoOffset));
4030 }
4031
4032
4033 void JSFunction::set_context(Object* value) {
4034   ASSERT(value->IsUndefined() || value->IsContext());
4035   WRITE_FIELD(this, kContextOffset, value);
4036   WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
4037 }
4038
4039 ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4040           kPrototypeOrInitialMapOffset)
4041
4042
4043 Map* JSFunction::initial_map() {
4044   return Map::cast(prototype_or_initial_map());
4045 }
4046
4047
4048 void JSFunction::set_initial_map(Map* value) {
4049   set_prototype_or_initial_map(value);
4050 }
4051
4052
4053 MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4054     Map* initial_map) {
4055   Context* global_context = context()->global_context();
4056   Object* array_function =
4057       global_context->get(Context::ARRAY_FUNCTION_INDEX);
4058   if (array_function->IsJSFunction() &&
4059       this == JSFunction::cast(array_function)) {
4060     ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
4061
4062     MaybeObject* maybe_map = initial_map->CopyDropTransitions();
4063     Map* new_double_map = NULL;
4064     if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
4065     new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
4066     maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS,
4067                                                    new_double_map);
4068     if (maybe_map->IsFailure()) return maybe_map;
4069
4070     maybe_map = new_double_map->CopyDropTransitions();
4071     Map* new_object_map = NULL;
4072     if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
4073     new_object_map->set_elements_kind(FAST_ELEMENTS);
4074     maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS,
4075                                                       new_object_map);
4076     if (maybe_map->IsFailure()) return maybe_map;
4077
4078     global_context->set_smi_js_array_map(initial_map);
4079     global_context->set_double_js_array_map(new_double_map);
4080     global_context->set_object_js_array_map(new_object_map);
4081   }
4082   set_initial_map(initial_map);
4083   return this;
4084 }
4085
4086
4087 bool JSFunction::has_initial_map() {
4088   return prototype_or_initial_map()->IsMap();
4089 }
4090
4091
4092 bool JSFunction::has_instance_prototype() {
4093   return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4094 }
4095
4096
4097 bool JSFunction::has_prototype() {
4098   return map()->has_non_instance_prototype() || has_instance_prototype();
4099 }
4100
4101
4102 Object* JSFunction::instance_prototype() {
4103   ASSERT(has_instance_prototype());
4104   if (has_initial_map()) return initial_map()->prototype();
4105   // When there is no initial map and the prototype is a JSObject, the
4106   // initial map field is used for the prototype field.
4107   return prototype_or_initial_map();
4108 }
4109
4110
4111 Object* JSFunction::prototype() {
4112   ASSERT(has_prototype());
4113   // If the function's prototype property has been set to a non-JSObject
4114   // value, that value is stored in the constructor field of the map.
4115   if (map()->has_non_instance_prototype()) return map()->constructor();
4116   return instance_prototype();
4117 }
4118
4119 bool JSFunction::should_have_prototype() {
4120   return map()->function_with_prototype();
4121 }
4122
4123
4124 bool JSFunction::is_compiled() {
4125   return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
4126 }
4127
4128
4129 FixedArray* JSFunction::literals() {
4130   ASSERT(!shared()->bound());
4131   return literals_or_bindings();
4132 }
4133
4134
4135 void JSFunction::set_literals(FixedArray* literals) {
4136   ASSERT(!shared()->bound());
4137   set_literals_or_bindings(literals);
4138 }
4139
4140
4141 FixedArray* JSFunction::function_bindings() {
4142   ASSERT(shared()->bound());
4143   return literals_or_bindings();
4144 }
4145
4146
4147 void JSFunction::set_function_bindings(FixedArray* bindings) {
4148   ASSERT(shared()->bound());
4149   // Bound function literal may be initialized to the empty fixed array
4150   // before the bindings are set.
4151   ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4152          bindings->map() == GetHeap()->fixed_cow_array_map());
4153   set_literals_or_bindings(bindings);
4154 }
4155
4156
4157 int JSFunction::NumberOfLiterals() {
4158   ASSERT(!shared()->bound());
4159   return literals()->length();
4160 }
4161
4162
4163 Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
4164   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
4165   return READ_FIELD(this, OffsetOfFunctionWithId(id));
4166 }
4167
4168
4169 void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4170                                               Object* value) {
4171   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
4172   WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
4173   WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
4174 }
4175
4176
4177 Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
4178   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
4179   return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4180 }
4181
4182
4183 void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4184                                                    Code* value) {
4185   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
4186   WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
4187   ASSERT(!HEAP->InNewSpace(value));
4188 }
4189
4190
4191 ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
4192 ACCESSORS(JSProxy, hash, Object, kHashOffset)
4193 ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4194 ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4195
4196
4197 void JSProxy::InitializeBody(int object_size, Object* value) {
4198   ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4199   for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4200     WRITE_FIELD(this, offset, value);
4201   }
4202 }
4203
4204
4205 ACCESSORS(JSSet, table, Object, kTableOffset)
4206 ACCESSORS(JSMap, table, Object, kTableOffset)
4207 ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4208 ACCESSORS(JSWeakMap, next, Object, kNextOffset)
4209
4210
4211 Address Foreign::foreign_address() {
4212   return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
4213 }
4214
4215
4216 void Foreign::set_foreign_address(Address value) {
4217   WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
4218 }
4219
4220
4221 ACCESSORS(JSModule, context, Object, kContextOffset)
4222
4223
4224 JSModule* JSModule::cast(Object* obj) {
4225   ASSERT(obj->IsJSModule());
4226   ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4227   return reinterpret_cast<JSModule*>(obj);
4228 }
4229
4230
4231 ACCESSORS(JSValue, value, Object, kValueOffset)
4232
4233
4234 JSValue* JSValue::cast(Object* obj) {
4235   ASSERT(obj->IsJSValue());
4236   ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4237   return reinterpret_cast<JSValue*>(obj);
4238 }
4239
4240
4241 ACCESSORS(JSDate, value, Object, kValueOffset)
4242 ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4243 ACCESSORS(JSDate, year, Object, kYearOffset)
4244 ACCESSORS(JSDate, month, Object, kMonthOffset)
4245 ACCESSORS(JSDate, day, Object, kDayOffset)
4246 ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4247 ACCESSORS(JSDate, hour, Object, kHourOffset)
4248 ACCESSORS(JSDate, min, Object, kMinOffset)
4249 ACCESSORS(JSDate, sec, Object, kSecOffset)
4250
4251
4252 JSDate* JSDate::cast(Object* obj) {
4253   ASSERT(obj->IsJSDate());
4254   ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4255   return reinterpret_cast<JSDate*>(obj);
4256 }
4257
4258
4259 ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4260 ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4261 ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4262 ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4263 ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4264 SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4265 SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4266
4267
4268 JSMessageObject* JSMessageObject::cast(Object* obj) {
4269   ASSERT(obj->IsJSMessageObject());
4270   ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4271   return reinterpret_cast<JSMessageObject*>(obj);
4272 }
4273
4274
4275 INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
4276 ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
4277 ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
4278 ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
4279 ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
4280 ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
4281 INT_ACCESSORS(Code, ic_age, kICAgeOffset)
4282
4283 byte* Code::instruction_start()  {
4284   return FIELD_ADDR(this, kHeaderSize);
4285 }
4286
4287
4288 byte* Code::instruction_end()  {
4289   return instruction_start() + instruction_size();
4290 }
4291
4292
4293 int Code::body_size() {
4294   return RoundUp(instruction_size(), kObjectAlignment);
4295 }
4296
4297
4298 FixedArray* Code::unchecked_deoptimization_data() {
4299   return reinterpret_cast<FixedArray*>(
4300       READ_FIELD(this, kDeoptimizationDataOffset));
4301 }
4302
4303
4304 ByteArray* Code::unchecked_relocation_info() {
4305   return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
4306 }
4307
4308
4309 byte* Code::relocation_start() {
4310   return unchecked_relocation_info()->GetDataStartAddress();
4311 }
4312
4313
4314 int Code::relocation_size() {
4315   return unchecked_relocation_info()->length();
4316 }
4317
4318
4319 byte* Code::entry() {
4320   return instruction_start();
4321 }
4322
4323
4324 bool Code::contains(byte* inner_pointer) {
4325   return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
4326 }
4327
4328
4329 ACCESSORS(JSArray, length, Object, kLengthOffset)
4330
4331
4332 ACCESSORS(JSRegExp, data, Object, kDataOffset)
4333
4334
4335 JSRegExp::Type JSRegExp::TypeTag() {
4336   Object* data = this->data();
4337   if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4338   Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4339   return static_cast<JSRegExp::Type>(smi->value());
4340 }
4341
4342
4343 JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4344   Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4345   return static_cast<JSRegExp::Type>(smi->value());
4346 }
4347
4348
4349 int JSRegExp::CaptureCount() {
4350   switch (TypeTag()) {
4351     case ATOM:
4352       return 0;
4353     case IRREGEXP:
4354       return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4355     default:
4356       UNREACHABLE();
4357       return -1;
4358   }
4359 }
4360
4361
4362 JSRegExp::Flags JSRegExp::GetFlags() {
4363   ASSERT(this->data()->IsFixedArray());
4364   Object* data = this->data();
4365   Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4366   return Flags(smi->value());
4367 }
4368
4369
4370 String* JSRegExp::Pattern() {
4371   ASSERT(this->data()->IsFixedArray());
4372   Object* data = this->data();
4373   String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4374   return pattern;
4375 }
4376
4377
4378 Object* JSRegExp::DataAt(int index) {
4379   ASSERT(TypeTag() != NOT_COMPILED);
4380   return FixedArray::cast(data())->get(index);
4381 }
4382
4383
4384 Object* JSRegExp::DataAtUnchecked(int index) {
4385   FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4386   int offset = FixedArray::kHeaderSize + index * kPointerSize;
4387   return READ_FIELD(fa, offset);
4388 }
4389
4390
4391 void JSRegExp::SetDataAt(int index, Object* value) {
4392   ASSERT(TypeTag() != NOT_COMPILED);
4393   ASSERT(index >= kDataIndex);  // Only implementation data can be set this way.
4394   FixedArray::cast(data())->set(index, value);
4395 }
4396
4397
4398 void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4399   ASSERT(index >= kDataIndex);  // Only implementation data can be set this way.
4400   FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4401   if (value->IsSmi()) {
4402     fa->set_unchecked(index, Smi::cast(value));
4403   } else {
4404     // We only do this during GC, so we don't need to notify the write barrier.
4405     fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4406   }
4407 }
4408
4409
4410 ElementsKind JSObject::GetElementsKind() {
4411   ElementsKind kind = map()->elements_kind();
4412 #if DEBUG
4413   FixedArrayBase* fixed_array =
4414       reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4415   Map* map = fixed_array->map();
4416     ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
4417             (map == GetHeap()->fixed_array_map() ||
4418              map == GetHeap()->fixed_cow_array_map())) ||
4419            (kind == FAST_DOUBLE_ELEMENTS &&
4420             (fixed_array->IsFixedDoubleArray() ||
4421             fixed_array == GetHeap()->empty_fixed_array())) ||
4422            (kind == DICTIONARY_ELEMENTS &&
4423             fixed_array->IsFixedArray() &&
4424             fixed_array->IsDictionary()) ||
4425            (kind > DICTIONARY_ELEMENTS));
4426     ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4427            (elements()->IsFixedArray() && elements()->length() >= 2));
4428 #endif
4429   return kind;
4430 }
4431
4432
4433 ElementsAccessor* JSObject::GetElementsAccessor() {
4434   return ElementsAccessor::ForKind(GetElementsKind());
4435 }
4436
4437
4438 bool JSObject::HasFastElements() {
4439   return GetElementsKind() == FAST_ELEMENTS;
4440 }
4441
4442
4443 bool JSObject::HasFastSmiOnlyElements() {
4444   return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4445 }
4446
4447
4448 bool JSObject::HasFastTypeElements() {
4449   ElementsKind elements_kind = GetElementsKind();
4450   return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4451       elements_kind == FAST_ELEMENTS;
4452 }
4453
4454
4455 bool JSObject::HasFastDoubleElements() {
4456   return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4457 }
4458
4459
4460 bool JSObject::HasDictionaryElements() {
4461   return GetElementsKind() == DICTIONARY_ELEMENTS;
4462 }
4463
4464
4465 bool JSObject::HasNonStrictArgumentsElements() {
4466   return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4467 }
4468
4469
4470 bool JSObject::HasExternalArrayElements() {
4471   HeapObject* array = elements();
4472   ASSERT(array != NULL);
4473   return array->IsExternalArray();
4474 }
4475
4476
4477 #define EXTERNAL_ELEMENTS_CHECK(name, type)          \
4478 bool JSObject::HasExternal##name##Elements() {       \
4479   HeapObject* array = elements();                    \
4480   ASSERT(array != NULL);                             \
4481   if (!array->IsHeapObject())                        \
4482     return false;                                    \
4483   return array->map()->instance_type() == type;      \
4484 }
4485
4486
4487 EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4488 EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4489 EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4490 EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4491                         EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4492 EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4493 EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4494                         EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4495 EXTERNAL_ELEMENTS_CHECK(Float,
4496                         EXTERNAL_FLOAT_ARRAY_TYPE)
4497 EXTERNAL_ELEMENTS_CHECK(Double,
4498                         EXTERNAL_DOUBLE_ARRAY_TYPE)
4499 EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
4500
4501
4502 bool JSObject::HasNamedInterceptor() {
4503   return map()->has_named_interceptor();
4504 }
4505
4506
4507 bool JSObject::HasIndexedInterceptor() {
4508   return map()->has_indexed_interceptor();
4509 }
4510
4511
4512 MaybeObject* JSObject::EnsureWritableFastElements() {
4513   ASSERT(HasFastTypeElements());
4514   FixedArray* elems = FixedArray::cast(elements());
4515   Isolate* isolate = GetIsolate();
4516   if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
4517   Object* writable_elems;
4518   { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4519       elems, isolate->heap()->fixed_array_map());
4520     if (!maybe_writable_elems->ToObject(&writable_elems)) {
4521       return maybe_writable_elems;
4522     }
4523   }
4524   set_elements(FixedArray::cast(writable_elems));
4525   isolate->counters()->cow_arrays_converted()->Increment();
4526   return writable_elems;
4527 }
4528
4529
4530 StringDictionary* JSObject::property_dictionary() {
4531   ASSERT(!HasFastProperties());
4532   return StringDictionary::cast(properties());
4533 }
4534
4535
4536 SeededNumberDictionary* JSObject::element_dictionary() {
4537   ASSERT(HasDictionaryElements());
4538   return SeededNumberDictionary::cast(elements());
4539 }
4540
4541
4542 bool String::IsHashFieldComputed(uint32_t field) {
4543   return (field & kHashNotComputedMask) == 0;
4544 }
4545
4546
4547 bool String::HasHashCode() {
4548   return IsHashFieldComputed(hash_field());
4549 }
4550
4551
4552 uint32_t String::Hash() {
4553   // Fast case: has hash code already been computed?
4554   uint32_t field = hash_field();
4555   if (IsHashFieldComputed(field)) return field >> kHashShift;
4556   // Slow case: compute hash code and set it.
4557   return ComputeAndSetHash();
4558 }
4559
4560
4561 StringHasher::StringHasher(int length, uint32_t seed)
4562   : length_(length),
4563     raw_running_hash_(seed),
4564     array_index_(0),
4565     is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4566     is_first_char_(true),
4567     is_valid_(true) {
4568   ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
4569 }
4570
4571
4572 bool StringHasher::has_trivial_hash() {
4573   return length_ > String::kMaxHashCalcLength;
4574 }
4575
4576
4577 void StringHasher::AddCharacter(uint32_t c) {
4578   if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4579     AddSurrogatePair(c);  // Not inlined.
4580     return;
4581   }
4582   // Use the Jenkins one-at-a-time hash function to update the hash
4583   // for the given character.
4584   raw_running_hash_ += c;
4585   raw_running_hash_ += (raw_running_hash_ << 10);
4586   raw_running_hash_ ^= (raw_running_hash_ >> 6);
4587   // Incremental array index computation.
4588   if (is_array_index_) {
4589     if (c < '0' || c > '9') {
4590       is_array_index_ = false;
4591     } else {
4592       int d = c - '0';
4593       if (is_first_char_) {
4594         is_first_char_ = false;
4595         if (c == '0' && length_ > 1) {
4596           is_array_index_ = false;
4597           return;
4598         }
4599       }
4600       if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4601         is_array_index_ = false;
4602       } else {
4603         array_index_ = array_index_ * 10 + d;
4604       }
4605     }
4606   }
4607 }
4608
4609
4610 void StringHasher::AddCharacterNoIndex(uint32_t c) {
4611   ASSERT(!is_array_index());
4612   if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4613     AddSurrogatePairNoIndex(c);  // Not inlined.
4614     return;
4615   }
4616   raw_running_hash_ += c;
4617   raw_running_hash_ += (raw_running_hash_ << 10);
4618   raw_running_hash_ ^= (raw_running_hash_ >> 6);
4619 }
4620
4621
4622 uint32_t StringHasher::GetHash() {
4623   // Get the calculated raw hash value and do some more bit ops to distribute
4624   // the hash further. Ensure that we never return zero as the hash value.
4625   uint32_t result = raw_running_hash_;
4626   result += (result << 3);
4627   result ^= (result >> 11);
4628   result += (result << 15);
4629   if ((result & String::kHashBitMask) == 0) {
4630     result = 27;
4631   }
4632   return result;
4633 }
4634
4635
4636 template <typename schar>
4637 uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4638   StringHasher hasher(length, seed);
4639   if (!hasher.has_trivial_hash()) {
4640     int i;
4641     for (i = 0; hasher.is_array_index() && (i < length); i++) {
4642       hasher.AddCharacter(chars[i]);
4643     }
4644     for (; i < length; i++) {
4645       hasher.AddCharacterNoIndex(chars[i]);
4646     }
4647   }
4648   return hasher.GetHashField();
4649 }
4650
4651
4652 bool String::AsArrayIndex(uint32_t* index) {
4653   uint32_t field = hash_field();
4654   if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4655     return false;
4656   }
4657   return SlowAsArrayIndex(index);
4658 }
4659
4660
4661 Object* JSReceiver::GetPrototype() {
4662   return HeapObject::cast(this)->map()->prototype();
4663 }
4664
4665
4666 bool JSReceiver::HasProperty(String* name) {
4667   if (IsJSProxy()) {
4668     return JSProxy::cast(this)->HasPropertyWithHandler(name);
4669   }
4670   return GetPropertyAttribute(name) != ABSENT;
4671 }
4672
4673
4674 bool JSReceiver::HasLocalProperty(String* name) {
4675   if (IsJSProxy()) {
4676     return JSProxy::cast(this)->HasPropertyWithHandler(name);
4677   }
4678   return GetLocalPropertyAttribute(name) != ABSENT;
4679 }
4680
4681
4682 PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
4683   return GetPropertyAttributeWithReceiver(this, key);
4684 }
4685
4686 // TODO(504): this may be useful in other places too where JSGlobalProxy
4687 // is used.
4688 Object* JSObject::BypassGlobalProxy() {
4689   if (IsJSGlobalProxy()) {
4690     Object* proto = GetPrototype();
4691     if (proto->IsNull()) return GetHeap()->undefined_value();
4692     ASSERT(proto->IsJSGlobalObject());
4693     return proto;
4694   }
4695   return this;
4696 }
4697
4698
4699 MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4700   return IsJSProxy()
4701       ? JSProxy::cast(this)->GetIdentityHash(flag)
4702       : JSObject::cast(this)->GetIdentityHash(flag);
4703 }
4704
4705
4706 bool JSReceiver::HasElement(uint32_t index) {
4707   if (IsJSProxy()) {
4708     return JSProxy::cast(this)->HasElementWithHandler(index);
4709   }
4710   return JSObject::cast(this)->HasElementWithReceiver(this, index);
4711 }
4712
4713
4714 bool AccessorInfo::all_can_read() {
4715   return BooleanBit::get(flag(), kAllCanReadBit);
4716 }
4717
4718
4719 void AccessorInfo::set_all_can_read(bool value) {
4720   set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4721 }
4722
4723
4724 bool AccessorInfo::all_can_write() {
4725   return BooleanBit::get(flag(), kAllCanWriteBit);
4726 }
4727
4728
4729 void AccessorInfo::set_all_can_write(bool value) {
4730   set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4731 }
4732
4733
4734 bool AccessorInfo::prohibits_overwriting() {
4735   return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4736 }
4737
4738
4739 void AccessorInfo::set_prohibits_overwriting(bool value) {
4740   set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4741 }
4742
4743
4744 PropertyAttributes AccessorInfo::property_attributes() {
4745   return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4746 }
4747
4748
4749 void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4750   set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
4751 }
4752
4753
4754 template<typename Shape, typename Key>
4755 void Dictionary<Shape, Key>::SetEntry(int entry,
4756                                       Object* key,
4757                                       Object* value) {
4758   SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4759 }
4760
4761
4762 template<typename Shape, typename Key>
4763 void Dictionary<Shape, Key>::SetEntry(int entry,
4764                                       Object* key,
4765                                       Object* value,
4766                                       PropertyDetails details) {
4767   ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
4768   int index = HashTable<Shape, Key>::EntryToIndex(entry);
4769   AssertNoAllocation no_gc;
4770   WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
4771   FixedArray::set(index, key, mode);
4772   FixedArray::set(index+1, value, mode);
4773   FixedArray::set(index+2, details.AsSmi());
4774 }
4775
4776
4777 bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4778   ASSERT(other->IsNumber());
4779   return key == static_cast<uint32_t>(other->Number());
4780 }
4781
4782
4783 uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4784   return ComputeIntegerHash(key, 0);
4785 }
4786
4787
4788 uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4789                                                       Object* other) {
4790   ASSERT(other->IsNumber());
4791   return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
4792 }
4793
4794 uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4795   return ComputeIntegerHash(key, seed);
4796 }
4797
4798 uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4799                                                           uint32_t seed,
4800                                                           Object* other) {
4801   ASSERT(other->IsNumber());
4802   return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4803 }
4804
4805 MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4806   return Isolate::Current()->heap()->NumberFromUint32(key);
4807 }
4808
4809
4810 bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4811   // We know that all entries in a hash table had their hash keys created.
4812   // Use that knowledge to have fast failure.
4813   if (key->Hash() != String::cast(other)->Hash()) return false;
4814   return key->Equals(String::cast(other));
4815 }
4816
4817
4818 uint32_t StringDictionaryShape::Hash(String* key) {
4819   return key->Hash();
4820 }
4821
4822
4823 uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4824   return String::cast(other)->Hash();
4825 }
4826
4827
4828 MaybeObject* StringDictionaryShape::AsObject(String* key) {
4829   return key;
4830 }
4831
4832
4833 template <int entrysize>
4834 bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4835   return key->SameValue(other);
4836 }
4837
4838
4839 template <int entrysize>
4840 uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
4841   MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4842   return Smi::cast(maybe_hash->ToObjectChecked())->value();
4843 }
4844
4845
4846 template <int entrysize>
4847 uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4848                                                         Object* other) {
4849   MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4850   return Smi::cast(maybe_hash->ToObjectChecked())->value();
4851 }
4852
4853
4854 template <int entrysize>
4855 MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
4856   return key;
4857 }
4858
4859
4860 void Map::ClearCodeCache(Heap* heap) {
4861   // No write barrier is needed since empty_fixed_array is not in new space.
4862   // Please note this function is used during marking:
4863   //  - MarkCompactCollector::MarkUnmarkedObject
4864   //  - IncrementalMarking::Step
4865   ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4866   WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
4867 }
4868
4869
4870 void JSArray::EnsureSize(int required_size) {
4871   ASSERT(HasFastTypeElements());
4872   FixedArray* elts = FixedArray::cast(elements());
4873   const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4874   if (elts->length() < required_size) {
4875     // Doubling in size would be overkill, but leave some slack to avoid
4876     // constantly growing.
4877     Expand(required_size + (required_size >> 3));
4878     // It's a performance benefit to keep a frequently used array in new-space.
4879   } else if (!GetHeap()->new_space()->Contains(elts) &&
4880              required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4881     // Expand will allocate a new backing store in new space even if the size
4882     // we asked for isn't larger than what we had before.
4883     Expand(required_size);
4884   }
4885 }
4886
4887
4888 void JSArray::set_length(Smi* length) {
4889   // Don't need a write barrier for a Smi.
4890   set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4891 }
4892
4893
4894 bool JSArray::AllowsSetElementsLength() {
4895   bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4896   ASSERT(result == !HasExternalArrayElements());
4897   return result;
4898 }
4899
4900
4901 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4902   MaybeObject* maybe_result = EnsureCanContainElements(
4903       storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4904   if (maybe_result->IsFailure()) return maybe_result;
4905   ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4906           GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4907          ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4908           ((GetElementsKind() == FAST_ELEMENTS) ||
4909            (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4910             FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
4911   set_elements(storage);
4912   set_length(Smi::FromInt(storage->length()));
4913   return this;
4914 }
4915
4916
4917 MaybeObject* FixedArray::Copy() {
4918   if (length() == 0) return this;
4919   return GetHeap()->CopyFixedArray(this);
4920 }
4921
4922
4923 MaybeObject* FixedDoubleArray::Copy() {
4924   if (length() == 0) return this;
4925   return GetHeap()->CopyFixedDoubleArray(this);
4926 }
4927
4928
4929 void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4930   set(1 + index * 2, id);
4931 }
4932
4933
4934 Smi* TypeFeedbackCells::AstId(int index) {
4935   return Smi::cast(get(1 + index * 2));
4936 }
4937
4938
4939 void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4940   set(index * 2, cell);
4941 }
4942
4943
4944 JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4945   return JSGlobalPropertyCell::cast(get(index * 2));
4946 }
4947
4948
4949 Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4950   return isolate->factory()->the_hole_value();
4951 }
4952
4953
4954 Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4955   return isolate->factory()->undefined_value();
4956 }
4957
4958
4959 Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4960   return heap->raw_unchecked_the_hole_value();
4961 }
4962
4963
4964 SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
4965 SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
4966               kIcWithTypeinfoCountOffset)
4967 ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
4968           kTypeFeedbackCellsOffset)
4969
4970
4971 SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
4972
4973
4974 Relocatable::Relocatable(Isolate* isolate) {
4975   ASSERT(isolate == Isolate::Current());
4976   isolate_ = isolate;
4977   prev_ = isolate->relocatable_top();
4978   isolate->set_relocatable_top(this);
4979 }
4980
4981
4982 Relocatable::~Relocatable() {
4983   ASSERT(isolate_ == Isolate::Current());
4984   ASSERT_EQ(isolate_->relocatable_top(), this);
4985   isolate_->set_relocatable_top(prev_);
4986 }
4987
4988
4989 int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4990   return map->instance_size();
4991 }
4992
4993
4994 void Foreign::ForeignIterateBody(ObjectVisitor* v) {
4995   v->VisitExternalReference(
4996       reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
4997 }
4998
4999
5000 template<typename StaticVisitor>
5001 void Foreign::ForeignIterateBody() {
5002   StaticVisitor::VisitExternalReference(
5003       reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
5004 }
5005
5006
5007 void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5008   typedef v8::String::ExternalAsciiStringResource Resource;
5009   v->VisitExternalAsciiString(
5010       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5011 }
5012
5013
5014 template<typename StaticVisitor>
5015 void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5016   typedef v8::String::ExternalAsciiStringResource Resource;
5017   StaticVisitor::VisitExternalAsciiString(
5018       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5019 }
5020
5021
5022 void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5023   typedef v8::String::ExternalStringResource Resource;
5024   v->VisitExternalTwoByteString(
5025       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5026 }
5027
5028
5029 template<typename StaticVisitor>
5030 void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5031   typedef v8::String::ExternalStringResource Resource;
5032   StaticVisitor::VisitExternalTwoByteString(
5033       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5034 }
5035
5036 #define SLOT_ADDR(obj, offset) \
5037   reinterpret_cast<Object**>((obj)->address() + offset)
5038
5039 template<int start_offset, int end_offset, int size>
5040 void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5041     HeapObject* obj,
5042     ObjectVisitor* v) {
5043     v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5044 }
5045
5046
5047 template<int start_offset>
5048 void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5049                                                        int object_size,
5050                                                        ObjectVisitor* v) {
5051   v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5052 }
5053
5054 #undef SLOT_ADDR
5055
5056 #undef TYPE_CHECKER
5057 #undef CAST_ACCESSOR
5058 #undef INT_ACCESSORS
5059 #undef ACCESSORS
5060 #undef ACCESSORS_TO_SMI
5061 #undef SMI_ACCESSORS
5062 #undef BOOL_GETTER
5063 #undef BOOL_ACCESSORS
5064 #undef FIELD_ADDR
5065 #undef READ_FIELD
5066 #undef WRITE_FIELD
5067 #undef WRITE_BARRIER
5068 #undef CONDITIONAL_WRITE_BARRIER
5069 #undef READ_DOUBLE_FIELD
5070 #undef WRITE_DOUBLE_FIELD
5071 #undef READ_INT_FIELD
5072 #undef WRITE_INT_FIELD
5073 #undef READ_INTPTR_FIELD
5074 #undef WRITE_INTPTR_FIELD
5075 #undef READ_UINT32_FIELD
5076 #undef WRITE_UINT32_FIELD
5077 #undef READ_SHORT_FIELD
5078 #undef WRITE_SHORT_FIELD
5079 #undef READ_BYTE_FIELD
5080 #undef WRITE_BYTE_FIELD
5081
5082
5083 } }  // namespace v8::internal
5084
5085 #endif  // V8_OBJECTS_INL_H_