blob: 0509a80b2329c74a406e82987304dbafeeee6f59 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004//
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
Ben Murdochb8a8cc12014-11-26 15:28:44 +000015#include "src/base/atomicops.h"
16#include "src/base/bits.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000017#include "src/contexts-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000018#include "src/conversions-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000019#include "src/factory.h"
20#include "src/field-index-inl.h"
21#include "src/heap/heap-inl.h"
22#include "src/heap/heap.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000023#include "src/isolate.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040024#include "src/layout-descriptor-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025#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"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000031#include "src/types-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000032#include "src/v8memory.h"
Ben Murdoch592a9fc2012-03-05 11:04:45 +000033
Steve Blocka7e24c12009-10-30 11:49:00 +000034namespace v8 {
35namespace internal {
36
37PropertyDetails::PropertyDetails(Smi* smi) {
38 value_ = smi->value();
39}
40
41
Ben Murdochb8a8cc12014-11-26 15:28:44 +000042Smi* 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);
Steve Blocka7e24c12009-10-30 11:49:00 +000047}
48
49
Emily Bernierd0a1eb72015-03-24 16:35:39 -040050int PropertyDetails::field_width_in_words() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000051 DCHECK(location() == kField);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040052 if (!FLAG_unbox_double_fields) return 1;
53 if (kDoubleSize == kPointerSize) return 1;
54 return representation().IsDouble() ? kDoubleSize / kPointerSize : 1;
55}
56
57
Ben Murdoch3ef787d2012-04-12 10:51:47 +010058#define TYPE_CHECKER(type, instancetype) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059 bool Object::Is##type() const { \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010060 return Object::IsHeapObject() && \
61 HeapObject::cast(this)->map()->instance_type() == instancetype; \
62 }
63
64
Ben Murdochb8a8cc12014-11-26 15:28:44 +000065#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); \
Steve Blocka7e24c12009-10-30 11:49:00 +000073 }
74
75
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076#define INT_ACCESSORS(holder, name, offset) \
77 int holder::name() const { return READ_INT_FIELD(this, offset); } \
Steve Blocka7e24c12009-10-30 11:49:00 +000078 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
79
80
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081#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); \
Steve Blocka7e24c12009-10-30 11:49:00 +000086 }
87
88
Ben Murdoch3ef787d2012-04-12 10:51:47 +010089// Getter that returns a Smi as an int and writes an int as a Smi.
Steve Blocka7e24c12009-10-30 11:49:00 +000090#define SMI_ACCESSORS(holder, name, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091 int holder::name() const { \
Steve Blocka7e24c12009-10-30 11:49:00 +000092 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +000099#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 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000116
117#define BOOL_GETTER(holder, field, name, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000118 bool holder::name() const { \
Steve Blocka7e24c12009-10-30 11:49:00 +0000119 return BooleanBit::get(field(), offset); \
120 } \
121
122
123#define BOOL_ACCESSORS(holder, field, name, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000124 bool holder::name() const { \
Steve Blocka7e24c12009-10-30 11:49:00 +0000125 return BooleanBit::get(field(), offset); \
126 } \
127 void holder::set_##name(bool value) { \
128 set_##field(BooleanBit::set(field(), offset, value)); \
129 }
130
131
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000132bool Object::IsFixedArrayBase() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000133 return IsFixedArray() || IsFixedDoubleArray() || IsFixedTypedArrayBase();
134}
135
136
137bool 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;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100142}
143
144
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145// External objects are not extensible, so the map check is enough.
146bool Object::IsExternal() const {
147 return Object::IsHeapObject() &&
148 HeapObject::cast(this)->map() ==
149 HeapObject::cast(this)->GetHeap()->external_map();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100150}
151
152
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000153bool Object::IsAccessorInfo() const { return IsExecutableAccessorInfo(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000154
155
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100156TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000157TYPE_CHECKER(MutableHeapNumber, MUTABLE_HEAP_NUMBER_TYPE)
158TYPE_CHECKER(Symbol, SYMBOL_TYPE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000159TYPE_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 }
168SIMD128_TYPES(SIMD128_TYPE_CHECKER)
169#undef SIMD128_TYPE_CHECKER
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100170
171
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172bool Object::IsString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000173 return Object::IsHeapObject()
174 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
175}
176
177
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000178bool Object::IsName() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000179 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
180 return Object::IsHeapObject() &&
181 HeapObject::cast(this)->map()->instance_type() <= LAST_NAME_TYPE;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000182}
183
184
185bool Object::IsUniqueName() const {
186 return IsInternalizedString() || IsSymbol();
187}
188
189
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000190bool 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;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000194}
195
196
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000197bool Object::IsCallable() const {
198 return Object::IsHeapObject() && HeapObject::cast(this)->map()->is_callable();
199}
200
201
202bool Object::IsConstructor() const {
203 return Object::IsHeapObject() &&
204 HeapObject::cast(this)->map()->is_constructor();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100205}
206
207
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208bool Object::IsTemplateInfo() const {
209 return IsObjectTemplateInfo() || IsFunctionTemplateInfo();
Steve Blocka7e24c12009-10-30 11:49:00 +0000210}
211
212
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213bool 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
222bool Object::IsConsString() const {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000223 if (!IsString()) return false;
224 return StringShape(String::cast(this)).IsCons();
225}
226
227
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000228bool Object::IsSlicedString() const {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000229 if (!IsString()) return false;
230 return StringShape(String::cast(this)).IsSliced();
Steve Blocka7e24c12009-10-30 11:49:00 +0000231}
232
233
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000234bool Object::IsSeqString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000235 if (!IsString()) return false;
236 return StringShape(String::cast(this)).IsSequential();
237}
238
239
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000240bool Object::IsSeqOneByteString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000241 if (!IsString()) return false;
242 return StringShape(String::cast(this)).IsSequential() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000243 String::cast(this)->IsOneByteRepresentation();
Steve Blocka7e24c12009-10-30 11:49:00 +0000244}
245
246
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000247bool Object::IsSeqTwoByteString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000248 if (!IsString()) return false;
249 return StringShape(String::cast(this)).IsSequential() &&
250 String::cast(this)->IsTwoByteRepresentation();
251}
252
253
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000254bool Object::IsExternalString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000255 if (!IsString()) return false;
256 return StringShape(String::cast(this)).IsExternal();
257}
258
259
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000260bool Object::IsExternalOneByteString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000261 if (!IsString()) return false;
262 return StringShape(String::cast(this)).IsExternal() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000263 String::cast(this)->IsOneByteRepresentation();
Steve Blocka7e24c12009-10-30 11:49:00 +0000264}
265
266
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000267bool Object::IsExternalTwoByteString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000268 if (!IsString()) return false;
269 return StringShape(String::cast(this)).IsExternal() &&
270 String::cast(this)->IsTwoByteRepresentation();
271}
272
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000273
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000274bool Object::HasValidElements() {
275 // Dictionary is covered under FixedArray.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000276 return IsFixedArray() || IsFixedDoubleArray() || IsFixedTypedArrayBase();
277}
278
279
280bool 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
298bool 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;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000306}
Steve Blocka7e24c12009-10-30 11:49:00 +0000307
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000308
309Handle<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
328Handle<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
340StringShape::StringShape(const String* str)
Steve Blocka7e24c12009-10-30 11:49:00 +0000341 : type_(str->map()->instance_type()) {
342 set_valid();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000343 DCHECK((type_ & kIsNotStringMask) == kStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000344}
345
346
347StringShape::StringShape(Map* map)
348 : type_(map->instance_type()) {
349 set_valid();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000350 DCHECK((type_ & kIsNotStringMask) == kStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000351}
352
353
354StringShape::StringShape(InstanceType t)
355 : type_(static_cast<uint32_t>(t)) {
356 set_valid();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000357 DCHECK((type_ & kIsNotStringMask) == kStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000358}
359
360
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000361bool StringShape::IsInternalized() {
362 DCHECK(valid());
363 STATIC_ASSERT(kNotInternalizedTag != 0);
364 return (type_ & (kIsNotStringMask | kIsNotInternalizedMask)) ==
365 (kStringTag | kInternalizedTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000366}
367
368
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000369bool String::IsOneByteRepresentation() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000370 uint32_t type = map()->instance_type();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000371 return (type & kStringEncodingMask) == kOneByteStringTag;
Steve Blocka7e24c12009-10-30 11:49:00 +0000372}
373
374
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000375bool String::IsTwoByteRepresentation() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000376 uint32_t type = map()->instance_type();
Steve Blocka7e24c12009-10-30 11:49:00 +0000377 return (type & kStringEncodingMask) == kTwoByteStringTag;
378}
379
380
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000381bool String::IsOneByteRepresentationUnderneath() {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000382 uint32_t type = map()->instance_type();
383 STATIC_ASSERT(kIsIndirectStringTag != 0);
384 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000385 DCHECK(IsFlat());
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000386 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000387 case kOneByteStringTag:
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000388 return true;
389 case kTwoByteStringTag:
390 return false;
391 default: // Cons or sliced string. Need to go deeper.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000392 return GetUnderlying()->IsOneByteRepresentation();
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000393 }
394}
395
396
397bool String::IsTwoByteRepresentationUnderneath() {
398 uint32_t type = map()->instance_type();
399 STATIC_ASSERT(kIsIndirectStringTag != 0);
400 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000401 DCHECK(IsFlat());
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000402 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000403 case kOneByteStringTag:
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000404 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000413bool String::HasOnlyOneByteChars() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100414 uint32_t type = map()->instance_type();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000415 return (type & kOneByteDataHintMask) == kOneByteDataHintTag ||
416 IsOneByteRepresentation();
Steve Block6ded16b2010-05-10 14:33:55 +0100417}
418
419
Steve Blocka7e24c12009-10-30 11:49:00 +0000420bool StringShape::IsCons() {
421 return (type_ & kStringRepresentationMask) == kConsStringTag;
422}
423
424
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000425bool StringShape::IsSliced() {
426 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
427}
428
429
430bool StringShape::IsIndirect() {
431 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
432}
433
434
Steve Blocka7e24c12009-10-30 11:49:00 +0000435bool StringShape::IsExternal() {
436 return (type_ & kStringRepresentationMask) == kExternalStringTag;
437}
438
439
440bool StringShape::IsSequential() {
441 return (type_ & kStringRepresentationMask) == kSeqStringTag;
442}
443
444
445StringRepresentationTag StringShape::representation_tag() {
446 uint32_t tag = (type_ & kStringRepresentationMask);
447 return static_cast<StringRepresentationTag>(tag);
448}
449
450
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000451uint32_t StringShape::encoding_tag() {
452 return type_ & kStringEncodingMask;
453}
454
455
Steve Blocka7e24c12009-10-30 11:49:00 +0000456uint32_t StringShape::full_representation_tag() {
457 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
458}
459
460
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000461STATIC_ASSERT((kStringRepresentationMask | kStringEncodingMask) ==
Steve Blocka7e24c12009-10-30 11:49:00 +0000462 Internals::kFullStringRepresentationMask);
463
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000464STATIC_ASSERT(static_cast<uint32_t>(kStringEncodingMask) ==
465 Internals::kStringEncodingMask);
Steve Blocka7e24c12009-10-30 11:49:00 +0000466
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000467
468bool StringShape::IsSequentialOneByte() {
469 return full_representation_tag() == (kSeqStringTag | kOneByteStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000470}
471
472
473bool StringShape::IsSequentialTwoByte() {
474 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
475}
476
477
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000478bool StringShape::IsExternalOneByte() {
479 return full_representation_tag() == (kExternalStringTag | kOneByteStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000480}
481
482
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000483STATIC_ASSERT((kExternalStringTag | kOneByteStringTag) ==
484 Internals::kExternalOneByteRepresentationTag);
485
486STATIC_ASSERT(v8::String::ONE_BYTE_ENCODING == kOneByteStringTag);
487
488
Steve Blocka7e24c12009-10-30 11:49:00 +0000489bool StringShape::IsExternalTwoByte() {
490 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
491}
492
493
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000494STATIC_ASSERT((kExternalStringTag | kTwoByteStringTag) ==
Steve Blocka7e24c12009-10-30 11:49:00 +0000495 Internals::kExternalTwoByteRepresentationTag);
496
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000497STATIC_ASSERT(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000498
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400499
Steve Blocka7e24c12009-10-30 11:49:00 +0000500uc32 FlatStringReader::Get(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000501 if (is_one_byte_) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400502 return Get<uint8_t>(index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000503 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400504 return Get<uc16>(index);
505 }
506}
507
508
509template <typename Char>
510Char 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]);
Steve Blocka7e24c12009-10-30 11:49:00 +0000517 }
518}
519
520
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000521Handle<Object> StringTableShape::AsHandle(Isolate* isolate, HashTableKey* key) {
522 return key->AsHandle(isolate);
523}
524
525
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000526Handle<Object> CompilationCacheShape::AsHandle(Isolate* isolate,
527 HashTableKey* key) {
528 return key->AsHandle(isolate);
529}
530
531
532Handle<Object> CodeCacheHashTableShape::AsHandle(Isolate* isolate,
533 HashTableKey* key) {
534 return key->AsHandle(isolate);
535}
536
537template <typename Char>
538class SequentialStringKey : public HashTableKey {
539 public:
540 explicit SequentialStringKey(Vector<const Char> string, uint32_t seed)
541 : string_(string), hash_field_(0), seed_(seed) { }
542
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000543 uint32_t Hash() override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000544 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000554 uint32_t HashForObject(Object* other) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000555 return String::cast(other)->Hash();
556 }
557
558 Vector<const Char> string_;
559 uint32_t hash_field_;
560 uint32_t seed_;
561};
562
563
564class OneByteStringKey : public SequentialStringKey<uint8_t> {
565 public:
566 OneByteStringKey(Vector<const uint8_t> str, uint32_t seed)
567 : SequentialStringKey<uint8_t>(str, seed) { }
568
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000569 bool IsMatch(Object* string) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000570 return String::cast(string)->IsOneByteEqualTo(string_);
571 }
572
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000573 Handle<Object> AsHandle(Isolate* isolate) override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000574};
575
576
577class SeqOneByteSubStringKey : public HashTableKey {
578 public:
579 SeqOneByteSubStringKey(Handle<SeqOneByteString> string, int from, int length)
580 : string_(string), from_(from), length_(length) {
581 DCHECK(string_->IsSeqOneByteString());
582 }
583
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000584 uint32_t Hash() override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000585 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000595 uint32_t HashForObject(Object* other) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000596 return String::cast(other)->Hash();
597 }
598
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000599 bool IsMatch(Object* string) override;
600 Handle<Object> AsHandle(Isolate* isolate) override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000601
602 private:
603 Handle<SeqOneByteString> string_;
604 int from_;
605 int length_;
606 uint32_t hash_field_;
607};
608
609
610class TwoByteStringKey : public SequentialStringKey<uc16> {
611 public:
612 explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed)
613 : SequentialStringKey<uc16>(str, seed) { }
614
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000615 bool IsMatch(Object* string) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000616 return String::cast(string)->IsTwoByteEqualTo(string_);
617 }
618
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000619 Handle<Object> AsHandle(Isolate* isolate) override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000620};
621
622
623// Utf8StringKey carries a vector of chars as key.
624class Utf8StringKey : public HashTableKey {
625 public:
626 explicit Utf8StringKey(Vector<const char> string, uint32_t seed)
627 : string_(string), hash_field_(0), seed_(seed) { }
628
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000629 bool IsMatch(Object* string) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000630 return String::cast(string)->IsUtf8EqualTo(string_);
631 }
632
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000633 uint32_t Hash() override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000634 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000641 uint32_t HashForObject(Object* other) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000642 return String::cast(other)->Hash();
643 }
644
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000645 Handle<Object> AsHandle(Isolate* isolate) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000646 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
658bool Object::IsNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000659 return IsSmi() || IsHeapNumber();
660}
661
662
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100663TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000664TYPE_CHECKER(BytecodeArray, BYTECODE_ARRAY_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100665TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
666
667
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000668bool Object::IsFiller() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100669 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;
Steve Blocka7e24c12009-10-30 11:49:00 +0000672}
673
674
Steve Block3ce2e202009-11-05 08:53:23 +0000675
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000676#define TYPED_ARRAY_TYPE_CHECKER(Type, type, TYPE, ctype, size) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000677 TYPE_CHECKER(Fixed##Type##Array, FIXED_##TYPE##_ARRAY_TYPE)
678
679TYPED_ARRAYS(TYPED_ARRAY_TYPE_CHECKER)
680#undef TYPED_ARRAY_TYPE_CHECKER
Ben Murdoch257744e2011-11-30 15:57:28 +0000681
682
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000683bool 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);
Steve Blocka7e24c12009-10-30 11:49:00 +0000690}
691
692
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000693bool Object::IsJSReceiver() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100694 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000695 return IsHeapObject() &&
696 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
697}
698
699
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000700bool Object::IsJSObject() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100701 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000702 return IsHeapObject() && HeapObject::cast(this)->map()->IsJSObjectMap();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000703}
704
705
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000706bool Object::IsJSProxy() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100707 if (!Object::IsHeapObject()) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000708 return HeapObject::cast(this)->map()->IsJSProxyMap();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000709}
710
711
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100712TYPE_CHECKER(JSSet, JS_SET_TYPE)
713TYPE_CHECKER(JSMap, JS_MAP_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000714TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE)
715TYPE_CHECKER(JSMapIterator, JS_MAP_ITERATOR_TYPE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000716TYPE_CHECKER(JSIteratorResult, JS_ITERATOR_RESULT_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100717TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000718TYPE_CHECKER(JSWeakSet, JS_WEAK_SET_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100719TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
720TYPE_CHECKER(Map, MAP_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100721TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400722TYPE_CHECKER(WeakFixedArray, FIXED_ARRAY_TYPE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000723TYPE_CHECKER(TransitionArray, TRANSITION_ARRAY_TYPE)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000724
725
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000726bool Object::IsJSWeakCollection() const {
727 return IsJSWeakMap() || IsJSWeakSet();
728}
729
730
731bool Object::IsDescriptorArray() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000732 return IsFixedArray();
733}
734
735
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000736bool Object::IsArrayList() const { return IsFixedArray(); }
737
738
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400739bool Object::IsLayoutDescriptor() const {
740 return IsSmi() || IsFixedTypedArrayBase();
741}
742
743
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000744bool Object::IsTypeFeedbackVector() const { return IsFixedArray(); }
745
746
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000747bool Object::IsTypeFeedbackMetadata() const { return IsFixedArray(); }
748
749
750bool Object::IsLiteralsArray() const { return IsFixedArray(); }
751
752
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000753bool Object::IsDeoptimizationInputData() const {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100754 // 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;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000765 return length >= 0 && length % DeoptimizationInputData::kDeoptEntrySize == 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100766}
767
768
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000769bool Object::IsDeoptimizationOutputData() const {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100770 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000779bool 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000787bool Object::IsDependentCode() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100788 if (!IsFixedArray()) return false;
789 // There's actually no way to see the difference between a fixed array and
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000790 // a dependent codes array.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100791 return true;
792}
793
794
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000795bool 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() ||
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400805 map == heap->script_context_map());
Steve Blocka7e24c12009-10-30 11:49:00 +0000806}
807
808
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000809bool Object::IsNativeContext() const {
Steve Block44f0eee2011-05-26 01:26:41 +0100810 return Object::IsHeapObject() &&
811 HeapObject::cast(this)->map() ==
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000812 HeapObject::cast(this)->GetHeap()->native_context_map();
Steve Blocka7e24c12009-10-30 11:49:00 +0000813}
814
815
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400816bool 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000824bool Object::IsScopeInfo() const {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000825 return Object::IsHeapObject() &&
826 HeapObject::cast(this)->map() ==
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100827 HeapObject::cast(this)->GetHeap()->scope_info_map();
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000828}
829
830
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000831TYPE_CHECKER(JSBoundFunction, JS_BOUND_FUNCTION_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100832TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000833
834
835template <> inline bool Is<JSFunction>(Object* obj) {
836 return obj->IsJSFunction();
837}
838
839
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100840TYPE_CHECKER(Code, CODE_TYPE)
841TYPE_CHECKER(Oddball, ODDBALL_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000842TYPE_CHECKER(Cell, CELL_TYPE)
843TYPE_CHECKER(PropertyCell, PROPERTY_CELL_TYPE)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400844TYPE_CHECKER(WeakCell, WEAK_CELL_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100845TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000846TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE)
847TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100848TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
849TYPE_CHECKER(JSDate, JS_DATE_TYPE)
850TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000851
852
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000853bool Object::IsStringWrapper() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000854 return IsJSValue() && JSValue::cast(this)->value()->IsString();
855}
856
857
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100858TYPE_CHECKER(Foreign, FOREIGN_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000859
860
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000861bool Object::IsBoolean() const {
Steve Block44f0eee2011-05-26 01:26:41 +0100862 return IsOddball() &&
863 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000864}
865
866
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100867TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000868TYPE_CHECKER(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE)
869TYPE_CHECKER(JSTypedArray, JS_TYPED_ARRAY_TYPE)
870TYPE_CHECKER(JSDataView, JS_DATA_VIEW_TYPE)
871
872
873bool Object::IsJSArrayBufferView() const {
874 return IsJSDataView() || IsJSTypedArray();
875}
876
877
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100878TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000879
880
881template <> inline bool Is<JSArray>(Object* obj) {
882 return obj->IsJSArray();
883}
884
885
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000886bool Object::IsHashTable() const {
Steve Block44f0eee2011-05-26 01:26:41 +0100887 return Object::IsHeapObject() &&
888 HeapObject::cast(this)->map() ==
889 HeapObject::cast(this)->GetHeap()->hash_table_map();
Steve Blocka7e24c12009-10-30 11:49:00 +0000890}
891
892
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000893bool Object::IsWeakHashTable() const {
894 return IsHashTable();
895}
896
897
898bool Object::IsDictionary() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000899 return IsHashTable() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000900 this != HeapObject::cast(this)->GetHeap()->string_table();
Steve Blocka7e24c12009-10-30 11:49:00 +0000901}
902
903
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000904bool Object::IsNameDictionary() const {
905 return IsDictionary();
Steve Blocka7e24c12009-10-30 11:49:00 +0000906}
907
908
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000909bool Object::IsGlobalDictionary() const { return IsDictionary(); }
910
911
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000912bool Object::IsSeededNumberDictionary() const {
913 return IsDictionary();
914}
915
916
917bool Object::IsUnseededNumberDictionary() const {
918 return IsDictionary();
919}
920
921
922bool Object::IsStringTable() const {
923 return IsHashTable();
924}
925
926
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000927bool Object::IsNormalizedMapCache() const {
928 return NormalizedMapCache::IsNormalizedMapCache(this);
929}
930
931
932int NormalizedMapCache::GetIndex(Handle<Map> map) {
933 return map->Hash() % NormalizedMapCache::kEntries;
934}
935
936
937bool NormalizedMapCache::IsNormalizedMapCache(const Object* obj) {
938 if (!obj->IsFixedArray()) return false;
939 if (FixedArray::cast(obj)->length() != NormalizedMapCache::kEntries) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100940 return false;
941 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000942#ifdef VERIFY_HEAP
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100943 if (FLAG_verify_heap) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000944 reinterpret_cast<NormalizedMapCache*>(const_cast<Object*>(obj))->
945 NormalizedMapCacheVerify();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100946 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100947#endif
948 return true;
949}
950
951
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000952bool Object::IsCompilationCacheTable() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000953 return IsHashTable();
954}
955
956
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000957bool Object::IsCodeCacheHashTable() const {
Steve Block6ded16b2010-05-10 14:33:55 +0100958 return IsHashTable();
959}
960
961
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000962bool Object::IsPolymorphicCodeCacheHashTable() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000963 return IsHashTable();
964}
965
966
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000967bool Object::IsMapCache() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000968 return IsHashTable();
969}
970
971
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000972bool Object::IsObjectHashTable() const {
973 return IsHashTable();
974}
975
976
977bool Object::IsOrderedHashTable() const {
978 return IsHeapObject() &&
979 HeapObject::cast(this)->map() ==
980 HeapObject::cast(this)->GetHeap()->ordered_hash_table_map();
981}
982
983
984bool Object::IsOrderedHashSet() const {
985 return IsOrderedHashTable();
986}
987
988
989bool Object::IsOrderedHashMap() const {
990 return IsOrderedHashTable();
991}
992
993
994bool Object::IsPrimitive() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000995 return IsSmi() || HeapObject::cast(this)->map()->IsPrimitiveMap();
Steve Blocka7e24c12009-10-30 11:49:00 +0000996}
997
998
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000999bool Object::IsJSGlobalProxy() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00001000 bool result = IsHeapObject() &&
1001 (HeapObject::cast(this)->map()->instance_type() ==
1002 JS_GLOBAL_PROXY_TYPE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001003 DCHECK(!result ||
1004 HeapObject::cast(this)->map()->is_access_check_needed());
Steve Blocka7e24c12009-10-30 11:49:00 +00001005 return result;
1006}
1007
1008
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001009TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +00001010
1011
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001012bool Object::IsUndetectableObject() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00001013 return IsHeapObject()
1014 && HeapObject::cast(this)->map()->is_undetectable();
1015}
1016
1017
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001018bool Object::IsAccessCheckNeeded() const {
1019 if (!IsHeapObject()) return false;
1020 if (IsJSGlobalProxy()) {
1021 const JSGlobalProxy* proxy = JSGlobalProxy::cast(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001022 JSGlobalObject* global = proxy->GetIsolate()->context()->global_object();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001023 return proxy->IsDetachedFrom(global);
1024 }
1025 return HeapObject::cast(this)->map()->is_access_check_needed();
Steve Blocka7e24c12009-10-30 11:49:00 +00001026}
1027
1028
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001029bool Object::IsStruct() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00001030 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001040#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
1041 bool Object::Is##Name() const { \
1042 return Object::IsHeapObject() \
Steve Blocka7e24c12009-10-30 11:49:00 +00001043 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
1044 }
1045 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
1046#undef MAKE_STRUCT_PREDICATE
1047
1048
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001049bool Object::IsUndefined() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001050 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
Steve Blocka7e24c12009-10-30 11:49:00 +00001051}
1052
1053
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001054bool Object::IsNull() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001055 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
1056}
1057
1058
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001059bool Object::IsTheHole() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001060 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
Steve Blocka7e24c12009-10-30 11:49:00 +00001061}
1062
1063
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001064bool Object::IsException() const {
1065 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kException;
1066}
1067
1068
1069bool Object::IsUninitialized() const {
1070 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUninitialized;
1071}
1072
1073
1074bool Object::IsTrue() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001075 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
Steve Blocka7e24c12009-10-30 11:49:00 +00001076}
1077
1078
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001079bool Object::IsFalse() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001080 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
Steve Blocka7e24c12009-10-30 11:49:00 +00001081}
1082
1083
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001084bool Object::IsArgumentsMarker() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001085 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
Ben Murdoch086aeea2011-05-13 15:57:08 +01001086}
1087
1088
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001089double Object::Number() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001090 DCHECK(IsNumber());
Steve Blocka7e24c12009-10-30 11:49:00 +00001091 return IsSmi()
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001092 ? static_cast<double>(reinterpret_cast<const Smi*>(this)->value())
1093 : reinterpret_cast<const HeapNumber*>(this)->value();
Steve Blocka7e24c12009-10-30 11:49:00 +00001094}
1095
1096
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001097bool Object::IsNaN() const {
1098 return this->IsHeapNumber() && std::isnan(HeapNumber::cast(this)->value());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001099}
1100
1101
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001102bool Object::IsMinusZero() const {
1103 return this->IsHeapNumber() &&
1104 i::IsMinusZero(HeapNumber::cast(this)->value());
1105}
1106
1107
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001108Representation 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();
Steve Blocka7e24c12009-10-30 11:49:00 +00001121 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001122}
1123
1124
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001125ElementsKind Object::OptimalElementsKind() {
1126 if (IsSmi()) return FAST_SMI_ELEMENTS;
1127 if (IsNumber()) return FAST_DOUBLE_ELEMENTS;
1128 return FAST_ELEMENTS;
1129}
1130
1131
1132bool 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001147MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
1148 Handle<Object> object) {
1149 return ToObject(
1150 isolate, object, handle(isolate->context()->native_context(), isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00001151}
1152
1153
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001154// static
1155MaybeHandle<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
Steve Blocka7e24c12009-10-30 11:49:00 +00001162bool Object::HasSpecificClassOf(String* name) {
1163 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
1164}
1165
1166
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001167MaybeHandle<Object> Object::GetProperty(Handle<Object> object,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001168 Handle<Name> name,
1169 LanguageMode language_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001170 LookupIterator it(object, name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001171 return GetProperty(&it, language_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001172}
1173
1174
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001175MaybeHandle<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);
Steve Blocka7e24c12009-10-30 11:49:00 +00001180}
1181
1182
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001183MaybeHandle<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
1193MaybeHandle<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));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001202 return PrototypeIterator::GetCurrent(iter);
1203}
1204
1205
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001206MaybeHandle<Object> Object::GetProperty(Isolate* isolate, Handle<Object> object,
1207 const char* name,
1208 LanguageMode language_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001209 Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001210 return GetProperty(object, str, language_mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00001211}
1212
1213
1214#define FIELD_ADDR(p, offset) \
1215 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
1216
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001217#define FIELD_ADDR_CONST(p, offset) \
1218 (reinterpret_cast<const byte*>(p) + offset - kHeapObjectTag)
1219
Steve Blocka7e24c12009-10-30 11:49:00 +00001220#define READ_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001221 (*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))))
Steve Blocka7e24c12009-10-30 11:49:00 +00001230
1231#define WRITE_FIELD(p, offset, value) \
1232 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
1233
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001234#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
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001244#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 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001250
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001251#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 } \
Steve Blocka7e24c12009-10-30 11:49:00 +00001260 }
1261
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001262#define READ_DOUBLE_FIELD(p, offset) \
1263 ReadDoubleValue(FIELD_ADDR_CONST(p, offset))
Steve Blocka7e24c12009-10-30 11:49:00 +00001264
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001265#define WRITE_DOUBLE_FIELD(p, offset, value) \
1266 WriteDoubleValue(FIELD_ADDR(p, offset), value)
Steve Blocka7e24c12009-10-30 11:49:00 +00001267
1268#define READ_INT_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001269 (*reinterpret_cast<const int*>(FIELD_ADDR_CONST(p, offset)))
Steve Blocka7e24c12009-10-30 11:49:00 +00001270
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) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001275 (*reinterpret_cast<const intptr_t*>(FIELD_ADDR_CONST(p, offset)))
Steve Blocka7e24c12009-10-30 11:49:00 +00001276
1277#define WRITE_INTPTR_FIELD(p, offset, value) \
1278 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
1279
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001280#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
Steve Blocka7e24c12009-10-30 11:49:00 +00001304#define READ_UINT32_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001305 (*reinterpret_cast<const uint32_t*>(FIELD_ADDR_CONST(p, offset)))
Steve Blocka7e24c12009-10-30 11:49:00 +00001306
1307#define WRITE_UINT32_FIELD(p, offset, value) \
1308 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
1309
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001310#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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001316#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
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001328#define READ_INT64_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001329 (*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset)))
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001330
1331#define WRITE_INT64_FIELD(p, offset, value) \
1332 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
1333
Steve Blocka7e24c12009-10-30 11:49:00 +00001334#define READ_BYTE_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001335 (*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))))
Steve Blocka7e24c12009-10-30 11:49:00 +00001340
1341#define WRITE_BYTE_FIELD(p, offset, value) \
1342 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
1343
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001344#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));
Steve Blocka7e24c12009-10-30 11:49:00 +00001348
1349Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001350 return reinterpret_cast<Object**>(FIELD_ADDR(obj, byte_offset));
Steve Blocka7e24c12009-10-30 11:49:00 +00001351}
1352
1353
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001354MapWord MapWord::FromMap(const Map* map) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001355 return MapWord(reinterpret_cast<uintptr_t>(map));
1356}
1357
1358
1359Map* MapWord::ToMap() {
1360 return reinterpret_cast<Map*>(value_);
1361}
1362
1363
1364bool MapWord::IsForwardingAddress() {
1365 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
1366}
1367
1368
1369MapWord MapWord::FromForwardingAddress(HeapObject* object) {
1370 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1371 return MapWord(reinterpret_cast<uintptr_t>(raw));
1372}
1373
1374
1375HeapObject* MapWord::ToForwardingAddress() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001376 DCHECK(IsForwardingAddress());
Steve Blocka7e24c12009-10-30 11:49:00 +00001377 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
1378}
1379
1380
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001381#ifdef VERIFY_HEAP
Steve Blocka7e24c12009-10-30 11:49:00 +00001382void HeapObject::VerifyObjectField(int offset) {
1383 VerifyPointer(READ_FIELD(this, offset));
1384}
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001385
1386void HeapObject::VerifySmiField(int offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001387 CHECK(READ_FIELD(this, offset)->IsSmi());
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001388}
Steve Blocka7e24c12009-10-30 11:49:00 +00001389#endif
1390
1391
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001392Heap* HeapObject::GetHeap() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001393 Heap* heap =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001394 MemoryChunk::FromAddress(reinterpret_cast<const byte*>(this))->heap();
1395 SLOW_DCHECK(heap != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001396 return heap;
Steve Block44f0eee2011-05-26 01:26:41 +01001397}
1398
1399
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001400Isolate* HeapObject::GetIsolate() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001401 return GetHeap()->isolate();
1402}
1403
1404
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001405Map* 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
Steve Blocka7e24c12009-10-30 11:49:00 +00001412 return map_word().ToMap();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001413#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00001414}
1415
1416
1417void HeapObject::set_map(Map* value) {
1418 set_map_word(MapWord::FromMap(value));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001419 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001427Map* HeapObject::synchronized_map() {
1428 return synchronized_map_word().ToMap();
1429}
1430
1431
1432void 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
1442void HeapObject::synchronized_set_map_no_write_barrier(Map* value) {
1443 synchronized_set_map_word(MapWord::FromMap(value));
1444}
1445
1446
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001447// Unsafe accessor omitting write barrier.
1448void HeapObject::set_map_no_write_barrier(Map* value) {
1449 set_map_word(MapWord::FromMap(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00001450}
1451
1452
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001453MapWord HeapObject::map_word() const {
1454 return MapWord(
1455 reinterpret_cast<uintptr_t>(NOBARRIER_READ_FIELD(this, kMapOffset)));
Steve Blocka7e24c12009-10-30 11:49:00 +00001456}
1457
1458
1459void HeapObject::set_map_word(MapWord map_word) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001460 NOBARRIER_WRITE_FIELD(
1461 this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1462}
1463
1464
1465MapWord HeapObject::synchronized_map_word() const {
1466 return MapWord(
1467 reinterpret_cast<uintptr_t>(ACQUIRE_READ_FIELD(this, kMapOffset)));
1468}
1469
1470
1471void HeapObject::synchronized_set_map_word(MapWord map_word) {
1472 RELEASE_WRITE_FIELD(
1473 this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
Steve Blocka7e24c12009-10-30 11:49:00 +00001474}
1475
1476
Steve Blocka7e24c12009-10-30 11:49:00 +00001477int HeapObject::Size() {
1478 return SizeFromMap(map());
1479}
1480
1481
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001482double HeapNumber::value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00001483 return READ_DOUBLE_FIELD(this, kValueOffset);
1484}
1485
1486
1487void HeapNumber::set_value(double value) {
1488 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1489}
1490
1491
Steve Block6ded16b2010-05-10 14:33:55 +01001492int HeapNumber::get_exponent() {
1493 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1494 kExponentShift) - kExponentBias;
1495}
1496
1497
1498int HeapNumber::get_sign() {
1499 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1500}
1501
1502
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001503bool 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
1516bool 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 }
1528SIMD128_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
1568SIMD128_NUMERIC_LANE_FNS(Float32x4, float, 4, FLOAT, kFloatSize)
1569SIMD128_NUMERIC_LANE_FNS(Int32x4, int32_t, 4, INT32, kInt32Size)
1570SIMD128_NUMERIC_LANE_FNS(Uint32x4, uint32_t, 4, UINT32, kInt32Size)
1571SIMD128_NUMERIC_LANE_FNS(Int16x8, int16_t, 8, INT16, kShortSize)
1572SIMD128_NUMERIC_LANE_FNS(Uint16x8, uint16_t, 8, UINT16, kShortSize)
1573SIMD128_NUMERIC_LANE_FNS(Int8x16, int8_t, 16, INT8, kCharSize)
1574SIMD128_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
1593SIMD128_BOOLEAN_LANE_FNS(Bool32x4, int32_t, 4, INT32, kInt32Size)
1594SIMD128_BOOLEAN_LANE_FNS(Bool16x8, int16_t, 8, INT16, kShortSize)
1595SIMD128_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
1602ACCESSORS(JSReceiver, properties, FixedArray, kPropertiesOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00001603
1604
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001605Object** FixedArray::GetFirstElementAddress() {
1606 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1607}
1608
1609
1610bool 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001621FixedArrayBase* JSObject::elements() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00001622 Object* array = READ_FIELD(this, kElementsOffset);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001623 return static_cast<FixedArrayBase*>(array);
Steve Blocka7e24c12009-10-30 11:49:00 +00001624}
1625
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001626
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001627void AllocationSite::Initialize() {
1628 set_transition_info(Smi::FromInt(0));
1629 SetElementsKind(GetInitialFastElementsKind());
1630 set_nested_site(Smi::FromInt(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001631 set_pretenure_data(0);
1632 set_pretenure_create_count(0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001633 set_dependent_code(DependentCode::cast(GetHeap()->empty_fixed_array()),
1634 SKIP_WRITE_BARRIER);
1635}
1636
1637
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001638bool AllocationSite::IsZombie() { return pretenure_decision() == kZombie; }
1639
1640
1641bool AllocationSite::IsMaybeTenure() {
1642 return pretenure_decision() == kMaybeTenure;
1643}
1644
1645
1646bool AllocationSite::PretenuringDecisionMade() {
1647 return pretenure_decision() != kUndecided;
1648}
1649
1650
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001651void AllocationSite::MarkZombie() {
1652 DCHECK(!IsZombie());
1653 Initialize();
1654 set_pretenure_decision(kZombie);
1655}
1656
1657
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001658ElementsKind AllocationSite::GetElementsKind() {
1659 DCHECK(!SitePointsToLiteral());
1660 int value = Smi::cast(transition_info())->value();
1661 return ElementsKindBits::decode(value);
1662}
1663
1664
1665void 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
1672bool AllocationSite::CanInlineCall() {
1673 int value = Smi::cast(transition_info())->value();
1674 return DoNotInlineBit::decode(value) == 0;
1675}
1676
1677
1678void 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
1685bool 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001693// Heuristic: We only need to create allocation site info if the boilerplate
1694// elements kind is the initial elements kind.
1695AllocationSiteMode AllocationSite::GetMode(
1696 ElementsKind boilerplate_elements_kind) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001697 if (IsFastSmiElementsKind(boilerplate_elements_kind)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001698 return TRACK_ALLOCATION_SITE;
1699 }
1700
1701 return DONT_TRACK_ALLOCATION_SITE;
1702}
1703
1704
1705AllocationSiteMode AllocationSite::GetMode(ElementsKind from,
1706 ElementsKind to) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001707 if (IsFastSmiElementsKind(from) &&
1708 IsMoreGeneralElementsKindTransition(from, to)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001709 return TRACK_ALLOCATION_SITE;
1710 }
1711
1712 return DONT_TRACK_ALLOCATION_SITE;
1713}
1714
1715
1716inline 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001726AllocationSite::PretenureDecision AllocationSite::pretenure_decision() {
1727 int value = pretenure_data();
1728 return PretenureDecisionBits::decode(value);
1729}
1730
1731
1732void AllocationSite::set_pretenure_decision(PretenureDecision decision) {
1733 int value = pretenure_data();
1734 set_pretenure_data(PretenureDecisionBits::update(value, decision));
1735}
1736
1737
1738bool AllocationSite::deopt_dependent_code() {
1739 int value = pretenure_data();
1740 return DeoptDependentCodeBit::decode(value);
1741}
1742
1743
1744void AllocationSite::set_deopt_dependent_code(bool deopt) {
1745 int value = pretenure_data();
1746 set_pretenure_data(DeoptDependentCodeBit::update(value, deopt));
1747}
1748
1749
1750int AllocationSite::memento_found_count() {
1751 int value = pretenure_data();
1752 return MementoFoundCountBits::decode(value);
1753}
1754
1755
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001756inline void AllocationSite::set_memento_found_count(int count) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001757 int value = pretenure_data();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001758 // Verify that we can count more mementos than we can possibly find in one
1759 // new space collection.
1760 DCHECK((GetHeap()->MaxSemiSpaceSize() /
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001761 (Heap::kMinObjectSizeInWords * kPointerSize +
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001762 AllocationMemento::kSize)) < MementoFoundCountBits::kMax);
1763 DCHECK(count < MementoFoundCountBits::kMax);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001764 set_pretenure_data(MementoFoundCountBits::update(value, count));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001765}
1766
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001767
1768int AllocationSite::memento_create_count() { return pretenure_create_count(); }
1769
1770
1771void AllocationSite::set_memento_create_count(int count) {
1772 set_pretenure_create_count(count);
1773}
1774
1775
1776bool AllocationSite::IncrementMementoFoundCount(int increment) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001777 if (IsZombie()) return false;
1778
1779 int value = memento_found_count();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001780 set_memento_found_count(value + increment);
1781 return memento_found_count() >= kPretenureMinimumCreated;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001782}
1783
1784
1785inline 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
1792inline 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;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001808 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001809 set_pretenure_decision(kMaybeTenure);
1810 } else {
1811 set_pretenure_decision(kDontTenure);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001812 }
1813 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001814 return false;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001815}
1816
1817
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001818inline 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);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001832 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001833
1834 if (FLAG_trace_pretenuring_statistics) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001835 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()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001841 }
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;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001847}
1848
1849
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001850bool AllocationMemento::IsValid() {
1851 return allocation_site()->IsAllocationSite() &&
1852 !AllocationSite::cast(allocation_site())->IsZombie();
1853}
1854
1855
1856AllocationSite* AllocationMemento::GetAllocationSite() {
1857 DCHECK(IsValid());
1858 return AllocationSite::cast(allocation_site());
1859}
1860
1861
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001862void 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
1875void JSObject::EnsureCanContainElements(Handle<JSObject> object,
1876 Object** objects,
1877 uint32_t count,
1878 EnsureElementsMode mode) {
1879 ElementsKind current_kind = object->map()->elements_kind();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001880 ElementsKind target_kind = current_kind;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001881 {
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 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001908 }
1909 }
1910 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001911 if (target_kind != current_kind) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001912 TransitionElementsKind(object, target_kind);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001913 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001914}
1915
1916
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001917void 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());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001925 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1926 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1927 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001928 Object** objects =
1929 Handle<FixedArray>::cast(elements)->GetFirstElementAddress();
1930 EnsureCanContainElements(object, objects, length, mode);
1931 return;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001932 }
1933
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001934 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;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001944 }
1945 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001946 TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001947 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001948}
1949
1950
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001951void 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
1966void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001967 WRITE_FIELD(this, kElementsOffset, value);
1968 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
1969}
1970
Steve Blocka7e24c12009-10-30 11:49:00 +00001971
Steve Blocka7e24c12009-10-30 11:49:00 +00001972void JSObject::initialize_elements() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001973 FixedArrayBase* elements = map()->GetInitialElements();
1974 WRITE_FIELD(this, kElementsOffset, elements);
Steve Blocka7e24c12009-10-30 11:49:00 +00001975}
1976
1977
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001978InterceptorInfo* 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);
Steve Block8defd9f2010-07-08 12:39:36 +01001985}
1986
1987
Steve Blocka7e24c12009-10-30 11:49:00 +00001988ACCESSORS(Oddball, to_string, String, kToStringOffset)
1989ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001990ACCESSORS(Oddball, type_of, String, kTypeOfOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00001991
1992
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001993byte Oddball::kind() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001994 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
Steve Block44f0eee2011-05-26 01:26:41 +01001995}
1996
1997
1998void Oddball::set_kind(byte value) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001999 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
Steve Block44f0eee2011-05-26 01:26:41 +01002000}
2001
2002
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002003// static
2004Handle<Object> Oddball::ToNumber(Handle<Oddball> input) {
2005 return handle(input->to_number(), input->GetIsolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00002006}
2007
2008
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002009ACCESSORS(Cell, value, Object, kValueOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002010ACCESSORS(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002011ACCESSORS(PropertyCell, property_details_raw, Object, kDetailsOffset)
2012ACCESSORS(PropertyCell, value, Object, kValueOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002013
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002014
2015PropertyDetails PropertyCell::property_details() {
2016 return PropertyDetails(Smi::cast(property_details_raw()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002017}
2018
2019
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002020void PropertyCell::set_property_details(PropertyDetails details) {
2021 set_property_details_raw(details.AsSmi());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002022}
2023
Steve Blocka7e24c12009-10-30 11:49:00 +00002024
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002025Object* WeakCell::value() const { return READ_FIELD(this, kValueOffset); }
2026
2027
2028void WeakCell::clear() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002029 // 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());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002033 WRITE_FIELD(this, kValueOffset, Smi::FromInt(0));
2034}
2035
2036
2037void WeakCell::initialize(HeapObject* val) {
2038 WRITE_FIELD(this, kValueOffset, val);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002039 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 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002046}
2047
2048
2049bool WeakCell::cleared() const { return value() == Smi::FromInt(0); }
2050
2051
2052Object* WeakCell::next() const { return READ_FIELD(this, kNextOffset); }
2053
2054
2055void 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002063void 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
2069bool WeakCell::next_cleared() { return next()->IsTheHole(); }
2070
2071
2072int JSObject::GetHeaderSize() { return GetHeaderSize(map()->instance_type()); }
2073
2074
2075int JSObject::GetHeaderSize(InstanceType type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002076 // 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) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002081 case JS_GENERATOR_OBJECT_TYPE:
2082 return JSGeneratorObject::kSize;
2083 case JS_MODULE_TYPE:
2084 return JSModule::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002085 case JS_GLOBAL_PROXY_TYPE:
2086 return JSGlobalProxy::kSize;
2087 case JS_GLOBAL_OBJECT_TYPE:
2088 return JSGlobalObject::kSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002089 case JS_BOUND_FUNCTION_TYPE:
2090 return JSBoundFunction::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002091 case JS_FUNCTION_TYPE:
2092 return JSFunction::kSize;
2093 case JS_VALUE_TYPE:
2094 return JSValue::kSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002095 case JS_DATE_TYPE:
2096 return JSDate::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002097 case JS_ARRAY_TYPE:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002098 return JSArray::kSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002099 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;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002113 case JS_ITERATOR_RESULT_TYPE:
2114 return JSIteratorResult::kSize;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002115 case JS_WEAK_MAP_TYPE:
2116 return JSWeakMap::kSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002117 case JS_WEAK_SET_TYPE:
2118 return JSWeakSet::kSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002119 case JS_PROMISE_TYPE:
2120 return JSObject::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002121 case JS_REGEXP_TYPE:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002122 return JSRegExp::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002123 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
2124 return JSObject::kHeaderSize;
Steve Block1e0659c2011-05-24 12:43:12 +01002125 case JS_MESSAGE_OBJECT_TYPE:
2126 return JSMessageObject::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002127 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002128 UNREACHABLE();
Steve Blocka7e24c12009-10-30 11:49:00 +00002129 return 0;
2130 }
2131}
2132
2133
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002134int 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();
Steve Blocka7e24c12009-10-30 11:49:00 +00002140}
2141
2142
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002143int JSObject::GetInternalFieldCount() { return GetInternalFieldCount(map()); }
2144
2145
Steve Block44f0eee2011-05-26 01:26:41 +01002146int JSObject::GetInternalFieldOffset(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002147 DCHECK(index < GetInternalFieldCount() && index >= 0);
Steve Block44f0eee2011-05-26 01:26:41 +01002148 return GetHeaderSize() + (kPointerSize * index);
2149}
2150
2151
Steve Blocka7e24c12009-10-30 11:49:00 +00002152Object* JSObject::GetInternalField(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002153 DCHECK(index < GetInternalFieldCount() && index >= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002154 // 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
2161void JSObject::SetInternalField(int index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002162 DCHECK(index < GetInternalFieldCount() && index >= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002163 // 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);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002168 WRITE_BARRIER(GetHeap(), this, offset, value);
2169}
2170
2171
2172void JSObject::SetInternalField(int index, Smi* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002173 DCHECK(index < GetInternalFieldCount() && index >= 0);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002174 // 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);
Steve Blocka7e24c12009-10-30 11:49:00 +00002179}
2180
2181
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002182bool JSObject::IsUnboxedDoubleField(FieldIndex index) {
2183 if (!FLAG_unbox_double_fields) return false;
2184 return map()->IsUnboxedDoubleField(index);
2185}
2186
2187
2188bool 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
Steve Blocka7e24c12009-10-30 11:49:00 +00002195// 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.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002198Object* JSObject::RawFastPropertyAt(FieldIndex index) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002199 DCHECK(!IsUnboxedDoubleField(index));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002200 if (index.is_inobject()) {
2201 return READ_FIELD(this, index.offset());
Steve Blocka7e24c12009-10-30 11:49:00 +00002202 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002203 return properties()->get(index.outobject_array_index());
Steve Blocka7e24c12009-10-30 11:49:00 +00002204 }
2205}
2206
2207
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002208double JSObject::RawFastDoublePropertyAt(FieldIndex index) {
2209 DCHECK(IsUnboxedDoubleField(index));
2210 return READ_DOUBLE_FIELD(this, index.offset());
2211}
2212
2213
2214void JSObject::RawFastPropertyAtPut(FieldIndex index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002215 if (index.is_inobject()) {
2216 int offset = index.offset();
Steve Blocka7e24c12009-10-30 11:49:00 +00002217 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002218 WRITE_BARRIER(GetHeap(), this, offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002219 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002220 properties()->set(index.outobject_array_index(), value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002221 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002222}
2223
2224
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002225void JSObject::RawFastDoublePropertyAtPut(FieldIndex index, double value) {
2226 WRITE_DOUBLE_FIELD(this, index.offset(), value);
2227}
2228
2229
2230void 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002240void 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
Steve Block44f0eee2011-05-26 01:26:41 +01002265int JSObject::GetInObjectPropertyOffset(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002266 return map()->GetInObjectPropertyOffset(index);
Steve Block44f0eee2011-05-26 01:26:41 +01002267}
2268
2269
Steve Blocka7e24c12009-10-30 11:49:00 +00002270Object* JSObject::InObjectPropertyAt(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002271 int offset = GetInObjectPropertyOffset(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002272 return READ_FIELD(this, offset);
2273}
2274
2275
2276Object* JSObject::InObjectPropertyAtPut(int index,
2277 Object* value,
2278 WriteBarrierMode mode) {
2279 // Adjust for the number of properties stored in the object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002280 int offset = GetInObjectPropertyOffset(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002281 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002282 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002283 return value;
2284}
2285
2286
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002287void JSObject::InitializeBody(Map* map, int start_offset,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002288 Object* pre_allocated_value,
2289 Object* filler_value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002290 DCHECK(!filler_value->IsHeapObject() ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002291 !GetHeap()->InNewSpace(filler_value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002292 DCHECK(!pre_allocated_value->IsHeapObject() ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002293 !GetHeap()->InNewSpace(pre_allocated_value));
2294 int size = map->instance_size();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002295 int offset = start_offset;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002296 if (filler_value != pre_allocated_value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002297 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) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002301 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;
Steve Blocka7e24c12009-10-30 11:49:00 +00002308 }
2309}
2310
2311
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002312bool 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;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002316 int limit = Max(minimum, GetInObjectProperties());
2317 int external = NumberOfFields() - GetInObjectProperties();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002318 return external > limit;
Steve Block8defd9f2010-07-08 12:39:36 +01002319}
2320
2321
Steve Blocka7e24c12009-10-30 11:49:00 +00002322void Struct::InitializeBody(int object_size) {
Steve Block44f0eee2011-05-26 01:26:41 +01002323 Object* value = GetHeap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00002324 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
2325 WRITE_FIELD(this, offset, value);
2326 }
2327}
2328
2329
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002330bool Object::ToArrayLength(uint32_t* index) { return Object::ToUint32(index); }
2331
2332
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002333bool Object::ToArrayIndex(uint32_t* index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002334 return Object::ToUint32(index) && *index != kMaxUInt32;
Steve Blocka7e24c12009-10-30 11:49:00 +00002335}
2336
2337
2338bool 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());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002345 if (index >= static_cast<uint32_t>(str->length())) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002346
2347 return true;
2348}
2349
2350
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002351void Object::VerifyApiCallResultType() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002352#if DEBUG
2353 if (!(IsSmi() || IsString() || IsSymbol() || IsJSReceiver() ||
2354 IsHeapNumber() || IsSimd128Value() || IsUndefined() || IsTrue() ||
2355 IsFalse() || IsNull())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002356 FATAL("API call returned invalid object");
2357 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002358#endif // DEBUG
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002359}
2360
2361
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002362Object* FixedArray::get(int index) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002363 SLOW_DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00002364 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
2365}
2366
2367
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002368Handle<Object> FixedArray::get(Handle<FixedArray> array, int index) {
2369 return handle(array->get(index), array->GetIsolate());
2370}
2371
2372
2373bool FixedArray::is_the_hole(int index) {
2374 return get(index) == GetHeap()->the_hole_value();
2375}
2376
2377
Steve Blocka7e24c12009-10-30 11:49:00 +00002378void FixedArray::set(int index, Smi* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002379 DCHECK(map() != GetHeap()->fixed_cow_array_map());
2380 DCHECK(index >= 0 && index < this->length());
2381 DCHECK(reinterpret_cast<Object*>(value)->IsSmi());
Steve Blocka7e24c12009-10-30 11:49:00 +00002382 int offset = kHeaderSize + index * kPointerSize;
2383 WRITE_FIELD(this, offset, value);
2384}
2385
2386
2387void FixedArray::set(int index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002388 DCHECK_NE(GetHeap()->fixed_cow_array_map(), map());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002389 DCHECK(IsFixedArray());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002390 DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00002391 int offset = kHeaderSize + index * kPointerSize;
2392 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002393 WRITE_BARRIER(GetHeap(), this, offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002394}
2395
2396
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002397double FixedDoubleArray::get_scalar(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002398 DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2399 map() != GetHeap()->fixed_array_map());
2400 DCHECK(index >= 0 && index < this->length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002401 DCHECK(!is_the_hole(index));
2402 return READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002403}
2404
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002405
2406uint64_t FixedDoubleArray::get_representation(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002407 DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2408 map() != GetHeap()->fixed_array_map());
2409 DCHECK(index >= 0 && index < this->length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002410 int offset = kHeaderSize + index * kDoubleSize;
2411 return READ_UINT64_FIELD(this, offset);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002412}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002413
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002414
2415Handle<Object> FixedDoubleArray::get(Handle<FixedDoubleArray> array,
2416 int index) {
2417 if (array->is_the_hole(index)) {
2418 return array->GetIsolate()->factory()->the_hole_value();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002419 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002420 return array->GetIsolate()->factory()->NewNumber(array->get_scalar(index));
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002421 }
2422}
2423
2424
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002425void FixedDoubleArray::set(int index, double value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002426 DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2427 map() != GetHeap()->fixed_array_map());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002428 int offset = kHeaderSize + index * kDoubleSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002429 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));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002435}
2436
2437
2438void FixedDoubleArray::set_the_hole(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002439 DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2440 map() != GetHeap()->fixed_array_map());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002441 int offset = kHeaderSize + index * kDoubleSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002442 WRITE_UINT64_FIELD(this, offset, kHoleNanInt64);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002443}
2444
2445
2446bool FixedDoubleArray::is_the_hole(int index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002447 return get_representation(index) == kHoleNanInt64;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002448}
2449
2450
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002451double* FixedDoubleArray::data_start() {
2452 return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
2453}
2454
2455
2456void FixedDoubleArray::FillWithHoles(int from, int to) {
2457 for (int i = from; i < to; i++) {
2458 set_the_hole(i);
2459 }
2460}
2461
2462
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002463Object* WeakFixedArray::Get(int index) const {
2464 Object* raw = FixedArray::cast(this)->get(index + kFirstIndex);
2465 if (raw->IsSmi()) return raw;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002466 DCHECK(raw->IsWeakCell());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002467 return WeakCell::cast(raw)->value();
2468}
2469
2470
2471bool WeakFixedArray::IsEmptySlot(int index) const {
2472 DCHECK(index < Length());
2473 return Get(index)->IsSmi();
2474}
2475
2476
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002477void WeakFixedArray::Clear(int index) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002478 FixedArray::cast(this)->set(index + kFirstIndex, Smi::FromInt(0));
2479}
2480
2481
2482int WeakFixedArray::Length() const {
2483 return FixedArray::cast(this)->length() - kFirstIndex;
2484}
2485
2486
2487int WeakFixedArray::last_used_index() const {
2488 return Smi::cast(FixedArray::cast(this)->get(kLastUsedIndexIndex))->value();
2489}
2490
2491
2492void WeakFixedArray::set_last_used_index(int index) {
2493 FixedArray::cast(this)->set(kLastUsedIndexIndex, Smi::FromInt(index));
2494}
2495
2496
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002497template <class T>
2498T* 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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002505 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002506 list_ = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002507 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002508 return NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002509}
2510
2511
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002512int ArrayList::Length() {
2513 if (FixedArray::cast(this)->length() == 0) return 0;
2514 return Smi::cast(FixedArray::cast(this)->get(kLengthIndex))->value();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002515}
2516
2517
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002518void ArrayList::SetLength(int length) {
2519 return FixedArray::cast(this)->set(kLengthIndex, Smi::FromInt(length));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002520}
2521
2522
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002523Object* ArrayList::Get(int index) {
2524 return FixedArray::cast(this)->get(kFirstIndex + index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002525}
2526
2527
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002528Object** ArrayList::Slot(int index) {
2529 return data_start() + kFirstIndex + index;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002530}
2531
2532
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002533void ArrayList::Set(int index, Object* obj) {
2534 FixedArray::cast(this)->set(kFirstIndex + index, obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002535}
2536
2537
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002538void ArrayList::Clear(int index, Object* undefined) {
2539 DCHECK(undefined->IsUndefined());
2540 FixedArray::cast(this)
2541 ->set(kFirstIndex + index, undefined, SKIP_WRITE_BARRIER);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002542}
2543
2544
2545WriteBarrierMode HeapObject::GetWriteBarrierMode(
2546 const DisallowHeapAllocation& promise) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002547 Heap* heap = GetHeap();
2548 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
2549 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
Steve Blocka7e24c12009-10-30 11:49:00 +00002550 return UPDATE_WRITE_BARRIER;
2551}
2552
2553
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002554AllocationAlignment 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;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002564}
2565
2566
Steve Blocka7e24c12009-10-30 11:49:00 +00002567void FixedArray::set(int index,
2568 Object* value,
2569 WriteBarrierMode mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002570 DCHECK(map() != GetHeap()->fixed_cow_array_map());
2571 DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00002572 int offset = kHeaderSize + index * kPointerSize;
2573 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002574 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002575}
2576
2577
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002578void FixedArray::NoWriteBarrierSet(FixedArray* array,
2579 int index,
2580 Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002581 DCHECK(array->map() != array->GetHeap()->fixed_cow_array_map());
2582 DCHECK(index >= 0 && index < array->length());
2583 DCHECK(!array->GetHeap()->InNewSpace(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00002584 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
2585}
2586
2587
2588void FixedArray::set_undefined(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002589 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());
Steve Blocka7e24c12009-10-30 11:49:00 +00002595}
2596
2597
2598void FixedArray::set_null(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002599 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());
Steve Blocka7e24c12009-10-30 11:49:00 +00002604}
2605
2606
2607void FixedArray::set_the_hole(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002608 DCHECK(map() != GetHeap()->fixed_cow_array_map());
2609 DCHECK(index >= 0 && index < this->length());
2610 DCHECK(!GetHeap()->InNewSpace(GetHeap()->the_hole_value()));
Steve Block44f0eee2011-05-26 01:26:41 +01002611 WRITE_FIELD(this,
2612 kHeaderSize + index * kPointerSize,
2613 GetHeap()->the_hole_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002614}
2615
2616
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002617void FixedArray::FillWithHoles(int from, int to) {
2618 for (int i = from; i < to; i++) {
2619 set_the_hole(i);
2620 }
Iain Merrick75681382010-08-19 15:07:18 +01002621}
2622
2623
Steve Block6ded16b2010-05-10 14:33:55 +01002624Object** FixedArray::data_start() {
2625 return HeapObject::RawField(this, kHeaderSize);
2626}
2627
2628
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002629Object** FixedArray::RawFieldOfElementAt(int index) {
2630 return HeapObject::RawField(this, OffsetOfElementAt(index));
2631}
2632
2633
Steve Blocka7e24c12009-10-30 11:49:00 +00002634bool DescriptorArray::IsEmpty() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002635 DCHECK(length() >= kFirstIndex ||
2636 this == GetHeap()->empty_descriptor_array());
2637 return length() < kFirstIndex;
Ben Murdoch257744e2011-11-30 15:57:28 +00002638}
2639
2640
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002641int 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
2648int DescriptorArray::number_of_descriptors_storage() {
2649 int len = length();
2650 return len == 0 ? 0 : (len - kFirstIndex) / kDescriptorSize;
2651}
2652
2653
2654int DescriptorArray::NumberOfSlackDescriptors() {
2655 return number_of_descriptors_storage() - number_of_descriptors();
2656}
2657
2658
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002659void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
2660 WRITE_FIELD(
2661 this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors));
Steve Blocka7e24c12009-10-30 11:49:00 +00002662}
2663
2664
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002665inline int DescriptorArray::number_of_entries() {
2666 return number_of_descriptors();
2667}
2668
2669
2670bool DescriptorArray::HasEnumCache() {
2671 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi();
2672}
2673
2674
2675void DescriptorArray::CopyEnumCacheFrom(DescriptorArray* array) {
2676 set(kEnumCacheIndex, array->get(kEnumCacheIndex));
2677}
2678
2679
2680FixedArray* DescriptorArray::GetEnumCache() {
2681 DCHECK(HasEnumCache());
2682 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
2683 return FixedArray::cast(bridge->get(kEnumCacheBridgeCacheIndex));
2684}
2685
2686
2687bool 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
2696FixedArray* DescriptorArray::GetEnumIndicesCache() {
2697 DCHECK(HasEnumIndicesCache());
2698 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
2699 return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex));
2700}
2701
2702
2703Object** DescriptorArray::GetEnumCacheSlot() {
2704 DCHECK(HasEnumCache());
2705 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
2706 kEnumCacheOffset);
2707}
2708
2709
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002710// 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.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002713template <SearchMode search_mode, typename T>
2714int 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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002717 uint32_t hash = name->Hash();
2718 int limit = high;
2719
2720 DCHECK(low <= high);
2721
2722 while (low != high) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002723 int mid = low + (high - low) / 2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002724 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);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002737 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 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002744 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
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002752 if (out_insertion_index != NULL) *out_insertion_index = limit + 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002753 return T::kNotFound;
Steve Blocka7e24c12009-10-30 11:49:00 +00002754}
2755
2756
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002757// Perform a linear search in this fixed array. len is the number of entry
2758// indices that are valid.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002759template <SearchMode search_mode, typename T>
2760int LinearSearch(T* array, Name* name, int len, int valid_entries,
2761 int* out_insertion_index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002762 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();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002768 if (current_hash > hash) {
2769 if (out_insertion_index != NULL) *out_insertion_index = sorted_index;
2770 return T::kNotFound;
2771 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002772 if (current_hash == hash && entry->Equals(name)) return sorted_index;
2773 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002774 if (out_insertion_index != NULL) *out_insertion_index = len;
2775 return T::kNotFound;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002776 } else {
2777 DCHECK(len >= valid_entries);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002778 DCHECK_NULL(out_insertion_index); // Not supported here.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002779 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 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002784 return T::kNotFound;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002785 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002786}
Steve Blocka7e24c12009-10-30 11:49:00 +00002787
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002788
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002789template <SearchMode search_mode, typename T>
2790int Search(T* array, Name* name, int valid_entries, int* out_insertion_index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002791 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();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002798 if (nof == 0) {
2799 if (out_insertion_index != NULL) *out_insertion_index = 0;
2800 return T::kNotFound;
2801 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002802
2803 // Fast case: do linear search for small arrays.
2804 const int kMaxElementsForLinearSearch = 8;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002805 if ((search_mode == ALL_ENTRIES &&
2806 nof <= kMaxElementsForLinearSearch) ||
2807 (search_mode == VALID_ENTRIES &&
2808 valid_entries <= (kMaxElementsForLinearSearch * 3))) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002809 return LinearSearch<search_mode>(array, name, nof, valid_entries,
2810 out_insertion_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002811 }
2812
2813 // Slow case: perform binary search.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002814 return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries,
2815 out_insertion_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002816}
2817
2818
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002819int DescriptorArray::Search(Name* name, int valid_descriptors) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002820 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors, NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002821}
2822
2823
2824int 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
Iain Merrick75681382010-08-19 15:07:18 +01002831 if (number == DescriptorLookupCache::kAbsent) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002832 number = Search(name, number_of_own_descriptors);
2833 cache->Update(map, name, number);
Iain Merrick75681382010-08-19 15:07:18 +01002834 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002835
Iain Merrick75681382010-08-19 15:07:18 +01002836 return number;
2837}
2838
2839
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002840PropertyDetails Map::GetLastDescriptorDetails() {
2841 return instance_descriptors()->GetDetails(LastAdded());
2842}
2843
2844
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002845int Map::LastAdded() {
2846 int number_of_own_descriptors = NumberOfOwnDescriptors();
2847 DCHECK(number_of_own_descriptors > 0);
2848 return number_of_own_descriptors - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002849}
2850
2851
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002852int Map::NumberOfOwnDescriptors() {
2853 return NumberOfOwnDescriptorsBits::decode(bit_field3());
2854}
2855
2856
2857void Map::SetNumberOfOwnDescriptors(int number) {
2858 DCHECK(number <= instance_descriptors()->number_of_descriptors());
2859 set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number));
2860}
2861
2862
2863int Map::EnumLength() { return EnumLengthBits::decode(bit_field3()); }
2864
2865
2866void 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));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002873}
2874
2875
2876FixedArrayBase* 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();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002881 } else if (has_fixed_typed_array_elements()) {
2882 FixedTypedArrayBase* empty_array =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002883 GetHeap()->EmptyFixedTypedArrayForMap(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002884 DCHECK(!GetHeap()->InNewSpace(empty_array));
2885 return empty_array;
2886 } else {
2887 UNREACHABLE();
2888 }
2889 return NULL;
2890}
2891
2892
2893Object** DescriptorArray::GetKeySlot(int descriptor_number) {
2894 DCHECK(descriptor_number < number_of_descriptors());
2895 return RawFieldOfElementAt(ToKeyIndex(descriptor_number));
2896}
2897
2898
2899Object** DescriptorArray::GetDescriptorStartSlot(int descriptor_number) {
2900 return GetKeySlot(descriptor_number);
2901}
2902
2903
2904Object** DescriptorArray::GetDescriptorEndSlot(int descriptor_number) {
2905 return GetValueSlot(descriptor_number - 1) + 1;
2906}
2907
2908
2909Name* DescriptorArray::GetKey(int descriptor_number) {
2910 DCHECK(descriptor_number < number_of_descriptors());
2911 return Name::cast(get(ToKeyIndex(descriptor_number)));
2912}
2913
2914
2915int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
2916 return GetDetails(descriptor_number).pointer();
2917}
2918
2919
2920Name* DescriptorArray::GetSortedKey(int descriptor_number) {
2921 return GetKey(GetSortedKeyIndex(descriptor_number));
2922}
2923
2924
2925void 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
2931void 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
2940Object** DescriptorArray::GetValueSlot(int descriptor_number) {
2941 DCHECK(descriptor_number < number_of_descriptors());
2942 return RawFieldOfElementAt(ToValueIndex(descriptor_number));
2943}
2944
2945
2946int DescriptorArray::GetValueOffset(int descriptor_number) {
2947 return OffsetOfElementAt(ToValueIndex(descriptor_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00002948}
2949
2950
2951Object* DescriptorArray::GetValue(int descriptor_number) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002952 DCHECK(descriptor_number < number_of_descriptors());
2953 return get(ToValueIndex(descriptor_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00002954}
2955
2956
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002957void DescriptorArray::SetValue(int descriptor_index, Object* value) {
2958 set(ToValueIndex(descriptor_index), value);
2959}
2960
2961
2962PropertyDetails 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));
Steve Blocka7e24c12009-10-30 11:49:00 +00002966}
2967
2968
2969PropertyType DescriptorArray::GetType(int descriptor_number) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002970 return GetDetails(descriptor_number).type();
Steve Blocka7e24c12009-10-30 11:49:00 +00002971}
2972
2973
2974int DescriptorArray::GetFieldIndex(int descriptor_number) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002975 DCHECK(GetDetails(descriptor_number).location() == kField);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002976 return GetDetails(descriptor_number).field_index();
Steve Blocka7e24c12009-10-30 11:49:00 +00002977}
2978
2979
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002980HeapType* DescriptorArray::GetFieldType(int descriptor_number) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002981 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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002988}
2989
2990
2991Object* DescriptorArray::GetConstant(int descriptor_number) {
2992 return GetValue(descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002993}
2994
2995
2996Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002997 DCHECK(GetType(descriptor_number) == ACCESSOR_CONSTANT);
Steve Blocka7e24c12009-10-30 11:49:00 +00002998 return GetValue(descriptor_number);
2999}
3000
3001
3002AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003003 DCHECK(GetType(descriptor_number) == ACCESSOR_CONSTANT);
Ben Murdoch257744e2011-11-30 15:57:28 +00003004 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003005 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
Steve Blocka7e24c12009-10-30 11:49:00 +00003006}
3007
3008
Steve Blocka7e24c12009-10-30 11:49:00 +00003009void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003010 desc->Init(handle(GetKey(descriptor_number), GetIsolate()),
3011 handle(GetValue(descriptor_number), GetIsolate()),
3012 GetDetails(descriptor_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00003013}
3014
3015
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003016void DescriptorArray::SetDescriptor(int descriptor_number, Descriptor* desc) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003017 // Range check.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003018 DCHECK(descriptor_number < number_of_descriptors());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003019 set(ToKeyIndex(descriptor_number), *desc->GetKey());
3020 set(ToValueIndex(descriptor_number), *desc->GetValue());
3021 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
Steve Blocka7e24c12009-10-30 11:49:00 +00003022}
3023
3024
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003025void 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
3035void 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
3055void DescriptorArray::SwapSortedKeys(int first, int second) {
3056 int first_key = GetSortedKeyIndex(first);
3057 SetSortedKey(first, GetSortedKeyIndex(second));
3058 SetSortedKey(second, first_key);
Ben Murdoch85b71792012-04-11 18:30:58 +01003059}
3060
3061
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003062PropertyType DescriptorArray::Entry::type() { return descs_->GetType(index_); }
3063
3064
3065Object* DescriptorArray::Entry::GetCallbackObject() {
3066 return descs_->GetValue(index_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003067}
3068
3069
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003070int HashTableBase::NumberOfElements() {
3071 return Smi::cast(get(kNumberOfElementsIndex))->value();
Steve Blocka7e24c12009-10-30 11:49:00 +00003072}
3073
3074
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003075int HashTableBase::NumberOfDeletedElements() {
3076 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
3077}
3078
3079
3080int HashTableBase::Capacity() {
3081 return Smi::cast(get(kCapacityIndex))->value();
3082}
3083
3084
3085void HashTableBase::ElementAdded() {
3086 SetNumberOfElements(NumberOfElements() + 1);
3087}
3088
3089
3090void HashTableBase::ElementRemoved() {
3091 SetNumberOfElements(NumberOfElements() - 1);
3092 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
3093}
3094
3095
3096void HashTableBase::ElementsRemoved(int n) {
3097 SetNumberOfElements(NumberOfElements() - n);
3098 SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
3099}
3100
3101
3102// static
3103int HashTableBase::ComputeCapacity(int at_least_space_for) {
3104 const int kMinCapacity = 4;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003105 int capacity = base::bits::RoundUpToPowerOfTwo32(at_least_space_for * 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003106 return Max(capacity, kMinCapacity);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003107}
3108
3109
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003110bool HashTableBase::IsKey(Object* k) {
3111 return !k->IsTheHole() && !k->IsUndefined();
3112}
3113
3114
3115void HashTableBase::SetNumberOfElements(int nof) {
3116 set(kNumberOfElementsIndex, Smi::FromInt(nof));
3117}
3118
3119
3120void HashTableBase::SetNumberOfDeletedElements(int nod) {
3121 set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod));
3122}
3123
3124
3125template <typename Derived, typename Shape, typename Key>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003126int HashTable<Derived, Shape, Key>::FindEntry(Key key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003127 return FindEntry(GetIsolate(), key);
3128}
3129
3130
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003131template<typename Derived, typename Shape, typename Key>
3132int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003133 return FindEntry(isolate, key, HashTable::Hash(key));
3134}
3135
3136
3137// Find entry for key otherwise return kNotFound.
3138template <typename Derived, typename Shape, typename Key>
3139int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key,
3140 int32_t hash) {
Steve Block44f0eee2011-05-26 01:26:41 +01003141 uint32_t capacity = Capacity();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003142 uint32_t entry = FirstProbe(hash, capacity);
Steve Block44f0eee2011-05-26 01:26:41 +01003143 uint32_t count = 1;
3144 // EnsureCapacity will guarantee the hash table is never full.
3145 while (true) {
3146 Object* element = KeyAt(entry);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003147 // Empty entry. Uses raw unchecked accessors because it is called by the
3148 // string table during bootstrapping.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003149 if (element == isolate->heap()->root(Heap::kUndefinedValueRootIndex)) break;
3150 if (element != isolate->heap()->root(Heap::kTheHoleValueRootIndex) &&
Steve Block44f0eee2011-05-26 01:26:41 +01003151 Shape::IsMatch(key, element)) return entry;
3152 entry = NextProbe(entry, count++, capacity);
3153 }
3154 return kNotFound;
3155}
3156
3157
Ben Murdochc7cc0282012-03-05 14:35:55 +00003158bool SeededNumberDictionary::requires_slow_elements() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003159 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003165
Ben Murdochc7cc0282012-03-05 14:35:55 +00003166uint32_t SeededNumberDictionary::max_number_key() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003167 DCHECK(!requires_slow_elements());
Steve Blocka7e24c12009-10-30 11:49:00 +00003168 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003174
Ben Murdochc7cc0282012-03-05 14:35:55 +00003175void SeededNumberDictionary::set_requires_slow_elements() {
Leon Clarke4515c472010-02-03 11:58:03 +00003176 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
Steve Blocka7e24c12009-10-30 11:49:00 +00003177}
3178
3179
3180// ------------------------------------
3181// Cast operations
3182
3183
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003184CAST_ACCESSOR(AccessorInfo)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003185CAST_ACCESSOR(ArrayList)
3186CAST_ACCESSOR(Bool16x8)
3187CAST_ACCESSOR(Bool32x4)
3188CAST_ACCESSOR(Bool8x16)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003189CAST_ACCESSOR(ByteArray)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003190CAST_ACCESSOR(BytecodeArray)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003191CAST_ACCESSOR(Cell)
3192CAST_ACCESSOR(Code)
3193CAST_ACCESSOR(CodeCacheHashTable)
3194CAST_ACCESSOR(CompilationCacheTable)
3195CAST_ACCESSOR(ConsString)
Ben Murdochb0fe1622011-05-05 13:52:32 +01003196CAST_ACCESSOR(DeoptimizationInputData)
3197CAST_ACCESSOR(DeoptimizationOutputData)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003198CAST_ACCESSOR(DependentCode)
3199CAST_ACCESSOR(DescriptorArray)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003200CAST_ACCESSOR(ExternalOneByteString)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003201CAST_ACCESSOR(ExternalString)
3202CAST_ACCESSOR(ExternalTwoByteString)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003203CAST_ACCESSOR(FixedArray)
3204CAST_ACCESSOR(FixedArrayBase)
3205CAST_ACCESSOR(FixedDoubleArray)
3206CAST_ACCESSOR(FixedTypedArrayBase)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003207CAST_ACCESSOR(Float32x4)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003208CAST_ACCESSOR(Foreign)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003209CAST_ACCESSOR(GlobalDictionary)
3210CAST_ACCESSOR(HandlerTable)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003211CAST_ACCESSOR(HeapObject)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003212CAST_ACCESSOR(Int16x8)
3213CAST_ACCESSOR(Int32x4)
3214CAST_ACCESSOR(Int8x16)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003215CAST_ACCESSOR(JSArray)
3216CAST_ACCESSOR(JSArrayBuffer)
3217CAST_ACCESSOR(JSArrayBufferView)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003218CAST_ACCESSOR(JSBoundFunction)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003219CAST_ACCESSOR(JSDataView)
3220CAST_ACCESSOR(JSDate)
3221CAST_ACCESSOR(JSFunction)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003222CAST_ACCESSOR(JSGeneratorObject)
3223CAST_ACCESSOR(JSGlobalObject)
3224CAST_ACCESSOR(JSGlobalProxy)
3225CAST_ACCESSOR(JSMap)
3226CAST_ACCESSOR(JSMapIterator)
3227CAST_ACCESSOR(JSMessageObject)
3228CAST_ACCESSOR(JSModule)
3229CAST_ACCESSOR(JSObject)
3230CAST_ACCESSOR(JSProxy)
3231CAST_ACCESSOR(JSReceiver)
3232CAST_ACCESSOR(JSRegExp)
3233CAST_ACCESSOR(JSSet)
3234CAST_ACCESSOR(JSSetIterator)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003235CAST_ACCESSOR(JSIteratorResult)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003236CAST_ACCESSOR(JSTypedArray)
3237CAST_ACCESSOR(JSValue)
3238CAST_ACCESSOR(JSWeakMap)
3239CAST_ACCESSOR(JSWeakSet)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003240CAST_ACCESSOR(LayoutDescriptor)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003241CAST_ACCESSOR(Map)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003242CAST_ACCESSOR(Name)
3243CAST_ACCESSOR(NameDictionary)
3244CAST_ACCESSOR(NormalizedMapCache)
3245CAST_ACCESSOR(Object)
3246CAST_ACCESSOR(ObjectHashTable)
3247CAST_ACCESSOR(Oddball)
3248CAST_ACCESSOR(OrderedHashMap)
3249CAST_ACCESSOR(OrderedHashSet)
3250CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
3251CAST_ACCESSOR(PropertyCell)
3252CAST_ACCESSOR(ScopeInfo)
3253CAST_ACCESSOR(SeededNumberDictionary)
3254CAST_ACCESSOR(SeqOneByteString)
3255CAST_ACCESSOR(SeqString)
3256CAST_ACCESSOR(SeqTwoByteString)
3257CAST_ACCESSOR(SharedFunctionInfo)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003258CAST_ACCESSOR(Simd128Value)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003259CAST_ACCESSOR(SlicedString)
3260CAST_ACCESSOR(Smi)
3261CAST_ACCESSOR(String)
3262CAST_ACCESSOR(StringTable)
Steve Blocka7e24c12009-10-30 11:49:00 +00003263CAST_ACCESSOR(Struct)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003264CAST_ACCESSOR(Symbol)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003265CAST_ACCESSOR(Uint16x8)
3266CAST_ACCESSOR(Uint32x4)
3267CAST_ACCESSOR(Uint8x16)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003268CAST_ACCESSOR(UnseededNumberDictionary)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003269CAST_ACCESSOR(WeakCell)
3270CAST_ACCESSOR(WeakFixedArray)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003271CAST_ACCESSOR(WeakHashTable)
3272
3273
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003274// static
3275template <class Traits>
3276STATIC_CONST_MEMBER_DEFINITION const InstanceType
3277 FixedTypedArray<Traits>::kInstanceType;
3278
3279
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003280template <class Traits>
3281FixedTypedArray<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
3289template <class Traits>
3290const FixedTypedArray<Traits>*
3291FixedTypedArray<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}
Steve Blocka7e24c12009-10-30 11:49:00 +00003297
3298
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003299#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
3307DEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
3308DEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
3309DEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
3310DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrAstId, Smi)
3311DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
3312DEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi)
3313DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
3314DEFINE_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
3327DEFINE_DEOPT_ENTRY_ACCESSORS(AstIdRaw, Smi)
3328DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
3329DEFINE_DEOPT_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
3330DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
3331
3332#undef DEFINE_DEOPT_ENTRY_ACCESSORS
3333
3334
3335BailoutId DeoptimizationInputData::AstId(int i) {
3336 return BailoutId(AstIdRaw(i)->value());
3337}
3338
3339
3340void DeoptimizationInputData::SetAstId(int i, BailoutId value) {
3341 SetAstIdRaw(i, Smi::FromInt(value.ToInt()));
3342}
3343
3344
3345int DeoptimizationInputData::DeoptCount() {
3346 return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
3347}
3348
3349
3350int DeoptimizationOutputData::DeoptPoints() { return length() / 2; }
3351
3352
3353BailoutId DeoptimizationOutputData::AstId(int index) {
3354 return BailoutId(Smi::cast(get(index * 2))->value());
3355}
3356
3357
3358void DeoptimizationOutputData::SetAstId(int index, BailoutId id) {
3359 set(index * 2, Smi::FromInt(id.ToInt()));
3360}
3361
3362
3363Smi* DeoptimizationOutputData::PcAndState(int index) {
3364 return Smi::cast(get(1 + index * 2));
3365}
3366
3367
3368void DeoptimizationOutputData::SetPcAndState(int index, Smi* offset) {
3369 set(1 + index * 2, offset);
3370}
3371
3372
3373Object* LiteralsArray::get(int index) const { return FixedArray::get(index); }
3374
3375
3376void LiteralsArray::set(int index, Object* value) {
3377 FixedArray::set(index, value);
3378}
3379
3380
3381void LiteralsArray::set(int index, Smi* value) {
3382 FixedArray::set(index, value);
3383}
3384
3385
3386void LiteralsArray::set(int index, Object* value, WriteBarrierMode mode) {
3387 FixedArray::set(index, value, mode);
3388}
3389
3390
3391LiteralsArray* LiteralsArray::cast(Object* object) {
3392 SLOW_DCHECK(object->IsLiteralsArray());
3393 return reinterpret_cast<LiteralsArray*>(object);
3394}
3395
3396
3397TypeFeedbackVector* LiteralsArray::feedback_vector() const {
3398 return TypeFeedbackVector::cast(get(kVectorIndex));
3399}
3400
3401
3402void LiteralsArray::set_feedback_vector(TypeFeedbackVector* vector) {
3403 set(kVectorIndex, vector);
3404}
3405
3406
3407Object* LiteralsArray::literal(int literal_index) const {
3408 return get(kFirstLiteralIndex + literal_index);
3409}
3410
3411
3412void LiteralsArray::set_literal(int literal_index, Object* literal) {
3413 set(kFirstLiteralIndex + literal_index, literal);
3414}
3415
3416
3417int LiteralsArray::literals_count() const {
3418 return length() - kFirstLiteralIndex;
3419}
3420
3421
3422void HandlerTable::SetRangeStart(int index, int value) {
3423 set(index * kRangeEntrySize + kRangeStartIndex, Smi::FromInt(value));
3424}
3425
3426
3427void HandlerTable::SetRangeEnd(int index, int value) {
3428 set(index * kRangeEntrySize + kRangeEndIndex, Smi::FromInt(value));
3429}
3430
3431
3432void 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
3440void HandlerTable::SetRangeDepth(int index, int value) {
3441 set(index * kRangeEntrySize + kRangeDepthIndex, Smi::FromInt(value));
3442}
3443
3444
3445void HandlerTable::SetReturnOffset(int index, int value) {
3446 set(index * kReturnEntrySize + kReturnOffsetIndex, Smi::FromInt(value));
3447}
3448
3449
3450void 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
Steve Blocka7e24c12009-10-30 11:49:00 +00003458#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
3459 STRUCT_LIST(MAKE_STRUCT_CAST)
3460#undef MAKE_STRUCT_CAST
3461
3462
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003463template <typename Derived, typename Shape, typename Key>
3464HashTable<Derived, Shape, Key>*
3465HashTable<Derived, Shape, Key>::cast(Object* obj) {
3466 SLOW_DCHECK(obj->IsHashTable());
Steve Blocka7e24c12009-10-30 11:49:00 +00003467 return reinterpret_cast<HashTable*>(obj);
3468}
3469
3470
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003471template <typename Derived, typename Shape, typename Key>
3472const HashTable<Derived, Shape, Key>*
3473HashTable<Derived, Shape, Key>::cast(const Object* obj) {
3474 SLOW_DCHECK(obj->IsHashTable());
3475 return reinterpret_cast<const HashTable*>(obj);
3476}
3477
3478
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003479SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003480SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
3481
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003482SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003483NOBARRIER_SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00003484
Steve Block6ded16b2010-05-10 14:33:55 +01003485SMI_ACCESSORS(String, length, kLengthOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003486SYNCHRONIZED_SMI_ACCESSORS(String, length, kLengthOffset)
Steve Blockd0582a62009-12-15 09:54:21 +00003487
3488
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003489int FreeSpace::Size() { return size(); }
3490
3491
3492FreeSpace* 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
3501void 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
3511FreeSpace* FreeSpace::cast(HeapObject* o) {
3512 SLOW_DCHECK(!o->GetHeap()->deserialization_complete() || o->IsFreeSpace());
3513 return reinterpret_cast<FreeSpace*>(o);
3514}
3515
3516
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003517uint32_t Name::hash_field() {
Steve Blockd0582a62009-12-15 09:54:21 +00003518 return READ_UINT32_FIELD(this, kHashFieldOffset);
3519}
3520
3521
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003522void Name::set_hash_field(uint32_t value) {
Steve Blockd0582a62009-12-15 09:54:21 +00003523 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01003524#if V8_HOST_ARCH_64_BIT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003525#if V8_TARGET_LITTLE_ENDIAN
3526 WRITE_UINT32_FIELD(this, kHashFieldSlot + kIntSize, 0);
3527#else
3528 WRITE_UINT32_FIELD(this, kHashFieldSlot, 0);
3529#endif
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01003530#endif
Steve Blockd0582a62009-12-15 09:54:21 +00003531}
3532
3533
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003534bool 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
3544bool 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
3555ACCESSORS(Symbol, name, Object, kNameOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003556SMI_ACCESSORS(Symbol, flags, kFlagsOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003557BOOL_ACCESSORS(Symbol, flags, is_private, kPrivateBit)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003558BOOL_ACCESSORS(Symbol, flags, is_well_known_symbol, kWellKnownSymbolBit)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003559
3560
Steve Blocka7e24c12009-10-30 11:49:00 +00003561bool String::Equals(String* other) {
3562 if (other == this) return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003563 if (this->IsInternalizedString() && other->IsInternalizedString()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003564 return false;
3565 }
3566 return SlowEquals(other);
3567}
3568
3569
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003570bool 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);
Steve Blocka7e24c12009-10-30 11:49:00 +00003576}
3577
3578
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003579Handle<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);
Leon Clarkef7060e22010-06-03 12:02:55 +01003584}
3585
3586
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003587Handle<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
Steve Blocka7e24c12009-10-30 11:49:00 +00003593uint16_t String::Get(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003594 DCHECK(index >= 0 && index < length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003595 switch (StringShape(this).full_representation_tag()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003596 case kSeqStringTag | kOneByteStringTag:
3597 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00003598 case kSeqStringTag | kTwoByteStringTag:
3599 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003600 case kConsStringTag | kOneByteStringTag:
Steve Blocka7e24c12009-10-30 11:49:00 +00003601 case kConsStringTag | kTwoByteStringTag:
3602 return ConsString::cast(this)->ConsStringGet(index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003603 case kExternalStringTag | kOneByteStringTag:
3604 return ExternalOneByteString::cast(this)->ExternalOneByteStringGet(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00003605 case kExternalStringTag | kTwoByteStringTag:
3606 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003607 case kSlicedStringTag | kOneByteStringTag:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003608 case kSlicedStringTag | kTwoByteStringTag:
3609 return SlicedString::cast(this)->SlicedStringGet(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00003610 default:
3611 break;
3612 }
3613
3614 UNREACHABLE();
3615 return 0;
3616}
3617
3618
3619void String::Set(int index, uint16_t value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003620 DCHECK(index >= 0 && index < length());
3621 DCHECK(StringShape(this).IsSequential());
Steve Blocka7e24c12009-10-30 11:49:00 +00003622
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003623 return this->IsOneByteRepresentation()
3624 ? SeqOneByteString::cast(this)->SeqOneByteStringSet(index, value)
Steve Blocka7e24c12009-10-30 11:49:00 +00003625 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
3626}
3627
3628
3629bool String::IsFlat() {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003630 if (!StringShape(this).IsCons()) return true;
3631 return ConsString::cast(this)->second()->length() == 0;
3632}
3633
3634
3635String* String::GetUnderlying() {
3636 // Giving direct access to underlying string only makes sense if the
3637 // wrapping string is already flattened.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003638 DCHECK(this->IsFlat());
3639 DCHECK(StringShape(this).IsIndirect());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003640 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
3641 const int kUnderlyingOffset = SlicedString::kParentOffset;
3642 return String::cast(READ_FIELD(this, kUnderlyingOffset));
Steve Blocka7e24c12009-10-30 11:49:00 +00003643}
3644
3645
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003646template<class Visitor>
3647ConsString* 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
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003700template <>
3701inline Vector<const uint8_t> String::GetCharVector() {
3702 String::FlatContent flat = GetFlatContent();
3703 DCHECK(flat.IsOneByte());
3704 return flat.ToOneByteVector();
3705}
3706
3707
3708template <>
3709inline Vector<const uc16> String::GetCharVector() {
3710 String::FlatContent flat = GetFlatContent();
3711 DCHECK(flat.IsTwoByte());
3712 return flat.ToUC16Vector();
3713}
3714
3715
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003716uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
3717 DCHECK(index >= 0 && index < length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003718 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
3719}
3720
3721
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003722void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) {
3723 DCHECK(index >= 0 && index < length() && value <= kMaxOneByteCharCode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003724 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
3725 static_cast<byte>(value));
3726}
3727
3728
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003729Address SeqOneByteString::GetCharsAddress() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003730 return FIELD_ADDR(this, kHeaderSize);
3731}
3732
3733
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003734uint8_t* SeqOneByteString::GetChars() {
3735 return reinterpret_cast<uint8_t*>(GetCharsAddress());
Steve Blocka7e24c12009-10-30 11:49:00 +00003736}
3737
3738
3739Address SeqTwoByteString::GetCharsAddress() {
3740 return FIELD_ADDR(this, kHeaderSize);
3741}
3742
3743
3744uc16* SeqTwoByteString::GetChars() {
3745 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
3746}
3747
3748
3749uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003750 DCHECK(index >= 0 && index < length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003751 return READ_UINT16_FIELD(this, kHeaderSize + index * kShortSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00003752}
3753
3754
3755void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003756 DCHECK(index >= 0 && index < length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003757 WRITE_UINT16_FIELD(this, kHeaderSize + index * kShortSize, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003758}
3759
3760
3761int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
Steve Block6ded16b2010-05-10 14:33:55 +01003762 return SizeFor(length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003763}
3764
3765
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003766int SeqOneByteString::SeqOneByteStringSize(InstanceType instance_type) {
Steve Block6ded16b2010-05-10 14:33:55 +01003767 return SizeFor(length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003768}
3769
3770
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003771String* SlicedString::parent() {
3772 return String::cast(READ_FIELD(this, kParentOffset));
3773}
3774
3775
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003776void SlicedString::set_parent(String* parent, WriteBarrierMode mode) {
3777 DCHECK(parent->IsSeqString() || parent->IsExternalString());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003778 WRITE_FIELD(this, kParentOffset, parent);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003779 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kParentOffset, parent, mode);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003780}
3781
3782
3783SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
3784
3785
Steve Blocka7e24c12009-10-30 11:49:00 +00003786String* ConsString::first() {
3787 return String::cast(READ_FIELD(this, kFirstOffset));
3788}
3789
3790
3791Object* ConsString::unchecked_first() {
3792 return READ_FIELD(this, kFirstOffset);
3793}
3794
3795
3796void ConsString::set_first(String* value, WriteBarrierMode mode) {
3797 WRITE_FIELD(this, kFirstOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003798 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003799}
3800
3801
3802String* ConsString::second() {
3803 return String::cast(READ_FIELD(this, kSecondOffset));
3804}
3805
3806
3807Object* ConsString::unchecked_second() {
3808 return READ_FIELD(this, kSecondOffset);
3809}
3810
3811
3812void ConsString::set_second(String* value, WriteBarrierMode mode) {
3813 WRITE_FIELD(this, kSecondOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003814 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003815}
3816
3817
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003818bool ExternalString::is_short() {
3819 InstanceType type = map()->instance_type();
3820 return (type & kShortExternalStringMask) == kShortExternalStringTag;
3821}
3822
3823
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003824const ExternalOneByteString::Resource* ExternalOneByteString::resource() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003825 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
3826}
3827
3828
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003829void ExternalOneByteString::update_data_cache() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003830 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003837void ExternalOneByteString::set_resource(
3838 const ExternalOneByteString::Resource* resource) {
3839 DCHECK(IsAligned(reinterpret_cast<intptr_t>(resource), kPointerSize));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003840 *reinterpret_cast<const Resource**>(
3841 FIELD_ADDR(this, kResourceOffset)) = resource;
3842 if (resource != NULL) update_data_cache();
Steve Blocka7e24c12009-10-30 11:49:00 +00003843}
3844
3845
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003846const uint8_t* ExternalOneByteString::GetChars() {
3847 return reinterpret_cast<const uint8_t*>(resource()->data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003848}
3849
3850
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003851uint16_t ExternalOneByteString::ExternalOneByteStringGet(int index) {
3852 DCHECK(index >= 0 && index < length());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003853 return GetChars()[index];
3854}
3855
3856
3857const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003858 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
3859}
3860
3861
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003862void 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
Steve Blocka7e24c12009-10-30 11:49:00 +00003870void ExternalTwoByteString::set_resource(
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003871 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
3878const uint16_t* ExternalTwoByteString::GetChars() {
3879 return resource()->data();
3880}
3881
3882
3883uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003884 DCHECK(index >= 0 && index < length());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003885 return GetChars()[index];
3886}
3887
3888
3889const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
3890 unsigned start) {
3891 return GetChars() + start;
Steve Blocka7e24c12009-10-30 11:49:00 +00003892}
3893
3894
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003895int ConsStringIterator::OffsetForDepth(int depth) { return depth & kDepthMask; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003896
3897
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003898void ConsStringIterator::PushLeft(ConsString* string) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003899 frames_[depth_++ & kDepthMask] = string;
3900}
3901
3902
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003903void ConsStringIterator::PushRight(ConsString* string) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003904 // Inplace update.
3905 frames_[(depth_-1) & kDepthMask] = string;
3906}
3907
3908
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003909void ConsStringIterator::AdjustMaximumDepth() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003910 if (depth_ > maximum_depth_) maximum_depth_ = depth_;
3911}
3912
3913
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003914void ConsStringIterator::Pop() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003915 DCHECK(depth_ > 0);
3916 DCHECK(depth_ <= maximum_depth_);
3917 depth_--;
3918}
3919
3920
3921uint16_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
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003930StringCharacterStream::StringCharacterStream(String* string, int offset)
3931 : is_one_byte_(false) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003932 Reset(string, offset);
3933}
3934
3935
3936void StringCharacterStream::Reset(String* string, int offset) {
3937 buffer8_ = NULL;
3938 end_ = NULL;
3939 ConsString* cons_string = String::VisitFlat(this, string, offset);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003940 iter_.Reset(cons_string, offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003941 if (cons_string != NULL) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003942 string = iter_.Next(&offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003943 if (string != NULL) String::VisitFlat(this, string, offset);
3944 }
3945}
3946
3947
3948bool StringCharacterStream::HasMore() {
3949 if (buffer8_ != end_) return true;
3950 int offset;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003951 String* string = iter_.Next(&offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003952 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
3960void StringCharacterStream::VisitOneByteString(
3961 const uint8_t* chars, int length) {
3962 is_one_byte_ = true;
3963 buffer8_ = chars;
3964 end_ = chars + length;
3965}
3966
3967
3968void 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003976int ByteArray::Size() { return RoundUp(length() + kHeaderSize, kPointerSize); }
Ben Murdochb8e0da22011-05-16 14:20:40 +01003977
3978
Steve Blocka7e24c12009-10-30 11:49:00 +00003979byte ByteArray::get(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003980 DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003981 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
3982}
3983
3984
3985void ByteArray::set(int index, byte value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003986 DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003987 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
3988}
3989
3990
3991int ByteArray::get_int(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003992 DCHECK(index >= 0 && (index * kIntSize) < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003993 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
3994}
3995
3996
3997ByteArray* ByteArray::FromDataStartAddress(Address address) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003998 DCHECK_TAG_ALIGNED(address);
Steve Blocka7e24c12009-10-30 11:49:00 +00003999 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
4000}
4001
4002
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004003int ByteArray::ByteArraySize() { return SizeFor(this->length()); }
4004
4005
Steve Blocka7e24c12009-10-30 11:49:00 +00004006Address ByteArray::GetDataStartAddress() {
4007 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
4008}
4009
4010
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004011byte BytecodeArray::get(int index) {
4012 DCHECK(index >= 0 && index < this->length());
4013 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00004014}
4015
4016
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004017void BytecodeArray::set(int index, byte value) {
4018 DCHECK(index >= 0 && index < this->length());
4019 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004020}
4021
4022
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004023void 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);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004027}
4028
4029
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004030int BytecodeArray::frame_size() const {
4031 return READ_INT_FIELD(this, kFrameSizeOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00004032}
4033
4034
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004035int BytecodeArray::register_count() const {
4036 return frame_size() / kPointerSize;
4037}
4038
4039
4040void 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
4049int 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
4056ACCESSORS(BytecodeArray, constant_pool, FixedArray, kConstantPoolOffset)
4057
4058
4059Address BytecodeArray::GetFirstBytecodeAddress() {
4060 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
4061}
4062
4063
4064int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); }
4065
4066
4067ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset)
4068
4069
4070void* FixedTypedArrayBase::external_pointer() const {
Steve Block3ce2e202009-11-05 08:53:23 +00004071 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
4072 return reinterpret_cast<void*>(ptr);
4073}
4074
4075
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004076void FixedTypedArrayBase::set_external_pointer(void* value,
4077 WriteBarrierMode mode) {
Steve Block3ce2e202009-11-05 08:53:23 +00004078 intptr_t ptr = reinterpret_cast<intptr_t>(value);
4079 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
4080}
4081
4082
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004083void* FixedTypedArrayBase::DataPtr() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004084 return reinterpret_cast<void*>(
4085 reinterpret_cast<intptr_t>(base_pointer()) +
4086 reinterpret_cast<intptr_t>(external_pointer()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004087}
4088
4089
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004090int FixedTypedArrayBase::ElementSize(InstanceType type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004091 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 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004104 return element_size;
4105}
4106
4107
4108int FixedTypedArrayBase::DataSize(InstanceType type) {
4109 if (base_pointer() == Smi::FromInt(0)) return 0;
4110 return length() * ElementSize(type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004111}
4112
4113
4114int FixedTypedArrayBase::DataSize() {
4115 return DataSize(map()->instance_type());
4116}
4117
4118
4119int FixedTypedArrayBase::size() {
4120 return OBJECT_POINTER_ALIGN(kDataOffset + DataSize());
4121}
4122
4123
4124int FixedTypedArrayBase::TypedArraySize(InstanceType type) {
4125 return OBJECT_POINTER_ALIGN(kDataOffset + DataSize(type));
4126}
4127
4128
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004129int FixedTypedArrayBase::TypedArraySize(InstanceType type, int length) {
4130 return OBJECT_POINTER_ALIGN(kDataOffset + length * ElementSize(type));
4131}
4132
4133
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004134uint8_t Uint8ArrayTraits::defaultValue() { return 0; }
4135
4136
4137uint8_t Uint8ClampedArrayTraits::defaultValue() { return 0; }
4138
4139
4140int8_t Int8ArrayTraits::defaultValue() { return 0; }
4141
4142
4143uint16_t Uint16ArrayTraits::defaultValue() { return 0; }
4144
4145
4146int16_t Int16ArrayTraits::defaultValue() { return 0; }
4147
4148
4149uint32_t Uint32ArrayTraits::defaultValue() { return 0; }
4150
4151
4152int32_t Int32ArrayTraits::defaultValue() { return 0; }
4153
4154
4155float Float32ArrayTraits::defaultValue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004156 return std::numeric_limits<float>::quiet_NaN();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004157}
4158
4159
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004160double Float64ArrayTraits::defaultValue() {
4161 return std::numeric_limits<double>::quiet_NaN();
4162}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004163
4164
4165template <class Traits>
4166typename Traits::ElementType FixedTypedArray<Traits>::get_scalar(int index) {
4167 DCHECK((index >= 0) && (index < this->length()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004168 ElementType* ptr = reinterpret_cast<ElementType*>(DataPtr());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004169 return ptr[index];
4170}
4171
4172
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004173template <class Traits>
4174void FixedTypedArray<Traits>::set(int index, ElementType value) {
4175 DCHECK((index >= 0) && (index < this->length()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004176 ElementType* ptr = reinterpret_cast<ElementType*>(DataPtr());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004177 ptr[index] = value;
4178}
4179
4180
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004181template <class Traits>
4182typename Traits::ElementType FixedTypedArray<Traits>::from_int(int value) {
4183 return static_cast<ElementType>(value);
4184}
4185
4186
4187template <> inline
4188uint8_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
4195template <class Traits>
4196typename Traits::ElementType FixedTypedArray<Traits>::from_double(
4197 double value) {
4198 return static_cast<ElementType>(DoubleToInt32(value));
4199}
4200
4201
4202template<> inline
4203uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from_double(double value) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004204 // Handle NaNs and less than zero values which clamp to zero.
4205 if (!(value > 0)) return 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004206 if (value > 0xFF) return 0xFF;
4207 return static_cast<uint8_t>(lrint(value));
4208}
4209
4210
4211template<> inline
4212float FixedTypedArray<Float32ArrayTraits>::from_double(double value) {
4213 return static_cast<float>(value);
4214}
4215
4216
4217template<> inline
4218double FixedTypedArray<Float64ArrayTraits>::from_double(double value) {
4219 return value;
4220}
4221
4222
4223template <class Traits>
4224Handle<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
4231template <class Traits>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004232void FixedTypedArray<Traits>::SetValue(uint32_t index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004233 ElementType cast_value = Traits::defaultValue();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004234 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());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004244 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004245 set(index, cast_value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004246}
4247
4248
4249Handle<Object> Uint8ArrayTraits::ToHandle(Isolate* isolate, uint8_t scalar) {
4250 return handle(Smi::FromInt(scalar), isolate);
4251}
4252
4253
4254Handle<Object> Uint8ClampedArrayTraits::ToHandle(Isolate* isolate,
4255 uint8_t scalar) {
4256 return handle(Smi::FromInt(scalar), isolate);
4257}
4258
4259
4260Handle<Object> Int8ArrayTraits::ToHandle(Isolate* isolate, int8_t scalar) {
4261 return handle(Smi::FromInt(scalar), isolate);
4262}
4263
4264
4265Handle<Object> Uint16ArrayTraits::ToHandle(Isolate* isolate, uint16_t scalar) {
4266 return handle(Smi::FromInt(scalar), isolate);
4267}
4268
4269
4270Handle<Object> Int16ArrayTraits::ToHandle(Isolate* isolate, int16_t scalar) {
4271 return handle(Smi::FromInt(scalar), isolate);
4272}
4273
4274
4275Handle<Object> Uint32ArrayTraits::ToHandle(Isolate* isolate, uint32_t scalar) {
4276 return isolate->factory()->NewNumberFromUint(scalar);
4277}
4278
4279
4280Handle<Object> Int32ArrayTraits::ToHandle(Isolate* isolate, int32_t scalar) {
4281 return isolate->factory()->NewNumberFromInt(scalar);
4282}
4283
4284
4285Handle<Object> Float32ArrayTraits::ToHandle(Isolate* isolate, float scalar) {
4286 return isolate->factory()->NewNumber(scalar);
4287}
4288
4289
4290Handle<Object> Float64ArrayTraits::ToHandle(Isolate* isolate, double scalar) {
4291 return isolate->factory()->NewNumber(scalar);
4292}
4293
4294
Iain Merrick9ac36c92010-09-13 15:29:50 +01004295int Map::visitor_id() {
4296 return READ_BYTE_FIELD(this, kVisitorIdOffset);
4297}
4298
4299
4300void Map::set_visitor_id(int id) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004301 DCHECK(0 <= id && id < 256);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004302 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
4303}
4304
Steve Block3ce2e202009-11-05 08:53:23 +00004305
Steve Blocka7e24c12009-10-30 11:49:00 +00004306int Map::instance_size() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004307 return NOBARRIER_READ_BYTE_FIELD(
4308 this, kInstanceSizeOffset) << kPointerSizeLog2;
Steve Blocka7e24c12009-10-30 11:49:00 +00004309}
4310
4311
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004312int Map::inobject_properties_or_constructor_function_index() {
4313 return READ_BYTE_FIELD(this,
4314 kInObjectPropertiesOrConstructorFunctionIndexOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00004315}
4316
4317
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004318void 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
4325int Map::GetInObjectProperties() {
4326 DCHECK(IsJSObjectMap());
4327 return inobject_properties_or_constructor_function_index();
4328}
4329
4330
4331void Map::SetInObjectProperties(int value) {
4332 DCHECK(IsJSObjectMap());
4333 set_inobject_properties_or_constructor_function_index(value);
4334}
4335
4336
4337int Map::GetConstructorFunctionIndex() {
4338 DCHECK(IsPrimitiveMap());
4339 return inobject_properties_or_constructor_function_index();
4340}
4341
4342
4343void Map::SetConstructorFunctionIndex(int value) {
4344 DCHECK(IsPrimitiveMap());
4345 set_inobject_properties_or_constructor_function_index(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004346}
4347
4348
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004349int Map::GetInObjectPropertyOffset(int index) {
4350 // Adjust for the number of properties stored in the object.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004351 index -= GetInObjectProperties();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004352 DCHECK(index <= 0);
4353 return instance_size() + (index * kPointerSize);
4354}
4355
4356
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004357Handle<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);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004361}
4362
4363
Steve Blocka7e24c12009-10-30 11:49:00 +00004364int HeapObject::SizeFromMap(Map* map) {
Steve Block791712a2010-08-27 10:21:07 +01004365 int instance_size = map->instance_size();
4366 if (instance_size != kVariableSizeSentinel) return instance_size;
Steve Blocka7e24c12009-10-30 11:49:00 +00004367 // Only inline the most frequent cases.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004368 InstanceType instance_type = map->instance_type();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004369 if (instance_type == FIXED_ARRAY_TYPE ||
4370 instance_type == TRANSITION_ARRAY_TYPE) {
4371 return FixedArray::SizeFor(
4372 reinterpret_cast<FixedArray*>(this)->synchronized_length());
Steve Blocka7e24c12009-10-30 11:49:00 +00004373 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004374 if (instance_type == ONE_BYTE_STRING_TYPE ||
4375 instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004376 // Strings may get concurrently truncated, hence we have to access its
4377 // length synchronized.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004378 return SeqOneByteString::SizeFor(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004379 reinterpret_cast<SeqOneByteString*>(this)->synchronized_length());
Steve Block791712a2010-08-27 10:21:07 +01004380 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004381 if (instance_type == BYTE_ARRAY_TYPE) {
4382 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
4383 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004384 if (instance_type == BYTECODE_ARRAY_TYPE) {
4385 return reinterpret_cast<BytecodeArray*>(this)->BytecodeArraySize();
4386 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004387 if (instance_type == FREE_SPACE_TYPE) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004388 return reinterpret_cast<FreeSpace*>(this)->nobarrier_size();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004389 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004390 if (instance_type == STRING_TYPE ||
4391 instance_type == INTERNALIZED_STRING_TYPE) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004392 // Strings may get concurrently truncated, hence we have to access its
4393 // length synchronized.
Steve Block791712a2010-08-27 10:21:07 +01004394 return SeqTwoByteString::SizeFor(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004395 reinterpret_cast<SeqTwoByteString*>(this)->synchronized_length());
Steve Block791712a2010-08-27 10:21:07 +01004396 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004397 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
4398 return FixedDoubleArray::SizeFor(
4399 reinterpret_cast<FixedDoubleArray*>(this)->length());
4400 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004401 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);
Steve Block791712a2010-08-27 10:21:07 +01004407 return reinterpret_cast<Code*>(this)->CodeSize();
Steve Blocka7e24c12009-10-30 11:49:00 +00004408}
4409
4410
4411void Map::set_instance_size(int value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004412 DCHECK_EQ(0, value & (kPointerSize - 1));
Steve Blocka7e24c12009-10-30 11:49:00 +00004413 value >>= kPointerSizeLog2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004414 DCHECK(0 <= value && value < 256);
4415 NOBARRIER_WRITE_BYTE_FIELD(
4416 this, kInstanceSizeOffset, static_cast<byte>(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00004417}
4418
4419
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004420void Map::clear_unused() { WRITE_BYTE_FIELD(this, kUnusedOffset, 0); }
Steve Blocka7e24c12009-10-30 11:49:00 +00004421
4422
4423InstanceType Map::instance_type() {
4424 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
4425}
4426
4427
4428void Map::set_instance_type(InstanceType value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004429 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
4430}
4431
4432
4433int Map::unused_property_fields() {
4434 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
4435}
4436
4437
4438void Map::set_unused_property_fields(int value) {
4439 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
4440}
4441
4442
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004443byte Map::bit_field() const { return READ_BYTE_FIELD(this, kBitFieldOffset); }
Steve Blocka7e24c12009-10-30 11:49:00 +00004444
4445
4446void Map::set_bit_field(byte value) {
4447 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
4448}
4449
4450
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004451byte Map::bit_field2() const { return READ_BYTE_FIELD(this, kBitField2Offset); }
Steve Blocka7e24c12009-10-30 11:49:00 +00004452
4453
4454void Map::set_bit_field2(byte value) {
4455 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
4456}
4457
4458
4459void 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
4468bool Map::has_non_instance_prototype() {
4469 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
4470}
4471
4472
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004473void Map::set_is_constructor() {
4474 set_bit_field(bit_field() | (1 << kIsConstructor));
Steve Block6ded16b2010-05-10 14:33:55 +01004475}
4476
4477
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004478bool Map::is_constructor() const {
4479 return ((1 << kIsConstructor) & bit_field()) != 0;
4480}
4481
4482
4483void Map::set_is_hidden_prototype() {
4484 set_bit_field3(IsHiddenPrototype::update(bit_field3(), true));
4485}
4486
4487
4488bool Map::is_hidden_prototype() const {
4489 return IsHiddenPrototype::decode(bit_field3());
4490}
4491
4492
4493void Map::set_has_indexed_interceptor() {
4494 set_bit_field(bit_field() | (1 << kHasIndexedInterceptor));
4495}
4496
4497
4498bool Map::has_indexed_interceptor() {
4499 return ((1 << kHasIndexedInterceptor) & bit_field()) != 0;
4500}
4501
4502
4503void Map::set_is_undetectable() {
4504 set_bit_field(bit_field() | (1 << kIsUndetectable));
4505}
4506
4507
4508bool Map::is_undetectable() {
4509 return ((1 << kIsUndetectable) & bit_field()) != 0;
4510}
4511
4512
4513void Map::set_is_observed() { set_bit_field(bit_field() | (1 << kIsObserved)); }
4514
4515bool Map::is_observed() { return ((1 << kIsObserved) & bit_field()) != 0; }
4516
4517
4518void Map::set_has_named_interceptor() {
4519 set_bit_field(bit_field() | (1 << kHasNamedInterceptor));
4520}
4521
4522
4523bool Map::has_named_interceptor() {
4524 return ((1 << kHasNamedInterceptor) & bit_field()) != 0;
Steve Block6ded16b2010-05-10 14:33:55 +01004525}
4526
4527
Steve Blocka7e24c12009-10-30 11:49:00 +00004528void 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
4537bool Map::is_access_check_needed() {
4538 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
4539}
4540
4541
Steve Block8defd9f2010-07-08 12:39:36 +01004542void 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
4550bool Map::is_extensible() {
4551 return ((1 << kIsExtensible) & bit_field2()) != 0;
4552}
4553
4554
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004555void Map::set_is_prototype_map(bool value) {
4556 set_bit_field2(IsPrototypeMapBits::update(bit_field2(), value));
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004557}
4558
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004559bool Map::is_prototype_map() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004560 return IsPrototypeMapBits::decode(bit_field2());
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004561}
4562
4563
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004564void 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
4572ElementsKind Map::elements_kind() {
4573 return Map::ElementsKindBits::decode(bit_field2());
4574}
4575
4576
4577bool Map::has_fast_smi_elements() {
4578 return IsFastSmiElementsKind(elements_kind());
4579}
4580
4581bool Map::has_fast_object_elements() {
4582 return IsFastObjectElementsKind(elements_kind());
4583}
4584
4585bool Map::has_fast_smi_or_object_elements() {
4586 return IsFastSmiOrObjectElementsKind(elements_kind());
4587}
4588
4589bool Map::has_fast_double_elements() {
4590 return IsFastDoubleElementsKind(elements_kind());
4591}
4592
4593bool Map::has_fast_elements() { return IsFastElementsKind(elements_kind()); }
4594
4595bool Map::has_sloppy_arguments_elements() {
4596 return IsSloppyArgumentsElements(elements_kind());
4597}
4598
4599bool Map::has_fixed_typed_array_elements() {
4600 return IsFixedTypedArrayElementsKind(elements_kind());
4601}
4602
4603bool Map::has_dictionary_elements() {
4604 return IsDictionaryElementsKind(elements_kind());
4605}
4606
4607
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004608void 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);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004612}
4613
4614
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004615bool Map::is_dictionary_map() {
4616 return DictionaryMap::decode(bit_field3());
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004617}
4618
Steve Block8defd9f2010-07-08 12:39:36 +01004619
Steve Blocka7e24c12009-10-30 11:49:00 +00004620Code::Flags Code::flags() {
4621 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
4622}
4623
4624
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004625void Map::set_owns_descriptors(bool owns_descriptors) {
4626 set_bit_field3(OwnsDescriptors::update(bit_field3(), owns_descriptors));
4627}
4628
4629
4630bool Map::owns_descriptors() {
4631 return OwnsDescriptors::decode(bit_field3());
4632}
4633
4634
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004635void Map::set_is_callable() { set_bit_field(bit_field() | (1 << kIsCallable)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004636
4637
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004638bool Map::is_callable() const {
4639 return ((1 << kIsCallable) & bit_field()) != 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004640}
4641
4642
4643void Map::deprecate() {
4644 set_bit_field3(Deprecated::update(bit_field3(), true));
4645}
4646
4647
4648bool Map::is_deprecated() {
4649 return Deprecated::decode(bit_field3());
4650}
4651
4652
4653void Map::set_migration_target(bool value) {
4654 set_bit_field3(IsMigrationTarget::update(bit_field3(), value));
4655}
4656
4657
4658bool Map::is_migration_target() {
4659 return IsMigrationTarget::decode(bit_field3());
4660}
4661
4662
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004663void Map::set_is_strong() {
4664 set_bit_field3(IsStrong::update(bit_field3(), true));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004665}
4666
4667
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004668bool Map::is_strong() {
4669 return IsStrong::decode(bit_field3());
4670}
4671
4672
4673void Map::set_new_target_is_base(bool value) {
4674 set_bit_field3(NewTargetIsBase::update(bit_field3(), value));
4675}
4676
4677
4678bool Map::new_target_is_base() { return NewTargetIsBase::decode(bit_field3()); }
4679
4680
4681void Map::set_construction_counter(int value) {
4682 set_bit_field3(ConstructionCounter::update(bit_field3(), value));
4683}
4684
4685
4686int Map::construction_counter() {
4687 return ConstructionCounter::decode(bit_field3());
4688}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004689
4690
4691void Map::mark_unstable() {
4692 set_bit_field3(IsUnstable::update(bit_field3(), true));
4693}
4694
4695
4696bool Map::is_stable() {
4697 return !IsUnstable::decode(bit_field3());
4698}
4699
4700
4701bool Map::has_code_cache() {
4702 return code_cache() != GetIsolate()->heap()->empty_fixed_array();
4703}
4704
4705
4706bool 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;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004714 if (details.type() == DATA_CONSTANT) return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004715 }
4716 return false;
4717}
4718
4719
4720void Map::NotifyLeafMapLayoutChange() {
4721 if (is_stable()) {
4722 mark_unstable();
4723 dependent_code()->DeoptimizeDependentCodeGroup(
4724 GetIsolate(),
4725 DependentCode::kPrototypeCheckGroup);
4726 }
4727}
4728
4729
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004730bool 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
4737bool Map::IsBooleanMap() { return this == GetHeap()->boolean_map(); }
4738bool Map::IsPrimitiveMap() {
4739 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE);
4740 return instance_type() <= LAST_PRIMITIVE_TYPE;
4741}
4742bool Map::IsJSReceiverMap() {
4743 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
4744 return instance_type() >= FIRST_JS_RECEIVER_TYPE;
4745}
4746bool Map::IsJSObjectMap() {
4747 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
4748 return instance_type() >= FIRST_JS_OBJECT_TYPE;
4749}
4750bool Map::IsJSArrayMap() { return instance_type() == JS_ARRAY_TYPE; }
4751bool Map::IsJSFunctionMap() { return instance_type() == JS_FUNCTION_TYPE; }
4752bool Map::IsStringMap() { return instance_type() < FIRST_NONSTRING_TYPE; }
4753bool Map::IsJSProxyMap() { return instance_type() == JS_PROXY_TYPE; }
4754bool Map::IsJSGlobalProxyMap() {
4755 return instance_type() == JS_GLOBAL_PROXY_TYPE;
4756}
4757bool Map::IsJSGlobalObjectMap() {
4758 return instance_type() == JS_GLOBAL_OBJECT_TYPE;
4759}
4760bool Map::IsJSTypedArrayMap() { return instance_type() == JS_TYPED_ARRAY_TYPE; }
4761bool Map::IsJSDataViewMap() { return instance_type() == JS_DATA_VIEW_TYPE; }
4762
4763
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004764bool Map::CanOmitMapChecks() {
4765 return is_stable() && FLAG_omit_map_checks_for_leaf_maps;
4766}
4767
4768
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004769DependentCode* DependentCode::next_link() {
4770 return DependentCode::cast(get(kNextLinkIndex));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004771}
4772
4773
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004774void DependentCode::set_next_link(DependentCode* next) {
4775 set(kNextLinkIndex, next);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004776}
4777
4778
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004779int DependentCode::flags() { return Smi::cast(get(kFlagsIndex))->value(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004780
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004781
4782void DependentCode::set_flags(int flags) {
4783 set(kFlagsIndex, Smi::FromInt(flags));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004784}
4785
4786
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004787int DependentCode::count() { return CountField::decode(flags()); }
4788
4789void DependentCode::set_count(int value) {
4790 set_flags(CountField::update(flags(), value));
4791}
4792
4793
4794DependentCode::DependencyGroup DependentCode::group() {
4795 return static_cast<DependencyGroup>(GroupField::decode(flags()));
4796}
4797
4798
4799void DependentCode::set_group(DependentCode::DependencyGroup group) {
4800 set_flags(GroupField::update(flags(), static_cast<int>(group)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004801}
4802
4803
4804void DependentCode::set_object_at(int i, Object* object) {
4805 set(kCodesStartIndex + i, object);
4806}
4807
4808
4809Object* DependentCode::object_at(int i) {
4810 return get(kCodesStartIndex + i);
4811}
4812
4813
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004814void DependentCode::clear_at(int i) {
4815 set_undefined(kCodesStartIndex + i);
4816}
4817
4818
4819void DependentCode::copy(int from, int to) {
4820 set(kCodesStartIndex + to, get(kCodesStartIndex + from));
4821}
4822
4823
Steve Blocka7e24c12009-10-30 11:49:00 +00004824void Code::set_flags(Code::Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00004825 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
Steve Blocka7e24c12009-10-30 11:49:00 +00004826 WRITE_INT_FIELD(this, kFlagsOffset, flags);
4827}
4828
4829
4830Code::Kind Code::kind() {
4831 return ExtractKindFromFlags(flags());
4832}
4833
4834
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004835bool 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004844bool Code::IsJavaScriptCode() {
4845 return kind() == FUNCTION || kind() == OPTIMIZED_FUNCTION ||
4846 is_interpreter_entry_trampoline();
4847}
4848
4849
Steve Blocka7e24c12009-10-30 11:49:00 +00004850InlineCacheState 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.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004855 DCHECK(is_inline_cache_stub() ||
Steve Blocka7e24c12009-10-30 11:49:00 +00004856 result == UNINITIALIZED ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004857 result == DEBUG_STUB);
Steve Blocka7e24c12009-10-30 11:49:00 +00004858 return result;
4859}
4860
4861
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004862ExtraICState Code::extra_ic_state() {
4863 DCHECK(is_inline_cache_stub() || ic_state() == DEBUG_STUB);
Ben Murdochb8e0da22011-05-16 14:20:40 +01004864 return ExtractExtraICStateFromFlags(flags());
4865}
4866
4867
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004868Code::StubType Code::type() {
Steve Blocka7e24c12009-10-30 11:49:00 +00004869 return ExtractTypeFromFlags(flags());
4870}
4871
4872
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004873// For initialization.
4874void Code::set_raw_kind_specific_flags1(int value) {
4875 WRITE_INT_FIELD(this, kKindSpecificFlags1Offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004876}
4877
4878
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004879void Code::set_raw_kind_specific_flags2(int value) {
4880 WRITE_INT_FIELD(this, kKindSpecificFlags2Offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004881}
4882
4883
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004884inline bool Code::is_crankshafted() {
4885 return IsCrankshaftedField::decode(
4886 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
Steve Blocka7e24c12009-10-30 11:49:00 +00004887}
4888
4889
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004890inline bool Code::is_hydrogen_stub() {
4891 return is_crankshafted() && kind() != OPTIMIZED_FUNCTION;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004892}
4893
4894
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004895inline 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004901inline 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
4908inline bool Code::is_turbofanned() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004909 return IsTurbofannedField::decode(
4910 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
4911}
4912
4913
4914inline void Code::set_is_turbofanned(bool value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004915 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4916 int updated = IsTurbofannedField::update(previous, value);
4917 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004918}
4919
4920
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004921inline bool Code::can_have_weak_objects() {
4922 DCHECK(kind() == OPTIMIZED_FUNCTION);
4923 return CanHaveWeakObjectsField::decode(
4924 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
Ben Murdochb0fe1622011-05-05 13:52:32 +01004925}
4926
4927
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004928inline 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);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004933}
4934
4935
4936bool Code::has_deoptimization_support() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004937 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004938 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004939 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004940}
4941
4942
4943void Code::set_has_deoptimization_support(bool value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004944 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004945 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004946 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004947 WRITE_UINT32_FIELD(this, kFullCodeFlags, flags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004948}
4949
4950
4951bool Code::has_debug_break_slots() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004952 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004953 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004954 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
4955}
4956
4957
4958void Code::set_has_debug_break_slots(bool value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004959 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004960 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004961 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004962 WRITE_UINT32_FIELD(this, kFullCodeFlags, flags);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004963}
4964
4965
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004966bool Code::has_reloc_info_for_serialization() {
4967 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004968 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004969 return FullCodeFlagsHasRelocInfoForSerialization::decode(flags);
4970}
4971
4972
4973void Code::set_has_reloc_info_for_serialization(bool value) {
4974 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004975 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004976 flags = FullCodeFlagsHasRelocInfoForSerialization::update(flags, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004977 WRITE_UINT32_FIELD(this, kFullCodeFlags, flags);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004978}
4979
4980
Ben Murdochb0fe1622011-05-05 13:52:32 +01004981int Code::allow_osr_at_loop_nesting_level() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004982 DCHECK_EQ(FUNCTION, kind());
4983 int fields = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4984 return AllowOSRAtLoopNestingLevelField::decode(fields);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004985}
4986
4987
4988void Code::set_allow_osr_at_loop_nesting_level(int level) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004989 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);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004994}
4995
4996
Ben Murdoch8f9999f2012-04-23 10:39:17 +01004997int Code::profiler_ticks() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004998 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004999 return ProfilerTicksField::decode(
5000 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
Ben Murdoch8f9999f2012-04-23 10:39:17 +01005001}
5002
5003
5004void Code::set_profiler_ticks(int ticks) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005005 if (kind() == FUNCTION) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005006 unsigned previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
5007 unsigned updated = ProfilerTicksField::update(previous, ticks);
5008 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005009 }
5010}
5011
5012
5013int Code::builtin_index() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005014 return READ_INT32_FIELD(this, kKindSpecificFlags1Offset);
5015}
5016
5017
5018void Code::set_builtin_index(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005019 WRITE_INT32_FIELD(this, kKindSpecificFlags1Offset, index);
Ben Murdoch8f9999f2012-04-23 10:39:17 +01005020}
5021
5022
Ben Murdochb0fe1622011-05-05 13:52:32 +01005023unsigned Code::stack_slots() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005024 DCHECK(is_crankshafted());
5025 return StackSlotsField::decode(
5026 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
Ben Murdochb0fe1622011-05-05 13:52:32 +01005027}
5028
5029
5030void Code::set_stack_slots(unsigned slots) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005031 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);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005036}
5037
5038
Steve Block1e0659c2011-05-24 12:43:12 +01005039unsigned Code::safepoint_table_offset() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005040 DCHECK(is_crankshafted());
5041 return SafepointTableOffsetField::decode(
5042 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
Ben Murdochb0fe1622011-05-05 13:52:32 +01005043}
5044
5045
Steve Block1e0659c2011-05-24 12:43:12 +01005046void Code::set_safepoint_table_offset(unsigned offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005047 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);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005053}
5054
5055
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005056unsigned Code::back_edge_table_offset() {
5057 DCHECK_EQ(FUNCTION, kind());
5058 return BackEdgeTableOffsetField::decode(
5059 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset)) << kPointerSizeLog2;
Ben Murdochb0fe1622011-05-05 13:52:32 +01005060}
5061
5062
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005063void 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);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005070}
5071
5072
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005073bool Code::back_edges_patched_for_osr() {
5074 DCHECK_EQ(FUNCTION, kind());
5075 return allow_osr_at_loop_nesting_level() > 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +01005076}
5077
5078
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005079uint16_t Code::to_boolean_state() { return extra_ic_state(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005080
5081
5082bool Code::marked_for_deoptimization() {
5083 DCHECK(kind() == OPTIMIZED_FUNCTION);
5084 return MarkedForDeoptimizationField::decode(
5085 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
5086}
5087
5088
5089void 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
Steve Blocka7e24c12009-10-30 11:49:00 +00005098bool Code::is_inline_cache_stub() {
5099 Kind kind = this->kind();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005100 switch (kind) {
5101#define CASE(name) case name: return true;
5102 IC_KIND_LIST(CASE)
5103#undef CASE
5104 default: return false;
5105 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005106}
5107
5108
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005109bool Code::is_keyed_stub() {
5110 return is_keyed_load_stub() || is_keyed_store_stub();
5111}
5112
5113
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005114bool Code::is_debug_stub() { return ic_state() == DEBUG_STUB; }
5115bool Code::is_handler() { return kind() == HANDLER; }
5116bool Code::is_load_stub() { return kind() == LOAD_IC; }
5117bool Code::is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
5118bool Code::is_store_stub() { return kind() == STORE_IC; }
5119bool Code::is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
5120bool Code::is_call_stub() { return kind() == CALL_IC; }
5121bool Code::is_binary_op_stub() { return kind() == BINARY_OP_IC; }
5122bool Code::is_compare_ic_stub() { return kind() == COMPARE_IC; }
5123bool Code::is_compare_nil_ic_stub() { return kind() == COMPARE_NIL_IC; }
5124bool Code::is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; }
5125bool Code::is_optimized_code() { return kind() == OPTIMIZED_FUNCTION; }
5126
5127
5128bool 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;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005133}
5134
5135
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005136Address 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;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005145}
5146
5147
5148Code::Flags Code::ComputeFlags(Kind kind, InlineCacheState ic_state,
5149 ExtraICState extra_ic_state, StubType type,
5150 CacheHolderFlag holder) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005151 // Compute the bit mask.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005152 unsigned int bits = KindField::encode(kind)
Ben Murdoch589d6972011-11-30 16:04:58 +00005153 | ICStateField::encode(ic_state)
5154 | TypeField::encode(type)
5155 | ExtraICStateField::encode(extra_ic_state)
Ben Murdoch589d6972011-11-30 16:04:58 +00005156 | CacheHolderField::encode(holder);
5157 return static_cast<Flags>(bits);
Steve Blocka7e24c12009-10-30 11:49:00 +00005158}
5159
5160
5161Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
Ben Murdochb8e0da22011-05-16 14:20:40 +01005162 ExtraICState extra_ic_state,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005163 CacheHolderFlag holder,
5164 StubType type) {
5165 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, holder);
5166}
5167
5168
5169Code::Flags Code::ComputeHandlerFlags(Kind handler_kind, StubType type,
5170 CacheHolderFlag holder) {
5171 return ComputeFlags(Code::HANDLER, MONOMORPHIC, handler_kind, type, holder);
Steve Blocka7e24c12009-10-30 11:49:00 +00005172}
5173
5174
5175Code::Kind Code::ExtractKindFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005176 return KindField::decode(flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005177}
5178
5179
5180InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005181 return ICStateField::decode(flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005182}
5183
5184
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005185ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005186 return ExtraICStateField::decode(flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005187}
5188
5189
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005190Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005191 return TypeField::decode(flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005192}
5193
5194
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005195CacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005196 return CacheHolderField::decode(flags);
Steve Block8defd9f2010-07-08 12:39:36 +01005197}
5198
5199
Steve Blocka7e24c12009-10-30 11:49:00 +00005200Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005201 int bits = flags & ~TypeField::kMask;
Steve Blocka7e24c12009-10-30 11:49:00 +00005202 return static_cast<Flags>(bits);
5203}
5204
5205
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005206Code::Flags Code::RemoveTypeAndHolderFromFlags(Flags flags) {
5207 int bits = flags & ~TypeField::kMask & ~CacheHolderField::kMask;
5208 return static_cast<Flags>(bits);
5209}
5210
5211
Steve Blocka7e24c12009-10-30 11:49:00 +00005212Code* 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
Steve Block791712a2010-08-27 10:21:07 +01005223Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
5224 return HeapObject::
5225 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
5226}
5227
5228
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005229bool Code::CanContainWeakObjects() {
5230 return is_optimized_code() && can_have_weak_objects();
5231}
5232
5233
5234bool Code::IsWeakObject(Object* object) {
5235 return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object));
5236}
5237
5238
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005239bool Code::IsWeakObjectInOptimizedCode(Object* object) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005240 if (object->IsMap()) {
5241 return Map::cast(object)->CanTransition() &&
5242 FLAG_weak_embedded_maps_in_optimized_code;
5243 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005244 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.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005254 return FLAG_weak_embedded_objects_in_optimized_code;
5255 }
5256 return false;
5257}
5258
5259
5260class Code::FindAndReplacePattern {
5261 public:
5262 FindAndReplacePattern() : count_(0) { }
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
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005278Object* Map::prototype() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005279 return READ_FIELD(this, kPrototypeOffset);
5280}
5281
5282
5283void Map::set_prototype(Object* value, WriteBarrierMode mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005284 DCHECK(value->IsNull() || value->IsJSReceiver());
Steve Blocka7e24c12009-10-30 11:49:00 +00005285 WRITE_FIELD(this, kPrototypeOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005286 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
Steve Block1e0659c2011-05-24 12:43:12 +01005287}
5288
5289
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005290LayoutDescriptor* Map::layout_descriptor_gc_safe() {
5291 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
5292 return LayoutDescriptor::cast_gc_safe(layout_desc);
5293}
5294
5295
5296bool Map::HasFastPointerLayout() const {
5297 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
5298 return LayoutDescriptor::IsFastPointerLayout(layout_desc);
5299}
5300
5301
5302void 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 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005309#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
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005316 SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005317 DCHECK(visitor_id() == Heap::GetStaticVisitorIdForMap(this));
5318#endif
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005319 }
5320}
5321
5322
5323void Map::InitializeDescriptors(DescriptorArray* descriptors,
5324 LayoutDescriptor* layout_desc) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005325 int len = descriptors->number_of_descriptors();
5326 set_instance_descriptors(descriptors);
5327 SetNumberOfOwnDescriptors(len);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005328
5329 if (FLAG_unbox_double_fields) {
5330 set_layout_descriptor(layout_desc);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005331#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
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005337 SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005338#endif
5339 set_visitor_id(Heap::GetStaticVisitorIdForMap(this));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005340 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005341}
5342
5343
5344ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005345ACCESSORS(Map, layout_descriptor, LayoutDescriptor, kLayoutDecriptorOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005346
5347
5348void 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005356uint32_t Map::bit_field3() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005357 return READ_UINT32_FIELD(this, kBitField3Offset);
5358}
5359
5360
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005361LayoutDescriptor* Map::GetLayoutDescriptor() {
5362 return FLAG_unbox_double_fields ? layout_descriptor()
5363 : LayoutDescriptor::FastPointerLayout();
5364}
5365
5366
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005367void 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);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005373
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();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005378 CHECK(details.type() != DATA || !details.representation().IsDouble());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005379#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005380}
5381
5382
5383Object* Map::GetBackPointer() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005384 Object* object = constructor_or_backpointer();
5385 if (object->IsMap()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005386 return object;
5387 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005388 return GetIsolate()->heap()->undefined_value();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005389}
5390
5391
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005392Map* Map::ElementsTransitionMap() {
5393 return TransitionArray::SearchSpecial(
5394 this, GetHeap()->elements_transition_symbol());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005395}
5396
5397
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005398ACCESSORS(Map, raw_transitions, Object, kTransitionsOrPrototypeInfoOffset)
5399
5400
5401Object* Map::prototype_info() const {
5402 DCHECK(is_prototype_map());
5403 return READ_FIELD(this, Map::kTransitionsOrPrototypeInfoOffset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005404}
5405
5406
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005407void Map::set_prototype_info(Object* value, WriteBarrierMode mode) {
5408 DCHECK(is_prototype_map());
5409 WRITE_FIELD(this, Map::kTransitionsOrPrototypeInfoOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005410 CONDITIONAL_WRITE_BARRIER(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005411 GetHeap(), this, Map::kTransitionsOrPrototypeInfoOffset, value, mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005412}
5413
5414
5415void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
5416 DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005417 DCHECK((value->IsMap() && GetBackPointer()->IsUndefined()));
5418 DCHECK(!value->IsMap() ||
5419 Map::cast(value)->GetConstructor() == constructor_or_backpointer());
5420 set_constructor_or_backpointer(value, mode);
Ben Murdoch257744e2011-11-30 15:57:28 +00005421}
5422
5423
Steve Block6ded16b2010-05-10 14:33:55 +01005424ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005425ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005426ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset)
5427ACCESSORS(Map, constructor_or_backpointer, Object,
5428 kConstructorOrBackPointerOffset)
5429
5430
5431Object* 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
5442void 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
5449Handle<Map> Map::CopyInitialMap(Handle<Map> map) {
5450 return CopyInitialMap(map, map->instance_size(), map->GetInObjectProperties(),
5451 map->unused_property_fields());
5452}
5453
5454
5455ACCESSORS(JSBoundFunction, length, Object, kLengthOffset)
5456ACCESSORS(JSBoundFunction, name, Object, kNameOffset)
5457ACCESSORS(JSBoundFunction, bound_target_function, JSReceiver,
5458 kBoundTargetFunctionOffset)
5459ACCESSORS(JSBoundFunction, bound_this, Object, kBoundThisOffset)
5460ACCESSORS(JSBoundFunction, bound_arguments, FixedArray, kBoundArgumentsOffset)
5461ACCESSORS(JSBoundFunction, creation_context, Context, kCreationContextOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005462
5463ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005464ACCESSORS(JSFunction, literals, LiteralsArray, kLiteralsOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005465ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005466
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005467ACCESSORS(JSGlobalObject, native_context, Context, kNativeContextOffset)
5468ACCESSORS(JSGlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005469
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005470ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
5471ACCESSORS(JSGlobalProxy, hash, Object, kHashOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005472
Steve Blocka7e24c12009-10-30 11:49:00 +00005473ACCESSORS(AccessorInfo, name, Object, kNameOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005474SMI_ACCESSORS(AccessorInfo, flag, kFlagOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005475ACCESSORS(AccessorInfo, expected_receiver_type, Object,
5476 kExpectedReceiverTypeOffset)
5477
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005478ACCESSORS(ExecutableAccessorInfo, getter, Object, kGetterOffset)
5479ACCESSORS(ExecutableAccessorInfo, setter, Object, kSetterOffset)
5480ACCESSORS(ExecutableAccessorInfo, data, Object, kDataOffset)
5481
5482ACCESSORS(Box, value, Object, kValueOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005483
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005484ACCESSORS(PrototypeInfo, prototype_users, Object, kPrototypeUsersOffset)
5485SMI_ACCESSORS(PrototypeInfo, registry_slot, kRegistrySlotOffset)
5486ACCESSORS(PrototypeInfo, validity_cell, Object, kValidityCellOffset)
5487
5488ACCESSORS(SloppyBlockWithEvalContextExtension, scope_info, ScopeInfo,
5489 kScopeInfoOffset)
5490ACCESSORS(SloppyBlockWithEvalContextExtension, extension, JSObject,
5491 kExtensionOffset)
5492
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005493ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
5494ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
Ben Murdochc7cc0282012-03-05 14:35:55 +00005495
Steve Blocka7e24c12009-10-30 11:49:00 +00005496ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
5497ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005498ACCESSORS(AccessCheckInfo, callback, Object, kCallbackOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005499ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
5500
5501ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
5502ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
5503ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
5504ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
5505ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
5506ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005507SMI_ACCESSORS(InterceptorInfo, flags, kFlagsOffset)
5508BOOL_ACCESSORS(InterceptorInfo, flags, can_intercept_symbols,
5509 kCanInterceptSymbolsBit)
5510BOOL_ACCESSORS(InterceptorInfo, flags, all_can_read, kAllCanReadBit)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005511BOOL_ACCESSORS(InterceptorInfo, flags, non_masking, kNonMasking)
Steve Blocka7e24c12009-10-30 11:49:00 +00005512
5513ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
5514ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005515ACCESSORS(CallHandlerInfo, fast_handler, Object, kFastHandlerOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005516
5517ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005518SMI_ACCESSORS(TemplateInfo, number_of_properties, kNumberOfProperties)
Steve Blocka7e24c12009-10-30 11:49:00 +00005519ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005520ACCESSORS(TemplateInfo, property_accessors, Object, kPropertyAccessorsOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005521
5522ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
5523ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005524ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
5525 kPrototypeTemplateOffset)
5526ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
5527ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
5528 kNamedPropertyHandlerOffset)
5529ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
5530 kIndexedPropertyHandlerOffset)
5531ACCESSORS(FunctionTemplateInfo, instance_template, Object,
5532 kInstanceTemplateOffset)
5533ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
5534ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
5535ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
5536 kInstanceCallHandlerOffset)
5537ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
5538 kAccessCheckInfoOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005539SMI_ACCESSORS(FunctionTemplateInfo, flag, kFlagOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005540
5541ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
5542ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
5543 kInternalFieldCountOffset)
5544
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005545ACCESSORS(AllocationSite, transition_info, Object, kTransitionInfoOffset)
5546ACCESSORS(AllocationSite, nested_site, Object, kNestedSiteOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005547SMI_ACCESSORS(AllocationSite, pretenure_data, kPretenureDataOffset)
5548SMI_ACCESSORS(AllocationSite, pretenure_create_count,
5549 kPretenureCreateCountOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005550ACCESSORS(AllocationSite, dependent_code, DependentCode,
5551 kDependentCodeOffset)
5552ACCESSORS(AllocationSite, weak_next, Object, kWeakNextOffset)
5553ACCESSORS(AllocationMemento, allocation_site, Object, kAllocationSiteOffset)
5554
Steve Blocka7e24c12009-10-30 11:49:00 +00005555ACCESSORS(Script, source, Object, kSourceOffset)
5556ACCESSORS(Script, name, Object, kNameOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005557SMI_ACCESSORS(Script, id, kIdOffset)
5558SMI_ACCESSORS(Script, line_offset, kLineOffsetOffset)
5559SMI_ACCESSORS(Script, column_offset, kColumnOffsetOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005560ACCESSORS(Script, context_data, Object, kContextOffset)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005561ACCESSORS(Script, wrapper, HeapObject, kWrapperOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005562SMI_ACCESSORS(Script, type, kTypeOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005563ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
Steve Blockd0582a62009-12-15 09:54:21 +00005564ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005565SMI_ACCESSORS(Script, eval_from_instructions_offset,
5566 kEvalFrominstructionsOffsetOffset)
5567ACCESSORS(Script, shared_function_infos, Object, kSharedFunctionInfosOffset)
5568SMI_ACCESSORS(Script, flags, kFlagsOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005569ACCESSORS(Script, source_url, Object, kSourceUrlOffset)
5570ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005571
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005572Script::CompilationType Script::compilation_type() {
5573 return BooleanBit::get(flags(), kCompilationTypeBit) ?
5574 COMPILATION_TYPE_EVAL : COMPILATION_TYPE_HOST;
5575}
5576void Script::set_compilation_type(CompilationType type) {
5577 set_flags(BooleanBit::set(flags(), kCompilationTypeBit,
5578 type == COMPILATION_TYPE_EVAL));
5579}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005580bool Script::hide_source() { return BooleanBit::get(flags(), kHideSourceBit); }
5581void Script::set_hide_source(bool value) {
5582 set_flags(BooleanBit::set(flags(), kHideSourceBit, value));
5583}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005584Script::CompilationState Script::compilation_state() {
5585 return BooleanBit::get(flags(), kCompilationStateBit) ?
5586 COMPILATION_STATE_COMPILED : COMPILATION_STATE_INITIAL;
5587}
5588void Script::set_compilation_state(CompilationState state) {
5589 set_flags(BooleanBit::set(flags(), kCompilationStateBit,
5590 state == COMPILATION_STATE_COMPILED));
5591}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005592ScriptOriginOptions Script::origin_options() {
5593 return ScriptOriginOptions((flags() & kOriginOptionsMask) >>
5594 kOriginOptionsShift);
5595}
5596void 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}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005601
5602
Steve Blocka7e24c12009-10-30 11:49:00 +00005603ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005604ACCESSORS(DebugInfo, code, Code, kCodeIndex)
Steve Blocka7e24c12009-10-30 11:49:00 +00005605ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
5606
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005607SMI_ACCESSORS(BreakPointInfo, code_position, kCodePositionIndex)
5608SMI_ACCESSORS(BreakPointInfo, source_position, kSourcePositionIndex)
5609SMI_ACCESSORS(BreakPointInfo, statement_position, kStatementPositionIndex)
Steve Blocka7e24c12009-10-30 11:49:00 +00005610ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
Steve Blocka7e24c12009-10-30 11:49:00 +00005611
Steve Blocka7e24c12009-10-30 11:49:00 +00005612ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005613ACCESSORS(SharedFunctionInfo, optimized_code_map, FixedArray,
5614 kOptimizedCodeMapOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005615ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005616ACCESSORS(SharedFunctionInfo, feedback_vector, TypeFeedbackVector,
5617 kFeedbackVectorOffset)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005618#if TRACE_MAPS
5619SMI_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset)
5620#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00005621ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
5622 kInstanceClassNameOffset)
Steve Block6ded16b2010-05-10 14:33:55 +01005623ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005624ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
5625ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
5626ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005627
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005628
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005629SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005630BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
5631 kHiddenPrototypeBit)
5632BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
5633BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
5634 kNeedsAccessCheckBit)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005635BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
5636 kReadOnlyPrototypeBit)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005637BOOL_ACCESSORS(FunctionTemplateInfo, flag, remove_prototype,
5638 kRemovePrototypeBit)
5639BOOL_ACCESSORS(FunctionTemplateInfo, flag, do_not_cache,
5640 kDoNotCacheBit)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005641BOOL_ACCESSORS(FunctionTemplateInfo, flag, instantiated, kInstantiatedBit)
5642BOOL_ACCESSORS(FunctionTemplateInfo, flag, accept_any_receiver,
5643 kAcceptAnyReceiver)
Steve Blocka7e24c12009-10-30 11:49:00 +00005644BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
5645 kIsExpressionBit)
5646BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
5647 kIsTopLevelBit)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005648
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005649BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, allows_lazy_compilation,
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005650 kAllowLazyCompilation)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005651BOOL_ACCESSORS(SharedFunctionInfo,
5652 compiler_hints,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005653 allows_lazy_compilation_without_context,
5654 kAllowLazyCompilationWithoutContext)
5655BOOL_ACCESSORS(SharedFunctionInfo,
5656 compiler_hints,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005657 uses_arguments,
5658 kUsesArguments)
5659BOOL_ACCESSORS(SharedFunctionInfo,
5660 compiler_hints,
5661 has_duplicate_parameters,
5662 kHasDuplicateParameters)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005663BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, asm_function, kIsAsmFunction)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005664BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, deserialized, kDeserialized)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005665BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, never_compiled,
5666 kNeverCompiled)
Steve Blocka7e24c12009-10-30 11:49:00 +00005667
Iain Merrick75681382010-08-19 15:07:18 +01005668
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005669#if V8_HOST_ARCH_32_BIT
5670SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005671SMI_ACCESSORS(SharedFunctionInfo, internal_formal_parameter_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00005672 kFormalParameterCountOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005673SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
Steve Blocka7e24c12009-10-30 11:49:00 +00005674 kExpectedNofPropertiesOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005675SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
5676SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
Steve Blocka7e24c12009-10-30 11:49:00 +00005677 kStartPositionAndTypeOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005678SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
5679SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
Steve Blocka7e24c12009-10-30 11:49:00 +00005680 kFunctionTokenPositionOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005681SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
Steve Blocka7e24c12009-10-30 11:49:00 +00005682 kCompilerHintsOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005683SMI_ACCESSORS(SharedFunctionInfo, opt_count_and_bailout_reason,
5684 kOptCountAndBailoutReasonOffset)
5685SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005686SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005687SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
5688
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005689#else
Steve Blocka7e24c12009-10-30 11:49:00 +00005690
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005691#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); \
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005711 }
5712
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005713#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
5714 STATIC_ASSERT(holder::offset % kPointerSize == PSEUDO_SMI_HI_ALIGN); \
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005715 INT_ACCESSORS(holder, name, offset)
5716
5717
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005718PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005719PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, internal_formal_parameter_count,
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005720 kFormalParameterCountOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005721
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005722PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5723 expected_nof_properties,
5724 kExpectedNofPropertiesOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005725PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
5726
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005727PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
5728PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5729 start_position_and_type,
5730 kStartPositionAndTypeOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005731
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005732PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5733 function_token_position,
5734 kFunctionTokenPositionOffset)
5735PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5736 compiler_hints,
5737 kCompilerHintsOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005738
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005739PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005740 opt_count_and_bailout_reason,
5741 kOptCountAndBailoutReasonOffset)
5742PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, counters, kCountersOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005743
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005744PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5745 ast_node_count,
5746 kAstNodeCountOffset)
5747PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5748 profiler_ticks,
5749 kProfilerTicksOffset)
5750
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005751#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00005752
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005753
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005754BOOL_GETTER(SharedFunctionInfo,
5755 compiler_hints,
5756 optimization_disabled,
5757 kOptimizationDisabled)
Ben Murdochb0fe1622011-05-05 13:52:32 +01005758
5759
5760void SharedFunctionInfo::set_optimization_disabled(bool disable) {
5761 set_compiler_hints(BooleanBit::set(compiler_hints(),
5762 kOptimizationDisabled,
5763 disable));
Ben Murdochb0fe1622011-05-05 13:52:32 +01005764}
5765
5766
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005767LanguageMode 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));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005772}
5773
5774
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005775void 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));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005780 int hints = compiler_hints();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005781 hints = BooleanBit::set(hints, kStrictModeFunction, is_strict(language_mode));
5782 hints = BooleanBit::set(hints, kStrongModeFunction, is_strong(language_mode));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005783 set_compiler_hints(hints);
5784}
5785
5786
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005787FunctionKind SharedFunctionInfo::kind() {
5788 return FunctionKindBits::decode(compiler_hints());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005789}
5790
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005791
5792void 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005800BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, needs_home_object,
5801 kNeedsHomeObject)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005802BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005803BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, force_inline, kForceInline)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005804BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
5805 name_should_print_as_anonymous,
5806 kNameShouldPrintAsAnonymous)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005807BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005808BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005809BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_crankshaft,
5810 kDontCrankshaft)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005811BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_flush, kDontFlush)
5812BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_arrow, kIsArrow)
5813BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator)
5814BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_concise_method,
5815 kIsConciseMethod)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005816BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_accessor_function,
5817 kIsAccessorFunction)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005818BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_default_constructor,
5819 kIsDefaultConstructor)
Ben Murdoch257744e2011-11-30 15:57:28 +00005820
Steve Block6ded16b2010-05-10 14:33:55 +01005821ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
5822ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
5823
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005824ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
5825
Steve Block3ce2e202009-11-05 08:53:23 +00005826bool 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;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005831 if (src_str->IsOneByteRepresentation()) {
5832 return ExternalOneByteString::cast(src)->resource() != NULL;
Steve Block3ce2e202009-11-05 08:53:23 +00005833 } else if (src_str->IsTwoByteRepresentation()) {
5834 return ExternalTwoByteString::cast(src)->resource() != NULL;
5835 }
5836 return true;
5837}
5838
5839
Steve Blocka7e24c12009-10-30 11:49:00 +00005840void SharedFunctionInfo::DontAdaptArguments() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005841 DCHECK(code()->kind() == Code::BUILTIN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005842 set_internal_formal_parameter_count(kDontAdaptArgumentsSentinel);
Steve Blocka7e24c12009-10-30 11:49:00 +00005843}
5844
5845
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005846int SharedFunctionInfo::start_position() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005847 return start_position_and_type() >> kStartPositionShift;
5848}
5849
5850
5851void 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005857Code* SharedFunctionInfo::code() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005858 return Code::cast(READ_FIELD(this, kCodeOffset));
5859}
5860
5861
5862void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005863 DCHECK(value->kind() != Code::OPTIMIZED_FUNCTION);
Steve Blocka7e24c12009-10-30 11:49:00 +00005864 WRITE_FIELD(this, kCodeOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005865 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00005866}
5867
5868
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005869void 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);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005878#ifdef DEBUG
5879 Code::VerifyRecompiledCode(code(), value);
5880#endif // DEBUG
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005881
5882 set_code(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005883
5884 if (is_compiled()) set_never_compiled(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005885}
5886
5887
5888ScopeInfo* SharedFunctionInfo::scope_info() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005889 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005890}
5891
5892
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005893void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005894 WriteBarrierMode mode) {
5895 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005896 CONDITIONAL_WRITE_BARRIER(GetHeap(),
5897 this,
5898 kScopeInfoOffset,
5899 reinterpret_cast<Object*>(value),
5900 mode);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005901}
5902
5903
Steve Blocka7e24c12009-10-30 11:49:00 +00005904bool SharedFunctionInfo::is_compiled() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005905 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
5912bool SharedFunctionInfo::has_simple_parameters() {
5913 return scope_info()->HasSimpleParameters();
5914}
5915
5916
5917bool SharedFunctionInfo::HasDebugInfo() {
5918 bool has_debug_info = debug_info()->IsStruct();
5919 DCHECK(!has_debug_info || HasDebugCode());
5920 return has_debug_info;
5921}
5922
5923
5924DebugInfo* SharedFunctionInfo::GetDebugInfo() {
5925 DCHECK(HasDebugInfo());
5926 return DebugInfo::cast(debug_info());
5927}
5928
5929
5930bool SharedFunctionInfo::HasDebugCode() {
5931 return code()->kind() == Code::FUNCTION && code()->has_debug_break_slots();
Steve Blocka7e24c12009-10-30 11:49:00 +00005932}
5933
5934
Steve Block6ded16b2010-05-10 14:33:55 +01005935bool SharedFunctionInfo::IsApiFunction() {
5936 return function_data()->IsFunctionTemplateInfo();
5937}
5938
5939
5940FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005941 DCHECK(IsApiFunction());
Steve Block6ded16b2010-05-10 14:33:55 +01005942 return FunctionTemplateInfo::cast(function_data());
5943}
5944
5945
Ben Murdochb0fe1622011-05-05 13:52:32 +01005946bool SharedFunctionInfo::HasBuiltinFunctionId() {
Kristian Monsen25f61362010-05-21 11:50:48 +01005947 return function_data()->IsSmi();
5948}
5949
5950
Ben Murdochb0fe1622011-05-05 13:52:32 +01005951BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005952 DCHECK(HasBuiltinFunctionId());
Ben Murdochb0fe1622011-05-05 13:52:32 +01005953 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
Steve Blocka7e24c12009-10-30 11:49:00 +00005954}
5955
5956
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005957bool SharedFunctionInfo::HasBytecodeArray() {
5958 return function_data()->IsBytecodeArray();
5959}
5960
5961
5962BytecodeArray* SharedFunctionInfo::bytecode_array() {
5963 DCHECK(HasBytecodeArray());
5964 return BytecodeArray::cast(function_data());
5965}
5966
5967
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005968int SharedFunctionInfo::ic_age() {
5969 return ICAgeBits::decode(counters());
Iain Merrick75681382010-08-19 15:07:18 +01005970}
5971
5972
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005973void SharedFunctionInfo::set_ic_age(int ic_age) {
5974 set_counters(ICAgeBits::update(counters(), ic_age));
5975}
5976
5977
5978int SharedFunctionInfo::deopt_count() {
5979 return DeoptCountBits::decode(counters());
5980}
5981
5982
5983void SharedFunctionInfo::set_deopt_count(int deopt_count) {
5984 set_counters(DeoptCountBits::update(counters(), deopt_count));
5985}
5986
5987
5988void 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
5996int SharedFunctionInfo::opt_reenable_tries() {
5997 return OptReenableTriesBits::decode(counters());
5998}
5999
6000
6001void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
6002 set_counters(OptReenableTriesBits::update(counters(), tries));
6003}
6004
6005
6006int SharedFunctionInfo::opt_count() {
6007 return OptCountBits::decode(opt_count_and_bailout_reason());
6008}
6009
6010
6011void 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
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006017BailoutReason SharedFunctionInfo::disable_optimization_reason() {
6018 return static_cast<BailoutReason>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006019 DisabledOptimizationReasonBits::decode(opt_count_and_bailout_reason()));
Iain Merrick75681382010-08-19 15:07:18 +01006020}
6021
6022
Ben Murdochb0fe1622011-05-05 13:52:32 +01006023bool SharedFunctionInfo::has_deoptimization_support() {
6024 Code* code = this->code();
6025 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
6026}
6027
6028
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006029void 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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006038 }
6039}
6040
6041
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006042void SharedFunctionInfo::set_disable_optimization_reason(BailoutReason reason) {
6043 set_opt_count_and_bailout_reason(DisabledOptimizationReasonBits::update(
6044 opt_count_and_bailout_reason(), reason));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006045}
6046
6047
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006048bool 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;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006054}
6055
6056
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006057bool SharedFunctionInfo::IsSubjectToDebugging() { return !IsBuiltin(); }
6058
6059
6060bool SharedFunctionInfo::OptimizedCodeMapIsCleared() const {
6061 return optimized_code_map() == GetHeap()->cleared_optimized_code_map();
Steve Blocka7e24c12009-10-30 11:49:00 +00006062}
6063
6064
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006065// static
6066void 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
6075void 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());
Ben Murdochb0fe1622011-05-05 13:52:32 +01006082}
6083
6084
6085bool JSFunction::IsOptimized() {
6086 return code()->kind() == Code::OPTIMIZED_FUNCTION;
6087}
6088
6089
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006090bool JSFunction::IsMarkedForOptimization() {
6091 return code() == GetIsolate()->builtins()->builtin(
6092 Builtins::kCompileOptimized);
6093}
6094
6095
6096bool JSFunction::IsMarkedForConcurrentOptimization() {
6097 return code() == GetIsolate()->builtins()->builtin(
6098 Builtins::kCompileOptimizedConcurrent);
6099}
6100
6101
6102bool JSFunction::IsInOptimizationQueue() {
6103 return code() == GetIsolate()->builtins()->builtin(
6104 Builtins::kInOptimizationQueue);
6105}
6106
6107
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006108void JSFunction::CompleteInobjectSlackTrackingIfActive() {
6109 if (has_initial_map() && initial_map()->IsInobjectSlackTrackingInProgress()) {
6110 initial_map()->CompleteInobjectSlackTracking();
6111 }
6112}
6113
6114
6115bool Map::IsInobjectSlackTrackingInProgress() {
6116 return construction_counter() != Map::kNoSlackTracking;
6117}
6118
6119
6120void Map::InobjectSlackTrackingStep() {
6121 if (!IsInobjectSlackTrackingInProgress()) return;
6122 int counter = construction_counter();
6123 set_construction_counter(counter - 1);
6124 if (counter == kSlackTrackingCounterEnd) {
6125 CompleteInobjectSlackTracking();
6126 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01006127}
6128
6129
Steve Blocka7e24c12009-10-30 11:49:00 +00006130Code* JSFunction::code() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006131 return Code::cast(
Steve Block791712a2010-08-27 10:21:07 +01006132 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
Steve Blocka7e24c12009-10-30 11:49:00 +00006133}
6134
6135
6136void JSFunction::set_code(Code* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006137 DCHECK(!GetHeap()->InNewSpace(value));
Steve Block791712a2010-08-27 10:21:07 +01006138 Address entry = value->entry();
6139 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006140 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
6141 this,
6142 HeapObject::RawField(this, kCodeEntryOffset),
6143 value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006144}
6145
6146
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006147void 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
Ben Murdochb0fe1622011-05-05 13:52:32 +01006154void JSFunction::ReplaceCode(Code* code) {
6155 bool was_optimized = IsOptimized();
6156 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
6157
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006158 if (was_optimized && is_optimized) {
6159 shared()->EvictFromOptimizedCodeMap(this->code(),
6160 "Replacing with another optimized code");
6161 }
6162
Ben Murdochb0fe1622011-05-05 13:52:32 +01006163 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) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006168 context()->native_context()->AddOptimizedFunction(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01006169 }
6170 if (was_optimized && !is_optimized) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006171 // TODO(titzer): linear in the number of optimized functions; fix!
6172 context()->native_context()->RemoveOptimizedFunction(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01006173 }
6174}
6175
6176
Steve Blocka7e24c12009-10-30 11:49:00 +00006177Context* JSFunction::context() {
6178 return Context::cast(READ_FIELD(this, kContextOffset));
6179}
6180
6181
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006182JSObject* JSFunction::global_proxy() {
6183 return context()->global_proxy();
Iain Merrick75681382010-08-19 15:07:18 +01006184}
6185
6186
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006187Context* JSFunction::native_context() { return context()->native_context(); }
6188
6189
Steve Blocka7e24c12009-10-30 11:49:00 +00006190void JSFunction::set_context(Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006191 DCHECK(value->IsUndefined() || value->IsContext());
Steve Blocka7e24c12009-10-30 11:49:00 +00006192 WRITE_FIELD(this, kContextOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006193 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006194}
6195
6196ACCESSORS(JSFunction, prototype_or_initial_map, Object,
6197 kPrototypeOrInitialMapOffset)
6198
6199
6200Map* JSFunction::initial_map() {
6201 return Map::cast(prototype_or_initial_map());
6202}
6203
6204
Steve Blocka7e24c12009-10-30 11:49:00 +00006205bool JSFunction::has_initial_map() {
6206 return prototype_or_initial_map()->IsMap();
6207}
6208
6209
6210bool JSFunction::has_instance_prototype() {
6211 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
6212}
6213
6214
6215bool JSFunction::has_prototype() {
6216 return map()->has_non_instance_prototype() || has_instance_prototype();
6217}
6218
6219
6220Object* JSFunction::instance_prototype() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006221 DCHECK(has_instance_prototype());
Steve Blocka7e24c12009-10-30 11:49:00 +00006222 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
6229Object* JSFunction::prototype() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006230 DCHECK(has_prototype());
Steve Blocka7e24c12009-10-30 11:49:00 +00006231 // 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.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006233 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 }
Steve Blocka7e24c12009-10-30 11:49:00 +00006239 return instance_prototype();
6240}
6241
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006242
Steve Blocka7e24c12009-10-30 11:49:00 +00006243bool JSFunction::is_compiled() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006244 Builtins* builtins = GetIsolate()->builtins();
6245 return code() != builtins->builtin(Builtins::kCompileLazy) &&
6246 code() != builtins->builtin(Builtins::kCompileOptimized) &&
6247 code() != builtins->builtin(Builtins::kCompileOptimizedConcurrent);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006248}
6249
6250
Steve Blocka7e24c12009-10-30 11:49:00 +00006251int JSFunction::NumberOfLiterals() {
6252 return literals()->length();
6253}
6254
6255
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006256ACCESSORS(JSProxy, target, JSReceiver, kTargetOffset)
Ben Murdoch257744e2011-11-30 15:57:28 +00006257ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006258ACCESSORS(JSProxy, hash, Object, kHashOffset)
Ben Murdoch589d6972011-11-30 16:04:58 +00006259
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006260bool JSProxy::IsRevoked() const { return !handler()->IsJSReceiver(); }
Ben Murdoch257744e2011-11-30 15:57:28 +00006261
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006262ACCESSORS(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
6277ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(table, Object, kTableOffset)
6278ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(index, Object, kIndexOffset)
6279ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(kind, Object, kKindOffset)
6280
6281#undef ORDERED_HASH_TABLE_ITERATOR_ACCESSORS
6282
6283
6284ACCESSORS(JSWeakCollection, table, Object, kTableOffset)
6285ACCESSORS(JSWeakCollection, next, Object, kNextOffset)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00006286
6287
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006288Address Foreign::foreign_address() {
6289 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
Ben Murdoch69a99ed2011-11-30 16:03:39 +00006290}
6291
6292
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006293void Foreign::set_foreign_address(Address value) {
6294 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00006295}
6296
6297
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006298ACCESSORS(JSGeneratorObject, function, JSFunction, kFunctionOffset)
6299ACCESSORS(JSGeneratorObject, context, Context, kContextOffset)
6300ACCESSORS(JSGeneratorObject, receiver, Object, kReceiverOffset)
6301SMI_ACCESSORS(JSGeneratorObject, continuation, kContinuationOffset)
6302ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006303
6304bool JSGeneratorObject::is_suspended() {
6305 DCHECK_LT(kGeneratorExecuting, kGeneratorClosed);
6306 DCHECK_EQ(kGeneratorClosed, 0);
6307 return continuation() > 0;
6308}
6309
6310bool JSGeneratorObject::is_closed() {
6311 return continuation() == kGeneratorClosed;
6312}
6313
6314bool JSGeneratorObject::is_executing() {
6315 return continuation() == kGeneratorExecuting;
6316}
6317
6318ACCESSORS(JSModule, context, Object, kContextOffset)
6319ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
6320
6321
Steve Blocka7e24c12009-10-30 11:49:00 +00006322ACCESSORS(JSValue, value, Object, kValueOffset)
6323
6324
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006325HeapNumber* HeapNumber::cast(Object* object) {
6326 SLOW_DCHECK(object->IsHeapNumber() || object->IsMutableHeapNumber());
6327 return reinterpret_cast<HeapNumber*>(object);
6328}
6329
6330
6331const HeapNumber* HeapNumber::cast(const Object* object) {
6332 SLOW_DCHECK(object->IsHeapNumber() || object->IsMutableHeapNumber());
6333 return reinterpret_cast<const HeapNumber*>(object);
Steve Blocka7e24c12009-10-30 11:49:00 +00006334}
6335
6336
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006337ACCESSORS(JSDate, value, Object, kValueOffset)
6338ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
6339ACCESSORS(JSDate, year, Object, kYearOffset)
6340ACCESSORS(JSDate, month, Object, kMonthOffset)
6341ACCESSORS(JSDate, day, Object, kDayOffset)
6342ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
6343ACCESSORS(JSDate, hour, Object, kHourOffset)
6344ACCESSORS(JSDate, min, Object, kMinOffset)
6345ACCESSORS(JSDate, sec, Object, kSecOffset)
6346
6347
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006348SMI_ACCESSORS(JSMessageObject, type, kTypeOffset)
6349ACCESSORS(JSMessageObject, argument, Object, kArgumentsOffset)
Steve Block1e0659c2011-05-24 12:43:12 +01006350ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
Steve Block1e0659c2011-05-24 12:43:12 +01006351ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
6352SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
6353SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
6354
6355
Steve Blocka7e24c12009-10-30 11:49:00 +00006356INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006357INT_ACCESSORS(Code, prologue_offset, kPrologueOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006358INT_ACCESSORS(Code, constant_pool_offset, kConstantPoolOffset)
Leon Clarkeac952652010-07-15 11:15:24 +01006359ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006360ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
Ben Murdochb0fe1622011-05-05 13:52:32 +01006361ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006362ACCESSORS(Code, raw_type_feedback_info, Object, kTypeFeedbackInfoOffset)
6363ACCESSORS(Code, next_code_link, Object, kNextCodeLinkOffset)
6364
6365
6366void Code::WipeOutHeader() {
6367 WRITE_FIELD(this, kRelocationInfoOffset, NULL);
6368 WRITE_FIELD(this, kHandlerTableOffset, NULL);
6369 WRITE_FIELD(this, kDeoptimizationDataOffset, NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006370 // 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 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006374 WRITE_FIELD(this, kNextCodeLinkOffset, NULL);
6375 WRITE_FIELD(this, kGCMetadataOffset, NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006376}
6377
6378
6379Object* Code::type_feedback_info() {
6380 DCHECK(kind() == FUNCTION);
6381 return raw_type_feedback_info();
6382}
6383
6384
6385void 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
6393uint32_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
6400void Code::set_stub_key(uint32_t key) {
6401 DCHECK(IsCodeStubOrIC());
6402 set_raw_type_feedback_info(Smi::FromInt(key));
6403}
6404
6405
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006406ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
6407INT_ACCESSORS(Code, ic_age, kICAgeOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00006408
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006409
Steve Blocka7e24c12009-10-30 11:49:00 +00006410byte* Code::instruction_start() {
6411 return FIELD_ADDR(this, kHeaderSize);
6412}
6413
6414
Leon Clarkeac952652010-07-15 11:15:24 +01006415byte* Code::instruction_end() {
6416 return instruction_start() + instruction_size();
6417}
6418
6419
Steve Blocka7e24c12009-10-30 11:49:00 +00006420int Code::body_size() {
Leon Clarkeac952652010-07-15 11:15:24 +01006421 return RoundUp(instruction_size(), kObjectAlignment);
6422}
6423
6424
6425ByteArray* Code::unchecked_relocation_info() {
6426 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
Steve Blocka7e24c12009-10-30 11:49:00 +00006427}
6428
6429
6430byte* Code::relocation_start() {
Leon Clarkeac952652010-07-15 11:15:24 +01006431 return unchecked_relocation_info()->GetDataStartAddress();
6432}
6433
6434
6435int Code::relocation_size() {
6436 return unchecked_relocation_info()->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00006437}
6438
6439
6440byte* Code::entry() {
6441 return instruction_start();
6442}
6443
6444
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006445bool Code::contains(byte* inner_pointer) {
6446 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
Steve Blocka7e24c12009-10-30 11:49:00 +00006447}
6448
6449
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006450int 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
6458int Code::CodeSize() { return SizeFor(body_size()); }
6459
6460
Steve Blocka7e24c12009-10-30 11:49:00 +00006461ACCESSORS(JSArray, length, Object, kLengthOffset)
6462
6463
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006464void* JSArrayBuffer::backing_store() const {
6465 intptr_t ptr = READ_INTPTR_FIELD(this, kBackingStoreOffset);
6466 return reinterpret_cast<void*>(ptr);
6467}
6468
6469
6470void 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
6476ACCESSORS(JSArrayBuffer, byte_length, Object, kByteLengthOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006477
6478
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006479void 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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006488}
6489
6490
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006491uint32_t JSArrayBuffer::bit_field() const {
6492 return READ_UINT32_FIELD(this, kBitFieldOffset);
6493}
6494
6495
6496bool JSArrayBuffer::is_external() { return IsExternal::decode(bit_field()); }
6497
6498
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006499void JSArrayBuffer::set_is_external(bool value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006500 set_bit_field(IsExternal::update(bit_field(), value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006501}
6502
6503
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006504bool JSArrayBuffer::is_neuterable() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006505 return IsNeuterable::decode(bit_field());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006506}
6507
6508
6509void JSArrayBuffer::set_is_neuterable(bool value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006510 set_bit_field(IsNeuterable::update(bit_field(), value));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006511}
6512
6513
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006514bool JSArrayBuffer::was_neutered() { return WasNeutered::decode(bit_field()); }
6515
6516
6517void JSArrayBuffer::set_was_neutered(bool value) {
6518 set_bit_field(WasNeutered::update(bit_field(), value));
6519}
6520
6521
6522bool JSArrayBuffer::is_shared() { return IsShared::decode(bit_field()); }
6523
6524
6525void JSArrayBuffer::set_is_shared(bool value) {
6526 set_bit_field(IsShared::update(bit_field(), value));
6527}
6528
6529
6530Object* JSArrayBufferView::byte_offset() const {
6531 if (WasNeutered()) return Smi::FromInt(0);
6532 return Object::cast(READ_FIELD(this, kByteOffsetOffset));
6533}
6534
6535
6536void 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
6542Object* JSArrayBufferView::byte_length() const {
6543 if (WasNeutered()) return Smi::FromInt(0);
6544 return Object::cast(READ_FIELD(this, kByteLengthOffset));
6545}
6546
6547
6548void JSArrayBufferView::set_byte_length(Object* value, WriteBarrierMode mode) {
6549 WRITE_FIELD(this, kByteLengthOffset, value);
6550 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kByteLengthOffset, value, mode);
6551}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006552
6553
6554ACCESSORS(JSArrayBufferView, buffer, Object, kBufferOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006555#ifdef VERIFY_HEAP
6556ACCESSORS(JSArrayBufferView, raw_byte_offset, Object, kByteOffsetOffset)
6557ACCESSORS(JSArrayBufferView, raw_byte_length, Object, kByteLengthOffset)
6558#endif
6559
6560
6561bool JSArrayBufferView::WasNeutered() const {
6562 return JSArrayBuffer::cast(buffer())->was_neutered();
6563}
6564
6565
6566Object* JSTypedArray::length() const {
6567 if (WasNeutered()) return Smi::FromInt(0);
6568 return Object::cast(READ_FIELD(this, kLengthOffset));
6569}
6570
6571
6572uint32_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
6580void 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
6587ACCESSORS(JSTypedArray, raw_length, Object, kLengthOffset)
6588#endif
6589
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006590
Steve Blocka7e24c12009-10-30 11:49:00 +00006591ACCESSORS(JSRegExp, data, Object, kDataOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006592ACCESSORS(JSRegExp, flags, Object, kFlagsOffset)
6593ACCESSORS(JSRegExp, source, Object, kSourceOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00006594
6595
6596JSRegExp::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
6604int 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
6617JSRegExp::Flags JSRegExp::GetFlags() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006618 DCHECK(this->data()->IsFixedArray());
Steve Blocka7e24c12009-10-30 11:49:00 +00006619 Object* data = this->data();
6620 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
6621 return Flags(smi->value());
6622}
6623
6624
6625String* JSRegExp::Pattern() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006626 DCHECK(this->data()->IsFixedArray());
Steve Blocka7e24c12009-10-30 11:49:00 +00006627 Object* data = this->data();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006628 String* pattern = String::cast(FixedArray::cast(data)->get(kSourceIndex));
Steve Blocka7e24c12009-10-30 11:49:00 +00006629 return pattern;
6630}
6631
6632
6633Object* JSRegExp::DataAt(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006634 DCHECK(TypeTag() != NOT_COMPILED);
Steve Blocka7e24c12009-10-30 11:49:00 +00006635 return FixedArray::cast(data())->get(index);
6636}
6637
6638
6639void JSRegExp::SetDataAt(int index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006640 DCHECK(TypeTag() != NOT_COMPILED);
6641 DCHECK(index >= kDataIndex); // Only implementation data can be set this way.
Steve Blocka7e24c12009-10-30 11:49:00 +00006642 FixedArray::cast(data())->set(index, value);
6643}
6644
6645
Ben Murdoch589d6972011-11-30 16:04:58 +00006646ElementsKind JSObject::GetElementsKind() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006647 ElementsKind kind = map()->elements_kind();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006648#if VERIFY_HEAP && DEBUG
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006649 FixedArrayBase* fixed_array =
6650 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006651
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) &&
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006657 (map == GetHeap()->fixed_array_map() ||
6658 map == GetHeap()->fixed_cow_array_map())) ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006659 (IsFastDoubleElementsKind(kind) &&
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006660 (fixed_array->IsFixedDoubleArray() ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006661 fixed_array == GetHeap()->empty_fixed_array())) ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006662 (kind == DICTIONARY_ELEMENTS &&
6663 fixed_array->IsFixedArray() &&
6664 fixed_array->IsDictionary()) ||
6665 (kind > DICTIONARY_ELEMENTS));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006666 DCHECK(!IsSloppyArgumentsElements(kind) ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006667 (elements()->IsFixedArray() && elements()->length() >= 2));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006668 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006669#endif
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006670 return kind;
Steve Blocka7e24c12009-10-30 11:49:00 +00006671}
6672
6673
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006674bool JSObject::HasFastObjectElements() {
6675 return IsFastObjectElementsKind(GetElementsKind());
Steve Blocka7e24c12009-10-30 11:49:00 +00006676}
6677
6678
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006679bool JSObject::HasFastSmiElements() {
6680 return IsFastSmiElementsKind(GetElementsKind());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006681}
6682
6683
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006684bool JSObject::HasFastSmiOrObjectElements() {
6685 return IsFastSmiOrObjectElementsKind(GetElementsKind());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006686}
6687
6688
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006689bool JSObject::HasFastDoubleElements() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006690 return IsFastDoubleElementsKind(GetElementsKind());
6691}
6692
6693
6694bool JSObject::HasFastHoleyElements() {
6695 return IsFastHoleyElementsKind(GetElementsKind());
6696}
6697
6698
6699bool JSObject::HasFastElements() {
6700 return IsFastElementsKind(GetElementsKind());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006701}
6702
6703
Steve Blocka7e24c12009-10-30 11:49:00 +00006704bool JSObject::HasDictionaryElements() {
6705 return GetElementsKind() == DICTIONARY_ELEMENTS;
6706}
6707
6708
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006709bool JSObject::HasFastArgumentsElements() {
6710 return GetElementsKind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
6711}
6712
6713
6714bool JSObject::HasSlowArgumentsElements() {
6715 return GetElementsKind() == SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
6716}
6717
6718
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006719bool JSObject::HasSloppyArgumentsElements() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006720 return IsSloppyArgumentsElements(GetElementsKind());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006721}
6722
6723
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006724bool JSObject::HasFixedTypedArrayElements() {
6725 HeapObject* array = elements();
6726 DCHECK(array != NULL);
6727 return array->IsFixedTypedArrayBase();
Steve Block3ce2e202009-11-05 08:53:23 +00006728}
6729
6730
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006731#define FIXED_TYPED_ELEMENTS_CHECK(Type, type, TYPE, ctype, size) \
6732bool 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
6740TYPED_ARRAYS(FIXED_TYPED_ELEMENTS_CHECK)
6741
6742#undef FIXED_TYPED_ELEMENTS_CHECK
Steve Block3ce2e202009-11-05 08:53:23 +00006743
6744
Steve Blocka7e24c12009-10-30 11:49:00 +00006745bool JSObject::HasNamedInterceptor() {
6746 return map()->has_named_interceptor();
6747}
6748
6749
6750bool JSObject::HasIndexedInterceptor() {
6751 return map()->has_indexed_interceptor();
6752}
6753
6754
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006755GlobalDictionary* JSObject::global_dictionary() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006756 DCHECK(!HasFastProperties());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006757 DCHECK(IsJSGlobalObject());
6758 return GlobalDictionary::cast(properties());
Steve Blocka7e24c12009-10-30 11:49:00 +00006759}
6760
6761
Ben Murdochc7cc0282012-03-05 14:35:55 +00006762SeededNumberDictionary* JSObject::element_dictionary() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006763 DCHECK(HasDictionaryElements());
Ben Murdochc7cc0282012-03-05 14:35:55 +00006764 return SeededNumberDictionary::cast(elements());
Steve Blocka7e24c12009-10-30 11:49:00 +00006765}
6766
6767
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006768bool Name::IsHashFieldComputed(uint32_t field) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006769 return (field & kHashNotComputedMask) == 0;
6770}
6771
6772
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006773bool Name::HasHashCode() {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006774 return IsHashFieldComputed(hash_field());
Steve Blocka7e24c12009-10-30 11:49:00 +00006775}
6776
6777
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006778uint32_t Name::Hash() {
Steve Blocka7e24c12009-10-30 11:49:00 +00006779 // Fast case: has hash code already been computed?
Steve Blockd0582a62009-12-15 09:54:21 +00006780 uint32_t field = hash_field();
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006781 if (IsHashFieldComputed(field)) return field >> kHashShift;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006782 // Slow case: compute hash code and set it. Has to be a string.
6783 return String::cast(this)->ComputeAndSetHash();
6784}
6785
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006786
6787bool Name::IsPrivate() {
6788 return this->IsSymbol() && Symbol::cast(this)->is_private();
Steve Blocka7e24c12009-10-30 11:49:00 +00006789}
6790
6791
Ben Murdochc7cc0282012-03-05 14:35:55 +00006792StringHasher::StringHasher(int length, uint32_t seed)
Steve Blocka7e24c12009-10-30 11:49:00 +00006793 : length_(length),
Ben Murdochc7cc0282012-03-05 14:35:55 +00006794 raw_running_hash_(seed),
Steve Blocka7e24c12009-10-30 11:49:00 +00006795 array_index_(0),
6796 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006797 is_first_char_(true) {
6798 DCHECK(FLAG_randomize_hashes || raw_running_hash_ == 0);
Ben Murdochc7cc0282012-03-05 14:35:55 +00006799}
Steve Blocka7e24c12009-10-30 11:49:00 +00006800
6801
6802bool StringHasher::has_trivial_hash() {
Steve Blockd0582a62009-12-15 09:54:21 +00006803 return length_ > String::kMaxHashCalcLength;
Steve Blocka7e24c12009-10-30 11:49:00 +00006804}
6805
6806
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006807uint32_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
6815uint32_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;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006821 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006822 return running_hash;
6823}
6824
6825
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006826uint32_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
6837uint32_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
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006850void StringHasher::AddCharacter(uint16_t c) {
Steve Blocka7e24c12009-10-30 11:49:00 +00006851 // Use the Jenkins one-at-a-time hash function to update the hash
6852 // for the given character.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006853 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c);
6854}
6855
6856
6857bool 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) {
Steve Blocka7e24c12009-10-30 11:49:00 +00006867 is_array_index_ = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006868 return false;
6869 }
6870 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006871 if (array_index_ > 429496729U - ((d + 3) >> 3)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006872 is_array_index_ = false;
6873 return false;
6874 }
6875 array_index_ = array_index_ * 10 + d;
6876 return true;
6877}
6878
6879
6880template<typename Char>
6881inline 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;
Steve Blocka7e24c12009-10-30 11:49:00 +00006890 }
6891 }
6892 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006893 for (; i < length; i++) {
6894 DCHECK(!is_array_index_);
6895 AddCharacter(chars[i]);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006896 }
Steve Blocka7e24c12009-10-30 11:49:00 +00006897}
6898
6899
Steve Block44f0eee2011-05-26 01:26:41 +01006900template <typename schar>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006901uint32_t StringHasher::HashSequentialString(const schar* chars,
6902 int length,
6903 uint32_t seed) {
Ben Murdochc7cc0282012-03-05 14:35:55 +00006904 StringHasher hasher(length, seed);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006905 if (!hasher.has_trivial_hash()) hasher.AddCharacters(chars, length);
6906 return hasher.GetHashField();
6907}
6908
6909
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006910IteratingStringHasher::IteratingStringHasher(int len, uint32_t seed)
6911 : StringHasher(len, seed) {}
6912
6913
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006914uint32_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);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006919 if (cons_string == nullptr) return hasher.GetHashField();
6920 hasher.VisitConsString(cons_string);
Steve Block44f0eee2011-05-26 01:26:41 +01006921 return hasher.GetHashField();
6922}
6923
6924
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006925void IteratingStringHasher::VisitOneByteString(const uint8_t* chars,
6926 int length) {
6927 AddCharacters(chars, length);
6928}
6929
6930
6931void IteratingStringHasher::VisitTwoByteString(const uint16_t* chars,
6932 int length) {
6933 AddCharacters(chars, length);
6934}
6935
6936
6937bool Name::AsArrayIndex(uint32_t* index) {
6938 return IsString() && String::cast(this)->AsArrayIndex(index);
6939}
6940
6941
Steve Blocka7e24c12009-10-30 11:49:00 +00006942bool String::AsArrayIndex(uint32_t* index) {
Steve Blockd0582a62009-12-15 09:54:21 +00006943 uint32_t field = hash_field();
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006944 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
6945 return false;
6946 }
Steve Blocka7e24c12009-10-30 11:49:00 +00006947 return SlowAsArrayIndex(index);
6948}
6949
6950
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006951void 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());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006958 WRITE_FIELD(this, kHashFieldSlot, canonical);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006959 // 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());
Steve Blocka7e24c12009-10-30 11:49:00 +00006963}
6964
6965
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006966String* String::GetForwardedInternalizedString() {
6967 DCHECK(IsInternalizedString());
6968 if (HasHashCode()) return this;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006969 String* canonical = String::cast(READ_FIELD(this, kHashFieldSlot));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006970 DCHECK(canonical->IsInternalizedString());
6971 DCHECK(SlowEquals(canonical));
6972 DCHECK(canonical->HasHashCode());
6973 return canonical;
6974}
6975
6976
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006977// static
6978Maybe<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
6996Maybe<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
7014Maybe<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
7032Maybe<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
7049MaybeHandle<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
7058MaybeHandle<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
7068void 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
7080bool JSReceiver::HasFastProperties() {
7081 DCHECK(properties()->IsDictionary() == map()->is_dictionary_map());
7082 return !properties()->IsDictionary();
7083}
7084
7085
7086NameDictionary* JSReceiver::property_dictionary() {
7087 DCHECK(!HasFastProperties());
7088 DCHECK(!IsJSGlobalObject());
7089 return NameDictionary::cast(properties());
7090}
7091
7092
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007093Maybe<bool> JSReceiver::HasProperty(Handle<JSReceiver> object,
7094 Handle<Name> name) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007095 LookupIterator it =
7096 LookupIterator::PropertyOrElement(object->GetIsolate(), object, name);
7097 return HasProperty(&it);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007098}
7099
7100
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007101Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object,
7102 Handle<Name> name) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007103 if (object->IsJSObject()) { // Shortcut
7104 LookupIterator it = LookupIterator::PropertyOrElement(
7105 object->GetIsolate(), object, name, LookupIterator::HIDDEN);
7106 return HasProperty(&it);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007107 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007108
7109 Maybe<PropertyAttributes> attributes =
7110 JSReceiver::GetOwnPropertyAttributes(object, name);
7111 MAYBE_RETURN(attributes, Nothing<bool>());
7112 return Just(attributes.FromJust() != ABSENT);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007113}
7114
7115
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007116Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007117 Handle<JSReceiver> object, Handle<Name> name) {
7118 LookupIterator it =
7119 LookupIterator::PropertyOrElement(name->GetIsolate(), object, name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007120 return GetPropertyAttributes(&it);
Steve Blockd0582a62009-12-15 09:54:21 +00007121}
7122
7123
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007124Maybe<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
7132Maybe<bool> JSReceiver::HasElement(Handle<JSReceiver> object, uint32_t index) {
7133 LookupIterator it(object->GetIsolate(), object, index);
7134 return HasProperty(&it);
7135}
7136
7137
7138Maybe<PropertyAttributes> JSReceiver::GetElementAttributes(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007139 Handle<JSReceiver> object, uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007140 Isolate* isolate = object->GetIsolate();
7141 LookupIterator it(isolate, object, index);
7142 return GetPropertyAttributes(&it);
7143}
7144
7145
7146Maybe<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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007151}
7152
7153
7154bool JSGlobalObject::IsDetached() {
7155 return JSGlobalProxy::cast(global_proxy())->IsDetachedFrom(this);
7156}
7157
7158
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007159bool JSGlobalProxy::IsDetachedFrom(JSGlobalObject* global) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007160 const PrototypeIterator iter(this->GetIsolate(),
7161 const_cast<JSGlobalProxy*>(this));
7162 return iter.GetCurrent() != global;
7163}
7164
7165
7166Handle<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
7173Object* JSReceiver::GetIdentityHash() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007174 return IsJSProxy()
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007175 ? JSProxy::cast(this)->GetIdentityHash()
7176 : JSObject::cast(this)->GetIdentityHash();
Steve Blockd0582a62009-12-15 09:54:21 +00007177}
7178
7179
Steve Blocka7e24c12009-10-30 11:49:00 +00007180bool AccessorInfo::all_can_read() {
7181 return BooleanBit::get(flag(), kAllCanReadBit);
7182}
7183
7184
7185void AccessorInfo::set_all_can_read(bool value) {
7186 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
7187}
7188
7189
7190bool AccessorInfo::all_can_write() {
7191 return BooleanBit::get(flag(), kAllCanWriteBit);
7192}
7193
7194
7195void AccessorInfo::set_all_can_write(bool value) {
7196 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
7197}
7198
7199
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007200bool AccessorInfo::is_special_data_property() {
7201 return BooleanBit::get(flag(), kSpecialDataProperty);
7202}
7203
7204
7205void AccessorInfo::set_is_special_data_property(bool value) {
7206 set_flag(BooleanBit::set(flag(), kSpecialDataProperty, value));
7207}
7208
7209
Steve Blocka7e24c12009-10-30 11:49:00 +00007210PropertyAttributes AccessorInfo::property_attributes() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007211 return AttributesField::decode(static_cast<uint32_t>(flag()));
Steve Blocka7e24c12009-10-30 11:49:00 +00007212}
7213
7214
7215void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007216 set_flag(AttributesField::update(flag(), attributes));
Steve Blocka7e24c12009-10-30 11:49:00 +00007217}
7218
Ben Murdoch8b112d22011-06-08 16:22:53 +01007219
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007220bool 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007228bool AccessorInfo::HasExpectedReceiverType() {
7229 return expected_receiver_type()->IsFunctionTemplateInfo();
7230}
7231
7232
7233Object* AccessorPair::get(AccessorComponent component) {
7234 return component == ACCESSOR_GETTER ? getter() : setter();
7235}
7236
7237
7238void 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
7247void AccessorPair::SetComponents(Object* getter, Object* setter) {
7248 if (!getter->IsNull()) set_getter(getter);
7249 if (!setter->IsNull()) set_setter(setter);
7250}
7251
7252
7253bool AccessorPair::Equals(AccessorPair* pair) {
7254 return (this == pair) || pair->Equals(getter(), setter());
7255}
7256
7257
7258bool AccessorPair::Equals(Object* getter_value, Object* setter_value) {
7259 return (getter() == getter_value) && (setter() == setter_value);
7260}
7261
7262
7263bool AccessorPair::ContainsAccessor() {
7264 return IsJSAccessor(getter()) || IsJSAccessor(setter());
7265}
7266
7267
7268bool AccessorPair::IsJSAccessor(Object* obj) {
7269 return obj->IsCallable() || obj->IsUndefined();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007270}
7271
7272
7273template<typename Derived, typename Shape, typename Key>
7274void Dictionary<Derived, Shape, Key>::SetEntry(int entry,
7275 Handle<Object> key,
7276 Handle<Object> value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007277 this->SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
Ben Murdoch8b112d22011-06-08 16:22:53 +01007278}
7279
7280
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007281template<typename Derived, typename Shape, typename Key>
7282void Dictionary<Derived, Shape, Key>::SetEntry(int entry,
7283 Handle<Object> key,
7284 Handle<Object> value,
7285 PropertyDetails details) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007286 Shape::SetEntry(static_cast<Derived*>(this), entry, key, value, details);
7287}
7288
7289
7290template <typename Key>
7291template <typename Dictionary>
7292void 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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007299 DisallowHeapAllocation no_gc;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007300 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
7307template <typename Dictionary>
7308void 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);
Steve Blocka7e24c12009-10-30 11:49:00 +00007320}
7321
7322
Steve Block44f0eee2011-05-26 01:26:41 +01007323bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007324 DCHECK(other->IsNumber());
Steve Block44f0eee2011-05-26 01:26:41 +01007325 return key == static_cast<uint32_t>(other->Number());
7326}
7327
7328
Ben Murdochc7cc0282012-03-05 14:35:55 +00007329uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
7330 return ComputeIntegerHash(key, 0);
Steve Block44f0eee2011-05-26 01:26:41 +01007331}
7332
7333
Ben Murdochc7cc0282012-03-05 14:35:55 +00007334uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
7335 Object* other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007336 DCHECK(other->IsNumber());
Ben Murdochc7cc0282012-03-05 14:35:55 +00007337 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
Steve Block44f0eee2011-05-26 01:26:41 +01007338}
7339
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007340
Ben Murdochc7cc0282012-03-05 14:35:55 +00007341uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
7342 return ComputeIntegerHash(key, seed);
7343}
7344
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007345
Ben Murdochc7cc0282012-03-05 14:35:55 +00007346uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
7347 uint32_t seed,
7348 Object* other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007349 DCHECK(other->IsNumber());
Ben Murdochc7cc0282012-03-05 14:35:55 +00007350 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
7351}
Steve Block44f0eee2011-05-26 01:26:41 +01007352
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007353
7354Handle<Object> NumberDictionaryShape::AsHandle(Isolate* isolate, uint32_t key) {
7355 return isolate->factory()->NewNumberFromUint(key);
Steve Block44f0eee2011-05-26 01:26:41 +01007356}
7357
7358
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007359bool NameDictionaryShape::IsMatch(Handle<Name> key, Object* other) {
Steve Block44f0eee2011-05-26 01:26:41 +01007360 // We know that all entries in a hash table had their hash keys created.
7361 // Use that knowledge to have fast failure.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007362 if (key->Hash() != Name::cast(other)->Hash()) return false;
7363 return key->Equals(Name::cast(other));
Steve Block44f0eee2011-05-26 01:26:41 +01007364}
7365
7366
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007367uint32_t NameDictionaryShape::Hash(Handle<Name> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01007368 return key->Hash();
7369}
7370
7371
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007372uint32_t NameDictionaryShape::HashForObject(Handle<Name> key, Object* other) {
7373 return Name::cast(other)->Hash();
Steve Block44f0eee2011-05-26 01:26:41 +01007374}
7375
7376
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007377Handle<Object> NameDictionaryShape::AsHandle(Isolate* isolate,
7378 Handle<Name> key) {
7379 DCHECK(key->IsUniqueName());
Steve Block44f0eee2011-05-26 01:26:41 +01007380 return key;
7381}
7382
7383
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007384Handle<FixedArray> NameDictionary::DoGenerateNewEnumerationIndices(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007385 Handle<NameDictionary> dictionary) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007386 return DerivedDictionary::GenerateNewEnumerationIndices(dictionary);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007387}
7388
7389
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007390template <typename Dictionary>
7391PropertyDetails 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
7400template <typename Dictionary>
7401void 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
7411template <typename Dictionary>
7412bool GlobalDictionaryShape::IsDeleted(Dictionary* dict, int entry) {
7413 DCHECK(dict->ValueAt(entry)->IsPropertyCell());
7414 return PropertyCell::cast(dict->ValueAt(entry))->value()->IsTheHole();
7415}
7416
7417
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007418bool ObjectHashTableShape::IsMatch(Handle<Object> key, Object* other) {
7419 return key->SameValue(other);
7420}
7421
7422
7423uint32_t ObjectHashTableShape::Hash(Handle<Object> key) {
7424 return Smi::cast(key->GetHash())->value();
7425}
7426
7427
7428uint32_t ObjectHashTableShape::HashForObject(Handle<Object> key,
7429 Object* other) {
7430 return Smi::cast(other->GetHash())->value();
7431}
7432
7433
7434Handle<Object> ObjectHashTableShape::AsHandle(Isolate* isolate,
7435 Handle<Object> key) {
7436 return key;
7437}
7438
7439
7440Handle<ObjectHashTable> ObjectHashTable::Shrink(
7441 Handle<ObjectHashTable> table, Handle<Object> key) {
7442 return DerivedHashTable::Shrink(table, key);
7443}
7444
7445
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007446Object* OrderedHashMap::ValueAt(int entry) {
7447 return get(EntryToIndex(entry) + kValueOffset);
7448}
7449
7450
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007451template <int entrysize>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007452bool WeakHashTableShape<entrysize>::IsMatch(Handle<Object> key, Object* other) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007453 if (other->IsWeakCell()) other = WeakCell::cast(other)->value();
7454 return key->IsWeakCell() ? WeakCell::cast(*key)->value() == other
7455 : *key == other;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007456}
7457
7458
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007459template <int entrysize>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007460uint32_t WeakHashTableShape<entrysize>::Hash(Handle<Object> key) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007461 intptr_t hash =
7462 key->IsWeakCell()
7463 ? reinterpret_cast<intptr_t>(WeakCell::cast(*key)->value())
7464 : reinterpret_cast<intptr_t>(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007465 return (uint32_t)(hash & 0xFFFFFFFF);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007466}
7467
7468
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007469template <int entrysize>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007470uint32_t WeakHashTableShape<entrysize>::HashForObject(Handle<Object> key,
7471 Object* other) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007472 if (other->IsWeakCell()) other = WeakCell::cast(other)->value();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007473 intptr_t hash = reinterpret_cast<intptr_t>(other);
7474 return (uint32_t)(hash & 0xFFFFFFFF);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007475}
7476
7477
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007478template <int entrysize>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007479Handle<Object> WeakHashTableShape<entrysize>::AsHandle(Isolate* isolate,
7480 Handle<Object> key) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007481 return key;
7482}
7483
7484
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007485bool ScopeInfo::IsAsmModule() { return AsmModuleField::decode(Flags()); }
7486
7487
7488bool ScopeInfo::IsAsmFunction() { return AsmFunctionField::decode(Flags()); }
7489
7490
7491bool 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 }
7505FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(SCOPE_INFO_FIELD_ACCESSORS)
7506#undef SCOPE_INFO_FIELD_ACCESSORS
7507
7508
Steve Block44f0eee2011-05-26 01:26:41 +01007509void Map::ClearCodeCache(Heap* heap) {
Steve Blocka7e24c12009-10-30 11:49:00 +00007510 // 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
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007513 // - IncrementalMarking::Step
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007514 DCHECK(!heap->InNewSpace(heap->empty_fixed_array()));
7515 WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array());
Steve Blocka7e24c12009-10-30 11:49:00 +00007516}
7517
7518
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007519int Map::SlackForArraySize(int old_size, int size_limit) {
7520 const int max_slack = size_limit - old_size;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007521 CHECK_LE(0, max_slack);
7522 if (old_size < 4) {
7523 DCHECK_LE(1, max_slack);
7524 return 1;
Steve Blockd0582a62009-12-15 09:54:21 +00007525 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007526 return Min(max_slack, old_size / 4);
Steve Blocka7e24c12009-10-30 11:49:00 +00007527}
7528
7529
Leon Clarke4515c472010-02-03 11:58:03 +00007530void JSArray::set_length(Smi* length) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007531 // Don't need a write barrier for a Smi.
Leon Clarke4515c472010-02-03 11:58:03 +00007532 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
7533}
7534
7535
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007536bool 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
7545bool JSArray::AllowsSetLength() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007546 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007547 DCHECK(result == !HasFixedTypedArrayElements());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007548 return result;
7549}
7550
7551
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007552void 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()));
Steve Blocka7e24c12009-10-30 11:49:00 +00007565}
7566
7567
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007568int TypeFeedbackInfo::ic_total_count() {
7569 int current = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7570 return ICTotalCountField::decode(current);
Steve Block44f0eee2011-05-26 01:26:41 +01007571}
7572
7573
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007574void 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));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007579}
7580
7581
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007582int TypeFeedbackInfo::ic_with_type_info_count() {
7583 int current = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7584 return ICsWithTypeInfoCountField::decode(current);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007585}
7586
7587
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007588void 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 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007602}
7603
7604
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007605int TypeFeedbackInfo::ic_generic_count() {
7606 return Smi::cast(READ_FIELD(this, kStorage3Offset))->value();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007607}
7608
7609
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007610void 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 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007617}
7618
7619
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007620void 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));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007624}
7625
7626
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007627void 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));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007636}
7637
7638
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007639void 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));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007647}
7648
7649
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007650int TypeFeedbackInfo::own_type_change_checksum() {
7651 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7652 return OwnTypeChangeChecksum::decode(value);
7653}
7654
7655
7656bool 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}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007661
7662
7663SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
7664
7665
Steve Block44f0eee2011-05-26 01:26:41 +01007666Relocatable::Relocatable(Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +01007667 isolate_ = isolate;
7668 prev_ = isolate->relocatable_top();
7669 isolate->set_relocatable_top(this);
7670}
7671
7672
7673Relocatable::~Relocatable() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007674 DCHECK_EQ(isolate_->relocatable_top(), this);
Steve Block44f0eee2011-05-26 01:26:41 +01007675 isolate_->set_relocatable_top(prev_);
Steve Blocka7e24c12009-10-30 11:49:00 +00007676}
7677
7678
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007679template<class Derived, class TableType>
7680Object* 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
7689void JSSetIterator::PopulateValueArray(FixedArray* array) {
7690 array->set(0, CurrentKey());
7691}
7692
7693
7694void JSMapIterator::PopulateValueArray(FixedArray* array) {
7695 array->set(0, CurrentKey());
7696 array->set(1, CurrentValue());
7697}
7698
7699
7700Object* 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
Iain Merrick75681382010-08-19 15:07:18 +01007708
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007709ACCESSORS(JSIteratorResult, done, Object, kDoneOffset)
7710ACCESSORS(JSIteratorResult, value, Object, kValueOffset)
7711
7712
7713String::SubStringRange::SubStringRange(String* string, int first, int length)
7714 : string_(string),
7715 first_(first),
7716 length_(length == -1 ? string->length() : length) {}
7717
7718
7719class 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
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;
7745 iterator(String* from, int offset)
7746 : content_(from->GetFlatContent()), offset_(offset) {}
7747 String::FlatContent content_;
7748 int offset_;
7749};
7750
7751
7752String::SubStringRange::iterator String::SubStringRange::begin() {
7753 return String::SubStringRange::iterator(string_, first_);
7754}
7755
7756
7757String::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.
7764static 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
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007770#undef TYPE_CHECKER
Steve Blocka7e24c12009-10-30 11:49:00 +00007771#undef CAST_ACCESSOR
7772#undef INT_ACCESSORS
Ben Murdoch85b71792012-04-11 18:30:58 +01007773#undef ACCESSORS
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007774#undef SMI_ACCESSORS
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007775#undef SYNCHRONIZED_SMI_ACCESSORS
7776#undef NOBARRIER_SMI_ACCESSORS
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007777#undef BOOL_GETTER
7778#undef BOOL_ACCESSORS
Steve Blocka7e24c12009-10-30 11:49:00 +00007779#undef FIELD_ADDR
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007780#undef FIELD_ADDR_CONST
Steve Blocka7e24c12009-10-30 11:49:00 +00007781#undef READ_FIELD
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007782#undef NOBARRIER_READ_FIELD
Steve Blocka7e24c12009-10-30 11:49:00 +00007783#undef WRITE_FIELD
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007784#undef NOBARRIER_WRITE_FIELD
Steve Blocka7e24c12009-10-30 11:49:00 +00007785#undef WRITE_BARRIER
7786#undef CONDITIONAL_WRITE_BARRIER
Steve Blocka7e24c12009-10-30 11:49:00 +00007787#undef READ_DOUBLE_FIELD
7788#undef WRITE_DOUBLE_FIELD
7789#undef READ_INT_FIELD
7790#undef WRITE_INT_FIELD
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007791#undef READ_INTPTR_FIELD
7792#undef WRITE_INTPTR_FIELD
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007793#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
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007801#undef READ_UINT32_FIELD
7802#undef WRITE_UINT32_FIELD
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007803#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
Steve Blocka7e24c12009-10-30 11:49:00 +00007811#undef READ_BYTE_FIELD
7812#undef WRITE_BYTE_FIELD
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007813#undef NOBARRIER_READ_BYTE_FIELD
7814#undef NOBARRIER_WRITE_BYTE_FIELD
Steve Blocka7e24c12009-10-30 11:49:00 +00007815
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007816} // namespace internal
7817} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +00007818
7819#endif // V8_OBJECTS_INL_H_