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