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