3c54afc6b3a8c0e903a3c3fc8e46cb759eea1aae
[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, native, kNative)
3827 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3828                name_should_print_as_anonymous,
3829                kNameShouldPrintAsAnonymous)
3830 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3831 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
3832 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3833 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3834                kDontOptimize)
3835 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
3836
3837 ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3838 ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3839
3840 ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3841
3842 bool Script::HasValidSource() {
3843   Object* src = this->source();
3844   if (!src->IsString()) return true;
3845   String* src_str = String::cast(src);
3846   if (!StringShape(src_str).IsExternal()) return true;
3847   if (src_str->IsAsciiRepresentation()) {
3848     return ExternalAsciiString::cast(src)->resource() != NULL;
3849   } else if (src_str->IsTwoByteRepresentation()) {
3850     return ExternalTwoByteString::cast(src)->resource() != NULL;
3851   }
3852   return true;
3853 }
3854
3855
3856 void SharedFunctionInfo::DontAdaptArguments() {
3857   ASSERT(code()->kind() == Code::BUILTIN);
3858   set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3859 }
3860
3861
3862 int SharedFunctionInfo::start_position() {
3863   return start_position_and_type() >> kStartPositionShift;
3864 }
3865
3866
3867 void SharedFunctionInfo::set_start_position(int start_position) {
3868   set_start_position_and_type((start_position << kStartPositionShift)
3869     | (start_position_and_type() & ~kStartPositionMask));
3870 }
3871
3872
3873 Code* SharedFunctionInfo::code() {
3874   return Code::cast(READ_FIELD(this, kCodeOffset));
3875 }
3876
3877
3878 Code* SharedFunctionInfo::unchecked_code() {
3879   return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3880 }
3881
3882
3883 void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
3884   WRITE_FIELD(this, kCodeOffset, value);
3885   CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
3886 }
3887
3888
3889 ScopeInfo* SharedFunctionInfo::scope_info() {
3890   return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
3891 }
3892
3893
3894 void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
3895                                         WriteBarrierMode mode) {
3896   WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
3897   CONDITIONAL_WRITE_BARRIER(GetHeap(),
3898                             this,
3899                             kScopeInfoOffset,
3900                             reinterpret_cast<Object*>(value),
3901                             mode);
3902 }
3903
3904
3905 bool SharedFunctionInfo::is_compiled() {
3906   return code() !=
3907       Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
3908 }
3909
3910
3911 bool SharedFunctionInfo::IsApiFunction() {
3912   return function_data()->IsFunctionTemplateInfo();
3913 }
3914
3915
3916 FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3917   ASSERT(IsApiFunction());
3918   return FunctionTemplateInfo::cast(function_data());
3919 }
3920
3921
3922 bool SharedFunctionInfo::HasBuiltinFunctionId() {
3923   return function_data()->IsSmi();
3924 }
3925
3926
3927 BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3928   ASSERT(HasBuiltinFunctionId());
3929   return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
3930 }
3931
3932
3933 int SharedFunctionInfo::code_age() {
3934   return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3935 }
3936
3937
3938 void SharedFunctionInfo::set_code_age(int code_age) {
3939   int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3940   set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
3941 }
3942
3943
3944 bool SharedFunctionInfo::has_deoptimization_support() {
3945   Code* code = this->code();
3946   return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3947 }
3948
3949
3950 bool JSFunction::IsBuiltin() {
3951   return context()->global()->IsJSBuiltinsObject();
3952 }
3953
3954
3955 bool JSFunction::NeedsArgumentsAdaption() {
3956   return shared()->formal_parameter_count() !=
3957       SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3958 }
3959
3960
3961 bool JSFunction::IsOptimized() {
3962   return code()->kind() == Code::OPTIMIZED_FUNCTION;
3963 }
3964
3965
3966 bool JSFunction::IsOptimizable() {
3967   return code()->kind() == Code::FUNCTION && code()->optimizable();
3968 }
3969
3970
3971 bool JSFunction::IsMarkedForLazyRecompilation() {
3972   return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
3973 }
3974
3975
3976 Code* JSFunction::code() {
3977   return Code::cast(unchecked_code());
3978 }
3979
3980
3981 Code* JSFunction::unchecked_code() {
3982   return reinterpret_cast<Code*>(
3983       Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
3984 }
3985
3986
3987 void JSFunction::set_code(Code* value) {
3988   ASSERT(!HEAP->InNewSpace(value));
3989   Address entry = value->entry();
3990   WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
3991   GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3992       this,
3993       HeapObject::RawField(this, kCodeEntryOffset),
3994       value);
3995 }
3996
3997
3998 void JSFunction::ReplaceCode(Code* code) {
3999   bool was_optimized = IsOptimized();
4000   bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4001
4002   set_code(code);
4003
4004   // Add/remove the function from the list of optimized functions for this
4005   // context based on the state change.
4006   if (!was_optimized && is_optimized) {
4007     context()->global_context()->AddOptimizedFunction(this);
4008   }
4009   if (was_optimized && !is_optimized) {
4010     context()->global_context()->RemoveOptimizedFunction(this);
4011   }
4012 }
4013
4014
4015 Context* JSFunction::context() {
4016   return Context::cast(READ_FIELD(this, kContextOffset));
4017 }
4018
4019
4020 Object* JSFunction::unchecked_context() {
4021   return READ_FIELD(this, kContextOffset);
4022 }
4023
4024
4025 SharedFunctionInfo* JSFunction::unchecked_shared() {
4026   return reinterpret_cast<SharedFunctionInfo*>(
4027       READ_FIELD(this, kSharedFunctionInfoOffset));
4028 }
4029
4030
4031 void JSFunction::set_context(Object* value) {
4032   ASSERT(value->IsUndefined() || value->IsContext());
4033   WRITE_FIELD(this, kContextOffset, value);
4034   WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
4035 }
4036
4037 ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4038           kPrototypeOrInitialMapOffset)
4039
4040
4041 Map* JSFunction::initial_map() {
4042   return Map::cast(prototype_or_initial_map());
4043 }
4044
4045
4046 void JSFunction::set_initial_map(Map* value) {
4047   set_prototype_or_initial_map(value);
4048 }
4049
4050
4051 MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4052     Map* initial_map) {
4053   Context* global_context = context()->global_context();
4054   Object* array_function =
4055       global_context->get(Context::ARRAY_FUNCTION_INDEX);
4056   if (array_function->IsJSFunction() &&
4057       this == JSFunction::cast(array_function)) {
4058     ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
4059
4060     MaybeObject* maybe_map = initial_map->CopyDropTransitions();
4061     Map* new_double_map = NULL;
4062     if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
4063     new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
4064     maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS,
4065                                                    new_double_map);
4066     if (maybe_map->IsFailure()) return maybe_map;
4067
4068     maybe_map = new_double_map->CopyDropTransitions();
4069     Map* new_object_map = NULL;
4070     if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
4071     new_object_map->set_elements_kind(FAST_ELEMENTS);
4072     maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS,
4073                                                       new_object_map);
4074     if (maybe_map->IsFailure()) return maybe_map;
4075
4076     global_context->set_smi_js_array_map(initial_map);
4077     global_context->set_double_js_array_map(new_double_map);
4078     global_context->set_object_js_array_map(new_object_map);
4079   }
4080   set_initial_map(initial_map);
4081   return this;
4082 }
4083
4084
4085 bool JSFunction::has_initial_map() {
4086   return prototype_or_initial_map()->IsMap();
4087 }
4088
4089
4090 bool JSFunction::has_instance_prototype() {
4091   return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4092 }
4093
4094
4095 bool JSFunction::has_prototype() {
4096   return map()->has_non_instance_prototype() || has_instance_prototype();
4097 }
4098
4099
4100 Object* JSFunction::instance_prototype() {
4101   ASSERT(has_instance_prototype());
4102   if (has_initial_map()) return initial_map()->prototype();
4103   // When there is no initial map and the prototype is a JSObject, the
4104   // initial map field is used for the prototype field.
4105   return prototype_or_initial_map();
4106 }
4107
4108
4109 Object* JSFunction::prototype() {
4110   ASSERT(has_prototype());
4111   // If the function's prototype property has been set to a non-JSObject
4112   // value, that value is stored in the constructor field of the map.
4113   if (map()->has_non_instance_prototype()) return map()->constructor();
4114   return instance_prototype();
4115 }
4116
4117 bool JSFunction::should_have_prototype() {
4118   return map()->function_with_prototype();
4119 }
4120
4121
4122 bool JSFunction::is_compiled() {
4123   return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
4124 }
4125
4126
4127 FixedArray* JSFunction::literals() {
4128   ASSERT(!shared()->bound());
4129   return literals_or_bindings();
4130 }
4131
4132
4133 void JSFunction::set_literals(FixedArray* literals) {
4134   ASSERT(!shared()->bound());
4135   set_literals_or_bindings(literals);
4136 }
4137
4138
4139 FixedArray* JSFunction::function_bindings() {
4140   ASSERT(shared()->bound());
4141   return literals_or_bindings();
4142 }
4143
4144
4145 void JSFunction::set_function_bindings(FixedArray* bindings) {
4146   ASSERT(shared()->bound());
4147   // Bound function literal may be initialized to the empty fixed array
4148   // before the bindings are set.
4149   ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4150          bindings->map() == GetHeap()->fixed_cow_array_map());
4151   set_literals_or_bindings(bindings);
4152 }
4153
4154
4155 int JSFunction::NumberOfLiterals() {
4156   ASSERT(!shared()->bound());
4157   return literals()->length();
4158 }
4159
4160
4161 Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
4162   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
4163   return READ_FIELD(this, OffsetOfFunctionWithId(id));
4164 }
4165
4166
4167 void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4168                                               Object* value) {
4169   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
4170   WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
4171   WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
4172 }
4173
4174
4175 Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
4176   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
4177   return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4178 }
4179
4180
4181 void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4182                                                    Code* value) {
4183   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
4184   WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
4185   ASSERT(!HEAP->InNewSpace(value));
4186 }
4187
4188
4189 ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
4190 ACCESSORS(JSProxy, hash, Object, kHashOffset)
4191 ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4192 ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4193
4194
4195 void JSProxy::InitializeBody(int object_size, Object* value) {
4196   ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4197   for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4198     WRITE_FIELD(this, offset, value);
4199   }
4200 }
4201
4202
4203 ACCESSORS(JSSet, table, Object, kTableOffset)
4204 ACCESSORS(JSMap, table, Object, kTableOffset)
4205 ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4206 ACCESSORS(JSWeakMap, next, Object, kNextOffset)
4207
4208
4209 Address Foreign::foreign_address() {
4210   return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
4211 }
4212
4213
4214 void Foreign::set_foreign_address(Address value) {
4215   WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
4216 }
4217
4218
4219 ACCESSORS(JSModule, context, Object, kContextOffset)
4220
4221
4222 JSModule* JSModule::cast(Object* obj) {
4223   ASSERT(obj->IsJSModule());
4224   ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4225   return reinterpret_cast<JSModule*>(obj);
4226 }
4227
4228
4229 ACCESSORS(JSValue, value, Object, kValueOffset)
4230
4231
4232 JSValue* JSValue::cast(Object* obj) {
4233   ASSERT(obj->IsJSValue());
4234   ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4235   return reinterpret_cast<JSValue*>(obj);
4236 }
4237
4238
4239 ACCESSORS(JSDate, value, Object, kValueOffset)
4240 ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4241 ACCESSORS(JSDate, year, Object, kYearOffset)
4242 ACCESSORS(JSDate, month, Object, kMonthOffset)
4243 ACCESSORS(JSDate, day, Object, kDayOffset)
4244 ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4245 ACCESSORS(JSDate, hour, Object, kHourOffset)
4246 ACCESSORS(JSDate, min, Object, kMinOffset)
4247 ACCESSORS(JSDate, sec, Object, kSecOffset)
4248
4249
4250 JSDate* JSDate::cast(Object* obj) {
4251   ASSERT(obj->IsJSDate());
4252   ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4253   return reinterpret_cast<JSDate*>(obj);
4254 }
4255
4256
4257 ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4258 ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4259 ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4260 ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4261 ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4262 SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4263 SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4264
4265
4266 JSMessageObject* JSMessageObject::cast(Object* obj) {
4267   ASSERT(obj->IsJSMessageObject());
4268   ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4269   return reinterpret_cast<JSMessageObject*>(obj);
4270 }
4271
4272
4273 INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
4274 ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
4275 ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
4276 ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
4277 ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
4278 ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
4279 INT_ACCESSORS(Code, ic_age, kICAgeOffset)
4280
4281 byte* Code::instruction_start()  {
4282   return FIELD_ADDR(this, kHeaderSize);
4283 }
4284
4285
4286 byte* Code::instruction_end()  {
4287   return instruction_start() + instruction_size();
4288 }
4289
4290
4291 int Code::body_size() {
4292   return RoundUp(instruction_size(), kObjectAlignment);
4293 }
4294
4295
4296 FixedArray* Code::unchecked_deoptimization_data() {
4297   return reinterpret_cast<FixedArray*>(
4298       READ_FIELD(this, kDeoptimizationDataOffset));
4299 }
4300
4301
4302 ByteArray* Code::unchecked_relocation_info() {
4303   return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
4304 }
4305
4306
4307 byte* Code::relocation_start() {
4308   return unchecked_relocation_info()->GetDataStartAddress();
4309 }
4310
4311
4312 int Code::relocation_size() {
4313   return unchecked_relocation_info()->length();
4314 }
4315
4316
4317 byte* Code::entry() {
4318   return instruction_start();
4319 }
4320
4321
4322 bool Code::contains(byte* inner_pointer) {
4323   return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
4324 }
4325
4326
4327 ACCESSORS(JSArray, length, Object, kLengthOffset)
4328
4329
4330 ACCESSORS(JSRegExp, data, Object, kDataOffset)
4331
4332
4333 JSRegExp::Type JSRegExp::TypeTag() {
4334   Object* data = this->data();
4335   if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4336   Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4337   return static_cast<JSRegExp::Type>(smi->value());
4338 }
4339
4340
4341 JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4342   Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4343   return static_cast<JSRegExp::Type>(smi->value());
4344 }
4345
4346
4347 int JSRegExp::CaptureCount() {
4348   switch (TypeTag()) {
4349     case ATOM:
4350       return 0;
4351     case IRREGEXP:
4352       return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4353     default:
4354       UNREACHABLE();
4355       return -1;
4356   }
4357 }
4358
4359
4360 JSRegExp::Flags JSRegExp::GetFlags() {
4361   ASSERT(this->data()->IsFixedArray());
4362   Object* data = this->data();
4363   Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4364   return Flags(smi->value());
4365 }
4366
4367
4368 String* JSRegExp::Pattern() {
4369   ASSERT(this->data()->IsFixedArray());
4370   Object* data = this->data();
4371   String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4372   return pattern;
4373 }
4374
4375
4376 Object* JSRegExp::DataAt(int index) {
4377   ASSERT(TypeTag() != NOT_COMPILED);
4378   return FixedArray::cast(data())->get(index);
4379 }
4380
4381
4382 Object* JSRegExp::DataAtUnchecked(int index) {
4383   FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4384   int offset = FixedArray::kHeaderSize + index * kPointerSize;
4385   return READ_FIELD(fa, offset);
4386 }
4387
4388
4389 void JSRegExp::SetDataAt(int index, Object* value) {
4390   ASSERT(TypeTag() != NOT_COMPILED);
4391   ASSERT(index >= kDataIndex);  // Only implementation data can be set this way.
4392   FixedArray::cast(data())->set(index, value);
4393 }
4394
4395
4396 void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4397   ASSERT(index >= kDataIndex);  // Only implementation data can be set this way.
4398   FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4399   if (value->IsSmi()) {
4400     fa->set_unchecked(index, Smi::cast(value));
4401   } else {
4402     // We only do this during GC, so we don't need to notify the write barrier.
4403     fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4404   }
4405 }
4406
4407
4408 ElementsKind JSObject::GetElementsKind() {
4409   ElementsKind kind = map()->elements_kind();
4410 #if DEBUG
4411   FixedArrayBase* fixed_array =
4412       reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4413   Map* map = fixed_array->map();
4414     ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
4415             (map == GetHeap()->fixed_array_map() ||
4416              map == GetHeap()->fixed_cow_array_map())) ||
4417            (kind == FAST_DOUBLE_ELEMENTS &&
4418             (fixed_array->IsFixedDoubleArray() ||
4419             fixed_array == GetHeap()->empty_fixed_array())) ||
4420            (kind == DICTIONARY_ELEMENTS &&
4421             fixed_array->IsFixedArray() &&
4422             fixed_array->IsDictionary()) ||
4423            (kind > DICTIONARY_ELEMENTS));
4424     ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4425            (elements()->IsFixedArray() && elements()->length() >= 2));
4426 #endif
4427   return kind;
4428 }
4429
4430
4431 ElementsAccessor* JSObject::GetElementsAccessor() {
4432   return ElementsAccessor::ForKind(GetElementsKind());
4433 }
4434
4435
4436 bool JSObject::HasFastElements() {
4437   return GetElementsKind() == FAST_ELEMENTS;
4438 }
4439
4440
4441 bool JSObject::HasFastSmiOnlyElements() {
4442   return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4443 }
4444
4445
4446 bool JSObject::HasFastTypeElements() {
4447   ElementsKind elements_kind = GetElementsKind();
4448   return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4449       elements_kind == FAST_ELEMENTS;
4450 }
4451
4452
4453 bool JSObject::HasFastDoubleElements() {
4454   return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4455 }
4456
4457
4458 bool JSObject::HasDictionaryElements() {
4459   return GetElementsKind() == DICTIONARY_ELEMENTS;
4460 }
4461
4462
4463 bool JSObject::HasNonStrictArgumentsElements() {
4464   return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4465 }
4466
4467
4468 bool JSObject::HasExternalArrayElements() {
4469   HeapObject* array = elements();
4470   ASSERT(array != NULL);
4471   return array->IsExternalArray();
4472 }
4473
4474
4475 #define EXTERNAL_ELEMENTS_CHECK(name, type)          \
4476 bool JSObject::HasExternal##name##Elements() {       \
4477   HeapObject* array = elements();                    \
4478   ASSERT(array != NULL);                             \
4479   if (!array->IsHeapObject())                        \
4480     return false;                                    \
4481   return array->map()->instance_type() == type;      \
4482 }
4483
4484
4485 EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4486 EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4487 EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4488 EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4489                         EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4490 EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4491 EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4492                         EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4493 EXTERNAL_ELEMENTS_CHECK(Float,
4494                         EXTERNAL_FLOAT_ARRAY_TYPE)
4495 EXTERNAL_ELEMENTS_CHECK(Double,
4496                         EXTERNAL_DOUBLE_ARRAY_TYPE)
4497 EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
4498
4499
4500 bool JSObject::HasNamedInterceptor() {
4501   return map()->has_named_interceptor();
4502 }
4503
4504
4505 bool JSObject::HasIndexedInterceptor() {
4506   return map()->has_indexed_interceptor();
4507 }
4508
4509
4510 MaybeObject* JSObject::EnsureWritableFastElements() {
4511   ASSERT(HasFastTypeElements());
4512   FixedArray* elems = FixedArray::cast(elements());
4513   Isolate* isolate = GetIsolate();
4514   if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
4515   Object* writable_elems;
4516   { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4517       elems, isolate->heap()->fixed_array_map());
4518     if (!maybe_writable_elems->ToObject(&writable_elems)) {
4519       return maybe_writable_elems;
4520     }
4521   }
4522   set_elements(FixedArray::cast(writable_elems));
4523   isolate->counters()->cow_arrays_converted()->Increment();
4524   return writable_elems;
4525 }
4526
4527
4528 StringDictionary* JSObject::property_dictionary() {
4529   ASSERT(!HasFastProperties());
4530   return StringDictionary::cast(properties());
4531 }
4532
4533
4534 SeededNumberDictionary* JSObject::element_dictionary() {
4535   ASSERT(HasDictionaryElements());
4536   return SeededNumberDictionary::cast(elements());
4537 }
4538
4539
4540 bool String::IsHashFieldComputed(uint32_t field) {
4541   return (field & kHashNotComputedMask) == 0;
4542 }
4543
4544
4545 bool String::HasHashCode() {
4546   return IsHashFieldComputed(hash_field());
4547 }
4548
4549
4550 uint32_t String::Hash() {
4551   // Fast case: has hash code already been computed?
4552   uint32_t field = hash_field();
4553   if (IsHashFieldComputed(field)) return field >> kHashShift;
4554   // Slow case: compute hash code and set it.
4555   return ComputeAndSetHash();
4556 }
4557
4558
4559 StringHasher::StringHasher(int length, uint32_t seed)
4560   : length_(length),
4561     raw_running_hash_(seed),
4562     array_index_(0),
4563     is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4564     is_first_char_(true),
4565     is_valid_(true) {
4566   ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
4567 }
4568
4569
4570 bool StringHasher::has_trivial_hash() {
4571   return length_ > String::kMaxHashCalcLength;
4572 }
4573
4574
4575 void StringHasher::AddCharacter(uint32_t c) {
4576   if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4577     AddSurrogatePair(c);  // Not inlined.
4578     return;
4579   }
4580   // Use the Jenkins one-at-a-time hash function to update the hash
4581   // for the given character.
4582   raw_running_hash_ += c;
4583   raw_running_hash_ += (raw_running_hash_ << 10);
4584   raw_running_hash_ ^= (raw_running_hash_ >> 6);
4585   // Incremental array index computation.
4586   if (is_array_index_) {
4587     if (c < '0' || c > '9') {
4588       is_array_index_ = false;
4589     } else {
4590       int d = c - '0';
4591       if (is_first_char_) {
4592         is_first_char_ = false;
4593         if (c == '0' && length_ > 1) {
4594           is_array_index_ = false;
4595           return;
4596         }
4597       }
4598       if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4599         is_array_index_ = false;
4600       } else {
4601         array_index_ = array_index_ * 10 + d;
4602       }
4603     }
4604   }
4605 }
4606
4607
4608 void StringHasher::AddCharacterNoIndex(uint32_t c) {
4609   ASSERT(!is_array_index());
4610   if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4611     AddSurrogatePairNoIndex(c);  // Not inlined.
4612     return;
4613   }
4614   raw_running_hash_ += c;
4615   raw_running_hash_ += (raw_running_hash_ << 10);
4616   raw_running_hash_ ^= (raw_running_hash_ >> 6);
4617 }
4618
4619
4620 uint32_t StringHasher::GetHash() {
4621   // Get the calculated raw hash value and do some more bit ops to distribute
4622   // the hash further. Ensure that we never return zero as the hash value.
4623   uint32_t result = raw_running_hash_;
4624   result += (result << 3);
4625   result ^= (result >> 11);
4626   result += (result << 15);
4627   if ((result & String::kHashBitMask) == 0) {
4628     result = 27;
4629   }
4630   return result;
4631 }
4632
4633
4634 template <typename schar>
4635 uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4636   StringHasher hasher(length, seed);
4637   if (!hasher.has_trivial_hash()) {
4638     int i;
4639     for (i = 0; hasher.is_array_index() && (i < length); i++) {
4640       hasher.AddCharacter(chars[i]);
4641     }
4642     for (; i < length; i++) {
4643       hasher.AddCharacterNoIndex(chars[i]);
4644     }
4645   }
4646   return hasher.GetHashField();
4647 }
4648
4649
4650 bool String::AsArrayIndex(uint32_t* index) {
4651   uint32_t field = hash_field();
4652   if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4653     return false;
4654   }
4655   return SlowAsArrayIndex(index);
4656 }
4657
4658
4659 Object* JSReceiver::GetPrototype() {
4660   return HeapObject::cast(this)->map()->prototype();
4661 }
4662
4663
4664 bool JSReceiver::HasProperty(String* name) {
4665   if (IsJSProxy()) {
4666     return JSProxy::cast(this)->HasPropertyWithHandler(name);
4667   }
4668   return GetPropertyAttribute(name) != ABSENT;
4669 }
4670
4671
4672 bool JSReceiver::HasLocalProperty(String* name) {
4673   if (IsJSProxy()) {
4674     return JSProxy::cast(this)->HasPropertyWithHandler(name);
4675   }
4676   return GetLocalPropertyAttribute(name) != ABSENT;
4677 }
4678
4679
4680 PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
4681   return GetPropertyAttributeWithReceiver(this, key);
4682 }
4683
4684 // TODO(504): this may be useful in other places too where JSGlobalProxy
4685 // is used.
4686 Object* JSObject::BypassGlobalProxy() {
4687   if (IsJSGlobalProxy()) {
4688     Object* proto = GetPrototype();
4689     if (proto->IsNull()) return GetHeap()->undefined_value();
4690     ASSERT(proto->IsJSGlobalObject());
4691     return proto;
4692   }
4693   return this;
4694 }
4695
4696
4697 MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4698   return IsJSProxy()
4699       ? JSProxy::cast(this)->GetIdentityHash(flag)
4700       : JSObject::cast(this)->GetIdentityHash(flag);
4701 }
4702
4703
4704 bool JSReceiver::HasElement(uint32_t index) {
4705   if (IsJSProxy()) {
4706     return JSProxy::cast(this)->HasElementWithHandler(index);
4707   }
4708   return JSObject::cast(this)->HasElementWithReceiver(this, index);
4709 }
4710
4711
4712 bool AccessorInfo::all_can_read() {
4713   return BooleanBit::get(flag(), kAllCanReadBit);
4714 }
4715
4716
4717 void AccessorInfo::set_all_can_read(bool value) {
4718   set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4719 }
4720
4721
4722 bool AccessorInfo::all_can_write() {
4723   return BooleanBit::get(flag(), kAllCanWriteBit);
4724 }
4725
4726
4727 void AccessorInfo::set_all_can_write(bool value) {
4728   set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4729 }
4730
4731
4732 bool AccessorInfo::prohibits_overwriting() {
4733   return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4734 }
4735
4736
4737 void AccessorInfo::set_prohibits_overwriting(bool value) {
4738   set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4739 }
4740
4741
4742 PropertyAttributes AccessorInfo::property_attributes() {
4743   return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4744 }
4745
4746
4747 void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4748   set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
4749 }
4750
4751
4752 template<typename Shape, typename Key>
4753 void Dictionary<Shape, Key>::SetEntry(int entry,
4754                                       Object* key,
4755                                       Object* value) {
4756   SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4757 }
4758
4759
4760 template<typename Shape, typename Key>
4761 void Dictionary<Shape, Key>::SetEntry(int entry,
4762                                       Object* key,
4763                                       Object* value,
4764                                       PropertyDetails details) {
4765   ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
4766   int index = HashTable<Shape, Key>::EntryToIndex(entry);
4767   AssertNoAllocation no_gc;
4768   WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
4769   FixedArray::set(index, key, mode);
4770   FixedArray::set(index+1, value, mode);
4771   FixedArray::set(index+2, details.AsSmi());
4772 }
4773
4774
4775 bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4776   ASSERT(other->IsNumber());
4777   return key == static_cast<uint32_t>(other->Number());
4778 }
4779
4780
4781 uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4782   return ComputeIntegerHash(key, 0);
4783 }
4784
4785
4786 uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4787                                                       Object* other) {
4788   ASSERT(other->IsNumber());
4789   return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
4790 }
4791
4792 uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4793   return ComputeIntegerHash(key, seed);
4794 }
4795
4796 uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4797                                                           uint32_t seed,
4798                                                           Object* other) {
4799   ASSERT(other->IsNumber());
4800   return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4801 }
4802
4803 MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4804   return Isolate::Current()->heap()->NumberFromUint32(key);
4805 }
4806
4807
4808 bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4809   // We know that all entries in a hash table had their hash keys created.
4810   // Use that knowledge to have fast failure.
4811   if (key->Hash() != String::cast(other)->Hash()) return false;
4812   return key->Equals(String::cast(other));
4813 }
4814
4815
4816 uint32_t StringDictionaryShape::Hash(String* key) {
4817   return key->Hash();
4818 }
4819
4820
4821 uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4822   return String::cast(other)->Hash();
4823 }
4824
4825
4826 MaybeObject* StringDictionaryShape::AsObject(String* key) {
4827   return key;
4828 }
4829
4830
4831 template <int entrysize>
4832 bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4833   return key->SameValue(other);
4834 }
4835
4836
4837 template <int entrysize>
4838 uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
4839   MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4840   return Smi::cast(maybe_hash->ToObjectChecked())->value();
4841 }
4842
4843
4844 template <int entrysize>
4845 uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4846                                                         Object* other) {
4847   MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4848   return Smi::cast(maybe_hash->ToObjectChecked())->value();
4849 }
4850
4851
4852 template <int entrysize>
4853 MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
4854   return key;
4855 }
4856
4857
4858 void Map::ClearCodeCache(Heap* heap) {
4859   // No write barrier is needed since empty_fixed_array is not in new space.
4860   // Please note this function is used during marking:
4861   //  - MarkCompactCollector::MarkUnmarkedObject
4862   //  - IncrementalMarking::Step
4863   ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4864   WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
4865 }
4866
4867
4868 void JSArray::EnsureSize(int required_size) {
4869   ASSERT(HasFastTypeElements());
4870   FixedArray* elts = FixedArray::cast(elements());
4871   const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4872   if (elts->length() < required_size) {
4873     // Doubling in size would be overkill, but leave some slack to avoid
4874     // constantly growing.
4875     Expand(required_size + (required_size >> 3));
4876     // It's a performance benefit to keep a frequently used array in new-space.
4877   } else if (!GetHeap()->new_space()->Contains(elts) &&
4878              required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4879     // Expand will allocate a new backing store in new space even if the size
4880     // we asked for isn't larger than what we had before.
4881     Expand(required_size);
4882   }
4883 }
4884
4885
4886 void JSArray::set_length(Smi* length) {
4887   // Don't need a write barrier for a Smi.
4888   set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4889 }
4890
4891
4892 bool JSArray::AllowsSetElementsLength() {
4893   bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4894   ASSERT(result == !HasExternalArrayElements());
4895   return result;
4896 }
4897
4898
4899 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4900   MaybeObject* maybe_result = EnsureCanContainElements(
4901       storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4902   if (maybe_result->IsFailure()) return maybe_result;
4903   ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4904           GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4905          ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4906           ((GetElementsKind() == FAST_ELEMENTS) ||
4907            (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4908             FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
4909   set_elements(storage);
4910   set_length(Smi::FromInt(storage->length()));
4911   return this;
4912 }
4913
4914
4915 MaybeObject* FixedArray::Copy() {
4916   if (length() == 0) return this;
4917   return GetHeap()->CopyFixedArray(this);
4918 }
4919
4920
4921 MaybeObject* FixedDoubleArray::Copy() {
4922   if (length() == 0) return this;
4923   return GetHeap()->CopyFixedDoubleArray(this);
4924 }
4925
4926
4927 void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4928   set(1 + index * 2, id);
4929 }
4930
4931
4932 Smi* TypeFeedbackCells::AstId(int index) {
4933   return Smi::cast(get(1 + index * 2));
4934 }
4935
4936
4937 void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4938   set(index * 2, cell);
4939 }
4940
4941
4942 JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4943   return JSGlobalPropertyCell::cast(get(index * 2));
4944 }
4945
4946
4947 Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4948   return isolate->factory()->the_hole_value();
4949 }
4950
4951
4952 Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4953   return isolate->factory()->undefined_value();
4954 }
4955
4956
4957 Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4958   return heap->raw_unchecked_the_hole_value();
4959 }
4960
4961
4962 SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
4963 SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
4964               kIcWithTypeinfoCountOffset)
4965 ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
4966           kTypeFeedbackCellsOffset)
4967
4968
4969 SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
4970
4971
4972 Relocatable::Relocatable(Isolate* isolate) {
4973   ASSERT(isolate == Isolate::Current());
4974   isolate_ = isolate;
4975   prev_ = isolate->relocatable_top();
4976   isolate->set_relocatable_top(this);
4977 }
4978
4979
4980 Relocatable::~Relocatable() {
4981   ASSERT(isolate_ == Isolate::Current());
4982   ASSERT_EQ(isolate_->relocatable_top(), this);
4983   isolate_->set_relocatable_top(prev_);
4984 }
4985
4986
4987 int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4988   return map->instance_size();
4989 }
4990
4991
4992 void Foreign::ForeignIterateBody(ObjectVisitor* v) {
4993   v->VisitExternalReference(
4994       reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
4995 }
4996
4997
4998 template<typename StaticVisitor>
4999 void Foreign::ForeignIterateBody() {
5000   StaticVisitor::VisitExternalReference(
5001       reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
5002 }
5003
5004
5005 void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5006   typedef v8::String::ExternalAsciiStringResource Resource;
5007   v->VisitExternalAsciiString(
5008       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5009 }
5010
5011
5012 template<typename StaticVisitor>
5013 void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5014   typedef v8::String::ExternalAsciiStringResource Resource;
5015   StaticVisitor::VisitExternalAsciiString(
5016       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5017 }
5018
5019
5020 void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5021   typedef v8::String::ExternalStringResource Resource;
5022   v->VisitExternalTwoByteString(
5023       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5024 }
5025
5026
5027 template<typename StaticVisitor>
5028 void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5029   typedef v8::String::ExternalStringResource Resource;
5030   StaticVisitor::VisitExternalTwoByteString(
5031       reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5032 }
5033
5034 #define SLOT_ADDR(obj, offset) \
5035   reinterpret_cast<Object**>((obj)->address() + offset)
5036
5037 template<int start_offset, int end_offset, int size>
5038 void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5039     HeapObject* obj,
5040     ObjectVisitor* v) {
5041     v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5042 }
5043
5044
5045 template<int start_offset>
5046 void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5047                                                        int object_size,
5048                                                        ObjectVisitor* v) {
5049   v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5050 }
5051
5052 #undef SLOT_ADDR
5053
5054 #undef TYPE_CHECKER
5055 #undef CAST_ACCESSOR
5056 #undef INT_ACCESSORS
5057 #undef ACCESSORS
5058 #undef ACCESSORS_TO_SMI
5059 #undef SMI_ACCESSORS
5060 #undef BOOL_GETTER
5061 #undef BOOL_ACCESSORS
5062 #undef FIELD_ADDR
5063 #undef READ_FIELD
5064 #undef WRITE_FIELD
5065 #undef WRITE_BARRIER
5066 #undef CONDITIONAL_WRITE_BARRIER
5067 #undef READ_DOUBLE_FIELD
5068 #undef WRITE_DOUBLE_FIELD
5069 #undef READ_INT_FIELD
5070 #undef WRITE_INT_FIELD
5071 #undef READ_INTPTR_FIELD
5072 #undef WRITE_INTPTR_FIELD
5073 #undef READ_UINT32_FIELD
5074 #undef WRITE_UINT32_FIELD
5075 #undef READ_SHORT_FIELD
5076 #undef WRITE_SHORT_FIELD
5077 #undef READ_BYTE_FIELD
5078 #undef WRITE_BYTE_FIELD
5079
5080
5081 } }  // namespace v8::internal
5082
5083 #endif  // V8_OBJECTS_INL_H_