blob: f4d7fb9fa2eb9b3ba21481b59363649552a85300 [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"
Ben Murdoch097c5b22016-05-18 11:27:45 +010021#include "src/handles-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000022#include "src/heap/heap-inl.h"
23#include "src/heap/heap.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024#include "src/isolate.h"
Ben Murdochda12d292016-06-02 14:46:10 +010025#include "src/isolate-inl.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040026#include "src/layout-descriptor-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000027#include "src/lookup.h"
28#include "src/objects.h"
29#include "src/property.h"
30#include "src/prototype.h"
31#include "src/transitions-inl.h"
32#include "src/type-feedback-vector-inl.h"
33#include "src/v8memory.h"
Ben Murdoch592a9fc2012-03-05 11:04:45 +000034
Steve Blocka7e24c12009-10-30 11:49:00 +000035namespace v8 {
36namespace internal {
37
38PropertyDetails::PropertyDetails(Smi* smi) {
39 value_ = smi->value();
40}
41
42
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043Smi* PropertyDetails::AsSmi() const {
44 // Ensure the upper 2 bits have the same value by sign extending it. This is
45 // necessary to be able to use the 31st bit of the property details.
46 int value = value_ << 1;
47 return Smi::FromInt(value >> 1);
Steve Blocka7e24c12009-10-30 11:49:00 +000048}
49
50
Emily Bernierd0a1eb72015-03-24 16:35:39 -040051int PropertyDetails::field_width_in_words() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000052 DCHECK(location() == kField);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040053 if (!FLAG_unbox_double_fields) return 1;
54 if (kDoubleSize == kPointerSize) return 1;
55 return representation().IsDouble() ? kDoubleSize / kPointerSize : 1;
56}
57
Ben Murdoch097c5b22016-05-18 11:27:45 +010058#define TYPE_CHECKER(type, instancetype) \
59 bool HeapObject::Is##type() const { \
60 return map()->instance_type() == instancetype; \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010061 }
62
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063#define CAST_ACCESSOR(type) \
64 type* type::cast(Object* object) { \
65 SLOW_DCHECK(object->Is##type()); \
66 return reinterpret_cast<type*>(object); \
67 } \
68 const type* type::cast(const Object* object) { \
69 SLOW_DCHECK(object->Is##type()); \
70 return reinterpret_cast<const type*>(object); \
Steve Blocka7e24c12009-10-30 11:49:00 +000071 }
72
73
Ben Murdochb8a8cc12014-11-26 15:28:44 +000074#define INT_ACCESSORS(holder, name, offset) \
75 int holder::name() const { return READ_INT_FIELD(this, offset); } \
Steve Blocka7e24c12009-10-30 11:49:00 +000076 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
77
78
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079#define ACCESSORS(holder, name, type, offset) \
80 type* holder::name() const { return type::cast(READ_FIELD(this, offset)); } \
81 void holder::set_##name(type* value, WriteBarrierMode mode) { \
82 WRITE_FIELD(this, offset, value); \
83 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
Steve Blocka7e24c12009-10-30 11:49:00 +000084 }
85
86
Ben Murdoch3ef787d2012-04-12 10:51:47 +010087// Getter that returns a Smi as an int and writes an int as a Smi.
Steve Blocka7e24c12009-10-30 11:49:00 +000088#define SMI_ACCESSORS(holder, name, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000089 int holder::name() const { \
Steve Blocka7e24c12009-10-30 11:49:00 +000090 Object* value = READ_FIELD(this, offset); \
91 return Smi::cast(value)->value(); \
92 } \
93 void holder::set_##name(int value) { \
94 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
95 }
96
Ben Murdochb8a8cc12014-11-26 15:28:44 +000097#define SYNCHRONIZED_SMI_ACCESSORS(holder, name, offset) \
98 int holder::synchronized_##name() const { \
99 Object* value = ACQUIRE_READ_FIELD(this, offset); \
100 return Smi::cast(value)->value(); \
101 } \
102 void holder::synchronized_set_##name(int value) { \
103 RELEASE_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
104 }
105
106#define NOBARRIER_SMI_ACCESSORS(holder, name, offset) \
107 int holder::nobarrier_##name() const { \
108 Object* value = NOBARRIER_READ_FIELD(this, offset); \
109 return Smi::cast(value)->value(); \
110 } \
111 void holder::nobarrier_set_##name(int value) { \
112 NOBARRIER_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
113 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000114
115#define BOOL_GETTER(holder, field, name, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000116 bool holder::name() const { \
Steve Blocka7e24c12009-10-30 11:49:00 +0000117 return BooleanBit::get(field(), offset); \
118 } \
119
120
121#define BOOL_ACCESSORS(holder, field, name, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000122 bool holder::name() const { \
Steve Blocka7e24c12009-10-30 11:49:00 +0000123 return BooleanBit::get(field(), offset); \
124 } \
125 void holder::set_##name(bool value) { \
126 set_##field(BooleanBit::set(field(), offset, value)); \
127 }
128
Ben Murdoch097c5b22016-05-18 11:27:45 +0100129bool HeapObject::IsFixedArrayBase() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000130 return IsFixedArray() || IsFixedDoubleArray() || IsFixedTypedArrayBase();
131}
132
Ben Murdoch097c5b22016-05-18 11:27:45 +0100133bool HeapObject::IsFixedArray() const {
134 InstanceType instance_type = map()->instance_type();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000135 return instance_type == FIXED_ARRAY_TYPE ||
136 instance_type == TRANSITION_ARRAY_TYPE;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100137}
138
139
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140// External objects are not extensible, so the map check is enough.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100141bool HeapObject::IsExternal() const {
142 return map() == GetHeap()->external_map();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100143}
144
145
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100146TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147TYPE_CHECKER(MutableHeapNumber, MUTABLE_HEAP_NUMBER_TYPE)
148TYPE_CHECKER(Symbol, SYMBOL_TYPE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000149TYPE_CHECKER(Simd128Value, SIMD128_VALUE_TYPE)
150
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000151#define SIMD128_TYPE_CHECKER(TYPE, Type, type, lane_count, lane_type) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100152 bool HeapObject::Is##Type() const { return map() == GetHeap()->type##_map(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000153SIMD128_TYPES(SIMD128_TYPE_CHECKER)
154#undef SIMD128_TYPE_CHECKER
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100155
Ben Murdoch097c5b22016-05-18 11:27:45 +0100156#define IS_TYPE_FUNCTION_DEF(type_) \
157 bool Object::Is##type_() const { \
158 return IsHeapObject() && HeapObject::cast(this)->Is##type_(); \
159 }
160HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DEF)
161ODDBALL_LIST(IS_TYPE_FUNCTION_DEF)
162#undef IS_TYPE_FUNCTION_DEF
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100163
Ben Murdoch097c5b22016-05-18 11:27:45 +0100164bool HeapObject::IsString() const {
165 return map()->instance_type() < FIRST_NONSTRING_TYPE;
Steve Blocka7e24c12009-10-30 11:49:00 +0000166}
167
Ben Murdoch097c5b22016-05-18 11:27:45 +0100168bool HeapObject::IsName() const {
169 return map()->instance_type() <= LAST_NAME_TYPE;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000170}
171
Ben Murdoch097c5b22016-05-18 11:27:45 +0100172bool HeapObject::IsUniqueName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000173 return IsInternalizedString() || IsSymbol();
174}
175
Ben Murdoch097c5b22016-05-18 11:27:45 +0100176bool Name::IsUniqueName() const {
177 uint32_t type = map()->instance_type();
178 return (type & (kIsNotStringMask | kIsNotInternalizedMask)) !=
179 (kStringTag | kNotInternalizedTag);
180}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000181
Ben Murdoch097c5b22016-05-18 11:27:45 +0100182bool HeapObject::IsFunction() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000183 STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100184 return map()->instance_type() >= FIRST_FUNCTION_TYPE;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000185}
186
Ben Murdoch097c5b22016-05-18 11:27:45 +0100187bool HeapObject::IsCallable() const { return map()->is_callable(); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000188
Ben Murdoch097c5b22016-05-18 11:27:45 +0100189bool HeapObject::IsConstructor() const { return map()->is_constructor(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000190
Ben Murdoch097c5b22016-05-18 11:27:45 +0100191bool HeapObject::IsTemplateInfo() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000192 return IsObjectTemplateInfo() || IsFunctionTemplateInfo();
Steve Blocka7e24c12009-10-30 11:49:00 +0000193}
194
Ben Murdoch097c5b22016-05-18 11:27:45 +0100195bool HeapObject::IsInternalizedString() const {
196 uint32_t type = map()->instance_type();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000197 STATIC_ASSERT(kNotInternalizedTag != 0);
198 return (type & (kIsNotStringMask | kIsNotInternalizedMask)) ==
199 (kStringTag | kInternalizedTag);
200}
201
Ben Murdoch097c5b22016-05-18 11:27:45 +0100202bool HeapObject::IsConsString() const {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000203 if (!IsString()) return false;
204 return StringShape(String::cast(this)).IsCons();
205}
206
Ben Murdoch097c5b22016-05-18 11:27:45 +0100207bool HeapObject::IsSlicedString() const {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000208 if (!IsString()) return false;
209 return StringShape(String::cast(this)).IsSliced();
Steve Blocka7e24c12009-10-30 11:49:00 +0000210}
211
Ben Murdoch097c5b22016-05-18 11:27:45 +0100212bool HeapObject::IsSeqString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000213 if (!IsString()) return false;
214 return StringShape(String::cast(this)).IsSequential();
215}
216
Ben Murdoch097c5b22016-05-18 11:27:45 +0100217bool HeapObject::IsSeqOneByteString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000218 if (!IsString()) return false;
219 return StringShape(String::cast(this)).IsSequential() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000220 String::cast(this)->IsOneByteRepresentation();
Steve Blocka7e24c12009-10-30 11:49:00 +0000221}
222
Ben Murdoch097c5b22016-05-18 11:27:45 +0100223bool HeapObject::IsSeqTwoByteString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000224 if (!IsString()) return false;
225 return StringShape(String::cast(this)).IsSequential() &&
226 String::cast(this)->IsTwoByteRepresentation();
227}
228
Ben Murdoch097c5b22016-05-18 11:27:45 +0100229bool HeapObject::IsExternalString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000230 if (!IsString()) return false;
231 return StringShape(String::cast(this)).IsExternal();
232}
233
Ben Murdoch097c5b22016-05-18 11:27:45 +0100234bool HeapObject::IsExternalOneByteString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000235 if (!IsString()) return false;
236 return StringShape(String::cast(this)).IsExternal() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000237 String::cast(this)->IsOneByteRepresentation();
Steve Blocka7e24c12009-10-30 11:49:00 +0000238}
239
Ben Murdoch097c5b22016-05-18 11:27:45 +0100240bool HeapObject::IsExternalTwoByteString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000241 if (!IsString()) return false;
242 return StringShape(String::cast(this)).IsExternal() &&
243 String::cast(this)->IsTwoByteRepresentation();
244}
245
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000246
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000247bool Object::HasValidElements() {
248 // Dictionary is covered under FixedArray.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000249 return IsFixedArray() || IsFixedDoubleArray() || IsFixedTypedArrayBase();
250}
251
252
253bool Object::KeyEquals(Object* second) {
254 Object* first = this;
255 if (second->IsNumber()) {
256 if (first->IsNumber()) return first->Number() == second->Number();
257 Object* temp = first;
258 first = second;
259 second = temp;
260 }
261 if (first->IsNumber()) {
262 DCHECK_LE(0, first->Number());
263 uint32_t expected = static_cast<uint32_t>(first->Number());
264 uint32_t index;
265 return Name::cast(second)->AsArrayIndex(&index) && index == expected;
266 }
267 return Name::cast(first)->Equals(Name::cast(second));
268}
269
270
271bool Object::FilterKey(PropertyFilter filter) {
272 if (IsSymbol()) {
273 if (filter & SKIP_SYMBOLS) return true;
274 if (Symbol::cast(this)->is_private()) return true;
275 } else {
276 if (filter & SKIP_STRINGS) return true;
277 }
278 return false;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000279}
Steve Blocka7e24c12009-10-30 11:49:00 +0000280
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000281
282Handle<Object> Object::NewStorageFor(Isolate* isolate,
283 Handle<Object> object,
284 Representation representation) {
285 if (representation.IsSmi() && object->IsUninitialized()) {
286 return handle(Smi::FromInt(0), isolate);
287 }
288 if (!representation.IsDouble()) return object;
289 double value;
290 if (object->IsUninitialized()) {
291 value = 0;
292 } else if (object->IsMutableHeapNumber()) {
293 value = HeapNumber::cast(*object)->value();
294 } else {
295 value = object->Number();
296 }
297 return isolate->factory()->NewHeapNumber(value, MUTABLE);
298}
299
300
301Handle<Object> Object::WrapForRead(Isolate* isolate,
302 Handle<Object> object,
303 Representation representation) {
304 DCHECK(!object->IsUninitialized());
305 if (!representation.IsDouble()) {
306 DCHECK(object->FitsRepresentation(representation));
307 return object;
308 }
309 return isolate->factory()->NewHeapNumber(HeapNumber::cast(*object)->value());
310}
311
312
313StringShape::StringShape(const String* str)
Steve Blocka7e24c12009-10-30 11:49:00 +0000314 : type_(str->map()->instance_type()) {
315 set_valid();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000316 DCHECK((type_ & kIsNotStringMask) == kStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000317}
318
319
320StringShape::StringShape(Map* map)
321 : type_(map->instance_type()) {
322 set_valid();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000323 DCHECK((type_ & kIsNotStringMask) == kStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000324}
325
326
327StringShape::StringShape(InstanceType t)
328 : type_(static_cast<uint32_t>(t)) {
329 set_valid();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000330 DCHECK((type_ & kIsNotStringMask) == kStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000331}
332
333
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000334bool StringShape::IsInternalized() {
335 DCHECK(valid());
336 STATIC_ASSERT(kNotInternalizedTag != 0);
337 return (type_ & (kIsNotStringMask | kIsNotInternalizedMask)) ==
338 (kStringTag | kInternalizedTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000339}
340
341
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000342bool String::IsOneByteRepresentation() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000343 uint32_t type = map()->instance_type();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000344 return (type & kStringEncodingMask) == kOneByteStringTag;
Steve Blocka7e24c12009-10-30 11:49:00 +0000345}
346
347
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000348bool String::IsTwoByteRepresentation() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000349 uint32_t type = map()->instance_type();
Steve Blocka7e24c12009-10-30 11:49:00 +0000350 return (type & kStringEncodingMask) == kTwoByteStringTag;
351}
352
353
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000354bool String::IsOneByteRepresentationUnderneath() {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000355 uint32_t type = map()->instance_type();
356 STATIC_ASSERT(kIsIndirectStringTag != 0);
357 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000358 DCHECK(IsFlat());
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000359 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000360 case kOneByteStringTag:
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000361 return true;
362 case kTwoByteStringTag:
363 return false;
364 default: // Cons or sliced string. Need to go deeper.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000365 return GetUnderlying()->IsOneByteRepresentation();
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000366 }
367}
368
369
370bool String::IsTwoByteRepresentationUnderneath() {
371 uint32_t type = map()->instance_type();
372 STATIC_ASSERT(kIsIndirectStringTag != 0);
373 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000374 DCHECK(IsFlat());
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000375 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000376 case kOneByteStringTag:
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000377 return false;
378 case kTwoByteStringTag:
379 return true;
380 default: // Cons or sliced string. Need to go deeper.
381 return GetUnderlying()->IsTwoByteRepresentation();
382 }
383}
384
385
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000386bool String::HasOnlyOneByteChars() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100387 uint32_t type = map()->instance_type();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000388 return (type & kOneByteDataHintMask) == kOneByteDataHintTag ||
389 IsOneByteRepresentation();
Steve Block6ded16b2010-05-10 14:33:55 +0100390}
391
392
Steve Blocka7e24c12009-10-30 11:49:00 +0000393bool StringShape::IsCons() {
394 return (type_ & kStringRepresentationMask) == kConsStringTag;
395}
396
397
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000398bool StringShape::IsSliced() {
399 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
400}
401
402
403bool StringShape::IsIndirect() {
404 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
405}
406
407
Steve Blocka7e24c12009-10-30 11:49:00 +0000408bool StringShape::IsExternal() {
409 return (type_ & kStringRepresentationMask) == kExternalStringTag;
410}
411
412
413bool StringShape::IsSequential() {
414 return (type_ & kStringRepresentationMask) == kSeqStringTag;
415}
416
417
418StringRepresentationTag StringShape::representation_tag() {
419 uint32_t tag = (type_ & kStringRepresentationMask);
420 return static_cast<StringRepresentationTag>(tag);
421}
422
423
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000424uint32_t StringShape::encoding_tag() {
425 return type_ & kStringEncodingMask;
426}
427
428
Steve Blocka7e24c12009-10-30 11:49:00 +0000429uint32_t StringShape::full_representation_tag() {
430 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
431}
432
433
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000434STATIC_ASSERT((kStringRepresentationMask | kStringEncodingMask) ==
Steve Blocka7e24c12009-10-30 11:49:00 +0000435 Internals::kFullStringRepresentationMask);
436
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000437STATIC_ASSERT(static_cast<uint32_t>(kStringEncodingMask) ==
438 Internals::kStringEncodingMask);
Steve Blocka7e24c12009-10-30 11:49:00 +0000439
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000440
441bool StringShape::IsSequentialOneByte() {
442 return full_representation_tag() == (kSeqStringTag | kOneByteStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000443}
444
445
446bool StringShape::IsSequentialTwoByte() {
447 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
448}
449
450
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000451bool StringShape::IsExternalOneByte() {
452 return full_representation_tag() == (kExternalStringTag | kOneByteStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000453}
454
455
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000456STATIC_ASSERT((kExternalStringTag | kOneByteStringTag) ==
457 Internals::kExternalOneByteRepresentationTag);
458
459STATIC_ASSERT(v8::String::ONE_BYTE_ENCODING == kOneByteStringTag);
460
461
Steve Blocka7e24c12009-10-30 11:49:00 +0000462bool StringShape::IsExternalTwoByte() {
463 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
464}
465
466
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000467STATIC_ASSERT((kExternalStringTag | kTwoByteStringTag) ==
Steve Blocka7e24c12009-10-30 11:49:00 +0000468 Internals::kExternalTwoByteRepresentationTag);
469
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000470STATIC_ASSERT(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000471
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400472
Steve Blocka7e24c12009-10-30 11:49:00 +0000473uc32 FlatStringReader::Get(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000474 if (is_one_byte_) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400475 return Get<uint8_t>(index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000476 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400477 return Get<uc16>(index);
478 }
479}
480
481
482template <typename Char>
483Char FlatStringReader::Get(int index) {
484 DCHECK_EQ(is_one_byte_, sizeof(Char) == 1);
485 DCHECK(0 <= index && index <= length_);
486 if (sizeof(Char) == 1) {
487 return static_cast<Char>(static_cast<const uint8_t*>(start_)[index]);
488 } else {
489 return static_cast<Char>(static_cast<const uc16*>(start_)[index]);
Steve Blocka7e24c12009-10-30 11:49:00 +0000490 }
491}
492
493
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000494Handle<Object> StringTableShape::AsHandle(Isolate* isolate, HashTableKey* key) {
495 return key->AsHandle(isolate);
496}
497
498
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000499Handle<Object> CompilationCacheShape::AsHandle(Isolate* isolate,
500 HashTableKey* key) {
501 return key->AsHandle(isolate);
502}
503
504
505Handle<Object> CodeCacheHashTableShape::AsHandle(Isolate* isolate,
506 HashTableKey* key) {
507 return key->AsHandle(isolate);
508}
509
510template <typename Char>
511class SequentialStringKey : public HashTableKey {
512 public:
513 explicit SequentialStringKey(Vector<const Char> string, uint32_t seed)
514 : string_(string), hash_field_(0), seed_(seed) { }
515
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000516 uint32_t Hash() override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000517 hash_field_ = StringHasher::HashSequentialString<Char>(string_.start(),
518 string_.length(),
519 seed_);
520
521 uint32_t result = hash_field_ >> String::kHashShift;
522 DCHECK(result != 0); // Ensure that the hash value of 0 is never computed.
523 return result;
524 }
525
526
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000527 uint32_t HashForObject(Object* other) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000528 return String::cast(other)->Hash();
529 }
530
531 Vector<const Char> string_;
532 uint32_t hash_field_;
533 uint32_t seed_;
534};
535
536
537class OneByteStringKey : public SequentialStringKey<uint8_t> {
538 public:
539 OneByteStringKey(Vector<const uint8_t> str, uint32_t seed)
540 : SequentialStringKey<uint8_t>(str, seed) { }
541
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000542 bool IsMatch(Object* string) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000543 return String::cast(string)->IsOneByteEqualTo(string_);
544 }
545
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000546 Handle<Object> AsHandle(Isolate* isolate) override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000547};
548
549
550class SeqOneByteSubStringKey : public HashTableKey {
551 public:
552 SeqOneByteSubStringKey(Handle<SeqOneByteString> string, int from, int length)
553 : string_(string), from_(from), length_(length) {
554 DCHECK(string_->IsSeqOneByteString());
555 }
556
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000557 uint32_t Hash() override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000558 DCHECK(length_ >= 0);
559 DCHECK(from_ + length_ <= string_->length());
560 const uint8_t* chars = string_->GetChars() + from_;
561 hash_field_ = StringHasher::HashSequentialString(
562 chars, length_, string_->GetHeap()->HashSeed());
563 uint32_t result = hash_field_ >> String::kHashShift;
564 DCHECK(result != 0); // Ensure that the hash value of 0 is never computed.
565 return result;
566 }
567
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000568 uint32_t HashForObject(Object* other) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000569 return String::cast(other)->Hash();
570 }
571
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000572 bool IsMatch(Object* string) override;
573 Handle<Object> AsHandle(Isolate* isolate) override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000574
575 private:
576 Handle<SeqOneByteString> string_;
577 int from_;
578 int length_;
579 uint32_t hash_field_;
580};
581
582
583class TwoByteStringKey : public SequentialStringKey<uc16> {
584 public:
585 explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed)
586 : SequentialStringKey<uc16>(str, seed) { }
587
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000588 bool IsMatch(Object* string) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000589 return String::cast(string)->IsTwoByteEqualTo(string_);
590 }
591
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000592 Handle<Object> AsHandle(Isolate* isolate) override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000593};
594
595
596// Utf8StringKey carries a vector of chars as key.
597class Utf8StringKey : public HashTableKey {
598 public:
599 explicit Utf8StringKey(Vector<const char> string, uint32_t seed)
600 : string_(string), hash_field_(0), seed_(seed) { }
601
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000602 bool IsMatch(Object* string) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000603 return String::cast(string)->IsUtf8EqualTo(string_);
604 }
605
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000606 uint32_t Hash() override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000607 if (hash_field_ != 0) return hash_field_ >> String::kHashShift;
608 hash_field_ = StringHasher::ComputeUtf8Hash(string_, seed_, &chars_);
609 uint32_t result = hash_field_ >> String::kHashShift;
610 DCHECK(result != 0); // Ensure that the hash value of 0 is never computed.
611 return result;
612 }
613
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000614 uint32_t HashForObject(Object* other) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000615 return String::cast(other)->Hash();
616 }
617
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000618 Handle<Object> AsHandle(Isolate* isolate) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000619 if (hash_field_ == 0) Hash();
620 return isolate->factory()->NewInternalizedStringFromUtf8(
621 string_, chars_, hash_field_);
622 }
623
624 Vector<const char> string_;
625 uint32_t hash_field_;
626 int chars_; // Caches the number of characters when computing the hash code.
627 uint32_t seed_;
628};
629
630
631bool Object::IsNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000632 return IsSmi() || IsHeapNumber();
633}
634
635
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100636TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000637TYPE_CHECKER(BytecodeArray, BYTECODE_ARRAY_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100638TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
639
Ben Murdoch097c5b22016-05-18 11:27:45 +0100640bool HeapObject::IsFiller() const {
641 InstanceType instance_type = map()->instance_type();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100642 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
Steve Blocka7e24c12009-10-30 11:49:00 +0000643}
644
645
Steve Block3ce2e202009-11-05 08:53:23 +0000646
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000647#define TYPED_ARRAY_TYPE_CHECKER(Type, type, TYPE, ctype, size) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000648 TYPE_CHECKER(Fixed##Type##Array, FIXED_##TYPE##_ARRAY_TYPE)
649
650TYPED_ARRAYS(TYPED_ARRAY_TYPE_CHECKER)
651#undef TYPED_ARRAY_TYPE_CHECKER
Ben Murdoch257744e2011-11-30 15:57:28 +0000652
Ben Murdoch097c5b22016-05-18 11:27:45 +0100653bool HeapObject::IsFixedTypedArrayBase() const {
654 InstanceType instance_type = map()->instance_type();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000655 return (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE &&
656 instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000657}
658
Ben Murdoch097c5b22016-05-18 11:27:45 +0100659bool HeapObject::IsJSReceiver() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100660 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100661 return map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000662}
663
Ben Murdoch097c5b22016-05-18 11:27:45 +0100664bool HeapObject::IsJSObject() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100665 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100666 return map()->IsJSObjectMap();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000667}
668
Ben Murdoch097c5b22016-05-18 11:27:45 +0100669bool HeapObject::IsJSProxy() const { return map()->IsJSProxyMap(); }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000670
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100671TYPE_CHECKER(JSSet, JS_SET_TYPE)
672TYPE_CHECKER(JSMap, JS_MAP_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000673TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE)
674TYPE_CHECKER(JSMapIterator, JS_MAP_ITERATOR_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100675TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000676TYPE_CHECKER(JSWeakSet, JS_WEAK_SET_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100677TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
678TYPE_CHECKER(Map, MAP_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100679TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400680TYPE_CHECKER(WeakFixedArray, FIXED_ARRAY_TYPE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000681TYPE_CHECKER(TransitionArray, TRANSITION_ARRAY_TYPE)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000682
Ben Murdoch097c5b22016-05-18 11:27:45 +0100683bool HeapObject::IsJSWeakCollection() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000684 return IsJSWeakMap() || IsJSWeakSet();
685}
686
Ben Murdoch097c5b22016-05-18 11:27:45 +0100687bool HeapObject::IsDescriptorArray() const { return IsFixedArray(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000688
Ben Murdoch097c5b22016-05-18 11:27:45 +0100689bool HeapObject::IsArrayList() const { return IsFixedArray(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000690
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400691bool Object::IsLayoutDescriptor() const {
692 return IsSmi() || IsFixedTypedArrayBase();
693}
694
Ben Murdoch097c5b22016-05-18 11:27:45 +0100695bool HeapObject::IsTypeFeedbackVector() const { return IsFixedArray(); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400696
Ben Murdoch097c5b22016-05-18 11:27:45 +0100697bool HeapObject::IsTypeFeedbackMetadata() const { return IsFixedArray(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000698
Ben Murdoch097c5b22016-05-18 11:27:45 +0100699bool HeapObject::IsLiteralsArray() const { return IsFixedArray(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000700
Ben Murdoch097c5b22016-05-18 11:27:45 +0100701bool HeapObject::IsDeoptimizationInputData() const {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100702 // Must be a fixed array.
703 if (!IsFixedArray()) return false;
704
705 // There's no sure way to detect the difference between a fixed array and
706 // a deoptimization data array. Since this is used for asserts we can
707 // check that the length is zero or else the fixed size plus a multiple of
708 // the entry size.
709 int length = FixedArray::cast(this)->length();
710 if (length == 0) return true;
711
712 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000713 return length >= 0 && length % DeoptimizationInputData::kDeoptEntrySize == 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100714}
715
Ben Murdoch097c5b22016-05-18 11:27:45 +0100716bool HeapObject::IsDeoptimizationOutputData() const {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100717 if (!IsFixedArray()) return false;
718 // There's actually no way to see the difference between a fixed array and
719 // a deoptimization data array. Since this is used for asserts we can check
720 // that the length is plausible though.
721 if (FixedArray::cast(this)->length() % 2 != 0) return false;
722 return true;
723}
724
Ben Murdoch097c5b22016-05-18 11:27:45 +0100725bool HeapObject::IsHandlerTable() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000726 if (!IsFixedArray()) return false;
727 // There's actually no way to see the difference between a fixed array and
728 // a handler table array.
729 return true;
730}
731
Ben Murdoch097c5b22016-05-18 11:27:45 +0100732bool HeapObject::IsDependentCode() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100733 if (!IsFixedArray()) return false;
734 // There's actually no way to see the difference between a fixed array and
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000735 // a dependent codes array.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100736 return true;
737}
738
Ben Murdoch097c5b22016-05-18 11:27:45 +0100739bool HeapObject::IsContext() const {
740 Map* map = this->map();
741 Heap* heap = GetHeap();
Ben Murdochda12d292016-06-02 14:46:10 +0100742 return (
743 map == heap->function_context_map() || map == heap->catch_context_map() ||
744 map == heap->with_context_map() || map == heap->native_context_map() ||
745 map == heap->block_context_map() || map == heap->module_context_map() ||
746 map == heap->script_context_map() ||
747 map == heap->debug_evaluate_context_map());
Steve Blocka7e24c12009-10-30 11:49:00 +0000748}
749
Ben Murdoch097c5b22016-05-18 11:27:45 +0100750bool HeapObject::IsNativeContext() const {
751 return map() == GetHeap()->native_context_map();
Steve Blocka7e24c12009-10-30 11:49:00 +0000752}
753
Ben Murdoch097c5b22016-05-18 11:27:45 +0100754bool HeapObject::IsScriptContextTable() const {
755 return map() == GetHeap()->script_context_table_map();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400756}
757
Ben Murdoch097c5b22016-05-18 11:27:45 +0100758bool HeapObject::IsScopeInfo() const {
759 return map() == GetHeap()->scope_info_map();
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000760}
761
762
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000763TYPE_CHECKER(JSBoundFunction, JS_BOUND_FUNCTION_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100764TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000765
766
767template <> inline bool Is<JSFunction>(Object* obj) {
768 return obj->IsJSFunction();
769}
770
771
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100772TYPE_CHECKER(Code, CODE_TYPE)
773TYPE_CHECKER(Oddball, ODDBALL_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000774TYPE_CHECKER(Cell, CELL_TYPE)
775TYPE_CHECKER(PropertyCell, PROPERTY_CELL_TYPE)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400776TYPE_CHECKER(WeakCell, WEAK_CELL_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100777TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000778TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE)
779TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100780TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
781TYPE_CHECKER(JSDate, JS_DATE_TYPE)
782TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000783
Ben Murdoch097c5b22016-05-18 11:27:45 +0100784bool HeapObject::IsAbstractCode() const {
785 return IsBytecodeArray() || IsCode();
786}
Steve Blocka7e24c12009-10-30 11:49:00 +0000787
Ben Murdoch097c5b22016-05-18 11:27:45 +0100788bool HeapObject::IsStringWrapper() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000789 return IsJSValue() && JSValue::cast(this)->value()->IsString();
790}
791
792
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100793TYPE_CHECKER(Foreign, FOREIGN_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000794
Ben Murdoch097c5b22016-05-18 11:27:45 +0100795bool HeapObject::IsBoolean() const {
Steve Block44f0eee2011-05-26 01:26:41 +0100796 return IsOddball() &&
797 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000798}
799
800
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100801TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000802TYPE_CHECKER(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE)
803TYPE_CHECKER(JSTypedArray, JS_TYPED_ARRAY_TYPE)
804TYPE_CHECKER(JSDataView, JS_DATA_VIEW_TYPE)
805
Ben Murdoch097c5b22016-05-18 11:27:45 +0100806bool HeapObject::IsJSArrayBufferView() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000807 return IsJSDataView() || IsJSTypedArray();
808}
809
810
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100811TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000812
813
814template <> inline bool Is<JSArray>(Object* obj) {
815 return obj->IsJSArray();
816}
817
Ben Murdoch097c5b22016-05-18 11:27:45 +0100818bool HeapObject::IsHashTable() const {
819 return map() == GetHeap()->hash_table_map();
Steve Blocka7e24c12009-10-30 11:49:00 +0000820}
821
Ben Murdoch097c5b22016-05-18 11:27:45 +0100822bool HeapObject::IsWeakHashTable() const { return IsHashTable(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000823
Ben Murdoch097c5b22016-05-18 11:27:45 +0100824bool HeapObject::IsDictionary() const {
825 return IsHashTable() && this != GetHeap()->string_table();
Steve Blocka7e24c12009-10-30 11:49:00 +0000826}
827
828
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000829bool Object::IsNameDictionary() const {
830 return IsDictionary();
Steve Blocka7e24c12009-10-30 11:49:00 +0000831}
832
833
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000834bool Object::IsGlobalDictionary() const { return IsDictionary(); }
835
836
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000837bool Object::IsSeededNumberDictionary() const {
838 return IsDictionary();
839}
840
841
842bool Object::IsUnseededNumberDictionary() const {
843 return IsDictionary();
844}
845
Ben Murdoch097c5b22016-05-18 11:27:45 +0100846bool HeapObject::IsStringTable() const { return IsHashTable(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000847
Ben Murdochda12d292016-06-02 14:46:10 +0100848bool HeapObject::IsStringSet() const { return IsHashTable(); }
849
Ben Murdoch097c5b22016-05-18 11:27:45 +0100850bool HeapObject::IsNormalizedMapCache() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000851 return NormalizedMapCache::IsNormalizedMapCache(this);
852}
853
854
855int NormalizedMapCache::GetIndex(Handle<Map> map) {
856 return map->Hash() % NormalizedMapCache::kEntries;
857}
858
Ben Murdoch097c5b22016-05-18 11:27:45 +0100859bool NormalizedMapCache::IsNormalizedMapCache(const HeapObject* obj) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000860 if (!obj->IsFixedArray()) return false;
861 if (FixedArray::cast(obj)->length() != NormalizedMapCache::kEntries) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100862 return false;
863 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000864#ifdef VERIFY_HEAP
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100865 if (FLAG_verify_heap) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100866 reinterpret_cast<NormalizedMapCache*>(const_cast<HeapObject*>(obj))
867 ->NormalizedMapCacheVerify();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100868 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100869#endif
870 return true;
871}
872
Ben Murdoch097c5b22016-05-18 11:27:45 +0100873bool HeapObject::IsCompilationCacheTable() const { return IsHashTable(); }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100874
Ben Murdoch097c5b22016-05-18 11:27:45 +0100875bool HeapObject::IsCodeCacheHashTable() const { return IsHashTable(); }
876
877bool HeapObject::IsPolymorphicCodeCacheHashTable() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000878 return IsHashTable();
879}
880
Ben Murdoch097c5b22016-05-18 11:27:45 +0100881bool HeapObject::IsMapCache() const { return IsHashTable(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000882
Ben Murdoch097c5b22016-05-18 11:27:45 +0100883bool HeapObject::IsObjectHashTable() const { return IsHashTable(); }
Steve Block6ded16b2010-05-10 14:33:55 +0100884
Ben Murdoch097c5b22016-05-18 11:27:45 +0100885bool HeapObject::IsOrderedHashTable() const {
886 return map() == GetHeap()->ordered_hash_table_map();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000887}
888
889
890bool Object::IsOrderedHashSet() const {
891 return IsOrderedHashTable();
892}
893
894
895bool Object::IsOrderedHashMap() const {
896 return IsOrderedHashTable();
897}
898
899
900bool Object::IsPrimitive() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000901 return IsSmi() || HeapObject::cast(this)->map()->IsPrimitiveMap();
Steve Blocka7e24c12009-10-30 11:49:00 +0000902}
903
Ben Murdoch097c5b22016-05-18 11:27:45 +0100904bool HeapObject::IsJSGlobalProxy() const {
905 bool result = map()->instance_type() == JS_GLOBAL_PROXY_TYPE;
906 DCHECK(!result || map()->is_access_check_needed());
Steve Blocka7e24c12009-10-30 11:49:00 +0000907 return result;
908}
909
910
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100911TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000912
Ben Murdochda12d292016-06-02 14:46:10 +0100913bool HeapObject::IsUndetectable() const { return map()->is_undetectable(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000914
Ben Murdoch097c5b22016-05-18 11:27:45 +0100915bool HeapObject::IsAccessCheckNeeded() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000916 if (IsJSGlobalProxy()) {
917 const JSGlobalProxy* proxy = JSGlobalProxy::cast(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000918 JSGlobalObject* global = proxy->GetIsolate()->context()->global_object();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000919 return proxy->IsDetachedFrom(global);
920 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100921 return map()->is_access_check_needed();
Steve Blocka7e24c12009-10-30 11:49:00 +0000922}
923
Ben Murdoch097c5b22016-05-18 11:27:45 +0100924bool HeapObject::IsStruct() const {
925 switch (map()->instance_type()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000926#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
927 STRUCT_LIST(MAKE_STRUCT_CASE)
928#undef MAKE_STRUCT_CASE
929 default: return false;
930 }
931}
932
Ben Murdoch097c5b22016-05-18 11:27:45 +0100933#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
934 bool Object::Is##Name() const { \
935 return IsHeapObject() && HeapObject::cast(this)->Is##Name(); \
936 } \
937 bool HeapObject::Is##Name() const { \
938 return map()->instance_type() == NAME##_TYPE; \
Steve Blocka7e24c12009-10-30 11:49:00 +0000939 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100940STRUCT_LIST(MAKE_STRUCT_PREDICATE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000941#undef MAKE_STRUCT_PREDICATE
942
Ben Murdoch097c5b22016-05-18 11:27:45 +0100943#define MAKE_ODDBALL_PREDICATE(Name) \
944 bool HeapObject::Is##Name() const { \
945 return IsOddball() && Oddball::cast(this)->kind() == Oddball::k##Name; \
946 }
947ODDBALL_LIST(MAKE_ODDBALL_PREDICATE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000948
Ben Murdoch097c5b22016-05-18 11:27:45 +0100949#undef MAKE_ODDBALL_PREDICATE
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000950double Object::Number() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000951 DCHECK(IsNumber());
Steve Blocka7e24c12009-10-30 11:49:00 +0000952 return IsSmi()
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000953 ? static_cast<double>(reinterpret_cast<const Smi*>(this)->value())
954 : reinterpret_cast<const HeapNumber*>(this)->value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000955}
956
957
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000958bool Object::IsNaN() const {
959 return this->IsHeapNumber() && std::isnan(HeapNumber::cast(this)->value());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100960}
961
962
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000963bool Object::IsMinusZero() const {
964 return this->IsHeapNumber() &&
965 i::IsMinusZero(HeapNumber::cast(this)->value());
966}
967
968
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000969Representation Object::OptimalRepresentation() {
970 if (!FLAG_track_fields) return Representation::Tagged();
971 if (IsSmi()) {
972 return Representation::Smi();
973 } else if (FLAG_track_double_fields && IsHeapNumber()) {
974 return Representation::Double();
975 } else if (FLAG_track_computed_fields && IsUninitialized()) {
976 return Representation::None();
977 } else if (FLAG_track_heap_object_fields) {
978 DCHECK(IsHeapObject());
979 return Representation::HeapObject();
980 } else {
981 return Representation::Tagged();
Steve Blocka7e24c12009-10-30 11:49:00 +0000982 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000983}
984
985
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000986ElementsKind Object::OptimalElementsKind() {
987 if (IsSmi()) return FAST_SMI_ELEMENTS;
988 if (IsNumber()) return FAST_DOUBLE_ELEMENTS;
989 return FAST_ELEMENTS;
990}
991
992
993bool Object::FitsRepresentation(Representation representation) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100994 if (FLAG_track_fields && representation.IsSmi()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000995 return IsSmi();
996 } else if (FLAG_track_double_fields && representation.IsDouble()) {
997 return IsMutableHeapNumber() || IsNumber();
998 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
999 return IsHeapObject();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001000 } else if (FLAG_track_fields && representation.IsNone()) {
1001 return false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001002 }
1003 return true;
1004}
1005
Ben Murdochda12d292016-06-02 14:46:10 +01001006bool Object::ToUint32(uint32_t* value) {
1007 if (IsSmi()) {
1008 int num = Smi::cast(this)->value();
1009 if (num < 0) return false;
1010 *value = static_cast<uint32_t>(num);
1011 return true;
1012 }
1013 if (IsHeapNumber()) {
1014 double num = HeapNumber::cast(this)->value();
1015 if (num < 0) return false;
1016 uint32_t uint_value = FastD2UI(num);
1017 if (FastUI2D(uint_value) == num) {
1018 *value = uint_value;
1019 return true;
1020 }
1021 }
1022 return false;
1023}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001024
1025// static
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001026MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
1027 Handle<Object> object) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001028 if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
1029 return ToObject(isolate, object, isolate->native_context());
Steve Blocka7e24c12009-10-30 11:49:00 +00001030}
1031
1032
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001033// static
Ben Murdochda12d292016-06-02 14:46:10 +01001034MaybeHandle<Name> Object::ToName(Isolate* isolate, Handle<Object> input) {
1035 if (input->IsName()) return Handle<Name>::cast(input);
1036 return ConvertToName(isolate, input);
1037}
1038
1039// static
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001040MaybeHandle<Object> Object::ToPrimitive(Handle<Object> input,
1041 ToPrimitiveHint hint) {
1042 if (input->IsPrimitive()) return input;
1043 return JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input), hint);
1044}
1045
1046
Steve Blocka7e24c12009-10-30 11:49:00 +00001047bool Object::HasSpecificClassOf(String* name) {
1048 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
1049}
1050
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001051MaybeHandle<Object> Object::GetProperty(Handle<Object> object,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001052 Handle<Name> name) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001053 LookupIterator it(object, name);
Ben Murdochda12d292016-06-02 14:46:10 +01001054 if (!it.IsFound()) return it.factory()->undefined_value();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001055 return GetProperty(&it);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001056}
1057
Ben Murdochda12d292016-06-02 14:46:10 +01001058MaybeHandle<Object> JSReceiver::GetProperty(Handle<JSReceiver> receiver,
1059 Handle<Name> name) {
1060 LookupIterator it(receiver, name, receiver);
1061 if (!it.IsFound()) return it.factory()->undefined_value();
1062 return Object::GetProperty(&it);
1063}
1064
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001065MaybeHandle<Object> Object::GetElement(Isolate* isolate, Handle<Object> object,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001066 uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001067 LookupIterator it(isolate, object, index);
Ben Murdochda12d292016-06-02 14:46:10 +01001068 if (!it.IsFound()) return it.factory()->undefined_value();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001069 return GetProperty(&it);
Steve Blocka7e24c12009-10-30 11:49:00 +00001070}
1071
Ben Murdochda12d292016-06-02 14:46:10 +01001072MaybeHandle<Object> JSReceiver::GetElement(Isolate* isolate,
1073 Handle<JSReceiver> receiver,
1074 uint32_t index) {
1075 LookupIterator it(isolate, receiver, index, receiver);
1076 if (!it.IsFound()) return it.factory()->undefined_value();
1077 return Object::GetProperty(&it);
1078}
1079
1080Handle<Object> JSReceiver::GetDataProperty(Handle<JSReceiver> object,
1081 Handle<Name> name) {
1082 LookupIterator it(object, name, object,
1083 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
1084 if (!it.IsFound()) return it.factory()->undefined_value();
1085 return GetDataProperty(&it);
1086}
Steve Blocka7e24c12009-10-30 11:49:00 +00001087
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001088MaybeHandle<Object> Object::SetElement(Isolate* isolate, Handle<Object> object,
1089 uint32_t index, Handle<Object> value,
1090 LanguageMode language_mode) {
1091 LookupIterator it(isolate, object, index);
1092 MAYBE_RETURN_NULL(
1093 SetProperty(&it, value, language_mode, MAY_BE_STORE_FROM_KEYED));
1094 return value;
1095}
1096
Ben Murdoch097c5b22016-05-18 11:27:45 +01001097MaybeHandle<Object> JSReceiver::GetPrototype(Isolate* isolate,
1098 Handle<JSReceiver> receiver) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001099 // We don't expect access checks to be needed on JSProxy objects.
1100 DCHECK(!receiver->IsAccessCheckNeeded() || receiver->IsJSObject());
1101 PrototypeIterator iter(isolate, receiver,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001102 PrototypeIterator::START_AT_RECEIVER,
1103 PrototypeIterator::END_AT_NON_HIDDEN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001104 do {
1105 if (!iter.AdvanceFollowingProxies()) return MaybeHandle<Object>();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001106 } while (!iter.IsAtEnd());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001107 return PrototypeIterator::GetCurrent(iter);
1108}
1109
Ben Murdochda12d292016-06-02 14:46:10 +01001110MaybeHandle<Object> JSReceiver::GetProperty(Isolate* isolate,
1111 Handle<JSReceiver> receiver,
1112 const char* name) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001113 Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
Ben Murdochda12d292016-06-02 14:46:10 +01001114 return GetProperty(receiver, str);
Steve Blocka7e24c12009-10-30 11:49:00 +00001115}
1116
1117
1118#define FIELD_ADDR(p, offset) \
1119 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
1120
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001121#define FIELD_ADDR_CONST(p, offset) \
1122 (reinterpret_cast<const byte*>(p) + offset - kHeapObjectTag)
1123
Steve Blocka7e24c12009-10-30 11:49:00 +00001124#define READ_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001125 (*reinterpret_cast<Object* const*>(FIELD_ADDR_CONST(p, offset)))
1126
1127#define ACQUIRE_READ_FIELD(p, offset) \
1128 reinterpret_cast<Object*>(base::Acquire_Load( \
1129 reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR_CONST(p, offset))))
1130
1131#define NOBARRIER_READ_FIELD(p, offset) \
1132 reinterpret_cast<Object*>(base::NoBarrier_Load( \
1133 reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR_CONST(p, offset))))
Steve Blocka7e24c12009-10-30 11:49:00 +00001134
1135#define WRITE_FIELD(p, offset, value) \
1136 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
1137
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001138#define RELEASE_WRITE_FIELD(p, offset, value) \
1139 base::Release_Store( \
1140 reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
1141 reinterpret_cast<base::AtomicWord>(value));
1142
1143#define NOBARRIER_WRITE_FIELD(p, offset, value) \
1144 base::NoBarrier_Store( \
1145 reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
1146 reinterpret_cast<base::AtomicWord>(value));
1147
Ben Murdoch097c5b22016-05-18 11:27:45 +01001148#define WRITE_BARRIER(heap, object, offset, value) \
1149 heap->incremental_marking()->RecordWrite( \
1150 object, HeapObject::RawField(object, offset), value); \
1151 heap->RecordWrite(object, offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00001152
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001153#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
1154 if (mode != SKIP_WRITE_BARRIER) { \
1155 if (mode == UPDATE_WRITE_BARRIER) { \
1156 heap->incremental_marking()->RecordWrite( \
1157 object, HeapObject::RawField(object, offset), value); \
1158 } \
Ben Murdoch097c5b22016-05-18 11:27:45 +01001159 heap->RecordWrite(object, offset, value); \
Steve Blocka7e24c12009-10-30 11:49:00 +00001160 }
1161
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001162#define READ_DOUBLE_FIELD(p, offset) \
1163 ReadDoubleValue(FIELD_ADDR_CONST(p, offset))
Steve Blocka7e24c12009-10-30 11:49:00 +00001164
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001165#define WRITE_DOUBLE_FIELD(p, offset, value) \
1166 WriteDoubleValue(FIELD_ADDR(p, offset), value)
Steve Blocka7e24c12009-10-30 11:49:00 +00001167
1168#define READ_INT_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001169 (*reinterpret_cast<const int*>(FIELD_ADDR_CONST(p, offset)))
Steve Blocka7e24c12009-10-30 11:49:00 +00001170
1171#define WRITE_INT_FIELD(p, offset, value) \
1172 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
1173
1174#define READ_INTPTR_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001175 (*reinterpret_cast<const intptr_t*>(FIELD_ADDR_CONST(p, offset)))
Steve Blocka7e24c12009-10-30 11:49:00 +00001176
1177#define WRITE_INTPTR_FIELD(p, offset, value) \
1178 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
1179
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001180#define READ_UINT8_FIELD(p, offset) \
1181 (*reinterpret_cast<const uint8_t*>(FIELD_ADDR_CONST(p, offset)))
1182
1183#define WRITE_UINT8_FIELD(p, offset, value) \
1184 (*reinterpret_cast<uint8_t*>(FIELD_ADDR(p, offset)) = value)
1185
1186#define READ_INT8_FIELD(p, offset) \
1187 (*reinterpret_cast<const int8_t*>(FIELD_ADDR_CONST(p, offset)))
1188
1189#define WRITE_INT8_FIELD(p, offset, value) \
1190 (*reinterpret_cast<int8_t*>(FIELD_ADDR(p, offset)) = value)
1191
1192#define READ_UINT16_FIELD(p, offset) \
1193 (*reinterpret_cast<const uint16_t*>(FIELD_ADDR_CONST(p, offset)))
1194
1195#define WRITE_UINT16_FIELD(p, offset, value) \
1196 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
1197
1198#define READ_INT16_FIELD(p, offset) \
1199 (*reinterpret_cast<const int16_t*>(FIELD_ADDR_CONST(p, offset)))
1200
1201#define WRITE_INT16_FIELD(p, offset, value) \
1202 (*reinterpret_cast<int16_t*>(FIELD_ADDR(p, offset)) = value)
1203
Steve Blocka7e24c12009-10-30 11:49:00 +00001204#define READ_UINT32_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001205 (*reinterpret_cast<const uint32_t*>(FIELD_ADDR_CONST(p, offset)))
Steve Blocka7e24c12009-10-30 11:49:00 +00001206
1207#define WRITE_UINT32_FIELD(p, offset, value) \
1208 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
1209
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001210#define READ_INT32_FIELD(p, offset) \
1211 (*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset)))
1212
1213#define WRITE_INT32_FIELD(p, offset, value) \
1214 (*reinterpret_cast<int32_t*>(FIELD_ADDR(p, offset)) = value)
1215
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001216#define READ_FLOAT_FIELD(p, offset) \
1217 (*reinterpret_cast<const float*>(FIELD_ADDR_CONST(p, offset)))
1218
1219#define WRITE_FLOAT_FIELD(p, offset, value) \
1220 (*reinterpret_cast<float*>(FIELD_ADDR(p, offset)) = value)
1221
1222#define READ_UINT64_FIELD(p, offset) \
1223 (*reinterpret_cast<const uint64_t*>(FIELD_ADDR_CONST(p, offset)))
1224
1225#define WRITE_UINT64_FIELD(p, offset, value) \
1226 (*reinterpret_cast<uint64_t*>(FIELD_ADDR(p, offset)) = value)
1227
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001228#define READ_INT64_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001229 (*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset)))
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001230
1231#define WRITE_INT64_FIELD(p, offset, value) \
1232 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
1233
Steve Blocka7e24c12009-10-30 11:49:00 +00001234#define READ_BYTE_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001235 (*reinterpret_cast<const byte*>(FIELD_ADDR_CONST(p, offset)))
1236
1237#define NOBARRIER_READ_BYTE_FIELD(p, offset) \
1238 static_cast<byte>(base::NoBarrier_Load( \
1239 reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset))))
Steve Blocka7e24c12009-10-30 11:49:00 +00001240
1241#define WRITE_BYTE_FIELD(p, offset, value) \
1242 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
1243
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001244#define NOBARRIER_WRITE_BYTE_FIELD(p, offset, value) \
1245 base::NoBarrier_Store( \
1246 reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset)), \
1247 static_cast<base::Atomic8>(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00001248
1249Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001250 return reinterpret_cast<Object**>(FIELD_ADDR(obj, byte_offset));
Steve Blocka7e24c12009-10-30 11:49:00 +00001251}
1252
1253
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001254MapWord MapWord::FromMap(const Map* map) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001255 return MapWord(reinterpret_cast<uintptr_t>(map));
1256}
1257
1258
1259Map* MapWord::ToMap() {
1260 return reinterpret_cast<Map*>(value_);
1261}
1262
1263
1264bool MapWord::IsForwardingAddress() {
1265 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
1266}
1267
1268
1269MapWord MapWord::FromForwardingAddress(HeapObject* object) {
1270 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1271 return MapWord(reinterpret_cast<uintptr_t>(raw));
1272}
1273
1274
1275HeapObject* MapWord::ToForwardingAddress() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001276 DCHECK(IsForwardingAddress());
Steve Blocka7e24c12009-10-30 11:49:00 +00001277 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
1278}
1279
1280
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001281#ifdef VERIFY_HEAP
Steve Blocka7e24c12009-10-30 11:49:00 +00001282void HeapObject::VerifyObjectField(int offset) {
1283 VerifyPointer(READ_FIELD(this, offset));
1284}
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001285
1286void HeapObject::VerifySmiField(int offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001287 CHECK(READ_FIELD(this, offset)->IsSmi());
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001288}
Steve Blocka7e24c12009-10-30 11:49:00 +00001289#endif
1290
1291
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001292Heap* HeapObject::GetHeap() const {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001293 Heap* heap = MemoryChunk::FromAddress(
1294 reinterpret_cast<Address>(const_cast<HeapObject*>(this)))
1295 ->heap();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001296 SLOW_DCHECK(heap != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001297 return heap;
Steve Block44f0eee2011-05-26 01:26:41 +01001298}
1299
1300
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001301Isolate* HeapObject::GetIsolate() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001302 return GetHeap()->isolate();
1303}
1304
1305
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001306Map* HeapObject::map() const {
1307#ifdef DEBUG
1308 // Clear mark potentially added by PathTracer.
1309 uintptr_t raw_value =
1310 map_word().ToRawValue() & ~static_cast<uintptr_t>(PathTracer::kMarkTag);
1311 return MapWord::FromRawValue(raw_value).ToMap();
1312#else
Steve Blocka7e24c12009-10-30 11:49:00 +00001313 return map_word().ToMap();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001314#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00001315}
1316
1317
1318void HeapObject::set_map(Map* value) {
1319 set_map_word(MapWord::FromMap(value));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001320 if (value != NULL) {
1321 // TODO(1600) We are passing NULL as a slot because maps can never be on
1322 // evacuation candidate.
1323 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1324 }
1325}
1326
1327
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001328Map* HeapObject::synchronized_map() {
1329 return synchronized_map_word().ToMap();
1330}
1331
1332
1333void HeapObject::synchronized_set_map(Map* value) {
1334 synchronized_set_map_word(MapWord::FromMap(value));
1335 if (value != NULL) {
1336 // TODO(1600) We are passing NULL as a slot because maps can never be on
1337 // evacuation candidate.
1338 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1339 }
1340}
1341
1342
1343void HeapObject::synchronized_set_map_no_write_barrier(Map* value) {
1344 synchronized_set_map_word(MapWord::FromMap(value));
1345}
1346
1347
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001348// Unsafe accessor omitting write barrier.
1349void HeapObject::set_map_no_write_barrier(Map* value) {
1350 set_map_word(MapWord::FromMap(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00001351}
1352
1353
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001354MapWord HeapObject::map_word() const {
1355 return MapWord(
1356 reinterpret_cast<uintptr_t>(NOBARRIER_READ_FIELD(this, kMapOffset)));
Steve Blocka7e24c12009-10-30 11:49:00 +00001357}
1358
1359
1360void HeapObject::set_map_word(MapWord map_word) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001361 NOBARRIER_WRITE_FIELD(
1362 this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1363}
1364
1365
1366MapWord HeapObject::synchronized_map_word() const {
1367 return MapWord(
1368 reinterpret_cast<uintptr_t>(ACQUIRE_READ_FIELD(this, kMapOffset)));
1369}
1370
1371
1372void HeapObject::synchronized_set_map_word(MapWord map_word) {
1373 RELEASE_WRITE_FIELD(
1374 this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
Steve Blocka7e24c12009-10-30 11:49:00 +00001375}
1376
1377
Steve Blocka7e24c12009-10-30 11:49:00 +00001378int HeapObject::Size() {
1379 return SizeFromMap(map());
1380}
1381
1382
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001383double HeapNumber::value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00001384 return READ_DOUBLE_FIELD(this, kValueOffset);
1385}
1386
1387
1388void HeapNumber::set_value(double value) {
1389 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1390}
1391
1392
Steve Block6ded16b2010-05-10 14:33:55 +01001393int HeapNumber::get_exponent() {
1394 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1395 kExponentShift) - kExponentBias;
1396}
1397
1398
1399int HeapNumber::get_sign() {
1400 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1401}
1402
1403
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001404bool Simd128Value::Equals(Simd128Value* that) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001405 // TODO(bmeurer): This doesn't match the SIMD.js specification, but it seems
1406 // to be consistent with what the CompareICStub does, and what is tested in
1407 // the current SIMD.js testsuite.
1408 if (this == that) return true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001409#define SIMD128_VALUE(TYPE, Type, type, lane_count, lane_type) \
1410 if (this->Is##Type()) { \
1411 if (!that->Is##Type()) return false; \
1412 return Type::cast(this)->Equals(Type::cast(that)); \
1413 }
1414 SIMD128_TYPES(SIMD128_VALUE)
1415#undef SIMD128_VALUE
1416 return false;
1417}
1418
1419
1420// static
1421bool Simd128Value::Equals(Handle<Simd128Value> one, Handle<Simd128Value> two) {
1422 return one->Equals(*two);
1423}
1424
1425
1426#define SIMD128_VALUE_EQUALS(TYPE, Type, type, lane_count, lane_type) \
1427 bool Type::Equals(Type* that) { \
1428 for (int lane = 0; lane < lane_count; ++lane) { \
1429 if (this->get_lane(lane) != that->get_lane(lane)) return false; \
1430 } \
1431 return true; \
1432 }
1433SIMD128_TYPES(SIMD128_VALUE_EQUALS)
1434#undef SIMD128_VALUE_EQUALS
1435
1436
1437#if defined(V8_TARGET_LITTLE_ENDIAN)
1438#define SIMD128_READ_LANE(lane_type, lane_count, field_type, field_size) \
1439 lane_type value = \
1440 READ_##field_type##_FIELD(this, kValueOffset + lane * field_size);
1441#elif defined(V8_TARGET_BIG_ENDIAN)
1442#define SIMD128_READ_LANE(lane_type, lane_count, field_type, field_size) \
1443 lane_type value = READ_##field_type##_FIELD( \
1444 this, kValueOffset + (lane_count - lane - 1) * field_size);
1445#else
1446#error Unknown byte ordering
1447#endif
1448
1449#if defined(V8_TARGET_LITTLE_ENDIAN)
1450#define SIMD128_WRITE_LANE(lane_count, field_type, field_size, value) \
1451 WRITE_##field_type##_FIELD(this, kValueOffset + lane * field_size, value);
1452#elif defined(V8_TARGET_BIG_ENDIAN)
1453#define SIMD128_WRITE_LANE(lane_count, field_type, field_size, value) \
1454 WRITE_##field_type##_FIELD( \
1455 this, kValueOffset + (lane_count - lane - 1) * field_size, value);
1456#else
1457#error Unknown byte ordering
1458#endif
1459
1460#define SIMD128_NUMERIC_LANE_FNS(type, lane_type, lane_count, field_type, \
1461 field_size) \
1462 lane_type type::get_lane(int lane) const { \
1463 DCHECK(lane < lane_count && lane >= 0); \
1464 SIMD128_READ_LANE(lane_type, lane_count, field_type, field_size) \
1465 return value; \
1466 } \
1467 \
1468 void type::set_lane(int lane, lane_type value) { \
1469 DCHECK(lane < lane_count && lane >= 0); \
1470 SIMD128_WRITE_LANE(lane_count, field_type, field_size, value) \
1471 }
1472
1473SIMD128_NUMERIC_LANE_FNS(Float32x4, float, 4, FLOAT, kFloatSize)
1474SIMD128_NUMERIC_LANE_FNS(Int32x4, int32_t, 4, INT32, kInt32Size)
1475SIMD128_NUMERIC_LANE_FNS(Uint32x4, uint32_t, 4, UINT32, kInt32Size)
1476SIMD128_NUMERIC_LANE_FNS(Int16x8, int16_t, 8, INT16, kShortSize)
1477SIMD128_NUMERIC_LANE_FNS(Uint16x8, uint16_t, 8, UINT16, kShortSize)
1478SIMD128_NUMERIC_LANE_FNS(Int8x16, int8_t, 16, INT8, kCharSize)
1479SIMD128_NUMERIC_LANE_FNS(Uint8x16, uint8_t, 16, UINT8, kCharSize)
1480#undef SIMD128_NUMERIC_LANE_FNS
1481
1482
1483#define SIMD128_BOOLEAN_LANE_FNS(type, lane_type, lane_count, field_type, \
1484 field_size) \
1485 bool type::get_lane(int lane) const { \
1486 DCHECK(lane < lane_count && lane >= 0); \
1487 SIMD128_READ_LANE(lane_type, lane_count, field_type, field_size) \
1488 DCHECK(value == 0 || value == -1); \
1489 return value != 0; \
1490 } \
1491 \
1492 void type::set_lane(int lane, bool value) { \
1493 DCHECK(lane < lane_count && lane >= 0); \
1494 int32_t int_val = value ? -1 : 0; \
1495 SIMD128_WRITE_LANE(lane_count, field_type, field_size, int_val) \
1496 }
1497
1498SIMD128_BOOLEAN_LANE_FNS(Bool32x4, int32_t, 4, INT32, kInt32Size)
1499SIMD128_BOOLEAN_LANE_FNS(Bool16x8, int16_t, 8, INT16, kShortSize)
1500SIMD128_BOOLEAN_LANE_FNS(Bool8x16, int8_t, 16, INT8, kCharSize)
1501#undef SIMD128_BOOLEAN_LANE_FNS
1502
1503#undef SIMD128_READ_LANE
1504#undef SIMD128_WRITE_LANE
1505
1506
1507ACCESSORS(JSReceiver, properties, FixedArray, kPropertiesOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00001508
1509
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001510Object** FixedArray::GetFirstElementAddress() {
1511 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1512}
1513
1514
1515bool FixedArray::ContainsOnlySmisOrHoles() {
1516 Object* the_hole = GetHeap()->the_hole_value();
1517 Object** current = GetFirstElementAddress();
1518 for (int i = 0; i < length(); ++i) {
1519 Object* candidate = *current++;
1520 if (!candidate->IsSmi() && candidate != the_hole) return false;
1521 }
1522 return true;
1523}
1524
1525
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001526FixedArrayBase* JSObject::elements() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00001527 Object* array = READ_FIELD(this, kElementsOffset);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001528 return static_cast<FixedArrayBase*>(array);
Steve Blocka7e24c12009-10-30 11:49:00 +00001529}
1530
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001531
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001532void AllocationSite::Initialize() {
1533 set_transition_info(Smi::FromInt(0));
1534 SetElementsKind(GetInitialFastElementsKind());
1535 set_nested_site(Smi::FromInt(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001536 set_pretenure_data(0);
1537 set_pretenure_create_count(0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001538 set_dependent_code(DependentCode::cast(GetHeap()->empty_fixed_array()),
1539 SKIP_WRITE_BARRIER);
1540}
1541
1542
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001543bool AllocationSite::IsZombie() { return pretenure_decision() == kZombie; }
1544
1545
1546bool AllocationSite::IsMaybeTenure() {
1547 return pretenure_decision() == kMaybeTenure;
1548}
1549
1550
1551bool AllocationSite::PretenuringDecisionMade() {
1552 return pretenure_decision() != kUndecided;
1553}
1554
1555
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001556void AllocationSite::MarkZombie() {
1557 DCHECK(!IsZombie());
1558 Initialize();
1559 set_pretenure_decision(kZombie);
1560}
1561
1562
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001563ElementsKind AllocationSite::GetElementsKind() {
1564 DCHECK(!SitePointsToLiteral());
1565 int value = Smi::cast(transition_info())->value();
1566 return ElementsKindBits::decode(value);
1567}
1568
1569
1570void AllocationSite::SetElementsKind(ElementsKind kind) {
1571 int value = Smi::cast(transition_info())->value();
1572 set_transition_info(Smi::FromInt(ElementsKindBits::update(value, kind)),
1573 SKIP_WRITE_BARRIER);
1574}
1575
1576
1577bool AllocationSite::CanInlineCall() {
1578 int value = Smi::cast(transition_info())->value();
1579 return DoNotInlineBit::decode(value) == 0;
1580}
1581
1582
1583void AllocationSite::SetDoNotInlineCall() {
1584 int value = Smi::cast(transition_info())->value();
1585 set_transition_info(Smi::FromInt(DoNotInlineBit::update(value, true)),
1586 SKIP_WRITE_BARRIER);
1587}
1588
1589
1590bool AllocationSite::SitePointsToLiteral() {
1591 // If transition_info is a smi, then it represents an ElementsKind
1592 // for a constructed array. Otherwise, it must be a boilerplate
1593 // for an object or array literal.
1594 return transition_info()->IsJSArray() || transition_info()->IsJSObject();
1595}
1596
1597
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001598// Heuristic: We only need to create allocation site info if the boilerplate
1599// elements kind is the initial elements kind.
1600AllocationSiteMode AllocationSite::GetMode(
1601 ElementsKind boilerplate_elements_kind) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001602 if (IsFastSmiElementsKind(boilerplate_elements_kind)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001603 return TRACK_ALLOCATION_SITE;
1604 }
1605
1606 return DONT_TRACK_ALLOCATION_SITE;
1607}
1608
1609
1610AllocationSiteMode AllocationSite::GetMode(ElementsKind from,
1611 ElementsKind to) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001612 if (IsFastSmiElementsKind(from) &&
1613 IsMoreGeneralElementsKindTransition(from, to)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001614 return TRACK_ALLOCATION_SITE;
1615 }
1616
1617 return DONT_TRACK_ALLOCATION_SITE;
1618}
1619
1620
1621inline bool AllocationSite::CanTrack(InstanceType type) {
1622 if (FLAG_allocation_site_pretenuring) {
1623 return type == JS_ARRAY_TYPE ||
1624 type == JS_OBJECT_TYPE ||
1625 type < FIRST_NONSTRING_TYPE;
1626 }
1627 return type == JS_ARRAY_TYPE;
1628}
1629
1630
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001631AllocationSite::PretenureDecision AllocationSite::pretenure_decision() {
1632 int value = pretenure_data();
1633 return PretenureDecisionBits::decode(value);
1634}
1635
1636
1637void AllocationSite::set_pretenure_decision(PretenureDecision decision) {
1638 int value = pretenure_data();
1639 set_pretenure_data(PretenureDecisionBits::update(value, decision));
1640}
1641
1642
1643bool AllocationSite::deopt_dependent_code() {
1644 int value = pretenure_data();
1645 return DeoptDependentCodeBit::decode(value);
1646}
1647
1648
1649void AllocationSite::set_deopt_dependent_code(bool deopt) {
1650 int value = pretenure_data();
1651 set_pretenure_data(DeoptDependentCodeBit::update(value, deopt));
1652}
1653
1654
1655int AllocationSite::memento_found_count() {
1656 int value = pretenure_data();
1657 return MementoFoundCountBits::decode(value);
1658}
1659
1660
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001661inline void AllocationSite::set_memento_found_count(int count) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001662 int value = pretenure_data();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001663 // Verify that we can count more mementos than we can possibly find in one
1664 // new space collection.
1665 DCHECK((GetHeap()->MaxSemiSpaceSize() /
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001666 (Heap::kMinObjectSizeInWords * kPointerSize +
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001667 AllocationMemento::kSize)) < MementoFoundCountBits::kMax);
1668 DCHECK(count < MementoFoundCountBits::kMax);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001669 set_pretenure_data(MementoFoundCountBits::update(value, count));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001670}
1671
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001672
1673int AllocationSite::memento_create_count() { return pretenure_create_count(); }
1674
1675
1676void AllocationSite::set_memento_create_count(int count) {
1677 set_pretenure_create_count(count);
1678}
1679
1680
1681bool AllocationSite::IncrementMementoFoundCount(int increment) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001682 if (IsZombie()) return false;
1683
1684 int value = memento_found_count();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001685 set_memento_found_count(value + increment);
1686 return memento_found_count() >= kPretenureMinimumCreated;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001687}
1688
1689
1690inline void AllocationSite::IncrementMementoCreateCount() {
1691 DCHECK(FLAG_allocation_site_pretenuring);
1692 int value = memento_create_count();
1693 set_memento_create_count(value + 1);
1694}
1695
1696
1697inline bool AllocationSite::MakePretenureDecision(
1698 PretenureDecision current_decision,
1699 double ratio,
1700 bool maximum_size_scavenge) {
1701 // Here we just allow state transitions from undecided or maybe tenure
1702 // to don't tenure, maybe tenure, or tenure.
1703 if ((current_decision == kUndecided || current_decision == kMaybeTenure)) {
1704 if (ratio >= kPretenureRatio) {
1705 // We just transition into tenure state when the semi-space was at
1706 // maximum capacity.
1707 if (maximum_size_scavenge) {
1708 set_deopt_dependent_code(true);
1709 set_pretenure_decision(kTenure);
1710 // Currently we just need to deopt when we make a state transition to
1711 // tenure.
1712 return true;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001713 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001714 set_pretenure_decision(kMaybeTenure);
1715 } else {
1716 set_pretenure_decision(kDontTenure);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001717 }
1718 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001719 return false;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001720}
1721
1722
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001723inline bool AllocationSite::DigestPretenuringFeedback(
1724 bool maximum_size_scavenge) {
1725 bool deopt = false;
1726 int create_count = memento_create_count();
1727 int found_count = memento_found_count();
1728 bool minimum_mementos_created = create_count >= kPretenureMinimumCreated;
1729 double ratio =
1730 minimum_mementos_created || FLAG_trace_pretenuring_statistics ?
1731 static_cast<double>(found_count) / create_count : 0.0;
1732 PretenureDecision current_decision = pretenure_decision();
1733
1734 if (minimum_mementos_created) {
1735 deopt = MakePretenureDecision(
1736 current_decision, ratio, maximum_size_scavenge);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001737 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001738
1739 if (FLAG_trace_pretenuring_statistics) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001740 PrintIsolate(GetIsolate(),
1741 "pretenuring: AllocationSite(%p): (created, found, ratio) "
1742 "(%d, %d, %f) %s => %s\n",
1743 this, create_count, found_count, ratio,
1744 PretenureDecisionName(current_decision),
1745 PretenureDecisionName(pretenure_decision()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001746 }
1747
1748 // Clear feedback calculation fields until the next gc.
1749 set_memento_found_count(0);
1750 set_memento_create_count(0);
1751 return deopt;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001752}
1753
1754
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001755bool AllocationMemento::IsValid() {
1756 return allocation_site()->IsAllocationSite() &&
1757 !AllocationSite::cast(allocation_site())->IsZombie();
1758}
1759
1760
1761AllocationSite* AllocationMemento::GetAllocationSite() {
1762 DCHECK(IsValid());
1763 return AllocationSite::cast(allocation_site());
1764}
1765
Ben Murdoch097c5b22016-05-18 11:27:45 +01001766Address AllocationMemento::GetAllocationSiteUnchecked() {
1767 return reinterpret_cast<Address>(allocation_site());
1768}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001769
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001770void JSObject::EnsureCanContainHeapObjectElements(Handle<JSObject> object) {
1771 JSObject::ValidateElements(object);
1772 ElementsKind elements_kind = object->map()->elements_kind();
1773 if (!IsFastObjectElementsKind(elements_kind)) {
1774 if (IsFastHoleyElementsKind(elements_kind)) {
1775 TransitionElementsKind(object, FAST_HOLEY_ELEMENTS);
1776 } else {
1777 TransitionElementsKind(object, FAST_ELEMENTS);
1778 }
1779 }
1780}
1781
1782
1783void JSObject::EnsureCanContainElements(Handle<JSObject> object,
1784 Object** objects,
1785 uint32_t count,
1786 EnsureElementsMode mode) {
1787 ElementsKind current_kind = object->map()->elements_kind();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001788 ElementsKind target_kind = current_kind;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001789 {
1790 DisallowHeapAllocation no_allocation;
1791 DCHECK(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1792 bool is_holey = IsFastHoleyElementsKind(current_kind);
1793 if (current_kind == FAST_HOLEY_ELEMENTS) return;
1794 Heap* heap = object->GetHeap();
1795 Object* the_hole = heap->the_hole_value();
1796 for (uint32_t i = 0; i < count; ++i) {
1797 Object* current = *objects++;
1798 if (current == the_hole) {
1799 is_holey = true;
1800 target_kind = GetHoleyElementsKind(target_kind);
1801 } else if (!current->IsSmi()) {
1802 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && current->IsNumber()) {
1803 if (IsFastSmiElementsKind(target_kind)) {
1804 if (is_holey) {
1805 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
1806 } else {
1807 target_kind = FAST_DOUBLE_ELEMENTS;
1808 }
1809 }
1810 } else if (is_holey) {
1811 target_kind = FAST_HOLEY_ELEMENTS;
1812 break;
1813 } else {
1814 target_kind = FAST_ELEMENTS;
1815 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001816 }
1817 }
1818 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001819 if (target_kind != current_kind) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001820 TransitionElementsKind(object, target_kind);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001821 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001822}
1823
1824
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001825void JSObject::EnsureCanContainElements(Handle<JSObject> object,
1826 Handle<FixedArrayBase> elements,
1827 uint32_t length,
1828 EnsureElementsMode mode) {
1829 Heap* heap = object->GetHeap();
1830 if (elements->map() != heap->fixed_double_array_map()) {
1831 DCHECK(elements->map() == heap->fixed_array_map() ||
1832 elements->map() == heap->fixed_cow_array_map());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001833 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1834 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1835 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001836 Object** objects =
1837 Handle<FixedArray>::cast(elements)->GetFirstElementAddress();
1838 EnsureCanContainElements(object, objects, length, mode);
1839 return;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001840 }
1841
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001842 DCHECK(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1843 if (object->GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) {
1844 TransitionElementsKind(object, FAST_HOLEY_DOUBLE_ELEMENTS);
1845 } else if (object->GetElementsKind() == FAST_SMI_ELEMENTS) {
1846 Handle<FixedDoubleArray> double_array =
1847 Handle<FixedDoubleArray>::cast(elements);
1848 for (uint32_t i = 0; i < length; ++i) {
1849 if (double_array->is_the_hole(i)) {
1850 TransitionElementsKind(object, FAST_HOLEY_DOUBLE_ELEMENTS);
1851 return;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001852 }
1853 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001854 TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001855 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001856}
1857
1858
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001859void JSObject::SetMapAndElements(Handle<JSObject> object,
1860 Handle<Map> new_map,
1861 Handle<FixedArrayBase> value) {
1862 JSObject::MigrateToMap(object, new_map);
1863 DCHECK((object->map()->has_fast_smi_or_object_elements() ||
Ben Murdoch097c5b22016-05-18 11:27:45 +01001864 (*value == object->GetHeap()->empty_fixed_array()) ||
1865 object->map()->has_fast_string_wrapper_elements()) ==
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001866 (value->map() == object->GetHeap()->fixed_array_map() ||
1867 value->map() == object->GetHeap()->fixed_cow_array_map()));
1868 DCHECK((*value == object->GetHeap()->empty_fixed_array()) ||
1869 (object->map()->has_fast_double_elements() ==
1870 value->IsFixedDoubleArray()));
1871 object->set_elements(*value);
1872}
1873
1874
1875void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001876 WRITE_FIELD(this, kElementsOffset, value);
1877 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
1878}
1879
Steve Blocka7e24c12009-10-30 11:49:00 +00001880
Steve Blocka7e24c12009-10-30 11:49:00 +00001881void JSObject::initialize_elements() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001882 FixedArrayBase* elements = map()->GetInitialElements();
1883 WRITE_FIELD(this, kElementsOffset, elements);
Steve Blocka7e24c12009-10-30 11:49:00 +00001884}
1885
1886
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001887InterceptorInfo* JSObject::GetIndexedInterceptor() {
Ben Murdochda12d292016-06-02 14:46:10 +01001888 return map()->GetIndexedInterceptor();
1889}
1890
1891InterceptorInfo* JSObject::GetNamedInterceptor() {
1892 return map()->GetNamedInterceptor();
1893}
1894
1895InterceptorInfo* Map::GetNamedInterceptor() {
1896 DCHECK(has_named_interceptor());
1897 JSFunction* constructor = JSFunction::cast(GetConstructor());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001898 DCHECK(constructor->shared()->IsApiFunction());
Ben Murdochda12d292016-06-02 14:46:10 +01001899 return InterceptorInfo::cast(
1900 constructor->shared()->get_api_func_data()->named_property_handler());
1901}
1902
1903InterceptorInfo* Map::GetIndexedInterceptor() {
1904 DCHECK(has_indexed_interceptor());
1905 JSFunction* constructor = JSFunction::cast(GetConstructor());
1906 DCHECK(constructor->shared()->IsApiFunction());
1907 return InterceptorInfo::cast(
1908 constructor->shared()->get_api_func_data()->indexed_property_handler());
Steve Block8defd9f2010-07-08 12:39:36 +01001909}
1910
1911
Steve Blocka7e24c12009-10-30 11:49:00 +00001912ACCESSORS(Oddball, to_string, String, kToStringOffset)
1913ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
Ben Murdochda12d292016-06-02 14:46:10 +01001914ACCESSORS(Oddball, to_boolean, Oddball, kToBooleanOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001915ACCESSORS(Oddball, type_of, String, kTypeOfOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00001916
1917
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001918byte Oddball::kind() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001919 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
Steve Block44f0eee2011-05-26 01:26:41 +01001920}
1921
1922
1923void Oddball::set_kind(byte value) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001924 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
Steve Block44f0eee2011-05-26 01:26:41 +01001925}
1926
1927
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001928// static
1929Handle<Object> Oddball::ToNumber(Handle<Oddball> input) {
1930 return handle(input->to_number(), input->GetIsolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00001931}
1932
1933
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001934ACCESSORS(Cell, value, Object, kValueOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001935ACCESSORS(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001936ACCESSORS(PropertyCell, property_details_raw, Object, kDetailsOffset)
1937ACCESSORS(PropertyCell, value, Object, kValueOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001938
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001939
1940PropertyDetails PropertyCell::property_details() {
1941 return PropertyDetails(Smi::cast(property_details_raw()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001942}
1943
1944
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001945void PropertyCell::set_property_details(PropertyDetails details) {
1946 set_property_details_raw(details.AsSmi());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001947}
1948
Steve Blocka7e24c12009-10-30 11:49:00 +00001949
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001950Object* WeakCell::value() const { return READ_FIELD(this, kValueOffset); }
1951
1952
1953void WeakCell::clear() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001954 // Either the garbage collector is clearing the cell or we are simply
1955 // initializing the root empty weak cell.
1956 DCHECK(GetHeap()->gc_state() == Heap::MARK_COMPACT ||
1957 this == GetHeap()->empty_weak_cell());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001958 WRITE_FIELD(this, kValueOffset, Smi::FromInt(0));
1959}
1960
1961
1962void WeakCell::initialize(HeapObject* val) {
1963 WRITE_FIELD(this, kValueOffset, val);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001964 // We just have to execute the generational barrier here because we never
1965 // mark through a weak cell and collect evacuation candidates when we process
1966 // all weak cells.
Ben Murdochda12d292016-06-02 14:46:10 +01001967 WriteBarrierMode mode =
1968 Page::FromAddress(this->address())->IsFlagSet(Page::BLACK_PAGE)
1969 ? UPDATE_WRITE_BARRIER
1970 : UPDATE_WEAK_WRITE_BARRIER;
1971 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kValueOffset, val, mode);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001972}
1973
1974
1975bool WeakCell::cleared() const { return value() == Smi::FromInt(0); }
1976
1977
1978Object* WeakCell::next() const { return READ_FIELD(this, kNextOffset); }
1979
1980
1981void WeakCell::set_next(Object* val, WriteBarrierMode mode) {
1982 WRITE_FIELD(this, kNextOffset, val);
1983 if (mode == UPDATE_WRITE_BARRIER) {
1984 WRITE_BARRIER(GetHeap(), this, kNextOffset, val);
1985 }
1986}
1987
1988
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001989void WeakCell::clear_next(Object* the_hole_value) {
1990 DCHECK_EQ(GetHeap()->the_hole_value(), the_hole_value);
1991 set_next(the_hole_value, SKIP_WRITE_BARRIER);
1992}
1993
1994
1995bool WeakCell::next_cleared() { return next()->IsTheHole(); }
1996
1997
1998int JSObject::GetHeaderSize() { return GetHeaderSize(map()->instance_type()); }
1999
2000
2001int JSObject::GetHeaderSize(InstanceType type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002002 // Check for the most common kind of JavaScript object before
2003 // falling into the generic switch. This speeds up the internal
2004 // field operations considerably on average.
2005 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
2006 switch (type) {
Ben Murdochda12d292016-06-02 14:46:10 +01002007 case JS_SPECIAL_API_OBJECT_TYPE:
2008 return JSObject::kHeaderSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002009 case JS_GENERATOR_OBJECT_TYPE:
2010 return JSGeneratorObject::kSize;
2011 case JS_MODULE_TYPE:
2012 return JSModule::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002013 case JS_GLOBAL_PROXY_TYPE:
2014 return JSGlobalProxy::kSize;
2015 case JS_GLOBAL_OBJECT_TYPE:
2016 return JSGlobalObject::kSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002017 case JS_BOUND_FUNCTION_TYPE:
2018 return JSBoundFunction::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002019 case JS_FUNCTION_TYPE:
2020 return JSFunction::kSize;
2021 case JS_VALUE_TYPE:
2022 return JSValue::kSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002023 case JS_DATE_TYPE:
2024 return JSDate::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002025 case JS_ARRAY_TYPE:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002026 return JSArray::kSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002027 case JS_ARRAY_BUFFER_TYPE:
2028 return JSArrayBuffer::kSize;
2029 case JS_TYPED_ARRAY_TYPE:
2030 return JSTypedArray::kSize;
2031 case JS_DATA_VIEW_TYPE:
2032 return JSDataView::kSize;
2033 case JS_SET_TYPE:
2034 return JSSet::kSize;
2035 case JS_MAP_TYPE:
2036 return JSMap::kSize;
2037 case JS_SET_ITERATOR_TYPE:
2038 return JSSetIterator::kSize;
2039 case JS_MAP_ITERATOR_TYPE:
2040 return JSMapIterator::kSize;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002041 case JS_WEAK_MAP_TYPE:
2042 return JSWeakMap::kSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002043 case JS_WEAK_SET_TYPE:
2044 return JSWeakSet::kSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002045 case JS_PROMISE_TYPE:
2046 return JSObject::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002047 case JS_REGEXP_TYPE:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002048 return JSRegExp::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002049 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
2050 return JSObject::kHeaderSize;
Steve Block1e0659c2011-05-24 12:43:12 +01002051 case JS_MESSAGE_OBJECT_TYPE:
2052 return JSMessageObject::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002053 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002054 UNREACHABLE();
Steve Blocka7e24c12009-10-30 11:49:00 +00002055 return 0;
2056 }
2057}
2058
2059
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002060int JSObject::GetInternalFieldCount(Map* map) {
2061 int instance_size = map->instance_size();
2062 if (instance_size == kVariableSizeSentinel) return 0;
2063 InstanceType instance_type = map->instance_type();
2064 return ((instance_size - GetHeaderSize(instance_type)) >> kPointerSizeLog2) -
2065 map->GetInObjectProperties();
Steve Blocka7e24c12009-10-30 11:49:00 +00002066}
2067
2068
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002069int JSObject::GetInternalFieldCount() { return GetInternalFieldCount(map()); }
2070
2071
Steve Block44f0eee2011-05-26 01:26:41 +01002072int JSObject::GetInternalFieldOffset(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002073 DCHECK(index < GetInternalFieldCount() && index >= 0);
Steve Block44f0eee2011-05-26 01:26:41 +01002074 return GetHeaderSize() + (kPointerSize * index);
2075}
2076
2077
Steve Blocka7e24c12009-10-30 11:49:00 +00002078Object* JSObject::GetInternalField(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002079 DCHECK(index < GetInternalFieldCount() && index >= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002080 // Internal objects do follow immediately after the header, whereas in-object
2081 // properties are at the end of the object. Therefore there is no need
2082 // to adjust the index here.
2083 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
2084}
2085
2086
2087void JSObject::SetInternalField(int index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002088 DCHECK(index < GetInternalFieldCount() && index >= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002089 // Internal objects do follow immediately after the header, whereas in-object
2090 // properties are at the end of the object. Therefore there is no need
2091 // to adjust the index here.
2092 int offset = GetHeaderSize() + (kPointerSize * index);
2093 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002094 WRITE_BARRIER(GetHeap(), this, offset, value);
2095}
2096
2097
2098void JSObject::SetInternalField(int index, Smi* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002099 DCHECK(index < GetInternalFieldCount() && index >= 0);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002100 // Internal objects do follow immediately after the header, whereas in-object
2101 // properties are at the end of the object. Therefore there is no need
2102 // to adjust the index here.
2103 int offset = GetHeaderSize() + (kPointerSize * index);
2104 WRITE_FIELD(this, offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002105}
2106
2107
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002108bool JSObject::IsUnboxedDoubleField(FieldIndex index) {
2109 if (!FLAG_unbox_double_fields) return false;
2110 return map()->IsUnboxedDoubleField(index);
2111}
2112
2113
2114bool Map::IsUnboxedDoubleField(FieldIndex index) {
2115 if (!FLAG_unbox_double_fields) return false;
2116 if (index.is_hidden_field() || !index.is_inobject()) return false;
2117 return !layout_descriptor()->IsTagged(index.property_index());
2118}
2119
2120
Steve Blocka7e24c12009-10-30 11:49:00 +00002121// Access fast-case object properties at index. The use of these routines
2122// is needed to correctly distinguish between properties stored in-object and
2123// properties stored in the properties array.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002124Object* JSObject::RawFastPropertyAt(FieldIndex index) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002125 DCHECK(!IsUnboxedDoubleField(index));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002126 if (index.is_inobject()) {
2127 return READ_FIELD(this, index.offset());
Steve Blocka7e24c12009-10-30 11:49:00 +00002128 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002129 return properties()->get(index.outobject_array_index());
Steve Blocka7e24c12009-10-30 11:49:00 +00002130 }
2131}
2132
2133
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002134double JSObject::RawFastDoublePropertyAt(FieldIndex index) {
2135 DCHECK(IsUnboxedDoubleField(index));
2136 return READ_DOUBLE_FIELD(this, index.offset());
2137}
2138
2139
2140void JSObject::RawFastPropertyAtPut(FieldIndex index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002141 if (index.is_inobject()) {
2142 int offset = index.offset();
Steve Blocka7e24c12009-10-30 11:49:00 +00002143 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002144 WRITE_BARRIER(GetHeap(), this, offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002145 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002146 properties()->set(index.outobject_array_index(), value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002147 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002148}
2149
2150
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002151void JSObject::RawFastDoublePropertyAtPut(FieldIndex index, double value) {
2152 WRITE_DOUBLE_FIELD(this, index.offset(), value);
2153}
2154
2155
2156void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
2157 if (IsUnboxedDoubleField(index)) {
2158 DCHECK(value->IsMutableHeapNumber());
2159 RawFastDoublePropertyAtPut(index, HeapNumber::cast(value)->value());
2160 } else {
2161 RawFastPropertyAtPut(index, value);
2162 }
2163}
2164
Ben Murdoch097c5b22016-05-18 11:27:45 +01002165void JSObject::WriteToField(int descriptor, PropertyDetails details,
2166 Object* value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002167 DCHECK(details.type() == DATA);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002168 DisallowHeapAllocation no_gc;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002169 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor);
2170 if (details.representation().IsDouble()) {
2171 // Nothing more to be done.
2172 if (value->IsUninitialized()) return;
2173 if (IsUnboxedDoubleField(index)) {
2174 RawFastDoublePropertyAtPut(index, value->Number());
2175 } else {
2176 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index));
2177 DCHECK(box->IsMutableHeapNumber());
2178 box->set_value(value->Number());
2179 }
2180 } else {
2181 RawFastPropertyAtPut(index, value);
2182 }
2183}
2184
Ben Murdoch097c5b22016-05-18 11:27:45 +01002185void JSObject::WriteToField(int descriptor, Object* value) {
2186 DescriptorArray* desc = map()->instance_descriptors();
2187 PropertyDetails details = desc->GetDetails(descriptor);
2188 WriteToField(descriptor, details, value);
2189}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002190
Steve Block44f0eee2011-05-26 01:26:41 +01002191int JSObject::GetInObjectPropertyOffset(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002192 return map()->GetInObjectPropertyOffset(index);
Steve Block44f0eee2011-05-26 01:26:41 +01002193}
2194
2195
Steve Blocka7e24c12009-10-30 11:49:00 +00002196Object* JSObject::InObjectPropertyAt(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002197 int offset = GetInObjectPropertyOffset(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002198 return READ_FIELD(this, offset);
2199}
2200
2201
2202Object* JSObject::InObjectPropertyAtPut(int index,
2203 Object* value,
2204 WriteBarrierMode mode) {
2205 // Adjust for the number of properties stored in the object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002206 int offset = GetInObjectPropertyOffset(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002207 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002208 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002209 return value;
2210}
2211
2212
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002213void JSObject::InitializeBody(Map* map, int start_offset,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002214 Object* pre_allocated_value,
2215 Object* filler_value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002216 DCHECK(!filler_value->IsHeapObject() ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002217 !GetHeap()->InNewSpace(filler_value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002218 DCHECK(!pre_allocated_value->IsHeapObject() ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002219 !GetHeap()->InNewSpace(pre_allocated_value));
2220 int size = map->instance_size();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002221 int offset = start_offset;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002222 if (filler_value != pre_allocated_value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002223 int end_of_pre_allocated_offset =
2224 size - (map->unused_property_fields() * kPointerSize);
2225 DCHECK_LE(kHeaderSize, end_of_pre_allocated_offset);
2226 while (offset < end_of_pre_allocated_offset) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002227 WRITE_FIELD(this, offset, pre_allocated_value);
2228 offset += kPointerSize;
2229 }
2230 }
2231 while (offset < size) {
2232 WRITE_FIELD(this, offset, filler_value);
2233 offset += kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002234 }
2235}
2236
2237
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002238bool Map::TooManyFastProperties(StoreFromKeyed store_mode) {
2239 if (unused_property_fields() != 0) return false;
2240 if (is_prototype_map()) return false;
2241 int minimum = store_mode == CERTAINLY_NOT_STORE_FROM_KEYED ? 128 : 12;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002242 int limit = Max(minimum, GetInObjectProperties());
2243 int external = NumberOfFields() - GetInObjectProperties();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002244 return external > limit;
Steve Block8defd9f2010-07-08 12:39:36 +01002245}
2246
2247
Steve Blocka7e24c12009-10-30 11:49:00 +00002248void Struct::InitializeBody(int object_size) {
Steve Block44f0eee2011-05-26 01:26:41 +01002249 Object* value = GetHeap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00002250 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
2251 WRITE_FIELD(this, offset, value);
2252 }
2253}
2254
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002255bool Object::ToArrayLength(uint32_t* index) { return Object::ToUint32(index); }
2256
2257
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002258bool Object::ToArrayIndex(uint32_t* index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002259 return Object::ToUint32(index) && *index != kMaxUInt32;
Steve Blocka7e24c12009-10-30 11:49:00 +00002260}
2261
2262
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002263void Object::VerifyApiCallResultType() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002264#if DEBUG
2265 if (!(IsSmi() || IsString() || IsSymbol() || IsJSReceiver() ||
2266 IsHeapNumber() || IsSimd128Value() || IsUndefined() || IsTrue() ||
2267 IsFalse() || IsNull())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002268 FATAL("API call returned invalid object");
2269 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002270#endif // DEBUG
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002271}
2272
2273
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002274Object* FixedArray::get(int index) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002275 SLOW_DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00002276 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
2277}
2278
Ben Murdoch097c5b22016-05-18 11:27:45 +01002279Handle<Object> FixedArray::get(FixedArray* array, int index, Isolate* isolate) {
2280 return handle(array->get(index), isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002281}
2282
2283
2284bool FixedArray::is_the_hole(int index) {
2285 return get(index) == GetHeap()->the_hole_value();
2286}
2287
2288
Steve Blocka7e24c12009-10-30 11:49:00 +00002289void FixedArray::set(int index, Smi* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002290 DCHECK(map() != GetHeap()->fixed_cow_array_map());
2291 DCHECK(index >= 0 && index < this->length());
2292 DCHECK(reinterpret_cast<Object*>(value)->IsSmi());
Steve Blocka7e24c12009-10-30 11:49:00 +00002293 int offset = kHeaderSize + index * kPointerSize;
2294 WRITE_FIELD(this, offset, value);
2295}
2296
2297
2298void FixedArray::set(int index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002299 DCHECK_NE(GetHeap()->fixed_cow_array_map(), map());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002300 DCHECK(IsFixedArray());
Ben Murdoch097c5b22016-05-18 11:27:45 +01002301 DCHECK_GE(index, 0);
2302 DCHECK_LT(index, this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00002303 int offset = kHeaderSize + index * kPointerSize;
2304 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002305 WRITE_BARRIER(GetHeap(), this, offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002306}
2307
2308
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002309double FixedDoubleArray::get_scalar(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002310 DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2311 map() != GetHeap()->fixed_array_map());
2312 DCHECK(index >= 0 && index < this->length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002313 DCHECK(!is_the_hole(index));
2314 return READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002315}
2316
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002317
2318uint64_t FixedDoubleArray::get_representation(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002319 DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2320 map() != GetHeap()->fixed_array_map());
2321 DCHECK(index >= 0 && index < this->length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002322 int offset = kHeaderSize + index * kDoubleSize;
2323 return READ_UINT64_FIELD(this, offset);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002324}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002325
Ben Murdoch097c5b22016-05-18 11:27:45 +01002326Handle<Object> FixedDoubleArray::get(FixedDoubleArray* array, int index,
2327 Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002328 if (array->is_the_hole(index)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002329 return isolate->factory()->the_hole_value();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002330 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002331 return isolate->factory()->NewNumber(array->get_scalar(index));
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002332 }
2333}
2334
2335
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002336void FixedDoubleArray::set(int index, double value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002337 DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2338 map() != GetHeap()->fixed_array_map());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002339 int offset = kHeaderSize + index * kDoubleSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002340 if (std::isnan(value)) {
2341 WRITE_DOUBLE_FIELD(this, offset, std::numeric_limits<double>::quiet_NaN());
2342 } else {
2343 WRITE_DOUBLE_FIELD(this, offset, value);
2344 }
2345 DCHECK(!is_the_hole(index));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002346}
2347
2348
2349void FixedDoubleArray::set_the_hole(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002350 DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2351 map() != GetHeap()->fixed_array_map());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002352 int offset = kHeaderSize + index * kDoubleSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002353 WRITE_UINT64_FIELD(this, offset, kHoleNanInt64);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002354}
2355
2356
2357bool FixedDoubleArray::is_the_hole(int index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002358 return get_representation(index) == kHoleNanInt64;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002359}
2360
2361
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002362double* FixedDoubleArray::data_start() {
2363 return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
2364}
2365
2366
2367void FixedDoubleArray::FillWithHoles(int from, int to) {
2368 for (int i = from; i < to; i++) {
2369 set_the_hole(i);
2370 }
2371}
2372
2373
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002374Object* WeakFixedArray::Get(int index) const {
2375 Object* raw = FixedArray::cast(this)->get(index + kFirstIndex);
2376 if (raw->IsSmi()) return raw;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002377 DCHECK(raw->IsWeakCell());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002378 return WeakCell::cast(raw)->value();
2379}
2380
2381
2382bool WeakFixedArray::IsEmptySlot(int index) const {
2383 DCHECK(index < Length());
2384 return Get(index)->IsSmi();
2385}
2386
2387
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002388void WeakFixedArray::Clear(int index) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002389 FixedArray::cast(this)->set(index + kFirstIndex, Smi::FromInt(0));
2390}
2391
2392
2393int WeakFixedArray::Length() const {
2394 return FixedArray::cast(this)->length() - kFirstIndex;
2395}
2396
2397
2398int WeakFixedArray::last_used_index() const {
2399 return Smi::cast(FixedArray::cast(this)->get(kLastUsedIndexIndex))->value();
2400}
2401
2402
2403void WeakFixedArray::set_last_used_index(int index) {
2404 FixedArray::cast(this)->set(kLastUsedIndexIndex, Smi::FromInt(index));
2405}
2406
2407
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002408template <class T>
2409T* WeakFixedArray::Iterator::Next() {
2410 if (list_ != NULL) {
2411 // Assert that list did not change during iteration.
2412 DCHECK_EQ(last_used_index_, list_->last_used_index());
2413 while (index_ < list_->Length()) {
2414 Object* item = list_->Get(index_++);
2415 if (item != Empty()) return T::cast(item);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002416 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002417 list_ = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002418 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002419 return NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002420}
2421
2422
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002423int ArrayList::Length() {
2424 if (FixedArray::cast(this)->length() == 0) return 0;
2425 return Smi::cast(FixedArray::cast(this)->get(kLengthIndex))->value();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002426}
2427
2428
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002429void ArrayList::SetLength(int length) {
2430 return FixedArray::cast(this)->set(kLengthIndex, Smi::FromInt(length));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002431}
2432
2433
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002434Object* ArrayList::Get(int index) {
2435 return FixedArray::cast(this)->get(kFirstIndex + index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002436}
2437
2438
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002439Object** ArrayList::Slot(int index) {
2440 return data_start() + kFirstIndex + index;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002441}
2442
2443
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002444void ArrayList::Set(int index, Object* obj) {
2445 FixedArray::cast(this)->set(kFirstIndex + index, obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002446}
2447
2448
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002449void ArrayList::Clear(int index, Object* undefined) {
2450 DCHECK(undefined->IsUndefined());
2451 FixedArray::cast(this)
2452 ->set(kFirstIndex + index, undefined, SKIP_WRITE_BARRIER);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002453}
2454
2455
2456WriteBarrierMode HeapObject::GetWriteBarrierMode(
2457 const DisallowHeapAllocation& promise) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002458 Heap* heap = GetHeap();
2459 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
2460 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
Steve Blocka7e24c12009-10-30 11:49:00 +00002461 return UPDATE_WRITE_BARRIER;
2462}
2463
2464
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002465AllocationAlignment HeapObject::RequiredAlignment() {
2466#ifdef V8_HOST_ARCH_32_BIT
2467 if ((IsFixedFloat64Array() || IsFixedDoubleArray()) &&
2468 FixedArrayBase::cast(this)->length() != 0) {
2469 return kDoubleAligned;
2470 }
2471 if (IsHeapNumber()) return kDoubleUnaligned;
2472 if (IsSimd128Value()) return kSimd128Unaligned;
2473#endif // V8_HOST_ARCH_32_BIT
2474 return kWordAligned;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002475}
2476
2477
Steve Blocka7e24c12009-10-30 11:49:00 +00002478void FixedArray::set(int index,
2479 Object* value,
2480 WriteBarrierMode mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002481 DCHECK(map() != GetHeap()->fixed_cow_array_map());
2482 DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00002483 int offset = kHeaderSize + index * kPointerSize;
2484 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002485 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002486}
2487
2488
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002489void FixedArray::NoWriteBarrierSet(FixedArray* array,
2490 int index,
2491 Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002492 DCHECK(array->map() != array->GetHeap()->fixed_cow_array_map());
2493 DCHECK(index >= 0 && index < array->length());
2494 DCHECK(!array->GetHeap()->InNewSpace(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00002495 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
2496}
2497
2498
2499void FixedArray::set_undefined(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002500 DCHECK(map() != GetHeap()->fixed_cow_array_map());
2501 DCHECK(index >= 0 && index < this->length());
2502 DCHECK(!GetHeap()->InNewSpace(GetHeap()->undefined_value()));
2503 WRITE_FIELD(this,
2504 kHeaderSize + index * kPointerSize,
2505 GetHeap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002506}
2507
2508
2509void FixedArray::set_null(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002510 DCHECK(index >= 0 && index < this->length());
2511 DCHECK(!GetHeap()->InNewSpace(GetHeap()->null_value()));
2512 WRITE_FIELD(this,
2513 kHeaderSize + index * kPointerSize,
2514 GetHeap()->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002515}
2516
2517
2518void FixedArray::set_the_hole(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002519 DCHECK(map() != GetHeap()->fixed_cow_array_map());
2520 DCHECK(index >= 0 && index < this->length());
2521 DCHECK(!GetHeap()->InNewSpace(GetHeap()->the_hole_value()));
Steve Block44f0eee2011-05-26 01:26:41 +01002522 WRITE_FIELD(this,
2523 kHeaderSize + index * kPointerSize,
2524 GetHeap()->the_hole_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002525}
2526
2527
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002528void FixedArray::FillWithHoles(int from, int to) {
2529 for (int i = from; i < to; i++) {
2530 set_the_hole(i);
2531 }
Iain Merrick75681382010-08-19 15:07:18 +01002532}
2533
2534
Steve Block6ded16b2010-05-10 14:33:55 +01002535Object** FixedArray::data_start() {
2536 return HeapObject::RawField(this, kHeaderSize);
2537}
2538
2539
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002540Object** FixedArray::RawFieldOfElementAt(int index) {
2541 return HeapObject::RawField(this, OffsetOfElementAt(index));
2542}
2543
2544
Steve Blocka7e24c12009-10-30 11:49:00 +00002545bool DescriptorArray::IsEmpty() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002546 DCHECK(length() >= kFirstIndex ||
2547 this == GetHeap()->empty_descriptor_array());
2548 return length() < kFirstIndex;
Ben Murdoch257744e2011-11-30 15:57:28 +00002549}
2550
2551
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002552int DescriptorArray::number_of_descriptors() {
2553 DCHECK(length() >= kFirstIndex || IsEmpty());
2554 int len = length();
2555 return len == 0 ? 0 : Smi::cast(get(kDescriptorLengthIndex))->value();
2556}
2557
2558
2559int DescriptorArray::number_of_descriptors_storage() {
2560 int len = length();
2561 return len == 0 ? 0 : (len - kFirstIndex) / kDescriptorSize;
2562}
2563
2564
2565int DescriptorArray::NumberOfSlackDescriptors() {
2566 return number_of_descriptors_storage() - number_of_descriptors();
2567}
2568
2569
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002570void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
2571 WRITE_FIELD(
2572 this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors));
Steve Blocka7e24c12009-10-30 11:49:00 +00002573}
2574
2575
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002576inline int DescriptorArray::number_of_entries() {
2577 return number_of_descriptors();
2578}
2579
2580
2581bool DescriptorArray::HasEnumCache() {
2582 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi();
2583}
2584
2585
2586void DescriptorArray::CopyEnumCacheFrom(DescriptorArray* array) {
2587 set(kEnumCacheIndex, array->get(kEnumCacheIndex));
2588}
2589
2590
2591FixedArray* DescriptorArray::GetEnumCache() {
2592 DCHECK(HasEnumCache());
2593 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
2594 return FixedArray::cast(bridge->get(kEnumCacheBridgeCacheIndex));
2595}
2596
2597
2598bool DescriptorArray::HasEnumIndicesCache() {
2599 if (IsEmpty()) return false;
2600 Object* object = get(kEnumCacheIndex);
2601 if (object->IsSmi()) return false;
2602 FixedArray* bridge = FixedArray::cast(object);
2603 return !bridge->get(kEnumCacheBridgeIndicesCacheIndex)->IsSmi();
2604}
2605
2606
2607FixedArray* DescriptorArray::GetEnumIndicesCache() {
2608 DCHECK(HasEnumIndicesCache());
2609 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
2610 return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex));
2611}
2612
2613
2614Object** DescriptorArray::GetEnumCacheSlot() {
2615 DCHECK(HasEnumCache());
2616 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
2617 kEnumCacheOffset);
2618}
2619
Ben Murdoch097c5b22016-05-18 11:27:45 +01002620// Perform a binary search in a fixed array.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002621template <SearchMode search_mode, typename T>
Ben Murdoch097c5b22016-05-18 11:27:45 +01002622int BinarySearch(T* array, Name* name, int valid_entries,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002623 int* out_insertion_index) {
2624 DCHECK(search_mode == ALL_ENTRIES || out_insertion_index == NULL);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002625 int low = 0;
2626 int high = array->number_of_entries() - 1;
2627 uint32_t hash = name->hash_field();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002628 int limit = high;
2629
2630 DCHECK(low <= high);
2631
2632 while (low != high) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002633 int mid = low + (high - low) / 2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002634 Name* mid_name = array->GetSortedKey(mid);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002635 uint32_t mid_hash = mid_name->hash_field();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002636
2637 if (mid_hash >= hash) {
2638 high = mid;
2639 } else {
2640 low = mid + 1;
2641 }
2642 }
2643
2644 for (; low <= limit; ++low) {
2645 int sort_index = array->GetSortedKeyIndex(low);
2646 Name* entry = array->GetKey(sort_index);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002647 uint32_t current_hash = entry->hash_field();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002648 if (current_hash != hash) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002649 if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002650 *out_insertion_index = sort_index + (current_hash > hash ? 0 : 1);
2651 }
2652 return T::kNotFound;
2653 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002654 if (entry == name) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002655 if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
2656 return sort_index;
2657 }
2658 return T::kNotFound;
2659 }
2660 }
2661
Ben Murdoch097c5b22016-05-18 11:27:45 +01002662 if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
2663 *out_insertion_index = limit + 1;
2664 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002665 return T::kNotFound;
Steve Blocka7e24c12009-10-30 11:49:00 +00002666}
2667
2668
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002669// Perform a linear search in this fixed array. len is the number of entry
2670// indices that are valid.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002671template <SearchMode search_mode, typename T>
Ben Murdoch097c5b22016-05-18 11:27:45 +01002672int LinearSearch(T* array, Name* name, int valid_entries,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002673 int* out_insertion_index) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002674 if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
2675 uint32_t hash = name->hash_field();
2676 int len = array->number_of_entries();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002677 for (int number = 0; number < len; number++) {
2678 int sorted_index = array->GetSortedKeyIndex(number);
2679 Name* entry = array->GetKey(sorted_index);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002680 uint32_t current_hash = entry->hash_field();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002681 if (current_hash > hash) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002682 *out_insertion_index = sorted_index;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002683 return T::kNotFound;
2684 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002685 if (entry == name) return sorted_index;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002686 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002687 *out_insertion_index = len;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002688 return T::kNotFound;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002689 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002690 DCHECK_LE(valid_entries, array->number_of_entries());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002691 DCHECK_NULL(out_insertion_index); // Not supported here.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002692 for (int number = 0; number < valid_entries; number++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002693 if (array->GetKey(number) == name) return number;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002694 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002695 return T::kNotFound;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002696 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002697}
Steve Blocka7e24c12009-10-30 11:49:00 +00002698
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002699
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002700template <SearchMode search_mode, typename T>
2701int Search(T* array, Name* name, int valid_entries, int* out_insertion_index) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002702 SLOW_DCHECK(array->IsSortedNoDuplicates());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002703
Ben Murdoch097c5b22016-05-18 11:27:45 +01002704 if (valid_entries == 0) {
2705 if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
2706 *out_insertion_index = 0;
2707 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002708 return T::kNotFound;
2709 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002710
2711 // Fast case: do linear search for small arrays.
2712 const int kMaxElementsForLinearSearch = 8;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002713 if (valid_entries <= kMaxElementsForLinearSearch) {
2714 return LinearSearch<search_mode>(array, name, valid_entries,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002715 out_insertion_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002716 }
2717
2718 // Slow case: perform binary search.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002719 return BinarySearch<search_mode>(array, name, valid_entries,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002720 out_insertion_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002721}
2722
2723
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002724int DescriptorArray::Search(Name* name, int valid_descriptors) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002725 DCHECK(name->IsUniqueName());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002726 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors, NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002727}
2728
Ben Murdoch097c5b22016-05-18 11:27:45 +01002729int DescriptorArray::SearchWithCache(Isolate* isolate, Name* name, Map* map) {
2730 DCHECK(name->IsUniqueName());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002731 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
2732 if (number_of_own_descriptors == 0) return kNotFound;
2733
Ben Murdoch097c5b22016-05-18 11:27:45 +01002734 DescriptorLookupCache* cache = isolate->descriptor_lookup_cache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002735 int number = cache->Lookup(map, name);
2736
Iain Merrick75681382010-08-19 15:07:18 +01002737 if (number == DescriptorLookupCache::kAbsent) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002738 number = Search(name, number_of_own_descriptors);
2739 cache->Update(map, name, number);
Iain Merrick75681382010-08-19 15:07:18 +01002740 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002741
Iain Merrick75681382010-08-19 15:07:18 +01002742 return number;
2743}
2744
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002745PropertyDetails Map::GetLastDescriptorDetails() {
2746 return instance_descriptors()->GetDetails(LastAdded());
2747}
2748
2749
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002750int Map::LastAdded() {
2751 int number_of_own_descriptors = NumberOfOwnDescriptors();
2752 DCHECK(number_of_own_descriptors > 0);
2753 return number_of_own_descriptors - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002754}
2755
2756
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002757int Map::NumberOfOwnDescriptors() {
2758 return NumberOfOwnDescriptorsBits::decode(bit_field3());
2759}
2760
2761
2762void Map::SetNumberOfOwnDescriptors(int number) {
2763 DCHECK(number <= instance_descriptors()->number_of_descriptors());
2764 set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number));
2765}
2766
2767
2768int Map::EnumLength() { return EnumLengthBits::decode(bit_field3()); }
2769
2770
2771void Map::SetEnumLength(int length) {
2772 if (length != kInvalidEnumCacheSentinel) {
2773 DCHECK(length >= 0);
2774 DCHECK(length == 0 || instance_descriptors()->HasEnumCache());
2775 DCHECK(length <= NumberOfOwnDescriptors());
2776 }
2777 set_bit_field3(EnumLengthBits::update(bit_field3(), length));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002778}
2779
2780
2781FixedArrayBase* Map::GetInitialElements() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002782 if (has_fast_elements() || has_fast_string_wrapper_elements()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002783 DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
2784 return GetHeap()->empty_fixed_array();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002785 } else if (has_fixed_typed_array_elements()) {
2786 FixedTypedArrayBase* empty_array =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002787 GetHeap()->EmptyFixedTypedArrayForMap(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002788 DCHECK(!GetHeap()->InNewSpace(empty_array));
2789 return empty_array;
2790 } else {
2791 UNREACHABLE();
2792 }
2793 return NULL;
2794}
2795
2796
2797Object** DescriptorArray::GetKeySlot(int descriptor_number) {
2798 DCHECK(descriptor_number < number_of_descriptors());
2799 return RawFieldOfElementAt(ToKeyIndex(descriptor_number));
2800}
2801
2802
2803Object** DescriptorArray::GetDescriptorStartSlot(int descriptor_number) {
2804 return GetKeySlot(descriptor_number);
2805}
2806
2807
2808Object** DescriptorArray::GetDescriptorEndSlot(int descriptor_number) {
2809 return GetValueSlot(descriptor_number - 1) + 1;
2810}
2811
2812
2813Name* DescriptorArray::GetKey(int descriptor_number) {
2814 DCHECK(descriptor_number < number_of_descriptors());
2815 return Name::cast(get(ToKeyIndex(descriptor_number)));
2816}
2817
2818
2819int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
2820 return GetDetails(descriptor_number).pointer();
2821}
2822
2823
2824Name* DescriptorArray::GetSortedKey(int descriptor_number) {
2825 return GetKey(GetSortedKeyIndex(descriptor_number));
2826}
2827
2828
2829void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
2830 PropertyDetails details = GetDetails(descriptor_index);
2831 set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi());
2832}
2833
2834
2835void DescriptorArray::SetRepresentation(int descriptor_index,
2836 Representation representation) {
2837 DCHECK(!representation.IsNone());
2838 PropertyDetails details = GetDetails(descriptor_index);
2839 set(ToDetailsIndex(descriptor_index),
2840 details.CopyWithRepresentation(representation).AsSmi());
2841}
2842
2843
2844Object** DescriptorArray::GetValueSlot(int descriptor_number) {
2845 DCHECK(descriptor_number < number_of_descriptors());
2846 return RawFieldOfElementAt(ToValueIndex(descriptor_number));
2847}
2848
2849
2850int DescriptorArray::GetValueOffset(int descriptor_number) {
2851 return OffsetOfElementAt(ToValueIndex(descriptor_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00002852}
2853
2854
2855Object* DescriptorArray::GetValue(int descriptor_number) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002856 DCHECK(descriptor_number < number_of_descriptors());
2857 return get(ToValueIndex(descriptor_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00002858}
2859
2860
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002861void DescriptorArray::SetValue(int descriptor_index, Object* value) {
2862 set(ToValueIndex(descriptor_index), value);
2863}
2864
2865
2866PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
2867 DCHECK(descriptor_number < number_of_descriptors());
2868 Object* details = get(ToDetailsIndex(descriptor_number));
2869 return PropertyDetails(Smi::cast(details));
Steve Blocka7e24c12009-10-30 11:49:00 +00002870}
2871
2872
2873PropertyType DescriptorArray::GetType(int descriptor_number) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002874 return GetDetails(descriptor_number).type();
Steve Blocka7e24c12009-10-30 11:49:00 +00002875}
2876
2877
2878int DescriptorArray::GetFieldIndex(int descriptor_number) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002879 DCHECK(GetDetails(descriptor_number).location() == kField);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002880 return GetDetails(descriptor_number).field_index();
Steve Blocka7e24c12009-10-30 11:49:00 +00002881}
2882
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002883Object* DescriptorArray::GetConstant(int descriptor_number) {
2884 return GetValue(descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002885}
2886
2887
2888Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002889 DCHECK(GetType(descriptor_number) == ACCESSOR_CONSTANT);
Steve Blocka7e24c12009-10-30 11:49:00 +00002890 return GetValue(descriptor_number);
2891}
2892
2893
2894AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002895 DCHECK(GetType(descriptor_number) == ACCESSOR_CONSTANT);
Ben Murdoch257744e2011-11-30 15:57:28 +00002896 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002897 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
Steve Blocka7e24c12009-10-30 11:49:00 +00002898}
2899
2900
Steve Blocka7e24c12009-10-30 11:49:00 +00002901void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002902 desc->Init(handle(GetKey(descriptor_number), GetIsolate()),
2903 handle(GetValue(descriptor_number), GetIsolate()),
2904 GetDetails(descriptor_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00002905}
2906
2907
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002908void DescriptorArray::SetDescriptor(int descriptor_number, Descriptor* desc) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002909 // Range check.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002910 DCHECK(descriptor_number < number_of_descriptors());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002911 set(ToKeyIndex(descriptor_number), *desc->GetKey());
2912 set(ToValueIndex(descriptor_number), *desc->GetValue());
2913 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
Steve Blocka7e24c12009-10-30 11:49:00 +00002914}
2915
2916
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002917void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
2918 // Range check.
2919 DCHECK(descriptor_number < number_of_descriptors());
2920
2921 set(ToKeyIndex(descriptor_number), *desc->GetKey());
2922 set(ToValueIndex(descriptor_number), *desc->GetValue());
2923 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
2924}
2925
2926
2927void DescriptorArray::Append(Descriptor* desc) {
2928 DisallowHeapAllocation no_gc;
2929 int descriptor_number = number_of_descriptors();
2930 SetNumberOfDescriptors(descriptor_number + 1);
2931 Set(descriptor_number, desc);
2932
2933 uint32_t hash = desc->GetKey()->Hash();
2934
2935 int insertion;
2936
2937 for (insertion = descriptor_number; insertion > 0; --insertion) {
2938 Name* key = GetSortedKey(insertion - 1);
2939 if (key->Hash() <= hash) break;
2940 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
2941 }
2942
2943 SetSortedKey(insertion, descriptor_number);
2944}
2945
2946
2947void DescriptorArray::SwapSortedKeys(int first, int second) {
2948 int first_key = GetSortedKeyIndex(first);
2949 SetSortedKey(first, GetSortedKeyIndex(second));
2950 SetSortedKey(second, first_key);
Ben Murdoch85b71792012-04-11 18:30:58 +01002951}
2952
2953
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002954PropertyType DescriptorArray::Entry::type() { return descs_->GetType(index_); }
2955
2956
2957Object* DescriptorArray::Entry::GetCallbackObject() {
2958 return descs_->GetValue(index_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002959}
2960
2961
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002962int HashTableBase::NumberOfElements() {
2963 return Smi::cast(get(kNumberOfElementsIndex))->value();
Steve Blocka7e24c12009-10-30 11:49:00 +00002964}
2965
2966
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002967int HashTableBase::NumberOfDeletedElements() {
2968 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
2969}
2970
2971
2972int HashTableBase::Capacity() {
2973 return Smi::cast(get(kCapacityIndex))->value();
2974}
2975
2976
2977void HashTableBase::ElementAdded() {
2978 SetNumberOfElements(NumberOfElements() + 1);
2979}
2980
2981
2982void HashTableBase::ElementRemoved() {
2983 SetNumberOfElements(NumberOfElements() - 1);
2984 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
2985}
2986
2987
2988void HashTableBase::ElementsRemoved(int n) {
2989 SetNumberOfElements(NumberOfElements() - n);
2990 SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
2991}
2992
2993
2994// static
2995int HashTableBase::ComputeCapacity(int at_least_space_for) {
2996 const int kMinCapacity = 4;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002997 int capacity = base::bits::RoundUpToPowerOfTwo32(at_least_space_for * 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002998 return Max(capacity, kMinCapacity);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002999}
3000
Ben Murdochda12d292016-06-02 14:46:10 +01003001bool HashTableBase::IsKey(Heap* heap, Object* k) {
3002 return k != heap->the_hole_value() && k != heap->undefined_value();
3003}
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003004
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003005bool HashTableBase::IsKey(Object* k) {
3006 return !k->IsTheHole() && !k->IsUndefined();
3007}
3008
3009
3010void HashTableBase::SetNumberOfElements(int nof) {
3011 set(kNumberOfElementsIndex, Smi::FromInt(nof));
3012}
3013
3014
3015void HashTableBase::SetNumberOfDeletedElements(int nod) {
3016 set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod));
3017}
3018
3019
3020template <typename Derived, typename Shape, typename Key>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003021int HashTable<Derived, Shape, Key>::FindEntry(Key key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003022 return FindEntry(GetIsolate(), key);
3023}
3024
3025
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003026template<typename Derived, typename Shape, typename Key>
3027int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003028 return FindEntry(isolate, key, HashTable::Hash(key));
3029}
3030
3031
3032// Find entry for key otherwise return kNotFound.
3033template <typename Derived, typename Shape, typename Key>
3034int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key,
3035 int32_t hash) {
Steve Block44f0eee2011-05-26 01:26:41 +01003036 uint32_t capacity = Capacity();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003037 uint32_t entry = FirstProbe(hash, capacity);
Steve Block44f0eee2011-05-26 01:26:41 +01003038 uint32_t count = 1;
3039 // EnsureCapacity will guarantee the hash table is never full.
3040 while (true) {
3041 Object* element = KeyAt(entry);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003042 // Empty entry. Uses raw unchecked accessors because it is called by the
3043 // string table during bootstrapping.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003044 if (element == isolate->heap()->root(Heap::kUndefinedValueRootIndex)) break;
3045 if (element != isolate->heap()->root(Heap::kTheHoleValueRootIndex) &&
Steve Block44f0eee2011-05-26 01:26:41 +01003046 Shape::IsMatch(key, element)) return entry;
3047 entry = NextProbe(entry, count++, capacity);
3048 }
3049 return kNotFound;
3050}
3051
Ben Murdochda12d292016-06-02 14:46:10 +01003052bool StringSetShape::IsMatch(String* key, Object* value) {
3053 return value->IsString() && key->Equals(String::cast(value));
3054}
3055
3056uint32_t StringSetShape::Hash(String* key) { return key->Hash(); }
3057
3058uint32_t StringSetShape::HashForObject(String* key, Object* object) {
3059 return object->IsString() ? String::cast(object)->Hash() : 0;
3060}
Steve Block44f0eee2011-05-26 01:26:41 +01003061
Ben Murdochc7cc0282012-03-05 14:35:55 +00003062bool SeededNumberDictionary::requires_slow_elements() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003063 Object* max_index_object = get(kMaxNumberKeyIndex);
3064 if (!max_index_object->IsSmi()) return false;
3065 return 0 !=
3066 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
3067}
3068
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003069
Ben Murdochc7cc0282012-03-05 14:35:55 +00003070uint32_t SeededNumberDictionary::max_number_key() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003071 DCHECK(!requires_slow_elements());
Steve Blocka7e24c12009-10-30 11:49:00 +00003072 Object* max_index_object = get(kMaxNumberKeyIndex);
3073 if (!max_index_object->IsSmi()) return 0;
3074 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
3075 return value >> kRequiresSlowElementsTagSize;
3076}
3077
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003078
Ben Murdochc7cc0282012-03-05 14:35:55 +00003079void SeededNumberDictionary::set_requires_slow_elements() {
Leon Clarke4515c472010-02-03 11:58:03 +00003080 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
Steve Blocka7e24c12009-10-30 11:49:00 +00003081}
3082
3083
3084// ------------------------------------
3085// Cast operations
3086
Ben Murdoch097c5b22016-05-18 11:27:45 +01003087CAST_ACCESSOR(AbstractCode)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003088CAST_ACCESSOR(ArrayList)
3089CAST_ACCESSOR(Bool16x8)
3090CAST_ACCESSOR(Bool32x4)
3091CAST_ACCESSOR(Bool8x16)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003092CAST_ACCESSOR(ByteArray)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003093CAST_ACCESSOR(BytecodeArray)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003094CAST_ACCESSOR(Cell)
3095CAST_ACCESSOR(Code)
3096CAST_ACCESSOR(CodeCacheHashTable)
3097CAST_ACCESSOR(CompilationCacheTable)
3098CAST_ACCESSOR(ConsString)
Ben Murdochb0fe1622011-05-05 13:52:32 +01003099CAST_ACCESSOR(DeoptimizationInputData)
3100CAST_ACCESSOR(DeoptimizationOutputData)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003101CAST_ACCESSOR(DependentCode)
3102CAST_ACCESSOR(DescriptorArray)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003103CAST_ACCESSOR(ExternalOneByteString)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003104CAST_ACCESSOR(ExternalString)
3105CAST_ACCESSOR(ExternalTwoByteString)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003106CAST_ACCESSOR(FixedArray)
3107CAST_ACCESSOR(FixedArrayBase)
3108CAST_ACCESSOR(FixedDoubleArray)
3109CAST_ACCESSOR(FixedTypedArrayBase)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003110CAST_ACCESSOR(Float32x4)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003111CAST_ACCESSOR(Foreign)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003112CAST_ACCESSOR(GlobalDictionary)
3113CAST_ACCESSOR(HandlerTable)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003114CAST_ACCESSOR(HeapObject)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003115CAST_ACCESSOR(Int16x8)
3116CAST_ACCESSOR(Int32x4)
3117CAST_ACCESSOR(Int8x16)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003118CAST_ACCESSOR(JSArray)
3119CAST_ACCESSOR(JSArrayBuffer)
3120CAST_ACCESSOR(JSArrayBufferView)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003121CAST_ACCESSOR(JSBoundFunction)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003122CAST_ACCESSOR(JSDataView)
3123CAST_ACCESSOR(JSDate)
3124CAST_ACCESSOR(JSFunction)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003125CAST_ACCESSOR(JSGeneratorObject)
3126CAST_ACCESSOR(JSGlobalObject)
3127CAST_ACCESSOR(JSGlobalProxy)
3128CAST_ACCESSOR(JSMap)
3129CAST_ACCESSOR(JSMapIterator)
3130CAST_ACCESSOR(JSMessageObject)
3131CAST_ACCESSOR(JSModule)
3132CAST_ACCESSOR(JSObject)
3133CAST_ACCESSOR(JSProxy)
3134CAST_ACCESSOR(JSReceiver)
3135CAST_ACCESSOR(JSRegExp)
3136CAST_ACCESSOR(JSSet)
3137CAST_ACCESSOR(JSSetIterator)
3138CAST_ACCESSOR(JSTypedArray)
3139CAST_ACCESSOR(JSValue)
3140CAST_ACCESSOR(JSWeakMap)
3141CAST_ACCESSOR(JSWeakSet)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003142CAST_ACCESSOR(LayoutDescriptor)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003143CAST_ACCESSOR(Map)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003144CAST_ACCESSOR(Name)
3145CAST_ACCESSOR(NameDictionary)
3146CAST_ACCESSOR(NormalizedMapCache)
3147CAST_ACCESSOR(Object)
3148CAST_ACCESSOR(ObjectHashTable)
3149CAST_ACCESSOR(Oddball)
3150CAST_ACCESSOR(OrderedHashMap)
3151CAST_ACCESSOR(OrderedHashSet)
3152CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
3153CAST_ACCESSOR(PropertyCell)
3154CAST_ACCESSOR(ScopeInfo)
3155CAST_ACCESSOR(SeededNumberDictionary)
3156CAST_ACCESSOR(SeqOneByteString)
3157CAST_ACCESSOR(SeqString)
3158CAST_ACCESSOR(SeqTwoByteString)
3159CAST_ACCESSOR(SharedFunctionInfo)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003160CAST_ACCESSOR(Simd128Value)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003161CAST_ACCESSOR(SlicedString)
3162CAST_ACCESSOR(Smi)
3163CAST_ACCESSOR(String)
Ben Murdochda12d292016-06-02 14:46:10 +01003164CAST_ACCESSOR(StringSet)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003165CAST_ACCESSOR(StringTable)
Steve Blocka7e24c12009-10-30 11:49:00 +00003166CAST_ACCESSOR(Struct)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003167CAST_ACCESSOR(Symbol)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003168CAST_ACCESSOR(Uint16x8)
3169CAST_ACCESSOR(Uint32x4)
3170CAST_ACCESSOR(Uint8x16)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003171CAST_ACCESSOR(UnseededNumberDictionary)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003172CAST_ACCESSOR(WeakCell)
3173CAST_ACCESSOR(WeakFixedArray)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003174CAST_ACCESSOR(WeakHashTable)
3175
3176
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003177// static
3178template <class Traits>
3179STATIC_CONST_MEMBER_DEFINITION const InstanceType
3180 FixedTypedArray<Traits>::kInstanceType;
3181
3182
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003183template <class Traits>
3184FixedTypedArray<Traits>* FixedTypedArray<Traits>::cast(Object* object) {
3185 SLOW_DCHECK(object->IsHeapObject() &&
3186 HeapObject::cast(object)->map()->instance_type() ==
3187 Traits::kInstanceType);
3188 return reinterpret_cast<FixedTypedArray<Traits>*>(object);
3189}
3190
3191
3192template <class Traits>
3193const FixedTypedArray<Traits>*
3194FixedTypedArray<Traits>::cast(const Object* object) {
3195 SLOW_DCHECK(object->IsHeapObject() &&
3196 HeapObject::cast(object)->map()->instance_type() ==
3197 Traits::kInstanceType);
3198 return reinterpret_cast<FixedTypedArray<Traits>*>(object);
3199}
Steve Blocka7e24c12009-10-30 11:49:00 +00003200
3201
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003202#define DEFINE_DEOPT_ELEMENT_ACCESSORS(name, type) \
3203 type* DeoptimizationInputData::name() { \
3204 return type::cast(get(k##name##Index)); \
3205 } \
3206 void DeoptimizationInputData::Set##name(type* value) { \
3207 set(k##name##Index, value); \
3208 }
3209
3210DEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
3211DEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
3212DEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
3213DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrAstId, Smi)
3214DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
3215DEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi)
3216DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
3217DEFINE_DEOPT_ELEMENT_ACCESSORS(WeakCellCache, Object)
3218
3219#undef DEFINE_DEOPT_ELEMENT_ACCESSORS
3220
3221
3222#define DEFINE_DEOPT_ENTRY_ACCESSORS(name, type) \
3223 type* DeoptimizationInputData::name(int i) { \
3224 return type::cast(get(IndexForEntry(i) + k##name##Offset)); \
3225 } \
3226 void DeoptimizationInputData::Set##name(int i, type* value) { \
3227 set(IndexForEntry(i) + k##name##Offset, value); \
3228 }
3229
3230DEFINE_DEOPT_ENTRY_ACCESSORS(AstIdRaw, Smi)
3231DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
3232DEFINE_DEOPT_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
3233DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
3234
3235#undef DEFINE_DEOPT_ENTRY_ACCESSORS
3236
3237
3238BailoutId DeoptimizationInputData::AstId(int i) {
3239 return BailoutId(AstIdRaw(i)->value());
3240}
3241
3242
3243void DeoptimizationInputData::SetAstId(int i, BailoutId value) {
3244 SetAstIdRaw(i, Smi::FromInt(value.ToInt()));
3245}
3246
3247
3248int DeoptimizationInputData::DeoptCount() {
3249 return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
3250}
3251
3252
3253int DeoptimizationOutputData::DeoptPoints() { return length() / 2; }
3254
3255
3256BailoutId DeoptimizationOutputData::AstId(int index) {
3257 return BailoutId(Smi::cast(get(index * 2))->value());
3258}
3259
3260
3261void DeoptimizationOutputData::SetAstId(int index, BailoutId id) {
3262 set(index * 2, Smi::FromInt(id.ToInt()));
3263}
3264
3265
3266Smi* DeoptimizationOutputData::PcAndState(int index) {
3267 return Smi::cast(get(1 + index * 2));
3268}
3269
3270
3271void DeoptimizationOutputData::SetPcAndState(int index, Smi* offset) {
3272 set(1 + index * 2, offset);
3273}
3274
3275
3276Object* LiteralsArray::get(int index) const { return FixedArray::get(index); }
3277
3278
3279void LiteralsArray::set(int index, Object* value) {
3280 FixedArray::set(index, value);
3281}
3282
3283
3284void LiteralsArray::set(int index, Smi* value) {
3285 FixedArray::set(index, value);
3286}
3287
3288
3289void LiteralsArray::set(int index, Object* value, WriteBarrierMode mode) {
3290 FixedArray::set(index, value, mode);
3291}
3292
3293
3294LiteralsArray* LiteralsArray::cast(Object* object) {
3295 SLOW_DCHECK(object->IsLiteralsArray());
3296 return reinterpret_cast<LiteralsArray*>(object);
3297}
3298
3299
3300TypeFeedbackVector* LiteralsArray::feedback_vector() const {
3301 return TypeFeedbackVector::cast(get(kVectorIndex));
3302}
3303
3304
3305void LiteralsArray::set_feedback_vector(TypeFeedbackVector* vector) {
3306 set(kVectorIndex, vector);
3307}
3308
3309
3310Object* LiteralsArray::literal(int literal_index) const {
3311 return get(kFirstLiteralIndex + literal_index);
3312}
3313
3314
3315void LiteralsArray::set_literal(int literal_index, Object* literal) {
3316 set(kFirstLiteralIndex + literal_index, literal);
3317}
3318
3319
3320int LiteralsArray::literals_count() const {
3321 return length() - kFirstLiteralIndex;
3322}
3323
Ben Murdoch097c5b22016-05-18 11:27:45 +01003324int HandlerTable::GetRangeStart(int index) const {
3325 return Smi::cast(get(index * kRangeEntrySize + kRangeStartIndex))->value();
3326}
3327
3328int HandlerTable::GetRangeEnd(int index) const {
3329 return Smi::cast(get(index * kRangeEntrySize + kRangeEndIndex))->value();
3330}
3331
3332int HandlerTable::GetRangeHandler(int index) const {
3333 return HandlerOffsetField::decode(
3334 Smi::cast(get(index * kRangeEntrySize + kRangeHandlerIndex))->value());
3335}
3336
3337int HandlerTable::GetRangeData(int index) const {
3338 return Smi::cast(get(index * kRangeEntrySize + kRangeDataIndex))->value();
3339}
3340
3341HandlerTable::CatchPrediction HandlerTable::GetRangePrediction(
3342 int index) const {
3343 return HandlerPredictionField::decode(
3344 Smi::cast(get(index * kRangeEntrySize + kRangeHandlerIndex))->value());
3345}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003346
3347void HandlerTable::SetRangeStart(int index, int value) {
3348 set(index * kRangeEntrySize + kRangeStartIndex, Smi::FromInt(value));
3349}
3350
3351
3352void HandlerTable::SetRangeEnd(int index, int value) {
3353 set(index * kRangeEntrySize + kRangeEndIndex, Smi::FromInt(value));
3354}
3355
3356
3357void HandlerTable::SetRangeHandler(int index, int offset,
3358 CatchPrediction prediction) {
3359 int value = HandlerOffsetField::encode(offset) |
3360 HandlerPredictionField::encode(prediction);
3361 set(index * kRangeEntrySize + kRangeHandlerIndex, Smi::FromInt(value));
3362}
3363
Ben Murdoch097c5b22016-05-18 11:27:45 +01003364void HandlerTable::SetRangeData(int index, int value) {
3365 set(index * kRangeEntrySize + kRangeDataIndex, Smi::FromInt(value));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003366}
3367
3368
3369void HandlerTable::SetReturnOffset(int index, int value) {
3370 set(index * kReturnEntrySize + kReturnOffsetIndex, Smi::FromInt(value));
3371}
3372
3373
3374void HandlerTable::SetReturnHandler(int index, int offset,
3375 CatchPrediction prediction) {
3376 int value = HandlerOffsetField::encode(offset) |
3377 HandlerPredictionField::encode(prediction);
3378 set(index * kReturnEntrySize + kReturnHandlerIndex, Smi::FromInt(value));
3379}
3380
Ben Murdoch097c5b22016-05-18 11:27:45 +01003381int HandlerTable::NumberOfRangeEntries() const {
3382 return length() / kRangeEntrySize;
3383}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003384
Steve Blocka7e24c12009-10-30 11:49:00 +00003385#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
3386 STRUCT_LIST(MAKE_STRUCT_CAST)
3387#undef MAKE_STRUCT_CAST
3388
3389
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003390template <typename Derived, typename Shape, typename Key>
3391HashTable<Derived, Shape, Key>*
3392HashTable<Derived, Shape, Key>::cast(Object* obj) {
3393 SLOW_DCHECK(obj->IsHashTable());
Steve Blocka7e24c12009-10-30 11:49:00 +00003394 return reinterpret_cast<HashTable*>(obj);
3395}
3396
3397
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003398template <typename Derived, typename Shape, typename Key>
3399const HashTable<Derived, Shape, Key>*
3400HashTable<Derived, Shape, Key>::cast(const Object* obj) {
3401 SLOW_DCHECK(obj->IsHashTable());
3402 return reinterpret_cast<const HashTable*>(obj);
3403}
3404
3405
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003406SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003407SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
3408
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003409SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003410NOBARRIER_SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00003411
Steve Block6ded16b2010-05-10 14:33:55 +01003412SMI_ACCESSORS(String, length, kLengthOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003413SYNCHRONIZED_SMI_ACCESSORS(String, length, kLengthOffset)
Steve Blockd0582a62009-12-15 09:54:21 +00003414
3415
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003416int FreeSpace::Size() { return size(); }
3417
3418
3419FreeSpace* FreeSpace::next() {
3420 DCHECK(map() == GetHeap()->root(Heap::kFreeSpaceMapRootIndex) ||
3421 (!GetHeap()->deserialization_complete() && map() == NULL));
3422 DCHECK_LE(kNextOffset + kPointerSize, nobarrier_size());
3423 return reinterpret_cast<FreeSpace*>(
3424 Memory::Address_at(address() + kNextOffset));
3425}
3426
3427
3428void FreeSpace::set_next(FreeSpace* next) {
3429 DCHECK(map() == GetHeap()->root(Heap::kFreeSpaceMapRootIndex) ||
3430 (!GetHeap()->deserialization_complete() && map() == NULL));
3431 DCHECK_LE(kNextOffset + kPointerSize, nobarrier_size());
3432 base::NoBarrier_Store(
3433 reinterpret_cast<base::AtomicWord*>(address() + kNextOffset),
3434 reinterpret_cast<base::AtomicWord>(next));
3435}
3436
3437
3438FreeSpace* FreeSpace::cast(HeapObject* o) {
3439 SLOW_DCHECK(!o->GetHeap()->deserialization_complete() || o->IsFreeSpace());
3440 return reinterpret_cast<FreeSpace*>(o);
3441}
3442
3443
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003444uint32_t Name::hash_field() {
Steve Blockd0582a62009-12-15 09:54:21 +00003445 return READ_UINT32_FIELD(this, kHashFieldOffset);
3446}
3447
3448
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003449void Name::set_hash_field(uint32_t value) {
Steve Blockd0582a62009-12-15 09:54:21 +00003450 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01003451#if V8_HOST_ARCH_64_BIT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003452#if V8_TARGET_LITTLE_ENDIAN
3453 WRITE_UINT32_FIELD(this, kHashFieldSlot + kIntSize, 0);
3454#else
3455 WRITE_UINT32_FIELD(this, kHashFieldSlot, 0);
3456#endif
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01003457#endif
Steve Blockd0582a62009-12-15 09:54:21 +00003458}
3459
3460
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003461bool Name::Equals(Name* other) {
3462 if (other == this) return true;
3463 if ((this->IsInternalizedString() && other->IsInternalizedString()) ||
3464 this->IsSymbol() || other->IsSymbol()) {
3465 return false;
3466 }
3467 return String::cast(this)->SlowEquals(String::cast(other));
3468}
3469
3470
3471bool Name::Equals(Handle<Name> one, Handle<Name> two) {
3472 if (one.is_identical_to(two)) return true;
3473 if ((one->IsInternalizedString() && two->IsInternalizedString()) ||
3474 one->IsSymbol() || two->IsSymbol()) {
3475 return false;
3476 }
3477 return String::SlowEquals(Handle<String>::cast(one),
3478 Handle<String>::cast(two));
3479}
3480
3481
3482ACCESSORS(Symbol, name, Object, kNameOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003483SMI_ACCESSORS(Symbol, flags, kFlagsOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003484BOOL_ACCESSORS(Symbol, flags, is_private, kPrivateBit)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003485BOOL_ACCESSORS(Symbol, flags, is_well_known_symbol, kWellKnownSymbolBit)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003486
3487
Steve Blocka7e24c12009-10-30 11:49:00 +00003488bool String::Equals(String* other) {
3489 if (other == this) return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003490 if (this->IsInternalizedString() && other->IsInternalizedString()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003491 return false;
3492 }
3493 return SlowEquals(other);
3494}
3495
3496
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003497bool String::Equals(Handle<String> one, Handle<String> two) {
3498 if (one.is_identical_to(two)) return true;
3499 if (one->IsInternalizedString() && two->IsInternalizedString()) {
3500 return false;
3501 }
3502 return SlowEquals(one, two);
Steve Blocka7e24c12009-10-30 11:49:00 +00003503}
3504
3505
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003506Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) {
3507 if (!string->IsConsString()) return string;
3508 Handle<ConsString> cons = Handle<ConsString>::cast(string);
3509 if (cons->IsFlat()) return handle(cons->first());
3510 return SlowFlatten(cons, pretenure);
Leon Clarkef7060e22010-06-03 12:02:55 +01003511}
3512
3513
Steve Blocka7e24c12009-10-30 11:49:00 +00003514uint16_t String::Get(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003515 DCHECK(index >= 0 && index < length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003516 switch (StringShape(this).full_representation_tag()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003517 case kSeqStringTag | kOneByteStringTag:
3518 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00003519 case kSeqStringTag | kTwoByteStringTag:
3520 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003521 case kConsStringTag | kOneByteStringTag:
Steve Blocka7e24c12009-10-30 11:49:00 +00003522 case kConsStringTag | kTwoByteStringTag:
3523 return ConsString::cast(this)->ConsStringGet(index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003524 case kExternalStringTag | kOneByteStringTag:
3525 return ExternalOneByteString::cast(this)->ExternalOneByteStringGet(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00003526 case kExternalStringTag | kTwoByteStringTag:
3527 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003528 case kSlicedStringTag | kOneByteStringTag:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003529 case kSlicedStringTag | kTwoByteStringTag:
3530 return SlicedString::cast(this)->SlicedStringGet(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00003531 default:
3532 break;
3533 }
3534
3535 UNREACHABLE();
3536 return 0;
3537}
3538
3539
3540void String::Set(int index, uint16_t value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003541 DCHECK(index >= 0 && index < length());
3542 DCHECK(StringShape(this).IsSequential());
Steve Blocka7e24c12009-10-30 11:49:00 +00003543
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003544 return this->IsOneByteRepresentation()
3545 ? SeqOneByteString::cast(this)->SeqOneByteStringSet(index, value)
Steve Blocka7e24c12009-10-30 11:49:00 +00003546 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
3547}
3548
3549
3550bool String::IsFlat() {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003551 if (!StringShape(this).IsCons()) return true;
3552 return ConsString::cast(this)->second()->length() == 0;
3553}
3554
3555
3556String* String::GetUnderlying() {
3557 // Giving direct access to underlying string only makes sense if the
3558 // wrapping string is already flattened.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003559 DCHECK(this->IsFlat());
3560 DCHECK(StringShape(this).IsIndirect());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003561 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
3562 const int kUnderlyingOffset = SlicedString::kParentOffset;
3563 return String::cast(READ_FIELD(this, kUnderlyingOffset));
Steve Blocka7e24c12009-10-30 11:49:00 +00003564}
3565
3566
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003567template<class Visitor>
3568ConsString* String::VisitFlat(Visitor* visitor,
3569 String* string,
3570 const int offset) {
3571 int slice_offset = offset;
3572 const int length = string->length();
3573 DCHECK(offset <= length);
3574 while (true) {
3575 int32_t type = string->map()->instance_type();
3576 switch (type & (kStringRepresentationMask | kStringEncodingMask)) {
3577 case kSeqStringTag | kOneByteStringTag:
3578 visitor->VisitOneByteString(
3579 SeqOneByteString::cast(string)->GetChars() + slice_offset,
3580 length - offset);
3581 return NULL;
3582
3583 case kSeqStringTag | kTwoByteStringTag:
3584 visitor->VisitTwoByteString(
3585 SeqTwoByteString::cast(string)->GetChars() + slice_offset,
3586 length - offset);
3587 return NULL;
3588
3589 case kExternalStringTag | kOneByteStringTag:
3590 visitor->VisitOneByteString(
3591 ExternalOneByteString::cast(string)->GetChars() + slice_offset,
3592 length - offset);
3593 return NULL;
3594
3595 case kExternalStringTag | kTwoByteStringTag:
3596 visitor->VisitTwoByteString(
3597 ExternalTwoByteString::cast(string)->GetChars() + slice_offset,
3598 length - offset);
3599 return NULL;
3600
3601 case kSlicedStringTag | kOneByteStringTag:
3602 case kSlicedStringTag | kTwoByteStringTag: {
3603 SlicedString* slicedString = SlicedString::cast(string);
3604 slice_offset += slicedString->offset();
3605 string = slicedString->parent();
3606 continue;
3607 }
3608
3609 case kConsStringTag | kOneByteStringTag:
3610 case kConsStringTag | kTwoByteStringTag:
3611 return ConsString::cast(string);
3612
3613 default:
3614 UNREACHABLE();
3615 return NULL;
3616 }
3617 }
3618}
3619
3620
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003621template <>
3622inline Vector<const uint8_t> String::GetCharVector() {
3623 String::FlatContent flat = GetFlatContent();
3624 DCHECK(flat.IsOneByte());
3625 return flat.ToOneByteVector();
3626}
3627
3628
3629template <>
3630inline Vector<const uc16> String::GetCharVector() {
3631 String::FlatContent flat = GetFlatContent();
3632 DCHECK(flat.IsTwoByte());
3633 return flat.ToUC16Vector();
3634}
3635
3636
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003637uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
3638 DCHECK(index >= 0 && index < length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003639 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
3640}
3641
3642
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003643void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) {
3644 DCHECK(index >= 0 && index < length() && value <= kMaxOneByteCharCode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003645 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
3646 static_cast<byte>(value));
3647}
3648
3649
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003650Address SeqOneByteString::GetCharsAddress() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003651 return FIELD_ADDR(this, kHeaderSize);
3652}
3653
3654
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003655uint8_t* SeqOneByteString::GetChars() {
3656 return reinterpret_cast<uint8_t*>(GetCharsAddress());
Steve Blocka7e24c12009-10-30 11:49:00 +00003657}
3658
3659
3660Address SeqTwoByteString::GetCharsAddress() {
3661 return FIELD_ADDR(this, kHeaderSize);
3662}
3663
3664
3665uc16* SeqTwoByteString::GetChars() {
3666 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
3667}
3668
3669
3670uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003671 DCHECK(index >= 0 && index < length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003672 return READ_UINT16_FIELD(this, kHeaderSize + index * kShortSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00003673}
3674
3675
3676void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003677 DCHECK(index >= 0 && index < length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003678 WRITE_UINT16_FIELD(this, kHeaderSize + index * kShortSize, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003679}
3680
3681
3682int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
Steve Block6ded16b2010-05-10 14:33:55 +01003683 return SizeFor(length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003684}
3685
3686
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003687int SeqOneByteString::SeqOneByteStringSize(InstanceType instance_type) {
Steve Block6ded16b2010-05-10 14:33:55 +01003688 return SizeFor(length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003689}
3690
3691
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003692String* SlicedString::parent() {
3693 return String::cast(READ_FIELD(this, kParentOffset));
3694}
3695
3696
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003697void SlicedString::set_parent(String* parent, WriteBarrierMode mode) {
3698 DCHECK(parent->IsSeqString() || parent->IsExternalString());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003699 WRITE_FIELD(this, kParentOffset, parent);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003700 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kParentOffset, parent, mode);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003701}
3702
3703
3704SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
3705
3706
Steve Blocka7e24c12009-10-30 11:49:00 +00003707String* ConsString::first() {
3708 return String::cast(READ_FIELD(this, kFirstOffset));
3709}
3710
3711
3712Object* ConsString::unchecked_first() {
3713 return READ_FIELD(this, kFirstOffset);
3714}
3715
3716
3717void ConsString::set_first(String* value, WriteBarrierMode mode) {
3718 WRITE_FIELD(this, kFirstOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003719 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003720}
3721
3722
3723String* ConsString::second() {
3724 return String::cast(READ_FIELD(this, kSecondOffset));
3725}
3726
3727
3728Object* ConsString::unchecked_second() {
3729 return READ_FIELD(this, kSecondOffset);
3730}
3731
3732
3733void ConsString::set_second(String* value, WriteBarrierMode mode) {
3734 WRITE_FIELD(this, kSecondOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003735 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003736}
3737
3738
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003739bool ExternalString::is_short() {
3740 InstanceType type = map()->instance_type();
3741 return (type & kShortExternalStringMask) == kShortExternalStringTag;
3742}
3743
3744
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003745const ExternalOneByteString::Resource* ExternalOneByteString::resource() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003746 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
3747}
3748
3749
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003750void ExternalOneByteString::update_data_cache() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003751 if (is_short()) return;
3752 const char** data_field =
3753 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
3754 *data_field = resource()->data();
3755}
3756
3757
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003758void ExternalOneByteString::set_resource(
3759 const ExternalOneByteString::Resource* resource) {
3760 DCHECK(IsAligned(reinterpret_cast<intptr_t>(resource), kPointerSize));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003761 *reinterpret_cast<const Resource**>(
3762 FIELD_ADDR(this, kResourceOffset)) = resource;
3763 if (resource != NULL) update_data_cache();
Steve Blocka7e24c12009-10-30 11:49:00 +00003764}
3765
3766
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003767const uint8_t* ExternalOneByteString::GetChars() {
3768 return reinterpret_cast<const uint8_t*>(resource()->data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003769}
3770
3771
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003772uint16_t ExternalOneByteString::ExternalOneByteStringGet(int index) {
3773 DCHECK(index >= 0 && index < length());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003774 return GetChars()[index];
3775}
3776
3777
3778const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003779 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
3780}
3781
3782
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003783void ExternalTwoByteString::update_data_cache() {
3784 if (is_short()) return;
3785 const uint16_t** data_field =
3786 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
3787 *data_field = resource()->data();
3788}
3789
3790
Steve Blocka7e24c12009-10-30 11:49:00 +00003791void ExternalTwoByteString::set_resource(
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003792 const ExternalTwoByteString::Resource* resource) {
3793 *reinterpret_cast<const Resource**>(
3794 FIELD_ADDR(this, kResourceOffset)) = resource;
3795 if (resource != NULL) update_data_cache();
3796}
3797
3798
3799const uint16_t* ExternalTwoByteString::GetChars() {
3800 return resource()->data();
3801}
3802
3803
3804uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003805 DCHECK(index >= 0 && index < length());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003806 return GetChars()[index];
3807}
3808
3809
3810const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
3811 unsigned start) {
3812 return GetChars() + start;
Steve Blocka7e24c12009-10-30 11:49:00 +00003813}
3814
3815
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003816int ConsStringIterator::OffsetForDepth(int depth) { return depth & kDepthMask; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003817
3818
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003819void ConsStringIterator::PushLeft(ConsString* string) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003820 frames_[depth_++ & kDepthMask] = string;
3821}
3822
3823
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003824void ConsStringIterator::PushRight(ConsString* string) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003825 // Inplace update.
3826 frames_[(depth_-1) & kDepthMask] = string;
3827}
3828
3829
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003830void ConsStringIterator::AdjustMaximumDepth() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003831 if (depth_ > maximum_depth_) maximum_depth_ = depth_;
3832}
3833
3834
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003835void ConsStringIterator::Pop() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003836 DCHECK(depth_ > 0);
3837 DCHECK(depth_ <= maximum_depth_);
3838 depth_--;
3839}
3840
3841
3842uint16_t StringCharacterStream::GetNext() {
3843 DCHECK(buffer8_ != NULL && end_ != NULL);
3844 // Advance cursor if needed.
3845 if (buffer8_ == end_) HasMore();
3846 DCHECK(buffer8_ < end_);
3847 return is_one_byte_ ? *buffer8_++ : *buffer16_++;
3848}
3849
3850
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003851StringCharacterStream::StringCharacterStream(String* string, int offset)
3852 : is_one_byte_(false) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003853 Reset(string, offset);
3854}
3855
3856
3857void StringCharacterStream::Reset(String* string, int offset) {
3858 buffer8_ = NULL;
3859 end_ = NULL;
3860 ConsString* cons_string = String::VisitFlat(this, string, offset);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003861 iter_.Reset(cons_string, offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003862 if (cons_string != NULL) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003863 string = iter_.Next(&offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003864 if (string != NULL) String::VisitFlat(this, string, offset);
3865 }
3866}
3867
3868
3869bool StringCharacterStream::HasMore() {
3870 if (buffer8_ != end_) return true;
3871 int offset;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003872 String* string = iter_.Next(&offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003873 DCHECK_EQ(offset, 0);
3874 if (string == NULL) return false;
3875 String::VisitFlat(this, string);
3876 DCHECK(buffer8_ != end_);
3877 return true;
3878}
3879
3880
3881void StringCharacterStream::VisitOneByteString(
3882 const uint8_t* chars, int length) {
3883 is_one_byte_ = true;
3884 buffer8_ = chars;
3885 end_ = chars + length;
3886}
3887
3888
3889void StringCharacterStream::VisitTwoByteString(
3890 const uint16_t* chars, int length) {
3891 is_one_byte_ = false;
3892 buffer16_ = chars;
3893 end_ = reinterpret_cast<const uint8_t*>(chars + length);
3894}
3895
3896
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003897int ByteArray::Size() { return RoundUp(length() + kHeaderSize, kPointerSize); }
Ben Murdochb8e0da22011-05-16 14:20:40 +01003898
3899
Steve Blocka7e24c12009-10-30 11:49:00 +00003900byte ByteArray::get(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003901 DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003902 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
3903}
3904
3905
3906void ByteArray::set(int index, byte value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003907 DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003908 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
3909}
3910
3911
3912int ByteArray::get_int(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003913 DCHECK(index >= 0 && (index * kIntSize) < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003914 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
3915}
3916
3917
3918ByteArray* ByteArray::FromDataStartAddress(Address address) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003919 DCHECK_TAG_ALIGNED(address);
Steve Blocka7e24c12009-10-30 11:49:00 +00003920 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
3921}
3922
3923
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003924int ByteArray::ByteArraySize() { return SizeFor(this->length()); }
3925
3926
Steve Blocka7e24c12009-10-30 11:49:00 +00003927Address ByteArray::GetDataStartAddress() {
3928 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
3929}
3930
3931
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003932byte BytecodeArray::get(int index) {
3933 DCHECK(index >= 0 && index < this->length());
3934 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00003935}
3936
3937
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003938void BytecodeArray::set(int index, byte value) {
3939 DCHECK(index >= 0 && index < this->length());
3940 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003941}
3942
3943
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003944void BytecodeArray::set_frame_size(int frame_size) {
3945 DCHECK_GE(frame_size, 0);
3946 DCHECK(IsAligned(frame_size, static_cast<unsigned>(kPointerSize)));
3947 WRITE_INT_FIELD(this, kFrameSizeOffset, frame_size);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003948}
3949
3950
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003951int BytecodeArray::frame_size() const {
3952 return READ_INT_FIELD(this, kFrameSizeOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00003953}
3954
3955
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003956int BytecodeArray::register_count() const {
3957 return frame_size() / kPointerSize;
3958}
3959
3960
3961void BytecodeArray::set_parameter_count(int number_of_parameters) {
3962 DCHECK_GE(number_of_parameters, 0);
3963 // Parameter count is stored as the size on stack of the parameters to allow
3964 // it to be used directly by generated code.
3965 WRITE_INT_FIELD(this, kParameterSizeOffset,
3966 (number_of_parameters << kPointerSizeLog2));
3967}
3968
Ben Murdoch097c5b22016-05-18 11:27:45 +01003969int BytecodeArray::interrupt_budget() const {
3970 return READ_INT_FIELD(this, kInterruptBudgetOffset);
3971}
3972
3973void BytecodeArray::set_interrupt_budget(int interrupt_budget) {
3974 DCHECK_GE(interrupt_budget, 0);
3975 WRITE_INT_FIELD(this, kInterruptBudgetOffset, interrupt_budget);
3976}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003977
3978int BytecodeArray::parameter_count() const {
3979 // Parameter count is stored as the size on stack of the parameters to allow
3980 // it to be used directly by generated code.
3981 return READ_INT_FIELD(this, kParameterSizeOffset) >> kPointerSizeLog2;
3982}
3983
3984
3985ACCESSORS(BytecodeArray, constant_pool, FixedArray, kConstantPoolOffset)
Ben Murdoch097c5b22016-05-18 11:27:45 +01003986ACCESSORS(BytecodeArray, handler_table, FixedArray, kHandlerTableOffset)
Ben Murdochda12d292016-06-02 14:46:10 +01003987ACCESSORS(BytecodeArray, source_position_table, ByteArray,
Ben Murdoch097c5b22016-05-18 11:27:45 +01003988 kSourcePositionTableOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003989
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003990Address BytecodeArray::GetFirstBytecodeAddress() {
3991 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
3992}
3993
3994
3995int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); }
3996
3997
3998ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset)
3999
4000
4001void* FixedTypedArrayBase::external_pointer() const {
Steve Block3ce2e202009-11-05 08:53:23 +00004002 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
4003 return reinterpret_cast<void*>(ptr);
4004}
4005
4006
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004007void FixedTypedArrayBase::set_external_pointer(void* value,
4008 WriteBarrierMode mode) {
Steve Block3ce2e202009-11-05 08:53:23 +00004009 intptr_t ptr = reinterpret_cast<intptr_t>(value);
4010 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
4011}
4012
4013
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004014void* FixedTypedArrayBase::DataPtr() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004015 return reinterpret_cast<void*>(
4016 reinterpret_cast<intptr_t>(base_pointer()) +
4017 reinterpret_cast<intptr_t>(external_pointer()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004018}
4019
4020
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004021int FixedTypedArrayBase::ElementSize(InstanceType type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004022 int element_size;
4023 switch (type) {
4024#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
4025 case FIXED_##TYPE##_ARRAY_TYPE: \
4026 element_size = size; \
4027 break;
4028
4029 TYPED_ARRAYS(TYPED_ARRAY_CASE)
4030#undef TYPED_ARRAY_CASE
4031 default:
4032 UNREACHABLE();
4033 return 0;
4034 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004035 return element_size;
4036}
4037
4038
4039int FixedTypedArrayBase::DataSize(InstanceType type) {
4040 if (base_pointer() == Smi::FromInt(0)) return 0;
4041 return length() * ElementSize(type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004042}
4043
4044
4045int FixedTypedArrayBase::DataSize() {
4046 return DataSize(map()->instance_type());
4047}
4048
4049
4050int FixedTypedArrayBase::size() {
4051 return OBJECT_POINTER_ALIGN(kDataOffset + DataSize());
4052}
4053
4054
4055int FixedTypedArrayBase::TypedArraySize(InstanceType type) {
4056 return OBJECT_POINTER_ALIGN(kDataOffset + DataSize(type));
4057}
4058
4059
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004060int FixedTypedArrayBase::TypedArraySize(InstanceType type, int length) {
4061 return OBJECT_POINTER_ALIGN(kDataOffset + length * ElementSize(type));
4062}
4063
4064
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004065uint8_t Uint8ArrayTraits::defaultValue() { return 0; }
4066
4067
4068uint8_t Uint8ClampedArrayTraits::defaultValue() { return 0; }
4069
4070
4071int8_t Int8ArrayTraits::defaultValue() { return 0; }
4072
4073
4074uint16_t Uint16ArrayTraits::defaultValue() { return 0; }
4075
4076
4077int16_t Int16ArrayTraits::defaultValue() { return 0; }
4078
4079
4080uint32_t Uint32ArrayTraits::defaultValue() { return 0; }
4081
4082
4083int32_t Int32ArrayTraits::defaultValue() { return 0; }
4084
4085
4086float Float32ArrayTraits::defaultValue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004087 return std::numeric_limits<float>::quiet_NaN();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004088}
4089
4090
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004091double Float64ArrayTraits::defaultValue() {
4092 return std::numeric_limits<double>::quiet_NaN();
4093}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004094
4095
4096template <class Traits>
4097typename Traits::ElementType FixedTypedArray<Traits>::get_scalar(int index) {
4098 DCHECK((index >= 0) && (index < this->length()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004099 ElementType* ptr = reinterpret_cast<ElementType*>(DataPtr());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004100 return ptr[index];
4101}
4102
4103
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004104template <class Traits>
4105void FixedTypedArray<Traits>::set(int index, ElementType value) {
4106 DCHECK((index >= 0) && (index < this->length()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004107 ElementType* ptr = reinterpret_cast<ElementType*>(DataPtr());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004108 ptr[index] = value;
4109}
4110
4111
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004112template <class Traits>
4113typename Traits::ElementType FixedTypedArray<Traits>::from_int(int value) {
4114 return static_cast<ElementType>(value);
4115}
4116
4117
4118template <> inline
4119uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from_int(int value) {
4120 if (value < 0) return 0;
4121 if (value > 0xFF) return 0xFF;
4122 return static_cast<uint8_t>(value);
4123}
4124
4125
4126template <class Traits>
4127typename Traits::ElementType FixedTypedArray<Traits>::from_double(
4128 double value) {
4129 return static_cast<ElementType>(DoubleToInt32(value));
4130}
4131
4132
4133template<> inline
4134uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from_double(double value) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004135 // Handle NaNs and less than zero values which clamp to zero.
4136 if (!(value > 0)) return 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004137 if (value > 0xFF) return 0xFF;
4138 return static_cast<uint8_t>(lrint(value));
4139}
4140
4141
4142template<> inline
4143float FixedTypedArray<Float32ArrayTraits>::from_double(double value) {
4144 return static_cast<float>(value);
4145}
4146
4147
4148template<> inline
4149double FixedTypedArray<Float64ArrayTraits>::from_double(double value) {
4150 return value;
4151}
4152
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004153template <class Traits>
Ben Murdoch097c5b22016-05-18 11:27:45 +01004154Handle<Object> FixedTypedArray<Traits>::get(FixedTypedArray<Traits>* array,
4155 int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004156 return Traits::ToHandle(array->GetIsolate(), array->get_scalar(index));
4157}
4158
4159
4160template <class Traits>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004161void FixedTypedArray<Traits>::SetValue(uint32_t index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004162 ElementType cast_value = Traits::defaultValue();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004163 if (value->IsSmi()) {
4164 int int_value = Smi::cast(value)->value();
4165 cast_value = from_int(int_value);
4166 } else if (value->IsHeapNumber()) {
4167 double double_value = HeapNumber::cast(value)->value();
4168 cast_value = from_double(double_value);
4169 } else {
4170 // Clamp undefined to the default value. All other types have been
4171 // converted to a number type further up in the call chain.
4172 DCHECK(value->IsUndefined());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004173 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004174 set(index, cast_value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004175}
4176
4177
4178Handle<Object> Uint8ArrayTraits::ToHandle(Isolate* isolate, uint8_t scalar) {
4179 return handle(Smi::FromInt(scalar), isolate);
4180}
4181
4182
4183Handle<Object> Uint8ClampedArrayTraits::ToHandle(Isolate* isolate,
4184 uint8_t scalar) {
4185 return handle(Smi::FromInt(scalar), isolate);
4186}
4187
4188
4189Handle<Object> Int8ArrayTraits::ToHandle(Isolate* isolate, int8_t scalar) {
4190 return handle(Smi::FromInt(scalar), isolate);
4191}
4192
4193
4194Handle<Object> Uint16ArrayTraits::ToHandle(Isolate* isolate, uint16_t scalar) {
4195 return handle(Smi::FromInt(scalar), isolate);
4196}
4197
4198
4199Handle<Object> Int16ArrayTraits::ToHandle(Isolate* isolate, int16_t scalar) {
4200 return handle(Smi::FromInt(scalar), isolate);
4201}
4202
4203
4204Handle<Object> Uint32ArrayTraits::ToHandle(Isolate* isolate, uint32_t scalar) {
4205 return isolate->factory()->NewNumberFromUint(scalar);
4206}
4207
4208
4209Handle<Object> Int32ArrayTraits::ToHandle(Isolate* isolate, int32_t scalar) {
4210 return isolate->factory()->NewNumberFromInt(scalar);
4211}
4212
4213
4214Handle<Object> Float32ArrayTraits::ToHandle(Isolate* isolate, float scalar) {
4215 return isolate->factory()->NewNumber(scalar);
4216}
4217
4218
4219Handle<Object> Float64ArrayTraits::ToHandle(Isolate* isolate, double scalar) {
4220 return isolate->factory()->NewNumber(scalar);
4221}
4222
4223
Iain Merrick9ac36c92010-09-13 15:29:50 +01004224int Map::visitor_id() {
4225 return READ_BYTE_FIELD(this, kVisitorIdOffset);
4226}
4227
4228
4229void Map::set_visitor_id(int id) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004230 DCHECK(0 <= id && id < 256);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004231 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
4232}
4233
Steve Block3ce2e202009-11-05 08:53:23 +00004234
Steve Blocka7e24c12009-10-30 11:49:00 +00004235int Map::instance_size() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004236 return NOBARRIER_READ_BYTE_FIELD(
4237 this, kInstanceSizeOffset) << kPointerSizeLog2;
Steve Blocka7e24c12009-10-30 11:49:00 +00004238}
4239
4240
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004241int Map::inobject_properties_or_constructor_function_index() {
4242 return READ_BYTE_FIELD(this,
4243 kInObjectPropertiesOrConstructorFunctionIndexOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00004244}
4245
4246
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004247void Map::set_inobject_properties_or_constructor_function_index(int value) {
4248 DCHECK(0 <= value && value < 256);
4249 WRITE_BYTE_FIELD(this, kInObjectPropertiesOrConstructorFunctionIndexOffset,
4250 static_cast<byte>(value));
4251}
4252
4253
4254int Map::GetInObjectProperties() {
4255 DCHECK(IsJSObjectMap());
4256 return inobject_properties_or_constructor_function_index();
4257}
4258
4259
4260void Map::SetInObjectProperties(int value) {
4261 DCHECK(IsJSObjectMap());
4262 set_inobject_properties_or_constructor_function_index(value);
4263}
4264
4265
4266int Map::GetConstructorFunctionIndex() {
4267 DCHECK(IsPrimitiveMap());
4268 return inobject_properties_or_constructor_function_index();
4269}
4270
4271
4272void Map::SetConstructorFunctionIndex(int value) {
4273 DCHECK(IsPrimitiveMap());
4274 set_inobject_properties_or_constructor_function_index(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004275}
4276
4277
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004278int Map::GetInObjectPropertyOffset(int index) {
4279 // Adjust for the number of properties stored in the object.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004280 index -= GetInObjectProperties();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004281 DCHECK(index <= 0);
4282 return instance_size() + (index * kPointerSize);
4283}
4284
4285
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004286Handle<Map> Map::AddMissingTransitionsForTesting(
4287 Handle<Map> split_map, Handle<DescriptorArray> descriptors,
4288 Handle<LayoutDescriptor> full_layout_descriptor) {
4289 return AddMissingTransitions(split_map, descriptors, full_layout_descriptor);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004290}
4291
4292
Steve Blocka7e24c12009-10-30 11:49:00 +00004293int HeapObject::SizeFromMap(Map* map) {
Steve Block791712a2010-08-27 10:21:07 +01004294 int instance_size = map->instance_size();
4295 if (instance_size != kVariableSizeSentinel) return instance_size;
Steve Blocka7e24c12009-10-30 11:49:00 +00004296 // Only inline the most frequent cases.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004297 InstanceType instance_type = map->instance_type();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004298 if (instance_type == FIXED_ARRAY_TYPE ||
4299 instance_type == TRANSITION_ARRAY_TYPE) {
4300 return FixedArray::SizeFor(
4301 reinterpret_cast<FixedArray*>(this)->synchronized_length());
Steve Blocka7e24c12009-10-30 11:49:00 +00004302 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004303 if (instance_type == ONE_BYTE_STRING_TYPE ||
4304 instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004305 // Strings may get concurrently truncated, hence we have to access its
4306 // length synchronized.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004307 return SeqOneByteString::SizeFor(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004308 reinterpret_cast<SeqOneByteString*>(this)->synchronized_length());
Steve Block791712a2010-08-27 10:21:07 +01004309 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004310 if (instance_type == BYTE_ARRAY_TYPE) {
4311 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
4312 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004313 if (instance_type == BYTECODE_ARRAY_TYPE) {
4314 return reinterpret_cast<BytecodeArray*>(this)->BytecodeArraySize();
4315 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004316 if (instance_type == FREE_SPACE_TYPE) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004317 return reinterpret_cast<FreeSpace*>(this)->nobarrier_size();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004318 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004319 if (instance_type == STRING_TYPE ||
4320 instance_type == INTERNALIZED_STRING_TYPE) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004321 // Strings may get concurrently truncated, hence we have to access its
4322 // length synchronized.
Steve Block791712a2010-08-27 10:21:07 +01004323 return SeqTwoByteString::SizeFor(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004324 reinterpret_cast<SeqTwoByteString*>(this)->synchronized_length());
Steve Block791712a2010-08-27 10:21:07 +01004325 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004326 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
4327 return FixedDoubleArray::SizeFor(
4328 reinterpret_cast<FixedDoubleArray*>(this)->length());
4329 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004330 if (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE &&
4331 instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE) {
4332 return reinterpret_cast<FixedTypedArrayBase*>(
4333 this)->TypedArraySize(instance_type);
4334 }
4335 DCHECK(instance_type == CODE_TYPE);
Steve Block791712a2010-08-27 10:21:07 +01004336 return reinterpret_cast<Code*>(this)->CodeSize();
Steve Blocka7e24c12009-10-30 11:49:00 +00004337}
4338
4339
4340void Map::set_instance_size(int value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004341 DCHECK_EQ(0, value & (kPointerSize - 1));
Steve Blocka7e24c12009-10-30 11:49:00 +00004342 value >>= kPointerSizeLog2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004343 DCHECK(0 <= value && value < 256);
4344 NOBARRIER_WRITE_BYTE_FIELD(
4345 this, kInstanceSizeOffset, static_cast<byte>(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00004346}
4347
4348
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004349void Map::clear_unused() { WRITE_BYTE_FIELD(this, kUnusedOffset, 0); }
Steve Blocka7e24c12009-10-30 11:49:00 +00004350
4351
4352InstanceType Map::instance_type() {
4353 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
4354}
4355
4356
4357void Map::set_instance_type(InstanceType value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004358 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
4359}
4360
4361
4362int Map::unused_property_fields() {
4363 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
4364}
4365
4366
4367void Map::set_unused_property_fields(int value) {
4368 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
4369}
4370
4371
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004372byte Map::bit_field() const { return READ_BYTE_FIELD(this, kBitFieldOffset); }
Steve Blocka7e24c12009-10-30 11:49:00 +00004373
4374
4375void Map::set_bit_field(byte value) {
4376 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
4377}
4378
4379
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004380byte Map::bit_field2() const { return READ_BYTE_FIELD(this, kBitField2Offset); }
Steve Blocka7e24c12009-10-30 11:49:00 +00004381
4382
4383void Map::set_bit_field2(byte value) {
4384 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
4385}
4386
4387
4388void Map::set_non_instance_prototype(bool value) {
4389 if (value) {
4390 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
4391 } else {
4392 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
4393 }
4394}
4395
4396
4397bool Map::has_non_instance_prototype() {
4398 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
4399}
4400
4401
Ben Murdoch097c5b22016-05-18 11:27:45 +01004402void Map::set_is_constructor(bool value) {
4403 if (value) {
4404 set_bit_field(bit_field() | (1 << kIsConstructor));
4405 } else {
4406 set_bit_field(bit_field() & ~(1 << kIsConstructor));
4407 }
Steve Block6ded16b2010-05-10 14:33:55 +01004408}
4409
4410
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004411bool Map::is_constructor() const {
4412 return ((1 << kIsConstructor) & bit_field()) != 0;
4413}
4414
Ben Murdoch097c5b22016-05-18 11:27:45 +01004415void Map::set_has_hidden_prototype(bool value) {
4416 set_bit_field3(HasHiddenPrototype::update(bit_field3(), value));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004417}
4418
Ben Murdoch097c5b22016-05-18 11:27:45 +01004419bool Map::has_hidden_prototype() const {
4420 return HasHiddenPrototype::decode(bit_field3());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004421}
4422
4423
4424void Map::set_has_indexed_interceptor() {
4425 set_bit_field(bit_field() | (1 << kHasIndexedInterceptor));
4426}
4427
4428
4429bool Map::has_indexed_interceptor() {
4430 return ((1 << kHasIndexedInterceptor) & bit_field()) != 0;
4431}
4432
4433
4434void Map::set_is_undetectable() {
4435 set_bit_field(bit_field() | (1 << kIsUndetectable));
4436}
4437
4438
4439bool Map::is_undetectable() {
4440 return ((1 << kIsUndetectable) & bit_field()) != 0;
4441}
4442
4443
4444void Map::set_is_observed() { set_bit_field(bit_field() | (1 << kIsObserved)); }
4445
4446bool Map::is_observed() { return ((1 << kIsObserved) & bit_field()) != 0; }
4447
4448
4449void Map::set_has_named_interceptor() {
4450 set_bit_field(bit_field() | (1 << kHasNamedInterceptor));
4451}
4452
4453
4454bool Map::has_named_interceptor() {
4455 return ((1 << kHasNamedInterceptor) & bit_field()) != 0;
Steve Block6ded16b2010-05-10 14:33:55 +01004456}
4457
4458
Steve Blocka7e24c12009-10-30 11:49:00 +00004459void Map::set_is_access_check_needed(bool access_check_needed) {
4460 if (access_check_needed) {
4461 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
4462 } else {
4463 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
4464 }
4465}
4466
4467
4468bool Map::is_access_check_needed() {
4469 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
4470}
4471
4472
Steve Block8defd9f2010-07-08 12:39:36 +01004473void Map::set_is_extensible(bool value) {
4474 if (value) {
4475 set_bit_field2(bit_field2() | (1 << kIsExtensible));
4476 } else {
4477 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
4478 }
4479}
4480
4481bool Map::is_extensible() {
4482 return ((1 << kIsExtensible) & bit_field2()) != 0;
4483}
4484
4485
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004486void Map::set_is_prototype_map(bool value) {
4487 set_bit_field2(IsPrototypeMapBits::update(bit_field2(), value));
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004488}
4489
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004490bool Map::is_prototype_map() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004491 return IsPrototypeMapBits::decode(bit_field2());
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004492}
4493
4494
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004495void Map::set_elements_kind(ElementsKind elements_kind) {
4496 DCHECK(static_cast<int>(elements_kind) < kElementsKindCount);
4497 DCHECK(kElementsKindCount <= (1 << Map::ElementsKindBits::kSize));
4498 set_bit_field2(Map::ElementsKindBits::update(bit_field2(), elements_kind));
4499 DCHECK(this->elements_kind() == elements_kind);
4500}
4501
4502
4503ElementsKind Map::elements_kind() {
4504 return Map::ElementsKindBits::decode(bit_field2());
4505}
4506
4507
4508bool Map::has_fast_smi_elements() {
4509 return IsFastSmiElementsKind(elements_kind());
4510}
4511
4512bool Map::has_fast_object_elements() {
4513 return IsFastObjectElementsKind(elements_kind());
4514}
4515
4516bool Map::has_fast_smi_or_object_elements() {
4517 return IsFastSmiOrObjectElementsKind(elements_kind());
4518}
4519
4520bool Map::has_fast_double_elements() {
4521 return IsFastDoubleElementsKind(elements_kind());
4522}
4523
4524bool Map::has_fast_elements() { return IsFastElementsKind(elements_kind()); }
4525
4526bool Map::has_sloppy_arguments_elements() {
4527 return IsSloppyArgumentsElements(elements_kind());
4528}
4529
Ben Murdoch097c5b22016-05-18 11:27:45 +01004530bool Map::has_fast_string_wrapper_elements() {
4531 return elements_kind() == FAST_STRING_WRAPPER_ELEMENTS;
4532}
4533
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004534bool Map::has_fixed_typed_array_elements() {
4535 return IsFixedTypedArrayElementsKind(elements_kind());
4536}
4537
4538bool Map::has_dictionary_elements() {
4539 return IsDictionaryElementsKind(elements_kind());
4540}
4541
4542
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004543void Map::set_dictionary_map(bool value) {
4544 uint32_t new_bit_field3 = DictionaryMap::update(bit_field3(), value);
4545 new_bit_field3 = IsUnstable::update(new_bit_field3, value);
4546 set_bit_field3(new_bit_field3);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004547}
4548
4549
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004550bool Map::is_dictionary_map() {
4551 return DictionaryMap::decode(bit_field3());
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004552}
4553
Steve Block8defd9f2010-07-08 12:39:36 +01004554
Steve Blocka7e24c12009-10-30 11:49:00 +00004555Code::Flags Code::flags() {
4556 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
4557}
4558
4559
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004560void Map::set_owns_descriptors(bool owns_descriptors) {
4561 set_bit_field3(OwnsDescriptors::update(bit_field3(), owns_descriptors));
4562}
4563
4564
4565bool Map::owns_descriptors() {
4566 return OwnsDescriptors::decode(bit_field3());
4567}
4568
4569
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004570void Map::set_is_callable() { set_bit_field(bit_field() | (1 << kIsCallable)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004571
4572
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004573bool Map::is_callable() const {
4574 return ((1 << kIsCallable) & bit_field()) != 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004575}
4576
4577
4578void Map::deprecate() {
4579 set_bit_field3(Deprecated::update(bit_field3(), true));
4580}
4581
4582
4583bool Map::is_deprecated() {
4584 return Deprecated::decode(bit_field3());
4585}
4586
4587
4588void Map::set_migration_target(bool value) {
4589 set_bit_field3(IsMigrationTarget::update(bit_field3(), value));
4590}
4591
4592
4593bool Map::is_migration_target() {
4594 return IsMigrationTarget::decode(bit_field3());
4595}
4596
4597
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004598void Map::set_new_target_is_base(bool value) {
4599 set_bit_field3(NewTargetIsBase::update(bit_field3(), value));
4600}
4601
4602
4603bool Map::new_target_is_base() { return NewTargetIsBase::decode(bit_field3()); }
4604
4605
4606void Map::set_construction_counter(int value) {
4607 set_bit_field3(ConstructionCounter::update(bit_field3(), value));
4608}
4609
4610
4611int Map::construction_counter() {
4612 return ConstructionCounter::decode(bit_field3());
4613}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004614
4615
4616void Map::mark_unstable() {
4617 set_bit_field3(IsUnstable::update(bit_field3(), true));
4618}
4619
4620
4621bool Map::is_stable() {
4622 return !IsUnstable::decode(bit_field3());
4623}
4624
4625
4626bool Map::has_code_cache() {
4627 return code_cache() != GetIsolate()->heap()->empty_fixed_array();
4628}
4629
4630
4631bool Map::CanBeDeprecated() {
4632 int descriptor = LastAdded();
4633 for (int i = 0; i <= descriptor; i++) {
4634 PropertyDetails details = instance_descriptors()->GetDetails(i);
4635 if (details.representation().IsNone()) return true;
4636 if (details.representation().IsSmi()) return true;
4637 if (details.representation().IsDouble()) return true;
4638 if (details.representation().IsHeapObject()) return true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004639 if (details.type() == DATA_CONSTANT) return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004640 }
4641 return false;
4642}
4643
4644
4645void Map::NotifyLeafMapLayoutChange() {
4646 if (is_stable()) {
4647 mark_unstable();
4648 dependent_code()->DeoptimizeDependentCodeGroup(
4649 GetIsolate(),
4650 DependentCode::kPrototypeCheckGroup);
4651 }
4652}
4653
4654
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004655bool Map::CanTransition() {
4656 // Only JSObject and subtypes have map transitions and back pointers.
4657 STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE);
4658 return instance_type() >= FIRST_JS_OBJECT_TYPE;
4659}
4660
4661
4662bool Map::IsBooleanMap() { return this == GetHeap()->boolean_map(); }
4663bool Map::IsPrimitiveMap() {
4664 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE);
4665 return instance_type() <= LAST_PRIMITIVE_TYPE;
4666}
4667bool Map::IsJSReceiverMap() {
4668 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
4669 return instance_type() >= FIRST_JS_RECEIVER_TYPE;
4670}
4671bool Map::IsJSObjectMap() {
4672 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
4673 return instance_type() >= FIRST_JS_OBJECT_TYPE;
4674}
4675bool Map::IsJSArrayMap() { return instance_type() == JS_ARRAY_TYPE; }
4676bool Map::IsJSFunctionMap() { return instance_type() == JS_FUNCTION_TYPE; }
4677bool Map::IsStringMap() { return instance_type() < FIRST_NONSTRING_TYPE; }
4678bool Map::IsJSProxyMap() { return instance_type() == JS_PROXY_TYPE; }
4679bool Map::IsJSGlobalProxyMap() {
4680 return instance_type() == JS_GLOBAL_PROXY_TYPE;
4681}
4682bool Map::IsJSGlobalObjectMap() {
4683 return instance_type() == JS_GLOBAL_OBJECT_TYPE;
4684}
4685bool Map::IsJSTypedArrayMap() { return instance_type() == JS_TYPED_ARRAY_TYPE; }
4686bool Map::IsJSDataViewMap() { return instance_type() == JS_DATA_VIEW_TYPE; }
4687
4688
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004689bool Map::CanOmitMapChecks() {
4690 return is_stable() && FLAG_omit_map_checks_for_leaf_maps;
4691}
4692
4693
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004694DependentCode* DependentCode::next_link() {
4695 return DependentCode::cast(get(kNextLinkIndex));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004696}
4697
4698
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004699void DependentCode::set_next_link(DependentCode* next) {
4700 set(kNextLinkIndex, next);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004701}
4702
4703
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004704int DependentCode::flags() { return Smi::cast(get(kFlagsIndex))->value(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004705
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004706
4707void DependentCode::set_flags(int flags) {
4708 set(kFlagsIndex, Smi::FromInt(flags));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004709}
4710
4711
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004712int DependentCode::count() { return CountField::decode(flags()); }
4713
4714void DependentCode::set_count(int value) {
4715 set_flags(CountField::update(flags(), value));
4716}
4717
4718
4719DependentCode::DependencyGroup DependentCode::group() {
4720 return static_cast<DependencyGroup>(GroupField::decode(flags()));
4721}
4722
4723
4724void DependentCode::set_group(DependentCode::DependencyGroup group) {
4725 set_flags(GroupField::update(flags(), static_cast<int>(group)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004726}
4727
4728
4729void DependentCode::set_object_at(int i, Object* object) {
4730 set(kCodesStartIndex + i, object);
4731}
4732
4733
4734Object* DependentCode::object_at(int i) {
4735 return get(kCodesStartIndex + i);
4736}
4737
4738
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004739void DependentCode::clear_at(int i) {
4740 set_undefined(kCodesStartIndex + i);
4741}
4742
4743
4744void DependentCode::copy(int from, int to) {
4745 set(kCodesStartIndex + to, get(kCodesStartIndex + from));
4746}
4747
4748
Steve Blocka7e24c12009-10-30 11:49:00 +00004749void Code::set_flags(Code::Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00004750 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
Steve Blocka7e24c12009-10-30 11:49:00 +00004751 WRITE_INT_FIELD(this, kFlagsOffset, flags);
4752}
4753
4754
4755Code::Kind Code::kind() {
4756 return ExtractKindFromFlags(flags());
4757}
4758
4759
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004760bool Code::IsCodeStubOrIC() {
4761 return kind() == STUB || kind() == HANDLER || kind() == LOAD_IC ||
4762 kind() == KEYED_LOAD_IC || kind() == CALL_IC || kind() == STORE_IC ||
4763 kind() == KEYED_STORE_IC || kind() == BINARY_OP_IC ||
Ben Murdochda12d292016-06-02 14:46:10 +01004764 kind() == COMPARE_IC || kind() == TO_BOOLEAN_IC;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004765}
4766
4767
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004768bool Code::IsJavaScriptCode() {
4769 return kind() == FUNCTION || kind() == OPTIMIZED_FUNCTION ||
4770 is_interpreter_entry_trampoline();
4771}
4772
4773
Steve Blocka7e24c12009-10-30 11:49:00 +00004774InlineCacheState Code::ic_state() {
4775 InlineCacheState result = ExtractICStateFromFlags(flags());
4776 // Only allow uninitialized or debugger states for non-IC code
4777 // objects. This is used in the debugger to determine whether or not
4778 // a call to code object has been replaced with a debug break call.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004779 DCHECK(is_inline_cache_stub() ||
Steve Blocka7e24c12009-10-30 11:49:00 +00004780 result == UNINITIALIZED ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004781 result == DEBUG_STUB);
Steve Blocka7e24c12009-10-30 11:49:00 +00004782 return result;
4783}
4784
4785
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004786ExtraICState Code::extra_ic_state() {
4787 DCHECK(is_inline_cache_stub() || ic_state() == DEBUG_STUB);
Ben Murdochb8e0da22011-05-16 14:20:40 +01004788 return ExtractExtraICStateFromFlags(flags());
4789}
4790
4791
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004792Code::StubType Code::type() {
Steve Blocka7e24c12009-10-30 11:49:00 +00004793 return ExtractTypeFromFlags(flags());
4794}
4795
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004796// For initialization.
4797void Code::set_raw_kind_specific_flags1(int value) {
4798 WRITE_INT_FIELD(this, kKindSpecificFlags1Offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004799}
4800
4801
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004802void Code::set_raw_kind_specific_flags2(int value) {
4803 WRITE_INT_FIELD(this, kKindSpecificFlags2Offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004804}
4805
4806
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004807inline bool Code::is_crankshafted() {
4808 return IsCrankshaftedField::decode(
4809 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
Steve Blocka7e24c12009-10-30 11:49:00 +00004810}
4811
4812
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004813inline bool Code::is_hydrogen_stub() {
4814 return is_crankshafted() && kind() != OPTIMIZED_FUNCTION;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004815}
4816
4817
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004818inline bool Code::is_interpreter_entry_trampoline() {
4819 Handle<Code> interpreter_entry =
4820 GetIsolate()->builtins()->InterpreterEntryTrampoline();
4821 return interpreter_entry.location() != nullptr && *interpreter_entry == this;
4822}
4823
Ben Murdoch097c5b22016-05-18 11:27:45 +01004824inline bool Code::is_interpreter_enter_bytecode_dispatch() {
4825 Handle<Code> interpreter_handler =
4826 GetIsolate()->builtins()->InterpreterEnterBytecodeDispatch();
4827 return interpreter_handler.location() != nullptr &&
4828 *interpreter_handler == this;
4829}
4830
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004831inline void Code::set_is_crankshafted(bool value) {
4832 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4833 int updated = IsCrankshaftedField::update(previous, value);
4834 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
4835}
4836
4837
4838inline bool Code::is_turbofanned() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004839 return IsTurbofannedField::decode(
4840 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
4841}
4842
4843
4844inline void Code::set_is_turbofanned(bool value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004845 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4846 int updated = IsTurbofannedField::update(previous, value);
4847 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004848}
4849
4850
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004851inline bool Code::can_have_weak_objects() {
4852 DCHECK(kind() == OPTIMIZED_FUNCTION);
4853 return CanHaveWeakObjectsField::decode(
4854 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
Ben Murdochb0fe1622011-05-05 13:52:32 +01004855}
4856
4857
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004858inline void Code::set_can_have_weak_objects(bool value) {
4859 DCHECK(kind() == OPTIMIZED_FUNCTION);
4860 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4861 int updated = CanHaveWeakObjectsField::update(previous, value);
4862 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004863}
4864
4865
4866bool Code::has_deoptimization_support() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004867 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004868 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004869 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004870}
4871
4872
4873void Code::set_has_deoptimization_support(bool value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004874 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004875 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004876 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004877 WRITE_UINT32_FIELD(this, kFullCodeFlags, flags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004878}
4879
4880
4881bool Code::has_debug_break_slots() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004882 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004883 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004884 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
4885}
4886
4887
4888void Code::set_has_debug_break_slots(bool value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004889 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004890 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004891 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004892 WRITE_UINT32_FIELD(this, kFullCodeFlags, flags);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004893}
4894
4895
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004896bool Code::has_reloc_info_for_serialization() {
4897 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004898 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004899 return FullCodeFlagsHasRelocInfoForSerialization::decode(flags);
4900}
4901
4902
4903void Code::set_has_reloc_info_for_serialization(bool value) {
4904 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004905 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004906 flags = FullCodeFlagsHasRelocInfoForSerialization::update(flags, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004907 WRITE_UINT32_FIELD(this, kFullCodeFlags, flags);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004908}
4909
4910
Ben Murdochb0fe1622011-05-05 13:52:32 +01004911int Code::allow_osr_at_loop_nesting_level() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004912 DCHECK_EQ(FUNCTION, kind());
4913 int fields = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4914 return AllowOSRAtLoopNestingLevelField::decode(fields);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004915}
4916
4917
4918void Code::set_allow_osr_at_loop_nesting_level(int level) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004919 DCHECK_EQ(FUNCTION, kind());
4920 DCHECK(level >= 0 && level <= kMaxLoopNestingMarker);
4921 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4922 int updated = AllowOSRAtLoopNestingLevelField::update(previous, level);
4923 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004924}
4925
4926
Ben Murdoch8f9999f2012-04-23 10:39:17 +01004927int Code::profiler_ticks() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004928 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004929 return ProfilerTicksField::decode(
4930 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
Ben Murdoch8f9999f2012-04-23 10:39:17 +01004931}
4932
4933
4934void Code::set_profiler_ticks(int ticks) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004935 if (kind() == FUNCTION) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004936 unsigned previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4937 unsigned updated = ProfilerTicksField::update(previous, ticks);
4938 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004939 }
4940}
4941
Ben Murdochda12d292016-06-02 14:46:10 +01004942int Code::builtin_index() { return READ_INT_FIELD(this, kBuiltinIndexOffset); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004943
4944void Code::set_builtin_index(int index) {
Ben Murdochda12d292016-06-02 14:46:10 +01004945 WRITE_INT_FIELD(this, kBuiltinIndexOffset, index);
Ben Murdoch8f9999f2012-04-23 10:39:17 +01004946}
4947
4948
Ben Murdochb0fe1622011-05-05 13:52:32 +01004949unsigned Code::stack_slots() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004950 DCHECK(is_crankshafted());
4951 return StackSlotsField::decode(
4952 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
Ben Murdochb0fe1622011-05-05 13:52:32 +01004953}
4954
4955
4956void Code::set_stack_slots(unsigned slots) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004957 CHECK(slots <= (1 << kStackSlotsBitCount));
4958 DCHECK(is_crankshafted());
4959 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4960 int updated = StackSlotsField::update(previous, slots);
4961 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004962}
4963
4964
Steve Block1e0659c2011-05-24 12:43:12 +01004965unsigned Code::safepoint_table_offset() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004966 DCHECK(is_crankshafted());
4967 return SafepointTableOffsetField::decode(
4968 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
Ben Murdochb0fe1622011-05-05 13:52:32 +01004969}
4970
4971
Steve Block1e0659c2011-05-24 12:43:12 +01004972void Code::set_safepoint_table_offset(unsigned offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004973 CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
4974 DCHECK(is_crankshafted());
4975 DCHECK(IsAligned(offset, static_cast<unsigned>(kIntSize)));
4976 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4977 int updated = SafepointTableOffsetField::update(previous, offset);
4978 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004979}
4980
4981
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004982unsigned Code::back_edge_table_offset() {
4983 DCHECK_EQ(FUNCTION, kind());
4984 return BackEdgeTableOffsetField::decode(
4985 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset)) << kPointerSizeLog2;
Ben Murdochb0fe1622011-05-05 13:52:32 +01004986}
4987
4988
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004989void Code::set_back_edge_table_offset(unsigned offset) {
4990 DCHECK_EQ(FUNCTION, kind());
4991 DCHECK(IsAligned(offset, static_cast<unsigned>(kPointerSize)));
4992 offset = offset >> kPointerSizeLog2;
4993 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4994 int updated = BackEdgeTableOffsetField::update(previous, offset);
4995 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004996}
4997
4998
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004999bool Code::back_edges_patched_for_osr() {
5000 DCHECK_EQ(FUNCTION, kind());
5001 return allow_osr_at_loop_nesting_level() > 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +01005002}
5003
5004
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005005uint16_t Code::to_boolean_state() { return extra_ic_state(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005006
5007
5008bool Code::marked_for_deoptimization() {
5009 DCHECK(kind() == OPTIMIZED_FUNCTION);
5010 return MarkedForDeoptimizationField::decode(
5011 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
5012}
5013
5014
5015void Code::set_marked_for_deoptimization(bool flag) {
5016 DCHECK(kind() == OPTIMIZED_FUNCTION);
5017 DCHECK(!flag || AllowDeoptimization::IsAllowed(GetIsolate()));
5018 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
5019 int updated = MarkedForDeoptimizationField::update(previous, flag);
5020 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
5021}
5022
5023
Steve Blocka7e24c12009-10-30 11:49:00 +00005024bool Code::is_inline_cache_stub() {
5025 Kind kind = this->kind();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005026 switch (kind) {
5027#define CASE(name) case name: return true;
5028 IC_KIND_LIST(CASE)
5029#undef CASE
5030 default: return false;
5031 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005032}
5033
5034
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005035bool Code::is_keyed_stub() {
5036 return is_keyed_load_stub() || is_keyed_store_stub();
5037}
5038
5039
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005040bool Code::is_debug_stub() { return ic_state() == DEBUG_STUB; }
5041bool Code::is_handler() { return kind() == HANDLER; }
5042bool Code::is_load_stub() { return kind() == LOAD_IC; }
5043bool Code::is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
5044bool Code::is_store_stub() { return kind() == STORE_IC; }
5045bool Code::is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
5046bool Code::is_call_stub() { return kind() == CALL_IC; }
5047bool Code::is_binary_op_stub() { return kind() == BINARY_OP_IC; }
5048bool Code::is_compare_ic_stub() { return kind() == COMPARE_IC; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005049bool Code::is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; }
5050bool Code::is_optimized_code() { return kind() == OPTIMIZED_FUNCTION; }
Ben Murdochda12d292016-06-02 14:46:10 +01005051bool Code::is_wasm_code() { return kind() == WASM_FUNCTION; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005052
5053bool Code::embeds_maps_weakly() {
5054 Kind k = kind();
5055 return (k == LOAD_IC || k == STORE_IC || k == KEYED_LOAD_IC ||
Ben Murdochda12d292016-06-02 14:46:10 +01005056 k == KEYED_STORE_IC) &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005057 ic_state() == MONOMORPHIC;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005058}
5059
5060
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005061Address Code::constant_pool() {
5062 Address constant_pool = NULL;
5063 if (FLAG_enable_embedded_constant_pool) {
5064 int offset = constant_pool_offset();
5065 if (offset < instruction_size()) {
5066 constant_pool = FIELD_ADDR(this, kHeaderSize + offset);
5067 }
5068 }
5069 return constant_pool;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005070}
5071
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005072Code::Flags Code::ComputeFlags(Kind kind, InlineCacheState ic_state,
5073 ExtraICState extra_ic_state, StubType type,
5074 CacheHolderFlag holder) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005075 // Compute the bit mask.
Ben Murdochda12d292016-06-02 14:46:10 +01005076 unsigned int bits = KindField::encode(kind) | ICStateField::encode(ic_state) |
5077 TypeField::encode(type) |
5078 ExtraICStateField::encode(extra_ic_state) |
5079 CacheHolderField::encode(holder);
Ben Murdoch589d6972011-11-30 16:04:58 +00005080 return static_cast<Flags>(bits);
Steve Blocka7e24c12009-10-30 11:49:00 +00005081}
5082
Steve Blocka7e24c12009-10-30 11:49:00 +00005083Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
Ben Murdochb8e0da22011-05-16 14:20:40 +01005084 ExtraICState extra_ic_state,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005085 CacheHolderFlag holder,
5086 StubType type) {
5087 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, holder);
5088}
5089
5090
5091Code::Flags Code::ComputeHandlerFlags(Kind handler_kind, StubType type,
5092 CacheHolderFlag holder) {
5093 return ComputeFlags(Code::HANDLER, MONOMORPHIC, handler_kind, type, holder);
Steve Blocka7e24c12009-10-30 11:49:00 +00005094}
5095
5096
5097Code::Kind Code::ExtractKindFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005098 return KindField::decode(flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005099}
5100
5101
5102InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005103 return ICStateField::decode(flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005104}
5105
5106
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005107ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005108 return ExtraICStateField::decode(flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005109}
5110
5111
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005112Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005113 return TypeField::decode(flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005114}
5115
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005116CacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005117 return CacheHolderField::decode(flags);
Steve Block8defd9f2010-07-08 12:39:36 +01005118}
5119
5120
Steve Blocka7e24c12009-10-30 11:49:00 +00005121Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005122 int bits = flags & ~TypeField::kMask;
Steve Blocka7e24c12009-10-30 11:49:00 +00005123 return static_cast<Flags>(bits);
5124}
5125
5126
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005127Code::Flags Code::RemoveTypeAndHolderFromFlags(Flags flags) {
5128 int bits = flags & ~TypeField::kMask & ~CacheHolderField::kMask;
5129 return static_cast<Flags>(bits);
5130}
5131
5132
Steve Blocka7e24c12009-10-30 11:49:00 +00005133Code* Code::GetCodeFromTargetAddress(Address address) {
5134 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
5135 // GetCodeFromTargetAddress might be called when marking objects during mark
5136 // sweep. reinterpret_cast is therefore used instead of the more appropriate
5137 // Code::cast. Code::cast does not work when the object's map is
5138 // marked.
5139 Code* result = reinterpret_cast<Code*>(code);
5140 return result;
5141}
5142
5143
Steve Block791712a2010-08-27 10:21:07 +01005144Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
5145 return HeapObject::
5146 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
5147}
5148
5149
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005150bool Code::CanContainWeakObjects() {
5151 return is_optimized_code() && can_have_weak_objects();
5152}
5153
5154
5155bool Code::IsWeakObject(Object* object) {
5156 return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object));
5157}
5158
5159
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005160bool Code::IsWeakObjectInOptimizedCode(Object* object) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005161 if (object->IsMap()) {
5162 return Map::cast(object)->CanTransition() &&
5163 FLAG_weak_embedded_maps_in_optimized_code;
5164 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005165 if (object->IsCell()) {
5166 object = Cell::cast(object)->value();
5167 } else if (object->IsPropertyCell()) {
5168 object = PropertyCell::cast(object)->value();
5169 }
5170 if (object->IsJSReceiver()) {
5171 return FLAG_weak_embedded_objects_in_optimized_code;
5172 }
5173 if (object->IsContext()) {
5174 // Contexts of inlined functions are embedded in optimized code.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005175 return FLAG_weak_embedded_objects_in_optimized_code;
5176 }
5177 return false;
5178}
5179
5180
5181class Code::FindAndReplacePattern {
5182 public:
5183 FindAndReplacePattern() : count_(0) { }
5184 void Add(Handle<Map> map_to_find, Handle<Object> obj_to_replace) {
5185 DCHECK(count_ < kMaxCount);
5186 find_[count_] = map_to_find;
5187 replace_[count_] = obj_to_replace;
5188 ++count_;
5189 }
5190 private:
5191 static const int kMaxCount = 4;
5192 int count_;
5193 Handle<Map> find_[kMaxCount];
5194 Handle<Object> replace_[kMaxCount];
5195 friend class Code;
5196};
5197
Ben Murdochda12d292016-06-02 14:46:10 +01005198int AbstractCode::instruction_size() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01005199 if (IsCode()) {
5200 return GetCode()->instruction_size();
5201 } else {
5202 return GetBytecodeArray()->length();
5203 }
5204}
5205
Ben Murdochda12d292016-06-02 14:46:10 +01005206int AbstractCode::ExecutableSize() {
5207 if (IsCode()) {
5208 return GetCode()->ExecutableSize();
5209 } else {
5210 return GetBytecodeArray()->BytecodeArraySize();
5211 }
5212}
5213
5214Address AbstractCode::instruction_start() {
5215 if (IsCode()) {
5216 return GetCode()->instruction_start();
5217 } else {
5218 return GetBytecodeArray()->GetFirstBytecodeAddress();
5219 }
5220}
5221
5222Address AbstractCode::instruction_end() {
5223 if (IsCode()) {
5224 return GetCode()->instruction_end();
5225 } else {
5226 return GetBytecodeArray()->GetFirstBytecodeAddress() +
5227 GetBytecodeArray()->length();
5228 }
5229}
5230
5231bool AbstractCode::contains(byte* inner_pointer) {
5232 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
5233}
5234
5235AbstractCode::Kind AbstractCode::kind() {
5236 if (IsCode()) {
5237 STATIC_ASSERT(AbstractCode::FUNCTION ==
5238 static_cast<AbstractCode::Kind>(Code::FUNCTION));
5239 return static_cast<AbstractCode::Kind>(GetCode()->kind());
5240 } else {
5241 return INTERPRETED_FUNCTION;
5242 }
5243}
5244
Ben Murdoch097c5b22016-05-18 11:27:45 +01005245Code* AbstractCode::GetCode() { return Code::cast(this); }
5246
5247BytecodeArray* AbstractCode::GetBytecodeArray() {
5248 return BytecodeArray::cast(this);
5249}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005250
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005251Object* Map::prototype() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005252 return READ_FIELD(this, kPrototypeOffset);
5253}
5254
5255
5256void Map::set_prototype(Object* value, WriteBarrierMode mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005257 DCHECK(value->IsNull() || value->IsJSReceiver());
Steve Blocka7e24c12009-10-30 11:49:00 +00005258 WRITE_FIELD(this, kPrototypeOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005259 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
Steve Block1e0659c2011-05-24 12:43:12 +01005260}
5261
5262
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005263LayoutDescriptor* Map::layout_descriptor_gc_safe() {
5264 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
5265 return LayoutDescriptor::cast_gc_safe(layout_desc);
5266}
5267
5268
5269bool Map::HasFastPointerLayout() const {
5270 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
5271 return LayoutDescriptor::IsFastPointerLayout(layout_desc);
5272}
5273
5274
5275void Map::UpdateDescriptors(DescriptorArray* descriptors,
5276 LayoutDescriptor* layout_desc) {
5277 set_instance_descriptors(descriptors);
5278 if (FLAG_unbox_double_fields) {
5279 if (layout_descriptor()->IsSlowLayout()) {
5280 set_layout_descriptor(layout_desc);
5281 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005282#ifdef VERIFY_HEAP
5283 // TODO(ishell): remove these checks from VERIFY_HEAP mode.
5284 if (FLAG_verify_heap) {
5285 CHECK(layout_descriptor()->IsConsistentWithMap(this));
5286 CHECK(visitor_id() == Heap::GetStaticVisitorIdForMap(this));
5287 }
5288#else
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005289 SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005290 DCHECK(visitor_id() == Heap::GetStaticVisitorIdForMap(this));
5291#endif
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005292 }
5293}
5294
5295
5296void Map::InitializeDescriptors(DescriptorArray* descriptors,
5297 LayoutDescriptor* layout_desc) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005298 int len = descriptors->number_of_descriptors();
5299 set_instance_descriptors(descriptors);
5300 SetNumberOfOwnDescriptors(len);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005301
5302 if (FLAG_unbox_double_fields) {
5303 set_layout_descriptor(layout_desc);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005304#ifdef VERIFY_HEAP
5305 // TODO(ishell): remove these checks from VERIFY_HEAP mode.
5306 if (FLAG_verify_heap) {
5307 CHECK(layout_descriptor()->IsConsistentWithMap(this));
5308 }
5309#else
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005310 SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005311#endif
5312 set_visitor_id(Heap::GetStaticVisitorIdForMap(this));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005313 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005314}
5315
5316
5317ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005318ACCESSORS(Map, layout_descriptor, LayoutDescriptor, kLayoutDecriptorOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005319
5320
5321void Map::set_bit_field3(uint32_t bits) {
5322 if (kInt32Size != kPointerSize) {
5323 WRITE_UINT32_FIELD(this, kBitField3Offset + kInt32Size, 0);
5324 }
5325 WRITE_UINT32_FIELD(this, kBitField3Offset, bits);
5326}
5327
5328
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005329uint32_t Map::bit_field3() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005330 return READ_UINT32_FIELD(this, kBitField3Offset);
5331}
5332
5333
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005334LayoutDescriptor* Map::GetLayoutDescriptor() {
5335 return FLAG_unbox_double_fields ? layout_descriptor()
5336 : LayoutDescriptor::FastPointerLayout();
5337}
5338
5339
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005340void Map::AppendDescriptor(Descriptor* desc) {
5341 DescriptorArray* descriptors = instance_descriptors();
5342 int number_of_own_descriptors = NumberOfOwnDescriptors();
5343 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors);
5344 descriptors->Append(desc);
5345 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005346
5347// This function does not support appending double field descriptors and
5348// it should never try to (otherwise, layout descriptor must be updated too).
5349#ifdef DEBUG
5350 PropertyDetails details = desc->GetDetails();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005351 CHECK(details.type() != DATA || !details.representation().IsDouble());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005352#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005353}
5354
5355
5356Object* Map::GetBackPointer() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005357 Object* object = constructor_or_backpointer();
5358 if (object->IsMap()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005359 return object;
5360 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005361 return GetIsolate()->heap()->undefined_value();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005362}
5363
5364
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005365Map* Map::ElementsTransitionMap() {
5366 return TransitionArray::SearchSpecial(
5367 this, GetHeap()->elements_transition_symbol());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005368}
5369
5370
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005371ACCESSORS(Map, raw_transitions, Object, kTransitionsOrPrototypeInfoOffset)
5372
5373
5374Object* Map::prototype_info() const {
5375 DCHECK(is_prototype_map());
5376 return READ_FIELD(this, Map::kTransitionsOrPrototypeInfoOffset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005377}
5378
5379
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005380void Map::set_prototype_info(Object* value, WriteBarrierMode mode) {
5381 DCHECK(is_prototype_map());
5382 WRITE_FIELD(this, Map::kTransitionsOrPrototypeInfoOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005383 CONDITIONAL_WRITE_BARRIER(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005384 GetHeap(), this, Map::kTransitionsOrPrototypeInfoOffset, value, mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005385}
5386
5387
5388void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
5389 DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005390 DCHECK((value->IsMap() && GetBackPointer()->IsUndefined()));
5391 DCHECK(!value->IsMap() ||
5392 Map::cast(value)->GetConstructor() == constructor_or_backpointer());
5393 set_constructor_or_backpointer(value, mode);
Ben Murdoch257744e2011-11-30 15:57:28 +00005394}
5395
5396
Steve Block6ded16b2010-05-10 14:33:55 +01005397ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005398ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005399ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset)
5400ACCESSORS(Map, constructor_or_backpointer, Object,
5401 kConstructorOrBackPointerOffset)
5402
5403
5404Object* Map::GetConstructor() const {
5405 Object* maybe_constructor = constructor_or_backpointer();
5406 // Follow any back pointers.
5407 while (maybe_constructor->IsMap()) {
5408 maybe_constructor =
5409 Map::cast(maybe_constructor)->constructor_or_backpointer();
5410 }
5411 return maybe_constructor;
5412}
5413
5414
5415void Map::SetConstructor(Object* constructor, WriteBarrierMode mode) {
5416 // Never overwrite a back pointer with a constructor.
5417 DCHECK(!constructor_or_backpointer()->IsMap());
5418 set_constructor_or_backpointer(constructor, mode);
5419}
5420
5421
5422Handle<Map> Map::CopyInitialMap(Handle<Map> map) {
5423 return CopyInitialMap(map, map->instance_size(), map->GetInObjectProperties(),
5424 map->unused_property_fields());
5425}
5426
5427
5428ACCESSORS(JSBoundFunction, length, Object, kLengthOffset)
5429ACCESSORS(JSBoundFunction, name, Object, kNameOffset)
5430ACCESSORS(JSBoundFunction, bound_target_function, JSReceiver,
5431 kBoundTargetFunctionOffset)
5432ACCESSORS(JSBoundFunction, bound_this, Object, kBoundThisOffset)
5433ACCESSORS(JSBoundFunction, bound_arguments, FixedArray, kBoundArgumentsOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005434
5435ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005436ACCESSORS(JSFunction, literals, LiteralsArray, kLiteralsOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005437ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005438
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005439ACCESSORS(JSGlobalObject, native_context, Context, kNativeContextOffset)
5440ACCESSORS(JSGlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005441
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005442ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
5443ACCESSORS(JSGlobalProxy, hash, Object, kHashOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005444
Steve Blocka7e24c12009-10-30 11:49:00 +00005445ACCESSORS(AccessorInfo, name, Object, kNameOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005446SMI_ACCESSORS(AccessorInfo, flag, kFlagOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005447ACCESSORS(AccessorInfo, expected_receiver_type, Object,
5448 kExpectedReceiverTypeOffset)
5449
Ben Murdoch097c5b22016-05-18 11:27:45 +01005450ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
5451ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
5452ACCESSORS(AccessorInfo, data, Object, kDataOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005453
5454ACCESSORS(Box, value, Object, kValueOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005455
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005456ACCESSORS(PrototypeInfo, prototype_users, Object, kPrototypeUsersOffset)
5457SMI_ACCESSORS(PrototypeInfo, registry_slot, kRegistrySlotOffset)
5458ACCESSORS(PrototypeInfo, validity_cell, Object, kValidityCellOffset)
5459
5460ACCESSORS(SloppyBlockWithEvalContextExtension, scope_info, ScopeInfo,
5461 kScopeInfoOffset)
5462ACCESSORS(SloppyBlockWithEvalContextExtension, extension, JSObject,
5463 kExtensionOffset)
5464
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005465ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
5466ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
Ben Murdochc7cc0282012-03-05 14:35:55 +00005467
Steve Blocka7e24c12009-10-30 11:49:00 +00005468ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
5469ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005470ACCESSORS(AccessCheckInfo, callback, Object, kCallbackOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005471ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
5472
5473ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
5474ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
5475ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
5476ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
5477ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
5478ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005479SMI_ACCESSORS(InterceptorInfo, flags, kFlagsOffset)
5480BOOL_ACCESSORS(InterceptorInfo, flags, can_intercept_symbols,
5481 kCanInterceptSymbolsBit)
5482BOOL_ACCESSORS(InterceptorInfo, flags, all_can_read, kAllCanReadBit)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005483BOOL_ACCESSORS(InterceptorInfo, flags, non_masking, kNonMasking)
Steve Blocka7e24c12009-10-30 11:49:00 +00005484
5485ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
5486ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005487ACCESSORS(CallHandlerInfo, fast_handler, Object, kFastHandlerOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005488
5489ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005490ACCESSORS(TemplateInfo, serial_number, Object, kSerialNumberOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005491SMI_ACCESSORS(TemplateInfo, number_of_properties, kNumberOfProperties)
Steve Blocka7e24c12009-10-30 11:49:00 +00005492ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005493ACCESSORS(TemplateInfo, property_accessors, Object, kPropertyAccessorsOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005494
Steve Blocka7e24c12009-10-30 11:49:00 +00005495ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005496ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
5497 kPrototypeTemplateOffset)
5498ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
5499ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
5500 kNamedPropertyHandlerOffset)
5501ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
5502 kIndexedPropertyHandlerOffset)
5503ACCESSORS(FunctionTemplateInfo, instance_template, Object,
5504 kInstanceTemplateOffset)
5505ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
5506ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
5507ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
5508 kInstanceCallHandlerOffset)
5509ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
5510 kAccessCheckInfoOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005511SMI_ACCESSORS(FunctionTemplateInfo, flag, kFlagOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005512
5513ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
5514ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
5515 kInternalFieldCountOffset)
5516
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005517ACCESSORS(AllocationSite, transition_info, Object, kTransitionInfoOffset)
5518ACCESSORS(AllocationSite, nested_site, Object, kNestedSiteOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005519SMI_ACCESSORS(AllocationSite, pretenure_data, kPretenureDataOffset)
5520SMI_ACCESSORS(AllocationSite, pretenure_create_count,
5521 kPretenureCreateCountOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005522ACCESSORS(AllocationSite, dependent_code, DependentCode,
5523 kDependentCodeOffset)
5524ACCESSORS(AllocationSite, weak_next, Object, kWeakNextOffset)
5525ACCESSORS(AllocationMemento, allocation_site, Object, kAllocationSiteOffset)
5526
Steve Blocka7e24c12009-10-30 11:49:00 +00005527ACCESSORS(Script, source, Object, kSourceOffset)
5528ACCESSORS(Script, name, Object, kNameOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005529SMI_ACCESSORS(Script, id, kIdOffset)
5530SMI_ACCESSORS(Script, line_offset, kLineOffsetOffset)
5531SMI_ACCESSORS(Script, column_offset, kColumnOffsetOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005532ACCESSORS(Script, context_data, Object, kContextOffset)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005533ACCESSORS(Script, wrapper, HeapObject, kWrapperOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005534SMI_ACCESSORS(Script, type, kTypeOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005535ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
Steve Blockd0582a62009-12-15 09:54:21 +00005536ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005537SMI_ACCESSORS(Script, eval_from_instructions_offset,
5538 kEvalFrominstructionsOffsetOffset)
5539ACCESSORS(Script, shared_function_infos, Object, kSharedFunctionInfosOffset)
5540SMI_ACCESSORS(Script, flags, kFlagsOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005541ACCESSORS(Script, source_url, Object, kSourceUrlOffset)
5542ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005543
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005544Script::CompilationType Script::compilation_type() {
5545 return BooleanBit::get(flags(), kCompilationTypeBit) ?
5546 COMPILATION_TYPE_EVAL : COMPILATION_TYPE_HOST;
5547}
5548void Script::set_compilation_type(CompilationType type) {
5549 set_flags(BooleanBit::set(flags(), kCompilationTypeBit,
5550 type == COMPILATION_TYPE_EVAL));
5551}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005552bool Script::hide_source() { return BooleanBit::get(flags(), kHideSourceBit); }
5553void Script::set_hide_source(bool value) {
5554 set_flags(BooleanBit::set(flags(), kHideSourceBit, value));
5555}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005556Script::CompilationState Script::compilation_state() {
5557 return BooleanBit::get(flags(), kCompilationStateBit) ?
5558 COMPILATION_STATE_COMPILED : COMPILATION_STATE_INITIAL;
5559}
5560void Script::set_compilation_state(CompilationState state) {
5561 set_flags(BooleanBit::set(flags(), kCompilationStateBit,
5562 state == COMPILATION_STATE_COMPILED));
5563}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005564ScriptOriginOptions Script::origin_options() {
5565 return ScriptOriginOptions((flags() & kOriginOptionsMask) >>
5566 kOriginOptionsShift);
5567}
5568void Script::set_origin_options(ScriptOriginOptions origin_options) {
5569 DCHECK(!(origin_options.Flags() & ~((1 << kOriginOptionsSize) - 1)));
5570 set_flags((flags() & ~kOriginOptionsMask) |
5571 (origin_options.Flags() << kOriginOptionsShift));
5572}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005573
5574
Steve Blocka7e24c12009-10-30 11:49:00 +00005575ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005576ACCESSORS(DebugInfo, abstract_code, AbstractCode, kAbstractCodeIndex)
Steve Blocka7e24c12009-10-30 11:49:00 +00005577ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
5578
Ben Murdoch097c5b22016-05-18 11:27:45 +01005579BytecodeArray* DebugInfo::original_bytecode_array() {
5580 return shared()->bytecode_array();
5581}
5582
5583SMI_ACCESSORS(BreakPointInfo, code_offset, kCodeOffsetIndex)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005584SMI_ACCESSORS(BreakPointInfo, source_position, kSourcePositionIndex)
5585SMI_ACCESSORS(BreakPointInfo, statement_position, kStatementPositionIndex)
Steve Blocka7e24c12009-10-30 11:49:00 +00005586ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
Steve Blocka7e24c12009-10-30 11:49:00 +00005587
Steve Blocka7e24c12009-10-30 11:49:00 +00005588ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005589ACCESSORS(SharedFunctionInfo, optimized_code_map, FixedArray,
5590 kOptimizedCodeMapOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005591ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005592ACCESSORS(SharedFunctionInfo, feedback_vector, TypeFeedbackVector,
5593 kFeedbackVectorOffset)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005594#if TRACE_MAPS
5595SMI_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset)
5596#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00005597ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
5598 kInstanceClassNameOffset)
Steve Block6ded16b2010-05-10 14:33:55 +01005599ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005600ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
5601ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
Ben Murdochda12d292016-06-02 14:46:10 +01005602ACCESSORS(SharedFunctionInfo, function_identifier, Object,
5603 kFunctionIdentifierOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005604
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005605SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005606BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
5607 kHiddenPrototypeBit)
5608BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
5609BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
5610 kNeedsAccessCheckBit)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005611BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
5612 kReadOnlyPrototypeBit)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005613BOOL_ACCESSORS(FunctionTemplateInfo, flag, remove_prototype,
5614 kRemovePrototypeBit)
5615BOOL_ACCESSORS(FunctionTemplateInfo, flag, do_not_cache,
5616 kDoNotCacheBit)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005617BOOL_ACCESSORS(FunctionTemplateInfo, flag, instantiated, kInstantiatedBit)
5618BOOL_ACCESSORS(FunctionTemplateInfo, flag, accept_any_receiver,
5619 kAcceptAnyReceiver)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005620BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_named_expression,
5621 kIsNamedExpressionBit)
Steve Blocka7e24c12009-10-30 11:49:00 +00005622BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
5623 kIsTopLevelBit)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005624
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005625BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, allows_lazy_compilation,
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005626 kAllowLazyCompilation)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005627BOOL_ACCESSORS(SharedFunctionInfo,
5628 compiler_hints,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005629 allows_lazy_compilation_without_context,
5630 kAllowLazyCompilationWithoutContext)
5631BOOL_ACCESSORS(SharedFunctionInfo,
5632 compiler_hints,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005633 uses_arguments,
5634 kUsesArguments)
5635BOOL_ACCESSORS(SharedFunctionInfo,
5636 compiler_hints,
5637 has_duplicate_parameters,
5638 kHasDuplicateParameters)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005639BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, asm_function, kIsAsmFunction)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005640BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, deserialized, kDeserialized)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005641BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, never_compiled,
5642 kNeverCompiled)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005643BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_declaration,
5644 kIsDeclaration)
Iain Merrick75681382010-08-19 15:07:18 +01005645
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005646#if V8_HOST_ARCH_32_BIT
5647SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005648SMI_ACCESSORS(SharedFunctionInfo, internal_formal_parameter_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00005649 kFormalParameterCountOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005650SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
Steve Blocka7e24c12009-10-30 11:49:00 +00005651 kExpectedNofPropertiesOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005652SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
5653SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
Steve Blocka7e24c12009-10-30 11:49:00 +00005654 kStartPositionAndTypeOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005655SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
5656SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
Steve Blocka7e24c12009-10-30 11:49:00 +00005657 kFunctionTokenPositionOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005658SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
Steve Blocka7e24c12009-10-30 11:49:00 +00005659 kCompilerHintsOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005660SMI_ACCESSORS(SharedFunctionInfo, opt_count_and_bailout_reason,
5661 kOptCountAndBailoutReasonOffset)
5662SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005663SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005664SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
5665
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005666#else
Steve Blocka7e24c12009-10-30 11:49:00 +00005667
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005668#if V8_TARGET_LITTLE_ENDIAN
5669#define PSEUDO_SMI_LO_ALIGN 0
5670#define PSEUDO_SMI_HI_ALIGN kIntSize
5671#else
5672#define PSEUDO_SMI_LO_ALIGN kIntSize
5673#define PSEUDO_SMI_HI_ALIGN 0
5674#endif
5675
5676#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
5677 STATIC_ASSERT(holder::offset % kPointerSize == PSEUDO_SMI_LO_ALIGN); \
5678 int holder::name() const { \
5679 int value = READ_INT_FIELD(this, offset); \
5680 DCHECK(kHeapObjectTag == 1); \
5681 DCHECK((value & kHeapObjectTag) == 0); \
5682 return value >> 1; \
5683 } \
5684 void holder::set_##name(int value) { \
5685 DCHECK(kHeapObjectTag == 1); \
5686 DCHECK((value & 0xC0000000) == 0xC0000000 || (value & 0xC0000000) == 0x0); \
5687 WRITE_INT_FIELD(this, offset, (value << 1) & ~kHeapObjectTag); \
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005688 }
5689
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005690#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
5691 STATIC_ASSERT(holder::offset % kPointerSize == PSEUDO_SMI_HI_ALIGN); \
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005692 INT_ACCESSORS(holder, name, offset)
5693
5694
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005695PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005696PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, internal_formal_parameter_count,
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005697 kFormalParameterCountOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005698
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005699PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5700 expected_nof_properties,
5701 kExpectedNofPropertiesOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005702PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
5703
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005704PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
5705PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5706 start_position_and_type,
5707 kStartPositionAndTypeOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005708
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005709PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5710 function_token_position,
5711 kFunctionTokenPositionOffset)
5712PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5713 compiler_hints,
5714 kCompilerHintsOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005715
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005716PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005717 opt_count_and_bailout_reason,
5718 kOptCountAndBailoutReasonOffset)
5719PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, counters, kCountersOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005720
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005721PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5722 ast_node_count,
5723 kAstNodeCountOffset)
5724PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5725 profiler_ticks,
5726 kProfilerTicksOffset)
5727
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005728#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00005729
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005730
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005731BOOL_GETTER(SharedFunctionInfo,
5732 compiler_hints,
5733 optimization_disabled,
5734 kOptimizationDisabled)
Ben Murdochb0fe1622011-05-05 13:52:32 +01005735
Ben Murdochda12d292016-06-02 14:46:10 +01005736AbstractCode* SharedFunctionInfo::abstract_code() {
5737 if (HasBytecodeArray()) {
5738 return AbstractCode::cast(bytecode_array());
5739 } else {
5740 return AbstractCode::cast(code());
5741 }
5742}
Ben Murdochb0fe1622011-05-05 13:52:32 +01005743
5744void SharedFunctionInfo::set_optimization_disabled(bool disable) {
5745 set_compiler_hints(BooleanBit::set(compiler_hints(),
5746 kOptimizationDisabled,
5747 disable));
Ben Murdochb0fe1622011-05-05 13:52:32 +01005748}
5749
5750
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005751LanguageMode SharedFunctionInfo::language_mode() {
5752 STATIC_ASSERT(LANGUAGE_END == 3);
5753 return construct_language_mode(
Ben Murdochda12d292016-06-02 14:46:10 +01005754 BooleanBit::get(compiler_hints(), kStrictModeFunction));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005755}
5756
5757
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005758void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
5759 STATIC_ASSERT(LANGUAGE_END == 3);
5760 // We only allow language mode transitions that set the same language mode
5761 // again or go up in the chain:
5762 DCHECK(is_sloppy(this->language_mode()) || is_strict(language_mode));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005763 int hints = compiler_hints();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005764 hints = BooleanBit::set(hints, kStrictModeFunction, is_strict(language_mode));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005765 set_compiler_hints(hints);
5766}
5767
5768
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005769FunctionKind SharedFunctionInfo::kind() {
5770 return FunctionKindBits::decode(compiler_hints());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005771}
5772
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005773
5774void SharedFunctionInfo::set_kind(FunctionKind kind) {
5775 DCHECK(IsValidFunctionKind(kind));
5776 int hints = compiler_hints();
5777 hints = FunctionKindBits::update(hints, kind);
5778 set_compiler_hints(hints);
5779}
5780
5781
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005782BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, needs_home_object,
5783 kNeedsHomeObject)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005784BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005785BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, force_inline, kForceInline)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005786BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
5787 name_should_print_as_anonymous,
5788 kNameShouldPrintAsAnonymous)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005789BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous_expression,
5790 kIsAnonymousExpression)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005791BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005792BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_crankshaft,
5793 kDontCrankshaft)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005794BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_flush, kDontFlush)
5795BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_arrow, kIsArrow)
5796BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator)
5797BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_concise_method,
5798 kIsConciseMethod)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005799BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_getter_function,
5800 kIsGetterFunction)
5801BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_setter_function,
5802 kIsSetterFunction)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005803BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_default_constructor,
5804 kIsDefaultConstructor)
Ben Murdoch257744e2011-11-30 15:57:28 +00005805
Steve Block6ded16b2010-05-10 14:33:55 +01005806ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
5807ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
5808
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005809ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
5810
Steve Block3ce2e202009-11-05 08:53:23 +00005811bool Script::HasValidSource() {
5812 Object* src = this->source();
5813 if (!src->IsString()) return true;
5814 String* src_str = String::cast(src);
5815 if (!StringShape(src_str).IsExternal()) return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005816 if (src_str->IsOneByteRepresentation()) {
5817 return ExternalOneByteString::cast(src)->resource() != NULL;
Steve Block3ce2e202009-11-05 08:53:23 +00005818 } else if (src_str->IsTwoByteRepresentation()) {
5819 return ExternalTwoByteString::cast(src)->resource() != NULL;
5820 }
5821 return true;
5822}
5823
5824
Steve Blocka7e24c12009-10-30 11:49:00 +00005825void SharedFunctionInfo::DontAdaptArguments() {
Ben Murdochda12d292016-06-02 14:46:10 +01005826 DCHECK(code()->kind() == Code::BUILTIN || code()->kind() == Code::STUB);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005827 set_internal_formal_parameter_count(kDontAdaptArgumentsSentinel);
Steve Blocka7e24c12009-10-30 11:49:00 +00005828}
5829
5830
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005831int SharedFunctionInfo::start_position() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005832 return start_position_and_type() >> kStartPositionShift;
5833}
5834
5835
5836void SharedFunctionInfo::set_start_position(int start_position) {
5837 set_start_position_and_type((start_position << kStartPositionShift)
5838 | (start_position_and_type() & ~kStartPositionMask));
5839}
5840
5841
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005842Code* SharedFunctionInfo::code() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005843 return Code::cast(READ_FIELD(this, kCodeOffset));
5844}
5845
5846
5847void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005848 DCHECK(value->kind() != Code::OPTIMIZED_FUNCTION);
Steve Blocka7e24c12009-10-30 11:49:00 +00005849 WRITE_FIELD(this, kCodeOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005850 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00005851}
5852
5853
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005854void SharedFunctionInfo::ReplaceCode(Code* value) {
5855 // If the GC metadata field is already used then the function was
5856 // enqueued as a code flushing candidate and we remove it now.
5857 if (code()->gc_metadata() != NULL) {
5858 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
5859 flusher->EvictCandidate(this);
5860 }
5861
5862 DCHECK(code()->gc_metadata() == NULL && value->gc_metadata() == NULL);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005863#ifdef DEBUG
5864 Code::VerifyRecompiledCode(code(), value);
5865#endif // DEBUG
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005866
5867 set_code(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005868
5869 if (is_compiled()) set_never_compiled(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005870}
5871
5872
5873ScopeInfo* SharedFunctionInfo::scope_info() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005874 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005875}
5876
5877
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005878void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005879 WriteBarrierMode mode) {
5880 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005881 CONDITIONAL_WRITE_BARRIER(GetHeap(),
5882 this,
5883 kScopeInfoOffset,
5884 reinterpret_cast<Object*>(value),
5885 mode);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005886}
5887
5888
Steve Blocka7e24c12009-10-30 11:49:00 +00005889bool SharedFunctionInfo::is_compiled() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005890 Builtins* builtins = GetIsolate()->builtins();
5891 DCHECK(code() != builtins->builtin(Builtins::kCompileOptimizedConcurrent));
5892 DCHECK(code() != builtins->builtin(Builtins::kCompileOptimized));
5893 return code() != builtins->builtin(Builtins::kCompileLazy);
5894}
5895
5896
5897bool SharedFunctionInfo::has_simple_parameters() {
5898 return scope_info()->HasSimpleParameters();
5899}
5900
5901
5902bool SharedFunctionInfo::HasDebugInfo() {
5903 bool has_debug_info = debug_info()->IsStruct();
5904 DCHECK(!has_debug_info || HasDebugCode());
5905 return has_debug_info;
5906}
5907
5908
5909DebugInfo* SharedFunctionInfo::GetDebugInfo() {
5910 DCHECK(HasDebugInfo());
5911 return DebugInfo::cast(debug_info());
5912}
5913
5914
5915bool SharedFunctionInfo::HasDebugCode() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01005916 return HasBytecodeArray() ||
5917 (code()->kind() == Code::FUNCTION && code()->has_debug_break_slots());
Steve Blocka7e24c12009-10-30 11:49:00 +00005918}
5919
5920
Steve Block6ded16b2010-05-10 14:33:55 +01005921bool SharedFunctionInfo::IsApiFunction() {
5922 return function_data()->IsFunctionTemplateInfo();
5923}
5924
5925
5926FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005927 DCHECK(IsApiFunction());
Steve Block6ded16b2010-05-10 14:33:55 +01005928 return FunctionTemplateInfo::cast(function_data());
5929}
5930
Ben Murdochda12d292016-06-02 14:46:10 +01005931void SharedFunctionInfo::set_api_func_data(FunctionTemplateInfo* data) {
5932 DCHECK(function_data()->IsUndefined());
5933 set_function_data(data);
Kristian Monsen25f61362010-05-21 11:50:48 +01005934}
5935
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005936bool SharedFunctionInfo::HasBytecodeArray() {
5937 return function_data()->IsBytecodeArray();
5938}
5939
5940
5941BytecodeArray* SharedFunctionInfo::bytecode_array() {
5942 DCHECK(HasBytecodeArray());
5943 return BytecodeArray::cast(function_data());
5944}
5945
Ben Murdochda12d292016-06-02 14:46:10 +01005946void SharedFunctionInfo::set_bytecode_array(BytecodeArray* bytecode) {
5947 DCHECK(function_data()->IsUndefined());
5948 set_function_data(bytecode);
5949}
5950
5951void SharedFunctionInfo::ClearBytecodeArray() {
5952 DCHECK(function_data()->IsUndefined() || HasBytecodeArray());
5953 set_function_data(GetHeap()->undefined_value());
5954}
5955
5956bool SharedFunctionInfo::HasBuiltinFunctionId() {
5957 return function_identifier()->IsSmi();
5958}
5959
5960BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
5961 DCHECK(HasBuiltinFunctionId());
5962 return static_cast<BuiltinFunctionId>(
5963 Smi::cast(function_identifier())->value());
5964}
5965
5966void SharedFunctionInfo::set_builtin_function_id(BuiltinFunctionId id) {
5967 set_function_identifier(Smi::FromInt(id));
5968}
5969
5970bool SharedFunctionInfo::HasInferredName() {
5971 return function_identifier()->IsString();
5972}
5973
5974String* SharedFunctionInfo::inferred_name() {
5975 if (HasInferredName()) {
5976 return String::cast(function_identifier());
5977 }
5978 DCHECK(function_identifier()->IsUndefined() || HasBuiltinFunctionId());
5979 return GetIsolate()->heap()->empty_string();
5980}
5981
5982void SharedFunctionInfo::set_inferred_name(String* inferred_name) {
5983 DCHECK(function_identifier()->IsUndefined() || HasInferredName());
5984 set_function_identifier(inferred_name);
5985}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005986
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005987int SharedFunctionInfo::ic_age() {
5988 return ICAgeBits::decode(counters());
Iain Merrick75681382010-08-19 15:07:18 +01005989}
5990
5991
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005992void SharedFunctionInfo::set_ic_age(int ic_age) {
5993 set_counters(ICAgeBits::update(counters(), ic_age));
5994}
5995
5996
5997int SharedFunctionInfo::deopt_count() {
5998 return DeoptCountBits::decode(counters());
5999}
6000
6001
6002void SharedFunctionInfo::set_deopt_count(int deopt_count) {
6003 set_counters(DeoptCountBits::update(counters(), deopt_count));
6004}
6005
6006
6007void SharedFunctionInfo::increment_deopt_count() {
6008 int value = counters();
6009 int deopt_count = DeoptCountBits::decode(value);
6010 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
6011 set_counters(DeoptCountBits::update(value, deopt_count));
6012}
6013
6014
6015int SharedFunctionInfo::opt_reenable_tries() {
6016 return OptReenableTriesBits::decode(counters());
6017}
6018
6019
6020void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
6021 set_counters(OptReenableTriesBits::update(counters(), tries));
6022}
6023
6024
6025int SharedFunctionInfo::opt_count() {
6026 return OptCountBits::decode(opt_count_and_bailout_reason());
6027}
6028
6029
6030void SharedFunctionInfo::set_opt_count(int opt_count) {
6031 set_opt_count_and_bailout_reason(
6032 OptCountBits::update(opt_count_and_bailout_reason(), opt_count));
6033}
6034
6035
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006036BailoutReason SharedFunctionInfo::disable_optimization_reason() {
6037 return static_cast<BailoutReason>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006038 DisabledOptimizationReasonBits::decode(opt_count_and_bailout_reason()));
Iain Merrick75681382010-08-19 15:07:18 +01006039}
6040
6041
Ben Murdochb0fe1622011-05-05 13:52:32 +01006042bool SharedFunctionInfo::has_deoptimization_support() {
6043 Code* code = this->code();
6044 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
6045}
6046
6047
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006048void SharedFunctionInfo::TryReenableOptimization() {
6049 int tries = opt_reenable_tries();
6050 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
6051 // We reenable optimization whenever the number of tries is a large
6052 // enough power of 2.
6053 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
6054 set_optimization_disabled(false);
6055 set_opt_count(0);
6056 set_deopt_count(0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006057 }
6058}
6059
6060
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006061void SharedFunctionInfo::set_disable_optimization_reason(BailoutReason reason) {
6062 set_opt_count_and_bailout_reason(DisabledOptimizationReasonBits::update(
6063 opt_count_and_bailout_reason(), reason));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006064}
6065
6066
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006067bool SharedFunctionInfo::IsBuiltin() {
6068 Object* script_obj = script();
6069 if (script_obj->IsUndefined()) return true;
6070 Script* script = Script::cast(script_obj);
6071 Script::Type type = static_cast<Script::Type>(script->type());
6072 return type != Script::TYPE_NORMAL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006073}
6074
6075
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006076bool SharedFunctionInfo::IsSubjectToDebugging() { return !IsBuiltin(); }
6077
6078
6079bool SharedFunctionInfo::OptimizedCodeMapIsCleared() const {
6080 return optimized_code_map() == GetHeap()->cleared_optimized_code_map();
Steve Blocka7e24c12009-10-30 11:49:00 +00006081}
6082
6083
Ben Murdochb0fe1622011-05-05 13:52:32 +01006084bool JSFunction::IsOptimized() {
6085 return code()->kind() == Code::OPTIMIZED_FUNCTION;
6086}
6087
6088
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006089bool JSFunction::IsMarkedForOptimization() {
6090 return code() == GetIsolate()->builtins()->builtin(
6091 Builtins::kCompileOptimized);
6092}
6093
6094
6095bool JSFunction::IsMarkedForConcurrentOptimization() {
6096 return code() == GetIsolate()->builtins()->builtin(
6097 Builtins::kCompileOptimizedConcurrent);
6098}
6099
6100
6101bool JSFunction::IsInOptimizationQueue() {
6102 return code() == GetIsolate()->builtins()->builtin(
6103 Builtins::kInOptimizationQueue);
6104}
6105
6106
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006107void JSFunction::CompleteInobjectSlackTrackingIfActive() {
6108 if (has_initial_map() && initial_map()->IsInobjectSlackTrackingInProgress()) {
6109 initial_map()->CompleteInobjectSlackTracking();
6110 }
6111}
6112
6113
6114bool Map::IsInobjectSlackTrackingInProgress() {
6115 return construction_counter() != Map::kNoSlackTracking;
6116}
6117
6118
6119void Map::InobjectSlackTrackingStep() {
6120 if (!IsInobjectSlackTrackingInProgress()) return;
6121 int counter = construction_counter();
6122 set_construction_counter(counter - 1);
6123 if (counter == kSlackTrackingCounterEnd) {
6124 CompleteInobjectSlackTracking();
6125 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01006126}
6127
Ben Murdochda12d292016-06-02 14:46:10 +01006128AbstractCode* JSFunction::abstract_code() {
6129 Code* code = this->code();
6130 if (code->is_interpreter_entry_trampoline()) {
6131 return AbstractCode::cast(shared()->bytecode_array());
6132 } else {
6133 return AbstractCode::cast(code);
6134 }
6135}
Ben Murdochb0fe1622011-05-05 13:52:32 +01006136
Steve Blocka7e24c12009-10-30 11:49:00 +00006137Code* JSFunction::code() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006138 return Code::cast(
Steve Block791712a2010-08-27 10:21:07 +01006139 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
Steve Blocka7e24c12009-10-30 11:49:00 +00006140}
6141
6142
6143void JSFunction::set_code(Code* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006144 DCHECK(!GetHeap()->InNewSpace(value));
Steve Block791712a2010-08-27 10:21:07 +01006145 Address entry = value->entry();
6146 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006147 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
6148 this,
6149 HeapObject::RawField(this, kCodeEntryOffset),
6150 value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006151}
6152
6153
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006154void JSFunction::set_code_no_write_barrier(Code* value) {
6155 DCHECK(!GetHeap()->InNewSpace(value));
6156 Address entry = value->entry();
6157 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
6158}
6159
6160
Ben Murdochb0fe1622011-05-05 13:52:32 +01006161void JSFunction::ReplaceCode(Code* code) {
6162 bool was_optimized = IsOptimized();
6163 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
6164
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006165 if (was_optimized && is_optimized) {
6166 shared()->EvictFromOptimizedCodeMap(this->code(),
6167 "Replacing with another optimized code");
6168 }
6169
Ben Murdochb0fe1622011-05-05 13:52:32 +01006170 set_code(code);
6171
6172 // Add/remove the function from the list of optimized functions for this
6173 // context based on the state change.
6174 if (!was_optimized && is_optimized) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006175 context()->native_context()->AddOptimizedFunction(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01006176 }
6177 if (was_optimized && !is_optimized) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006178 // TODO(titzer): linear in the number of optimized functions; fix!
6179 context()->native_context()->RemoveOptimizedFunction(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01006180 }
6181}
6182
6183
Steve Blocka7e24c12009-10-30 11:49:00 +00006184Context* JSFunction::context() {
6185 return Context::cast(READ_FIELD(this, kContextOffset));
6186}
6187
6188
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006189JSObject* JSFunction::global_proxy() {
6190 return context()->global_proxy();
Iain Merrick75681382010-08-19 15:07:18 +01006191}
6192
6193
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006194Context* JSFunction::native_context() { return context()->native_context(); }
6195
6196
Steve Blocka7e24c12009-10-30 11:49:00 +00006197void JSFunction::set_context(Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006198 DCHECK(value->IsUndefined() || value->IsContext());
Steve Blocka7e24c12009-10-30 11:49:00 +00006199 WRITE_FIELD(this, kContextOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006200 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006201}
6202
6203ACCESSORS(JSFunction, prototype_or_initial_map, Object,
6204 kPrototypeOrInitialMapOffset)
6205
6206
6207Map* JSFunction::initial_map() {
6208 return Map::cast(prototype_or_initial_map());
6209}
6210
6211
Steve Blocka7e24c12009-10-30 11:49:00 +00006212bool JSFunction::has_initial_map() {
6213 return prototype_or_initial_map()->IsMap();
6214}
6215
6216
6217bool JSFunction::has_instance_prototype() {
6218 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
6219}
6220
6221
6222bool JSFunction::has_prototype() {
6223 return map()->has_non_instance_prototype() || has_instance_prototype();
6224}
6225
6226
6227Object* JSFunction::instance_prototype() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006228 DCHECK(has_instance_prototype());
Steve Blocka7e24c12009-10-30 11:49:00 +00006229 if (has_initial_map()) return initial_map()->prototype();
6230 // When there is no initial map and the prototype is a JSObject, the
6231 // initial map field is used for the prototype field.
6232 return prototype_or_initial_map();
6233}
6234
6235
6236Object* JSFunction::prototype() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006237 DCHECK(has_prototype());
Steve Blocka7e24c12009-10-30 11:49:00 +00006238 // If the function's prototype property has been set to a non-JSObject
6239 // value, that value is stored in the constructor field of the map.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006240 if (map()->has_non_instance_prototype()) {
6241 Object* prototype = map()->GetConstructor();
6242 // The map must have a prototype in that field, not a back pointer.
6243 DCHECK(!prototype->IsMap());
6244 return prototype;
6245 }
Steve Blocka7e24c12009-10-30 11:49:00 +00006246 return instance_prototype();
6247}
6248
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006249
Steve Blocka7e24c12009-10-30 11:49:00 +00006250bool JSFunction::is_compiled() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006251 Builtins* builtins = GetIsolate()->builtins();
6252 return code() != builtins->builtin(Builtins::kCompileLazy) &&
6253 code() != builtins->builtin(Builtins::kCompileOptimized) &&
6254 code() != builtins->builtin(Builtins::kCompileOptimizedConcurrent);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006255}
6256
6257
Steve Blocka7e24c12009-10-30 11:49:00 +00006258int JSFunction::NumberOfLiterals() {
6259 return literals()->length();
6260}
6261
6262
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006263ACCESSORS(JSProxy, target, JSReceiver, kTargetOffset)
Ben Murdoch257744e2011-11-30 15:57:28 +00006264ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006265ACCESSORS(JSProxy, hash, Object, kHashOffset)
Ben Murdoch589d6972011-11-30 16:04:58 +00006266
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006267bool JSProxy::IsRevoked() const { return !handler()->IsJSReceiver(); }
Ben Murdoch257744e2011-11-30 15:57:28 +00006268
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006269ACCESSORS(JSCollection, table, Object, kTableOffset)
6270
6271
6272#define ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(name, type, offset) \
6273 template<class Derived, class TableType> \
6274 type* OrderedHashTableIterator<Derived, TableType>::name() const { \
6275 return type::cast(READ_FIELD(this, offset)); \
6276 } \
6277 template<class Derived, class TableType> \
6278 void OrderedHashTableIterator<Derived, TableType>::set_##name( \
6279 type* value, WriteBarrierMode mode) { \
6280 WRITE_FIELD(this, offset, value); \
6281 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
6282 }
6283
6284ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(table, Object, kTableOffset)
6285ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(index, Object, kIndexOffset)
6286ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(kind, Object, kKindOffset)
6287
6288#undef ORDERED_HASH_TABLE_ITERATOR_ACCESSORS
6289
6290
6291ACCESSORS(JSWeakCollection, table, Object, kTableOffset)
6292ACCESSORS(JSWeakCollection, next, Object, kNextOffset)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00006293
6294
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006295Address Foreign::foreign_address() {
6296 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
Ben Murdoch69a99ed2011-11-30 16:03:39 +00006297}
6298
6299
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006300void Foreign::set_foreign_address(Address value) {
6301 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00006302}
6303
6304
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006305ACCESSORS(JSGeneratorObject, function, JSFunction, kFunctionOffset)
6306ACCESSORS(JSGeneratorObject, context, Context, kContextOffset)
6307ACCESSORS(JSGeneratorObject, receiver, Object, kReceiverOffset)
Ben Murdoch097c5b22016-05-18 11:27:45 +01006308ACCESSORS(JSGeneratorObject, input, Object, kInputOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006309SMI_ACCESSORS(JSGeneratorObject, continuation, kContinuationOffset)
6310ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006311
6312bool JSGeneratorObject::is_suspended() {
6313 DCHECK_LT(kGeneratorExecuting, kGeneratorClosed);
6314 DCHECK_EQ(kGeneratorClosed, 0);
6315 return continuation() > 0;
6316}
6317
6318bool JSGeneratorObject::is_closed() {
6319 return continuation() == kGeneratorClosed;
6320}
6321
6322bool JSGeneratorObject::is_executing() {
6323 return continuation() == kGeneratorExecuting;
6324}
6325
6326ACCESSORS(JSModule, context, Object, kContextOffset)
6327ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
6328
6329
Steve Blocka7e24c12009-10-30 11:49:00 +00006330ACCESSORS(JSValue, value, Object, kValueOffset)
6331
6332
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006333HeapNumber* HeapNumber::cast(Object* object) {
6334 SLOW_DCHECK(object->IsHeapNumber() || object->IsMutableHeapNumber());
6335 return reinterpret_cast<HeapNumber*>(object);
6336}
6337
6338
6339const HeapNumber* HeapNumber::cast(const Object* object) {
6340 SLOW_DCHECK(object->IsHeapNumber() || object->IsMutableHeapNumber());
6341 return reinterpret_cast<const HeapNumber*>(object);
Steve Blocka7e24c12009-10-30 11:49:00 +00006342}
6343
6344
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006345ACCESSORS(JSDate, value, Object, kValueOffset)
6346ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
6347ACCESSORS(JSDate, year, Object, kYearOffset)
6348ACCESSORS(JSDate, month, Object, kMonthOffset)
6349ACCESSORS(JSDate, day, Object, kDayOffset)
6350ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
6351ACCESSORS(JSDate, hour, Object, kHourOffset)
6352ACCESSORS(JSDate, min, Object, kMinOffset)
6353ACCESSORS(JSDate, sec, Object, kSecOffset)
6354
6355
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006356SMI_ACCESSORS(JSMessageObject, type, kTypeOffset)
6357ACCESSORS(JSMessageObject, argument, Object, kArgumentsOffset)
Steve Block1e0659c2011-05-24 12:43:12 +01006358ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
Steve Block1e0659c2011-05-24 12:43:12 +01006359ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
6360SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
6361SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
6362
6363
Steve Blocka7e24c12009-10-30 11:49:00 +00006364INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006365INT_ACCESSORS(Code, prologue_offset, kPrologueOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006366INT_ACCESSORS(Code, constant_pool_offset, kConstantPoolOffset)
Leon Clarkeac952652010-07-15 11:15:24 +01006367ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006368ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
Ben Murdochb0fe1622011-05-05 13:52:32 +01006369ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006370ACCESSORS(Code, raw_type_feedback_info, Object, kTypeFeedbackInfoOffset)
6371ACCESSORS(Code, next_code_link, Object, kNextCodeLinkOffset)
6372
6373
6374void Code::WipeOutHeader() {
6375 WRITE_FIELD(this, kRelocationInfoOffset, NULL);
6376 WRITE_FIELD(this, kHandlerTableOffset, NULL);
6377 WRITE_FIELD(this, kDeoptimizationDataOffset, NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006378 // Do not wipe out major/minor keys on a code stub or IC
6379 if (!READ_FIELD(this, kTypeFeedbackInfoOffset)->IsSmi()) {
6380 WRITE_FIELD(this, kTypeFeedbackInfoOffset, NULL);
6381 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006382 WRITE_FIELD(this, kNextCodeLinkOffset, NULL);
6383 WRITE_FIELD(this, kGCMetadataOffset, NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006384}
6385
6386
6387Object* Code::type_feedback_info() {
6388 DCHECK(kind() == FUNCTION);
6389 return raw_type_feedback_info();
6390}
6391
6392
6393void Code::set_type_feedback_info(Object* value, WriteBarrierMode mode) {
6394 DCHECK(kind() == FUNCTION);
6395 set_raw_type_feedback_info(value, mode);
6396 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kTypeFeedbackInfoOffset,
6397 value, mode);
6398}
6399
6400
6401uint32_t Code::stub_key() {
6402 DCHECK(IsCodeStubOrIC());
6403 Smi* smi_key = Smi::cast(raw_type_feedback_info());
6404 return static_cast<uint32_t>(smi_key->value());
6405}
6406
6407
6408void Code::set_stub_key(uint32_t key) {
6409 DCHECK(IsCodeStubOrIC());
6410 set_raw_type_feedback_info(Smi::FromInt(key));
6411}
6412
6413
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006414ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
6415INT_ACCESSORS(Code, ic_age, kICAgeOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00006416
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006417
Steve Blocka7e24c12009-10-30 11:49:00 +00006418byte* Code::instruction_start() {
6419 return FIELD_ADDR(this, kHeaderSize);
6420}
6421
6422
Leon Clarkeac952652010-07-15 11:15:24 +01006423byte* Code::instruction_end() {
6424 return instruction_start() + instruction_size();
6425}
6426
6427
Steve Blocka7e24c12009-10-30 11:49:00 +00006428int Code::body_size() {
Leon Clarkeac952652010-07-15 11:15:24 +01006429 return RoundUp(instruction_size(), kObjectAlignment);
6430}
6431
6432
6433ByteArray* Code::unchecked_relocation_info() {
6434 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
Steve Blocka7e24c12009-10-30 11:49:00 +00006435}
6436
6437
6438byte* Code::relocation_start() {
Leon Clarkeac952652010-07-15 11:15:24 +01006439 return unchecked_relocation_info()->GetDataStartAddress();
6440}
6441
6442
6443int Code::relocation_size() {
6444 return unchecked_relocation_info()->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00006445}
6446
6447
6448byte* Code::entry() {
6449 return instruction_start();
6450}
6451
6452
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006453bool Code::contains(byte* inner_pointer) {
6454 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
Steve Blocka7e24c12009-10-30 11:49:00 +00006455}
6456
6457
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006458int Code::ExecutableSize() {
6459 // Check that the assumptions about the layout of the code object holds.
6460 DCHECK_EQ(static_cast<int>(instruction_start() - address()),
6461 Code::kHeaderSize);
6462 return instruction_size() + Code::kHeaderSize;
6463}
6464
6465
6466int Code::CodeSize() { return SizeFor(body_size()); }
6467
6468
Steve Blocka7e24c12009-10-30 11:49:00 +00006469ACCESSORS(JSArray, length, Object, kLengthOffset)
6470
6471
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006472void* JSArrayBuffer::backing_store() const {
6473 intptr_t ptr = READ_INTPTR_FIELD(this, kBackingStoreOffset);
6474 return reinterpret_cast<void*>(ptr);
6475}
6476
6477
6478void JSArrayBuffer::set_backing_store(void* value, WriteBarrierMode mode) {
6479 intptr_t ptr = reinterpret_cast<intptr_t>(value);
6480 WRITE_INTPTR_FIELD(this, kBackingStoreOffset, ptr);
6481}
6482
6483
6484ACCESSORS(JSArrayBuffer, byte_length, Object, kByteLengthOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006485
6486
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006487void JSArrayBuffer::set_bit_field(uint32_t bits) {
6488 if (kInt32Size != kPointerSize) {
6489#if V8_TARGET_LITTLE_ENDIAN
6490 WRITE_UINT32_FIELD(this, kBitFieldSlot + kInt32Size, 0);
6491#else
6492 WRITE_UINT32_FIELD(this, kBitFieldSlot, 0);
6493#endif
6494 }
6495 WRITE_UINT32_FIELD(this, kBitFieldOffset, bits);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006496}
6497
6498
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006499uint32_t JSArrayBuffer::bit_field() const {
6500 return READ_UINT32_FIELD(this, kBitFieldOffset);
6501}
6502
6503
6504bool JSArrayBuffer::is_external() { return IsExternal::decode(bit_field()); }
6505
6506
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006507void JSArrayBuffer::set_is_external(bool value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006508 set_bit_field(IsExternal::update(bit_field(), value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006509}
6510
6511
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006512bool JSArrayBuffer::is_neuterable() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006513 return IsNeuterable::decode(bit_field());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006514}
6515
6516
6517void JSArrayBuffer::set_is_neuterable(bool value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006518 set_bit_field(IsNeuterable::update(bit_field(), value));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006519}
6520
6521
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006522bool JSArrayBuffer::was_neutered() { return WasNeutered::decode(bit_field()); }
6523
6524
6525void JSArrayBuffer::set_was_neutered(bool value) {
6526 set_bit_field(WasNeutered::update(bit_field(), value));
6527}
6528
6529
6530bool JSArrayBuffer::is_shared() { return IsShared::decode(bit_field()); }
6531
6532
6533void JSArrayBuffer::set_is_shared(bool value) {
6534 set_bit_field(IsShared::update(bit_field(), value));
6535}
6536
6537
6538Object* JSArrayBufferView::byte_offset() const {
6539 if (WasNeutered()) return Smi::FromInt(0);
6540 return Object::cast(READ_FIELD(this, kByteOffsetOffset));
6541}
6542
6543
6544void JSArrayBufferView::set_byte_offset(Object* value, WriteBarrierMode mode) {
6545 WRITE_FIELD(this, kByteOffsetOffset, value);
6546 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kByteOffsetOffset, value, mode);
6547}
6548
6549
6550Object* JSArrayBufferView::byte_length() const {
6551 if (WasNeutered()) return Smi::FromInt(0);
6552 return Object::cast(READ_FIELD(this, kByteLengthOffset));
6553}
6554
6555
6556void JSArrayBufferView::set_byte_length(Object* value, WriteBarrierMode mode) {
6557 WRITE_FIELD(this, kByteLengthOffset, value);
6558 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kByteLengthOffset, value, mode);
6559}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006560
6561
6562ACCESSORS(JSArrayBufferView, buffer, Object, kBufferOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006563#ifdef VERIFY_HEAP
6564ACCESSORS(JSArrayBufferView, raw_byte_offset, Object, kByteOffsetOffset)
6565ACCESSORS(JSArrayBufferView, raw_byte_length, Object, kByteLengthOffset)
6566#endif
6567
6568
6569bool JSArrayBufferView::WasNeutered() const {
6570 return JSArrayBuffer::cast(buffer())->was_neutered();
6571}
6572
6573
6574Object* JSTypedArray::length() const {
6575 if (WasNeutered()) return Smi::FromInt(0);
6576 return Object::cast(READ_FIELD(this, kLengthOffset));
6577}
6578
6579
6580uint32_t JSTypedArray::length_value() const {
6581 if (WasNeutered()) return 0;
6582 uint32_t index = 0;
6583 CHECK(Object::cast(READ_FIELD(this, kLengthOffset))->ToArrayLength(&index));
6584 return index;
6585}
6586
6587
6588void JSTypedArray::set_length(Object* value, WriteBarrierMode mode) {
6589 WRITE_FIELD(this, kLengthOffset, value);
6590 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kLengthOffset, value, mode);
6591}
6592
6593
6594#ifdef VERIFY_HEAP
6595ACCESSORS(JSTypedArray, raw_length, Object, kLengthOffset)
6596#endif
6597
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006598
Steve Blocka7e24c12009-10-30 11:49:00 +00006599ACCESSORS(JSRegExp, data, Object, kDataOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006600ACCESSORS(JSRegExp, flags, Object, kFlagsOffset)
6601ACCESSORS(JSRegExp, source, Object, kSourceOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00006602
6603
6604JSRegExp::Type JSRegExp::TypeTag() {
6605 Object* data = this->data();
6606 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
6607 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
6608 return static_cast<JSRegExp::Type>(smi->value());
6609}
6610
6611
6612int JSRegExp::CaptureCount() {
6613 switch (TypeTag()) {
6614 case ATOM:
6615 return 0;
6616 case IRREGEXP:
6617 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
6618 default:
6619 UNREACHABLE();
6620 return -1;
6621 }
6622}
6623
6624
6625JSRegExp::Flags JSRegExp::GetFlags() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006626 DCHECK(this->data()->IsFixedArray());
Steve Blocka7e24c12009-10-30 11:49:00 +00006627 Object* data = this->data();
6628 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
6629 return Flags(smi->value());
6630}
6631
6632
6633String* JSRegExp::Pattern() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006634 DCHECK(this->data()->IsFixedArray());
Steve Blocka7e24c12009-10-30 11:49:00 +00006635 Object* data = this->data();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006636 String* pattern = String::cast(FixedArray::cast(data)->get(kSourceIndex));
Steve Blocka7e24c12009-10-30 11:49:00 +00006637 return pattern;
6638}
6639
6640
6641Object* JSRegExp::DataAt(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006642 DCHECK(TypeTag() != NOT_COMPILED);
Steve Blocka7e24c12009-10-30 11:49:00 +00006643 return FixedArray::cast(data())->get(index);
6644}
6645
6646
6647void JSRegExp::SetDataAt(int index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006648 DCHECK(TypeTag() != NOT_COMPILED);
6649 DCHECK(index >= kDataIndex); // Only implementation data can be set this way.
Steve Blocka7e24c12009-10-30 11:49:00 +00006650 FixedArray::cast(data())->set(index, value);
6651}
6652
6653
Ben Murdoch589d6972011-11-30 16:04:58 +00006654ElementsKind JSObject::GetElementsKind() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006655 ElementsKind kind = map()->elements_kind();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006656#if VERIFY_HEAP && DEBUG
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006657 FixedArrayBase* fixed_array =
6658 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006659
6660 // If a GC was caused while constructing this object, the elements
6661 // pointer may point to a one pointer filler map.
6662 if (ElementsAreSafeToExamine()) {
6663 Map* map = fixed_array->map();
6664 DCHECK((IsFastSmiOrObjectElementsKind(kind) &&
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006665 (map == GetHeap()->fixed_array_map() ||
6666 map == GetHeap()->fixed_cow_array_map())) ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006667 (IsFastDoubleElementsKind(kind) &&
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006668 (fixed_array->IsFixedDoubleArray() ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006669 fixed_array == GetHeap()->empty_fixed_array())) ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006670 (kind == DICTIONARY_ELEMENTS &&
6671 fixed_array->IsFixedArray() &&
6672 fixed_array->IsDictionary()) ||
6673 (kind > DICTIONARY_ELEMENTS));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006674 DCHECK(!IsSloppyArgumentsElements(kind) ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006675 (elements()->IsFixedArray() && elements()->length() >= 2));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006676 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006677#endif
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006678 return kind;
Steve Blocka7e24c12009-10-30 11:49:00 +00006679}
6680
6681
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006682bool JSObject::HasFastObjectElements() {
6683 return IsFastObjectElementsKind(GetElementsKind());
Steve Blocka7e24c12009-10-30 11:49:00 +00006684}
6685
6686
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006687bool JSObject::HasFastSmiElements() {
6688 return IsFastSmiElementsKind(GetElementsKind());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006689}
6690
6691
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006692bool JSObject::HasFastSmiOrObjectElements() {
6693 return IsFastSmiOrObjectElementsKind(GetElementsKind());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006694}
6695
6696
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006697bool JSObject::HasFastDoubleElements() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006698 return IsFastDoubleElementsKind(GetElementsKind());
6699}
6700
6701
6702bool JSObject::HasFastHoleyElements() {
6703 return IsFastHoleyElementsKind(GetElementsKind());
6704}
6705
6706
6707bool JSObject::HasFastElements() {
6708 return IsFastElementsKind(GetElementsKind());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006709}
6710
6711
Steve Blocka7e24c12009-10-30 11:49:00 +00006712bool JSObject::HasDictionaryElements() {
6713 return GetElementsKind() == DICTIONARY_ELEMENTS;
6714}
6715
6716
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006717bool JSObject::HasFastArgumentsElements() {
6718 return GetElementsKind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
6719}
6720
6721
6722bool JSObject::HasSlowArgumentsElements() {
6723 return GetElementsKind() == SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
6724}
6725
6726
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006727bool JSObject::HasSloppyArgumentsElements() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006728 return IsSloppyArgumentsElements(GetElementsKind());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006729}
6730
Ben Murdoch097c5b22016-05-18 11:27:45 +01006731bool JSObject::HasStringWrapperElements() {
6732 return IsStringWrapperElementsKind(GetElementsKind());
6733}
6734
6735bool JSObject::HasFastStringWrapperElements() {
6736 return GetElementsKind() == FAST_STRING_WRAPPER_ELEMENTS;
6737}
6738
6739bool JSObject::HasSlowStringWrapperElements() {
6740 return GetElementsKind() == SLOW_STRING_WRAPPER_ELEMENTS;
6741}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006742
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006743bool JSObject::HasFixedTypedArrayElements() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01006744 DCHECK_NOT_NULL(elements());
6745 return map()->has_fixed_typed_array_elements();
Steve Block3ce2e202009-11-05 08:53:23 +00006746}
6747
Ben Murdoch097c5b22016-05-18 11:27:45 +01006748#define FIXED_TYPED_ELEMENTS_CHECK(Type, type, TYPE, ctype, size) \
6749 bool JSObject::HasFixed##Type##Elements() { \
6750 HeapObject* array = elements(); \
6751 DCHECK(array != NULL); \
6752 if (!array->IsHeapObject()) return false; \
6753 return array->map()->instance_type() == FIXED_##TYPE##_ARRAY_TYPE; \
6754 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006755
6756TYPED_ARRAYS(FIXED_TYPED_ELEMENTS_CHECK)
6757
6758#undef FIXED_TYPED_ELEMENTS_CHECK
Steve Block3ce2e202009-11-05 08:53:23 +00006759
6760
Steve Blocka7e24c12009-10-30 11:49:00 +00006761bool JSObject::HasNamedInterceptor() {
6762 return map()->has_named_interceptor();
6763}
6764
6765
6766bool JSObject::HasIndexedInterceptor() {
6767 return map()->has_indexed_interceptor();
6768}
6769
6770
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006771GlobalDictionary* JSObject::global_dictionary() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006772 DCHECK(!HasFastProperties());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006773 DCHECK(IsJSGlobalObject());
6774 return GlobalDictionary::cast(properties());
Steve Blocka7e24c12009-10-30 11:49:00 +00006775}
6776
6777
Ben Murdochc7cc0282012-03-05 14:35:55 +00006778SeededNumberDictionary* JSObject::element_dictionary() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01006779 DCHECK(HasDictionaryElements() || HasSlowStringWrapperElements());
Ben Murdochc7cc0282012-03-05 14:35:55 +00006780 return SeededNumberDictionary::cast(elements());
Steve Blocka7e24c12009-10-30 11:49:00 +00006781}
6782
6783
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006784bool Name::IsHashFieldComputed(uint32_t field) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006785 return (field & kHashNotComputedMask) == 0;
6786}
6787
6788
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006789bool Name::HasHashCode() {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006790 return IsHashFieldComputed(hash_field());
Steve Blocka7e24c12009-10-30 11:49:00 +00006791}
6792
6793
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006794uint32_t Name::Hash() {
Steve Blocka7e24c12009-10-30 11:49:00 +00006795 // Fast case: has hash code already been computed?
Steve Blockd0582a62009-12-15 09:54:21 +00006796 uint32_t field = hash_field();
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006797 if (IsHashFieldComputed(field)) return field >> kHashShift;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006798 // Slow case: compute hash code and set it. Has to be a string.
6799 return String::cast(this)->ComputeAndSetHash();
6800}
6801
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006802
6803bool Name::IsPrivate() {
6804 return this->IsSymbol() && Symbol::cast(this)->is_private();
Steve Blocka7e24c12009-10-30 11:49:00 +00006805}
6806
6807
Ben Murdochc7cc0282012-03-05 14:35:55 +00006808StringHasher::StringHasher(int length, uint32_t seed)
Steve Blocka7e24c12009-10-30 11:49:00 +00006809 : length_(length),
Ben Murdochc7cc0282012-03-05 14:35:55 +00006810 raw_running_hash_(seed),
Steve Blocka7e24c12009-10-30 11:49:00 +00006811 array_index_(0),
6812 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006813 is_first_char_(true) {
6814 DCHECK(FLAG_randomize_hashes || raw_running_hash_ == 0);
Ben Murdochc7cc0282012-03-05 14:35:55 +00006815}
Steve Blocka7e24c12009-10-30 11:49:00 +00006816
6817
6818bool StringHasher::has_trivial_hash() {
Steve Blockd0582a62009-12-15 09:54:21 +00006819 return length_ > String::kMaxHashCalcLength;
Steve Blocka7e24c12009-10-30 11:49:00 +00006820}
6821
6822
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006823uint32_t StringHasher::AddCharacterCore(uint32_t running_hash, uint16_t c) {
6824 running_hash += c;
6825 running_hash += (running_hash << 10);
6826 running_hash ^= (running_hash >> 6);
6827 return running_hash;
6828}
6829
6830
6831uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
6832 running_hash += (running_hash << 3);
6833 running_hash ^= (running_hash >> 11);
6834 running_hash += (running_hash << 15);
6835 if ((running_hash & String::kHashBitMask) == 0) {
6836 return kZeroHash;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006837 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006838 return running_hash;
6839}
6840
6841
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006842uint32_t StringHasher::ComputeRunningHash(uint32_t running_hash,
6843 const uc16* chars, int length) {
6844 DCHECK_NOT_NULL(chars);
6845 DCHECK(length >= 0);
6846 for (int i = 0; i < length; ++i) {
6847 running_hash = AddCharacterCore(running_hash, *chars++);
6848 }
6849 return running_hash;
6850}
6851
6852
6853uint32_t StringHasher::ComputeRunningHashOneByte(uint32_t running_hash,
6854 const char* chars,
6855 int length) {
6856 DCHECK_NOT_NULL(chars);
6857 DCHECK(length >= 0);
6858 for (int i = 0; i < length; ++i) {
6859 uint16_t c = static_cast<uint16_t>(*chars++);
6860 running_hash = AddCharacterCore(running_hash, c);
6861 }
6862 return running_hash;
6863}
6864
6865
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006866void StringHasher::AddCharacter(uint16_t c) {
Steve Blocka7e24c12009-10-30 11:49:00 +00006867 // Use the Jenkins one-at-a-time hash function to update the hash
6868 // for the given character.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006869 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c);
6870}
6871
6872
6873bool StringHasher::UpdateIndex(uint16_t c) {
6874 DCHECK(is_array_index_);
6875 if (c < '0' || c > '9') {
6876 is_array_index_ = false;
6877 return false;
6878 }
6879 int d = c - '0';
6880 if (is_first_char_) {
6881 is_first_char_ = false;
6882 if (c == '0' && length_ > 1) {
Steve Blocka7e24c12009-10-30 11:49:00 +00006883 is_array_index_ = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006884 return false;
6885 }
6886 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006887 if (array_index_ > 429496729U - ((d + 3) >> 3)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006888 is_array_index_ = false;
6889 return false;
6890 }
6891 array_index_ = array_index_ * 10 + d;
6892 return true;
6893}
6894
6895
6896template<typename Char>
6897inline void StringHasher::AddCharacters(const Char* chars, int length) {
6898 DCHECK(sizeof(Char) == 1 || sizeof(Char) == 2);
6899 int i = 0;
6900 if (is_array_index_) {
6901 for (; i < length; i++) {
6902 AddCharacter(chars[i]);
6903 if (!UpdateIndex(chars[i])) {
6904 i++;
6905 break;
Steve Blocka7e24c12009-10-30 11:49:00 +00006906 }
6907 }
6908 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006909 for (; i < length; i++) {
6910 DCHECK(!is_array_index_);
6911 AddCharacter(chars[i]);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006912 }
Steve Blocka7e24c12009-10-30 11:49:00 +00006913}
6914
6915
Steve Block44f0eee2011-05-26 01:26:41 +01006916template <typename schar>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006917uint32_t StringHasher::HashSequentialString(const schar* chars,
6918 int length,
6919 uint32_t seed) {
Ben Murdochc7cc0282012-03-05 14:35:55 +00006920 StringHasher hasher(length, seed);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006921 if (!hasher.has_trivial_hash()) hasher.AddCharacters(chars, length);
6922 return hasher.GetHashField();
6923}
6924
6925
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006926IteratingStringHasher::IteratingStringHasher(int len, uint32_t seed)
6927 : StringHasher(len, seed) {}
6928
6929
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006930uint32_t IteratingStringHasher::Hash(String* string, uint32_t seed) {
6931 IteratingStringHasher hasher(string->length(), seed);
6932 // Nothing to do.
6933 if (hasher.has_trivial_hash()) return hasher.GetHashField();
6934 ConsString* cons_string = String::VisitFlat(&hasher, string);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006935 if (cons_string == nullptr) return hasher.GetHashField();
6936 hasher.VisitConsString(cons_string);
Steve Block44f0eee2011-05-26 01:26:41 +01006937 return hasher.GetHashField();
6938}
6939
6940
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006941void IteratingStringHasher::VisitOneByteString(const uint8_t* chars,
6942 int length) {
6943 AddCharacters(chars, length);
6944}
6945
6946
6947void IteratingStringHasher::VisitTwoByteString(const uint16_t* chars,
6948 int length) {
6949 AddCharacters(chars, length);
6950}
6951
6952
6953bool Name::AsArrayIndex(uint32_t* index) {
6954 return IsString() && String::cast(this)->AsArrayIndex(index);
6955}
6956
6957
Steve Blocka7e24c12009-10-30 11:49:00 +00006958bool String::AsArrayIndex(uint32_t* index) {
Steve Blockd0582a62009-12-15 09:54:21 +00006959 uint32_t field = hash_field();
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006960 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
6961 return false;
6962 }
Steve Blocka7e24c12009-10-30 11:49:00 +00006963 return SlowAsArrayIndex(index);
6964}
6965
6966
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006967void String::SetForwardedInternalizedString(String* canonical) {
6968 DCHECK(IsInternalizedString());
6969 DCHECK(HasHashCode());
6970 if (canonical == this) return; // No need to forward.
6971 DCHECK(SlowEquals(canonical));
6972 DCHECK(canonical->IsInternalizedString());
6973 DCHECK(canonical->HasHashCode());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006974 WRITE_FIELD(this, kHashFieldSlot, canonical);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006975 // Setting the hash field to a tagged value sets the LSB, causing the hash
6976 // code to be interpreted as uninitialized. We use this fact to recognize
6977 // that we have a forwarded string.
6978 DCHECK(!HasHashCode());
Steve Blocka7e24c12009-10-30 11:49:00 +00006979}
6980
6981
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006982String* String::GetForwardedInternalizedString() {
6983 DCHECK(IsInternalizedString());
6984 if (HasHashCode()) return this;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006985 String* canonical = String::cast(READ_FIELD(this, kHashFieldSlot));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006986 DCHECK(canonical->IsInternalizedString());
6987 DCHECK(SlowEquals(canonical));
6988 DCHECK(canonical->HasHashCode());
6989 return canonical;
6990}
6991
6992
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006993// static
Ben Murdoch097c5b22016-05-18 11:27:45 +01006994Maybe<bool> Object::GreaterThan(Handle<Object> x, Handle<Object> y) {
6995 Maybe<ComparisonResult> result = Compare(x, y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006996 if (result.IsJust()) {
6997 switch (result.FromJust()) {
6998 case ComparisonResult::kGreaterThan:
6999 return Just(true);
7000 case ComparisonResult::kLessThan:
7001 case ComparisonResult::kEqual:
7002 case ComparisonResult::kUndefined:
7003 return Just(false);
7004 }
7005 }
7006 return Nothing<bool>();
7007}
7008
7009
7010// static
Ben Murdoch097c5b22016-05-18 11:27:45 +01007011Maybe<bool> Object::GreaterThanOrEqual(Handle<Object> x, Handle<Object> y) {
7012 Maybe<ComparisonResult> result = Compare(x, y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007013 if (result.IsJust()) {
7014 switch (result.FromJust()) {
7015 case ComparisonResult::kEqual:
7016 case ComparisonResult::kGreaterThan:
7017 return Just(true);
7018 case ComparisonResult::kLessThan:
7019 case ComparisonResult::kUndefined:
7020 return Just(false);
7021 }
7022 }
7023 return Nothing<bool>();
7024}
7025
7026
7027// static
Ben Murdoch097c5b22016-05-18 11:27:45 +01007028Maybe<bool> Object::LessThan(Handle<Object> x, Handle<Object> y) {
7029 Maybe<ComparisonResult> result = Compare(x, y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007030 if (result.IsJust()) {
7031 switch (result.FromJust()) {
7032 case ComparisonResult::kLessThan:
7033 return Just(true);
7034 case ComparisonResult::kEqual:
7035 case ComparisonResult::kGreaterThan:
7036 case ComparisonResult::kUndefined:
7037 return Just(false);
7038 }
7039 }
7040 return Nothing<bool>();
7041}
7042
7043
7044// static
Ben Murdoch097c5b22016-05-18 11:27:45 +01007045Maybe<bool> Object::LessThanOrEqual(Handle<Object> x, Handle<Object> y) {
7046 Maybe<ComparisonResult> result = Compare(x, y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007047 if (result.IsJust()) {
7048 switch (result.FromJust()) {
7049 case ComparisonResult::kEqual:
7050 case ComparisonResult::kLessThan:
7051 return Just(true);
7052 case ComparisonResult::kGreaterThan:
7053 case ComparisonResult::kUndefined:
7054 return Just(false);
7055 }
7056 }
7057 return Nothing<bool>();
7058}
7059
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007060MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> object,
Ben Murdoch097c5b22016-05-18 11:27:45 +01007061 Handle<Name> name) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007062 LookupIterator it =
7063 LookupIterator::PropertyOrElement(name->GetIsolate(), object, name);
Ben Murdoch097c5b22016-05-18 11:27:45 +01007064 return GetProperty(&it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007065}
7066
Ben Murdochda12d292016-06-02 14:46:10 +01007067MaybeHandle<Object> Object::SetPropertyOrElement(Handle<Object> object,
7068 Handle<Name> name,
7069 Handle<Object> value,
7070 LanguageMode language_mode,
7071 StoreFromKeyed store_mode) {
7072 LookupIterator it =
7073 LookupIterator::PropertyOrElement(name->GetIsolate(), object, name);
7074 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode));
7075 return value;
7076}
7077
Ben Murdoch097c5b22016-05-18 11:27:45 +01007078MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> receiver,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007079 Handle<Name> name,
Ben Murdoch097c5b22016-05-18 11:27:45 +01007080 Handle<JSReceiver> holder) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007081 LookupIterator it = LookupIterator::PropertyOrElement(
7082 name->GetIsolate(), receiver, name, holder);
Ben Murdoch097c5b22016-05-18 11:27:45 +01007083 return GetProperty(&it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007084}
7085
7086
7087void JSReceiver::initialize_properties() {
7088 DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
7089 DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_properties_dictionary()));
7090 if (map()->is_dictionary_map()) {
7091 WRITE_FIELD(this, kPropertiesOffset,
7092 GetHeap()->empty_properties_dictionary());
7093 } else {
7094 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
7095 }
7096}
7097
7098
7099bool JSReceiver::HasFastProperties() {
7100 DCHECK(properties()->IsDictionary() == map()->is_dictionary_map());
7101 return !properties()->IsDictionary();
7102}
7103
7104
7105NameDictionary* JSReceiver::property_dictionary() {
7106 DCHECK(!HasFastProperties());
7107 DCHECK(!IsJSGlobalObject());
7108 return NameDictionary::cast(properties());
7109}
7110
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007111Maybe<bool> JSReceiver::HasProperty(Handle<JSReceiver> object,
7112 Handle<Name> name) {
Ben Murdochda12d292016-06-02 14:46:10 +01007113 LookupIterator it = LookupIterator::PropertyOrElement(object->GetIsolate(),
7114 object, name, object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007115 return HasProperty(&it);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007116}
7117
7118
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007119Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object,
7120 Handle<Name> name) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007121 if (object->IsJSObject()) { // Shortcut
7122 LookupIterator it = LookupIterator::PropertyOrElement(
Ben Murdochda12d292016-06-02 14:46:10 +01007123 object->GetIsolate(), object, name, object, LookupIterator::HIDDEN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007124 return HasProperty(&it);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007125 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007126
7127 Maybe<PropertyAttributes> attributes =
7128 JSReceiver::GetOwnPropertyAttributes(object, name);
7129 MAYBE_RETURN(attributes, Nothing<bool>());
7130 return Just(attributes.FromJust() != ABSENT);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007131}
7132
7133
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007134Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007135 Handle<JSReceiver> object, Handle<Name> name) {
Ben Murdochda12d292016-06-02 14:46:10 +01007136 LookupIterator it = LookupIterator::PropertyOrElement(name->GetIsolate(),
7137 object, name, object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007138 return GetPropertyAttributes(&it);
Steve Blockd0582a62009-12-15 09:54:21 +00007139}
7140
7141
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007142Maybe<PropertyAttributes> JSReceiver::GetOwnPropertyAttributes(
7143 Handle<JSReceiver> object, Handle<Name> name) {
7144 LookupIterator it = LookupIterator::PropertyOrElement(
Ben Murdochda12d292016-06-02 14:46:10 +01007145 name->GetIsolate(), object, name, object, LookupIterator::HIDDEN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007146 return GetPropertyAttributes(&it);
7147}
7148
7149
7150Maybe<bool> JSReceiver::HasElement(Handle<JSReceiver> object, uint32_t index) {
Ben Murdochda12d292016-06-02 14:46:10 +01007151 LookupIterator it(object->GetIsolate(), object, index, object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007152 return HasProperty(&it);
7153}
7154
7155
7156Maybe<PropertyAttributes> JSReceiver::GetElementAttributes(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007157 Handle<JSReceiver> object, uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007158 Isolate* isolate = object->GetIsolate();
Ben Murdochda12d292016-06-02 14:46:10 +01007159 LookupIterator it(isolate, object, index, object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007160 return GetPropertyAttributes(&it);
7161}
7162
7163
7164Maybe<PropertyAttributes> JSReceiver::GetOwnElementAttributes(
7165 Handle<JSReceiver> object, uint32_t index) {
7166 Isolate* isolate = object->GetIsolate();
Ben Murdochda12d292016-06-02 14:46:10 +01007167 LookupIterator it(isolate, object, index, object, LookupIterator::HIDDEN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007168 return GetPropertyAttributes(&it);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007169}
7170
7171
7172bool JSGlobalObject::IsDetached() {
7173 return JSGlobalProxy::cast(global_proxy())->IsDetachedFrom(this);
7174}
7175
7176
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007177bool JSGlobalProxy::IsDetachedFrom(JSGlobalObject* global) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007178 const PrototypeIterator iter(this->GetIsolate(),
7179 const_cast<JSGlobalProxy*>(this));
7180 return iter.GetCurrent() != global;
7181}
7182
7183
7184Handle<Smi> JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver> object) {
7185 return object->IsJSProxy()
7186 ? JSProxy::GetOrCreateIdentityHash(Handle<JSProxy>::cast(object))
7187 : JSObject::GetOrCreateIdentityHash(Handle<JSObject>::cast(object));
7188}
7189
Ben Murdochda12d292016-06-02 14:46:10 +01007190Handle<Object> JSReceiver::GetIdentityHash(Isolate* isolate,
7191 Handle<JSReceiver> receiver) {
7192 return receiver->IsJSProxy() ? JSProxy::GetIdentityHash(
7193 isolate, Handle<JSProxy>::cast(receiver))
7194 : JSObject::GetIdentityHash(
7195 isolate, Handle<JSObject>::cast(receiver));
Steve Blockd0582a62009-12-15 09:54:21 +00007196}
7197
7198
Steve Blocka7e24c12009-10-30 11:49:00 +00007199bool AccessorInfo::all_can_read() {
7200 return BooleanBit::get(flag(), kAllCanReadBit);
7201}
7202
7203
7204void AccessorInfo::set_all_can_read(bool value) {
7205 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
7206}
7207
7208
7209bool AccessorInfo::all_can_write() {
7210 return BooleanBit::get(flag(), kAllCanWriteBit);
7211}
7212
7213
7214void AccessorInfo::set_all_can_write(bool value) {
7215 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
7216}
7217
7218
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007219bool AccessorInfo::is_special_data_property() {
7220 return BooleanBit::get(flag(), kSpecialDataProperty);
7221}
7222
7223
7224void AccessorInfo::set_is_special_data_property(bool value) {
7225 set_flag(BooleanBit::set(flag(), kSpecialDataProperty, value));
7226}
7227
Ben Murdochda12d292016-06-02 14:46:10 +01007228bool AccessorInfo::is_sloppy() { return BooleanBit::get(flag(), kIsSloppy); }
7229
7230void AccessorInfo::set_is_sloppy(bool value) {
7231 set_flag(BooleanBit::set(flag(), kIsSloppy, value));
7232}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007233
Steve Blocka7e24c12009-10-30 11:49:00 +00007234PropertyAttributes AccessorInfo::property_attributes() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007235 return AttributesField::decode(static_cast<uint32_t>(flag()));
Steve Blocka7e24c12009-10-30 11:49:00 +00007236}
7237
7238
7239void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007240 set_flag(AttributesField::update(flag(), attributes));
Steve Blocka7e24c12009-10-30 11:49:00 +00007241}
7242
Ben Murdoch8b112d22011-06-08 16:22:53 +01007243
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007244bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
7245 if (!HasExpectedReceiverType()) return true;
7246 if (!receiver->IsJSObject()) return false;
7247 return FunctionTemplateInfo::cast(expected_receiver_type())
7248 ->IsTemplateFor(JSObject::cast(receiver)->map());
7249}
7250
7251
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007252bool AccessorInfo::HasExpectedReceiverType() {
7253 return expected_receiver_type()->IsFunctionTemplateInfo();
7254}
7255
7256
7257Object* AccessorPair::get(AccessorComponent component) {
7258 return component == ACCESSOR_GETTER ? getter() : setter();
7259}
7260
7261
7262void AccessorPair::set(AccessorComponent component, Object* value) {
7263 if (component == ACCESSOR_GETTER) {
7264 set_getter(value);
7265 } else {
7266 set_setter(value);
7267 }
7268}
7269
7270
7271void AccessorPair::SetComponents(Object* getter, Object* setter) {
7272 if (!getter->IsNull()) set_getter(getter);
7273 if (!setter->IsNull()) set_setter(setter);
7274}
7275
7276
7277bool AccessorPair::Equals(AccessorPair* pair) {
7278 return (this == pair) || pair->Equals(getter(), setter());
7279}
7280
7281
7282bool AccessorPair::Equals(Object* getter_value, Object* setter_value) {
7283 return (getter() == getter_value) && (setter() == setter_value);
7284}
7285
7286
7287bool AccessorPair::ContainsAccessor() {
7288 return IsJSAccessor(getter()) || IsJSAccessor(setter());
7289}
7290
7291
7292bool AccessorPair::IsJSAccessor(Object* obj) {
7293 return obj->IsCallable() || obj->IsUndefined();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007294}
7295
7296
7297template<typename Derived, typename Shape, typename Key>
7298void Dictionary<Derived, Shape, Key>::SetEntry(int entry,
7299 Handle<Object> key,
7300 Handle<Object> value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007301 this->SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
Ben Murdoch8b112d22011-06-08 16:22:53 +01007302}
7303
7304
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007305template<typename Derived, typename Shape, typename Key>
7306void Dictionary<Derived, Shape, Key>::SetEntry(int entry,
7307 Handle<Object> key,
7308 Handle<Object> value,
7309 PropertyDetails details) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007310 Shape::SetEntry(static_cast<Derived*>(this), entry, key, value, details);
7311}
7312
7313
7314template <typename Key>
7315template <typename Dictionary>
7316void BaseDictionaryShape<Key>::SetEntry(Dictionary* dict, int entry,
7317 Handle<Object> key,
7318 Handle<Object> value,
7319 PropertyDetails details) {
7320 STATIC_ASSERT(Dictionary::kEntrySize == 3);
7321 DCHECK(!key->IsName() || details.dictionary_index() > 0);
7322 int index = dict->EntryToIndex(entry);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007323 DisallowHeapAllocation no_gc;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007324 WriteBarrierMode mode = dict->GetWriteBarrierMode(no_gc);
7325 dict->set(index, *key, mode);
7326 dict->set(index + 1, *value, mode);
7327 dict->set(index + 2, details.AsSmi());
7328}
7329
7330
7331template <typename Dictionary>
7332void GlobalDictionaryShape::SetEntry(Dictionary* dict, int entry,
7333 Handle<Object> key, Handle<Object> value,
7334 PropertyDetails details) {
7335 STATIC_ASSERT(Dictionary::kEntrySize == 2);
7336 DCHECK(!key->IsName() || details.dictionary_index() > 0);
7337 DCHECK(value->IsPropertyCell());
7338 int index = dict->EntryToIndex(entry);
7339 DisallowHeapAllocation no_gc;
7340 WriteBarrierMode mode = dict->GetWriteBarrierMode(no_gc);
7341 dict->set(index, *key, mode);
7342 dict->set(index + 1, *value, mode);
7343 PropertyCell::cast(*value)->set_property_details(details);
Steve Blocka7e24c12009-10-30 11:49:00 +00007344}
7345
7346
Steve Block44f0eee2011-05-26 01:26:41 +01007347bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007348 DCHECK(other->IsNumber());
Steve Block44f0eee2011-05-26 01:26:41 +01007349 return key == static_cast<uint32_t>(other->Number());
7350}
7351
7352
Ben Murdochc7cc0282012-03-05 14:35:55 +00007353uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
7354 return ComputeIntegerHash(key, 0);
Steve Block44f0eee2011-05-26 01:26:41 +01007355}
7356
7357
Ben Murdochc7cc0282012-03-05 14:35:55 +00007358uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
7359 Object* other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007360 DCHECK(other->IsNumber());
Ben Murdochc7cc0282012-03-05 14:35:55 +00007361 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
Steve Block44f0eee2011-05-26 01:26:41 +01007362}
7363
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007364
Ben Murdochc7cc0282012-03-05 14:35:55 +00007365uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
7366 return ComputeIntegerHash(key, seed);
7367}
7368
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007369
Ben Murdochc7cc0282012-03-05 14:35:55 +00007370uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
7371 uint32_t seed,
7372 Object* other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007373 DCHECK(other->IsNumber());
Ben Murdochc7cc0282012-03-05 14:35:55 +00007374 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
7375}
Steve Block44f0eee2011-05-26 01:26:41 +01007376
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007377
7378Handle<Object> NumberDictionaryShape::AsHandle(Isolate* isolate, uint32_t key) {
7379 return isolate->factory()->NewNumberFromUint(key);
Steve Block44f0eee2011-05-26 01:26:41 +01007380}
7381
7382
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007383bool NameDictionaryShape::IsMatch(Handle<Name> key, Object* other) {
Steve Block44f0eee2011-05-26 01:26:41 +01007384 // We know that all entries in a hash table had their hash keys created.
7385 // Use that knowledge to have fast failure.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007386 if (key->Hash() != Name::cast(other)->Hash()) return false;
7387 return key->Equals(Name::cast(other));
Steve Block44f0eee2011-05-26 01:26:41 +01007388}
7389
7390
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007391uint32_t NameDictionaryShape::Hash(Handle<Name> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01007392 return key->Hash();
7393}
7394
7395
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007396uint32_t NameDictionaryShape::HashForObject(Handle<Name> key, Object* other) {
7397 return Name::cast(other)->Hash();
Steve Block44f0eee2011-05-26 01:26:41 +01007398}
7399
7400
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007401Handle<Object> NameDictionaryShape::AsHandle(Isolate* isolate,
7402 Handle<Name> key) {
7403 DCHECK(key->IsUniqueName());
Steve Block44f0eee2011-05-26 01:26:41 +01007404 return key;
7405}
7406
7407
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007408Handle<FixedArray> NameDictionary::DoGenerateNewEnumerationIndices(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007409 Handle<NameDictionary> dictionary) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007410 return DerivedDictionary::GenerateNewEnumerationIndices(dictionary);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007411}
7412
7413
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007414template <typename Dictionary>
7415PropertyDetails GlobalDictionaryShape::DetailsAt(Dictionary* dict, int entry) {
7416 DCHECK(entry >= 0); // Not found is -1, which is not caught by get().
7417 Object* raw_value = dict->ValueAt(entry);
7418 DCHECK(raw_value->IsPropertyCell());
7419 PropertyCell* cell = PropertyCell::cast(raw_value);
7420 return cell->property_details();
7421}
7422
7423
7424template <typename Dictionary>
7425void GlobalDictionaryShape::DetailsAtPut(Dictionary* dict, int entry,
7426 PropertyDetails value) {
7427 DCHECK(entry >= 0); // Not found is -1, which is not caught by get().
7428 Object* raw_value = dict->ValueAt(entry);
7429 DCHECK(raw_value->IsPropertyCell());
7430 PropertyCell* cell = PropertyCell::cast(raw_value);
7431 cell->set_property_details(value);
7432}
7433
7434
7435template <typename Dictionary>
7436bool GlobalDictionaryShape::IsDeleted(Dictionary* dict, int entry) {
7437 DCHECK(dict->ValueAt(entry)->IsPropertyCell());
7438 return PropertyCell::cast(dict->ValueAt(entry))->value()->IsTheHole();
7439}
7440
7441
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007442bool ObjectHashTableShape::IsMatch(Handle<Object> key, Object* other) {
7443 return key->SameValue(other);
7444}
7445
7446
7447uint32_t ObjectHashTableShape::Hash(Handle<Object> key) {
7448 return Smi::cast(key->GetHash())->value();
7449}
7450
7451
7452uint32_t ObjectHashTableShape::HashForObject(Handle<Object> key,
7453 Object* other) {
7454 return Smi::cast(other->GetHash())->value();
7455}
7456
7457
7458Handle<Object> ObjectHashTableShape::AsHandle(Isolate* isolate,
7459 Handle<Object> key) {
7460 return key;
7461}
7462
7463
7464Handle<ObjectHashTable> ObjectHashTable::Shrink(
7465 Handle<ObjectHashTable> table, Handle<Object> key) {
7466 return DerivedHashTable::Shrink(table, key);
7467}
7468
7469
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007470Object* OrderedHashMap::ValueAt(int entry) {
7471 return get(EntryToIndex(entry) + kValueOffset);
7472}
7473
7474
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007475template <int entrysize>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007476bool WeakHashTableShape<entrysize>::IsMatch(Handle<Object> key, Object* other) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007477 if (other->IsWeakCell()) other = WeakCell::cast(other)->value();
7478 return key->IsWeakCell() ? WeakCell::cast(*key)->value() == other
7479 : *key == other;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007480}
7481
7482
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007483template <int entrysize>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007484uint32_t WeakHashTableShape<entrysize>::Hash(Handle<Object> key) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007485 intptr_t hash =
7486 key->IsWeakCell()
7487 ? reinterpret_cast<intptr_t>(WeakCell::cast(*key)->value())
7488 : reinterpret_cast<intptr_t>(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007489 return (uint32_t)(hash & 0xFFFFFFFF);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007490}
7491
7492
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007493template <int entrysize>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007494uint32_t WeakHashTableShape<entrysize>::HashForObject(Handle<Object> key,
7495 Object* other) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007496 if (other->IsWeakCell()) other = WeakCell::cast(other)->value();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007497 intptr_t hash = reinterpret_cast<intptr_t>(other);
7498 return (uint32_t)(hash & 0xFFFFFFFF);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007499}
7500
7501
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007502template <int entrysize>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007503Handle<Object> WeakHashTableShape<entrysize>::AsHandle(Isolate* isolate,
7504 Handle<Object> key) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007505 return key;
7506}
7507
7508
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007509bool ScopeInfo::IsAsmModule() { return AsmModuleField::decode(Flags()); }
7510
7511
7512bool ScopeInfo::IsAsmFunction() { return AsmFunctionField::decode(Flags()); }
7513
7514
7515bool ScopeInfo::HasSimpleParameters() {
7516 return HasSimpleParametersField::decode(Flags());
7517}
7518
7519
7520#define SCOPE_INFO_FIELD_ACCESSORS(name) \
7521 void ScopeInfo::Set##name(int value) { set(k##name, Smi::FromInt(value)); } \
7522 int ScopeInfo::name() { \
7523 if (length() > 0) { \
7524 return Smi::cast(get(k##name))->value(); \
7525 } else { \
7526 return 0; \
7527 } \
7528 }
7529FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(SCOPE_INFO_FIELD_ACCESSORS)
7530#undef SCOPE_INFO_FIELD_ACCESSORS
7531
7532
Steve Block44f0eee2011-05-26 01:26:41 +01007533void Map::ClearCodeCache(Heap* heap) {
Steve Blocka7e24c12009-10-30 11:49:00 +00007534 // No write barrier is needed since empty_fixed_array is not in new space.
7535 // Please note this function is used during marking:
7536 // - MarkCompactCollector::MarkUnmarkedObject
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007537 // - IncrementalMarking::Step
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007538 DCHECK(!heap->InNewSpace(heap->empty_fixed_array()));
7539 WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array());
Steve Blocka7e24c12009-10-30 11:49:00 +00007540}
7541
7542
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007543int Map::SlackForArraySize(int old_size, int size_limit) {
7544 const int max_slack = size_limit - old_size;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007545 CHECK_LE(0, max_slack);
7546 if (old_size < 4) {
7547 DCHECK_LE(1, max_slack);
7548 return 1;
Steve Blockd0582a62009-12-15 09:54:21 +00007549 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007550 return Min(max_slack, old_size / 4);
Steve Blocka7e24c12009-10-30 11:49:00 +00007551}
7552
7553
Leon Clarke4515c472010-02-03 11:58:03 +00007554void JSArray::set_length(Smi* length) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007555 // Don't need a write barrier for a Smi.
Leon Clarke4515c472010-02-03 11:58:03 +00007556 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
7557}
7558
7559
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007560bool JSArray::SetLengthWouldNormalize(Heap* heap, uint32_t new_length) {
7561 // If the new array won't fit in a some non-trivial fraction of the max old
7562 // space size, then force it to go dictionary mode.
7563 uint32_t max_fast_array_size =
7564 static_cast<uint32_t>((heap->MaxOldGenerationSize() / kDoubleSize) / 4);
7565 return new_length >= max_fast_array_size;
7566}
7567
7568
7569bool JSArray::AllowsSetLength() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007570 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007571 DCHECK(result == !HasFixedTypedArrayElements());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007572 return result;
7573}
7574
7575
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007576void JSArray::SetContent(Handle<JSArray> array,
7577 Handle<FixedArrayBase> storage) {
7578 EnsureCanContainElements(array, storage, storage->length(),
7579 ALLOW_COPIED_DOUBLE_ELEMENTS);
7580
7581 DCHECK((storage->map() == array->GetHeap()->fixed_double_array_map() &&
7582 IsFastDoubleElementsKind(array->GetElementsKind())) ||
7583 ((storage->map() != array->GetHeap()->fixed_double_array_map()) &&
7584 (IsFastObjectElementsKind(array->GetElementsKind()) ||
7585 (IsFastSmiElementsKind(array->GetElementsKind()) &&
7586 Handle<FixedArray>::cast(storage)->ContainsOnlySmisOrHoles()))));
7587 array->set_elements(*storage);
7588 array->set_length(Smi::FromInt(storage->length()));
Steve Blocka7e24c12009-10-30 11:49:00 +00007589}
7590
7591
Ben Murdochda12d292016-06-02 14:46:10 +01007592bool JSArray::HasArrayPrototype(Isolate* isolate) {
7593 return map()->prototype() == *isolate->initial_array_prototype();
7594}
7595
7596
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007597int TypeFeedbackInfo::ic_total_count() {
7598 int current = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7599 return ICTotalCountField::decode(current);
Steve Block44f0eee2011-05-26 01:26:41 +01007600}
7601
7602
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007603void TypeFeedbackInfo::set_ic_total_count(int count) {
7604 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7605 value = ICTotalCountField::update(value,
7606 ICTotalCountField::decode(count));
7607 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007608}
7609
7610
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007611int TypeFeedbackInfo::ic_with_type_info_count() {
7612 int current = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7613 return ICsWithTypeInfoCountField::decode(current);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007614}
7615
7616
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007617void TypeFeedbackInfo::change_ic_with_type_info_count(int delta) {
7618 if (delta == 0) return;
7619 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7620 int new_count = ICsWithTypeInfoCountField::decode(value) + delta;
7621 // We can get negative count here when the type-feedback info is
7622 // shared between two code objects. The can only happen when
7623 // the debugger made a shallow copy of code object (see Heap::CopyCode).
7624 // Since we do not optimize when the debugger is active, we can skip
7625 // this counter update.
7626 if (new_count >= 0) {
7627 new_count &= ICsWithTypeInfoCountField::kMask;
7628 value = ICsWithTypeInfoCountField::update(value, new_count);
7629 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
7630 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007631}
7632
7633
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007634int TypeFeedbackInfo::ic_generic_count() {
7635 return Smi::cast(READ_FIELD(this, kStorage3Offset))->value();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007636}
7637
7638
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007639void TypeFeedbackInfo::change_ic_generic_count(int delta) {
7640 if (delta == 0) return;
7641 int new_count = ic_generic_count() + delta;
7642 if (new_count >= 0) {
7643 new_count &= ~Smi::kMinValue;
7644 WRITE_FIELD(this, kStorage3Offset, Smi::FromInt(new_count));
7645 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007646}
7647
7648
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007649void TypeFeedbackInfo::initialize_storage() {
7650 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(0));
7651 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(0));
7652 WRITE_FIELD(this, kStorage3Offset, Smi::FromInt(0));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007653}
7654
7655
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007656void TypeFeedbackInfo::change_own_type_change_checksum() {
7657 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7658 int checksum = OwnTypeChangeChecksum::decode(value);
7659 checksum = (checksum + 1) % (1 << kTypeChangeChecksumBits);
7660 value = OwnTypeChangeChecksum::update(value, checksum);
7661 // Ensure packed bit field is in Smi range.
7662 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
7663 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
7664 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007665}
7666
7667
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007668void TypeFeedbackInfo::set_inlined_type_change_checksum(int checksum) {
7669 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7670 int mask = (1 << kTypeChangeChecksumBits) - 1;
7671 value = InlinedTypeChangeChecksum::update(value, checksum & mask);
7672 // Ensure packed bit field is in Smi range.
7673 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
7674 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
7675 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007676}
7677
7678
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007679int TypeFeedbackInfo::own_type_change_checksum() {
7680 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7681 return OwnTypeChangeChecksum::decode(value);
7682}
7683
7684
7685bool TypeFeedbackInfo::matches_inlined_type_change_checksum(int checksum) {
7686 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7687 int mask = (1 << kTypeChangeChecksumBits) - 1;
7688 return InlinedTypeChangeChecksum::decode(value) == (checksum & mask);
7689}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007690
7691
7692SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
7693
7694
Steve Block44f0eee2011-05-26 01:26:41 +01007695Relocatable::Relocatable(Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +01007696 isolate_ = isolate;
7697 prev_ = isolate->relocatable_top();
7698 isolate->set_relocatable_top(this);
7699}
7700
7701
7702Relocatable::~Relocatable() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007703 DCHECK_EQ(isolate_->relocatable_top(), this);
Steve Block44f0eee2011-05-26 01:26:41 +01007704 isolate_->set_relocatable_top(prev_);
Steve Blocka7e24c12009-10-30 11:49:00 +00007705}
7706
7707
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007708template<class Derived, class TableType>
7709Object* OrderedHashTableIterator<Derived, TableType>::CurrentKey() {
7710 TableType* table(TableType::cast(this->table()));
7711 int index = Smi::cast(this->index())->value();
7712 Object* key = table->KeyAt(index);
7713 DCHECK(!key->IsTheHole());
7714 return key;
7715}
7716
7717
7718void JSSetIterator::PopulateValueArray(FixedArray* array) {
7719 array->set(0, CurrentKey());
7720}
7721
7722
7723void JSMapIterator::PopulateValueArray(FixedArray* array) {
7724 array->set(0, CurrentKey());
7725 array->set(1, CurrentValue());
7726}
7727
7728
7729Object* JSMapIterator::CurrentValue() {
7730 OrderedHashMap* table(OrderedHashMap::cast(this->table()));
7731 int index = Smi::cast(this->index())->value();
7732 Object* value = table->ValueAt(index);
7733 DCHECK(!value->IsTheHole());
7734 return value;
7735}
7736
Iain Merrick75681382010-08-19 15:07:18 +01007737
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007738String::SubStringRange::SubStringRange(String* string, int first, int length)
7739 : string_(string),
7740 first_(first),
7741 length_(length == -1 ? string->length() : length) {}
7742
7743
7744class String::SubStringRange::iterator final {
7745 public:
7746 typedef std::forward_iterator_tag iterator_category;
7747 typedef int difference_type;
7748 typedef uc16 value_type;
7749 typedef uc16* pointer;
7750 typedef uc16& reference;
7751
7752 iterator(const iterator& other)
7753 : content_(other.content_), offset_(other.offset_) {}
7754
7755 uc16 operator*() { return content_.Get(offset_); }
7756 bool operator==(const iterator& other) const {
7757 return content_.UsesSameString(other.content_) && offset_ == other.offset_;
7758 }
7759 bool operator!=(const iterator& other) const {
7760 return !content_.UsesSameString(other.content_) || offset_ != other.offset_;
7761 }
7762 iterator& operator++() {
7763 ++offset_;
7764 return *this;
7765 }
7766 iterator operator++(int);
7767
7768 private:
7769 friend class String;
7770 iterator(String* from, int offset)
7771 : content_(from->GetFlatContent()), offset_(offset) {}
7772 String::FlatContent content_;
7773 int offset_;
7774};
7775
7776
7777String::SubStringRange::iterator String::SubStringRange::begin() {
7778 return String::SubStringRange::iterator(string_, first_);
7779}
7780
7781
7782String::SubStringRange::iterator String::SubStringRange::end() {
7783 return String::SubStringRange::iterator(string_, first_ + length_);
7784}
7785
7786
7787// Predictably converts HeapObject* or Address to uint32 by calculating
7788// offset of the address in respective MemoryChunk.
7789static inline uint32_t ObjectAddressForHashing(void* object) {
7790 uint32_t value = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(object));
7791 return value & MemoryChunk::kAlignmentMask;
7792}
7793
Ben Murdochda12d292016-06-02 14:46:10 +01007794static inline Handle<Object> MakeEntryPair(Isolate* isolate, uint32_t index,
7795 Handle<Object> value) {
7796 Handle<Object> key = isolate->factory()->Uint32ToString(index);
7797 Handle<FixedArray> entry_storage =
7798 isolate->factory()->NewUninitializedFixedArray(2);
7799 {
7800 entry_storage->set(0, *key, SKIP_WRITE_BARRIER);
7801 entry_storage->set(1, *value, SKIP_WRITE_BARRIER);
7802 }
7803 return isolate->factory()->NewJSArrayWithElements(entry_storage,
7804 FAST_ELEMENTS, 2);
7805}
7806
7807static inline Handle<Object> MakeEntryPair(Isolate* isolate, Handle<Name> key,
7808 Handle<Object> value) {
7809 Handle<FixedArray> entry_storage =
7810 isolate->factory()->NewUninitializedFixedArray(2);
7811 {
7812 entry_storage->set(0, *key, SKIP_WRITE_BARRIER);
7813 entry_storage->set(1, *value, SKIP_WRITE_BARRIER);
7814 }
7815 return isolate->factory()->NewJSArrayWithElements(entry_storage,
7816 FAST_ELEMENTS, 2);
7817}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007818
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007819#undef TYPE_CHECKER
Steve Blocka7e24c12009-10-30 11:49:00 +00007820#undef CAST_ACCESSOR
7821#undef INT_ACCESSORS
Ben Murdoch85b71792012-04-11 18:30:58 +01007822#undef ACCESSORS
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007823#undef SMI_ACCESSORS
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007824#undef SYNCHRONIZED_SMI_ACCESSORS
7825#undef NOBARRIER_SMI_ACCESSORS
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007826#undef BOOL_GETTER
7827#undef BOOL_ACCESSORS
Steve Blocka7e24c12009-10-30 11:49:00 +00007828#undef FIELD_ADDR
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007829#undef FIELD_ADDR_CONST
Steve Blocka7e24c12009-10-30 11:49:00 +00007830#undef READ_FIELD
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007831#undef NOBARRIER_READ_FIELD
Steve Blocka7e24c12009-10-30 11:49:00 +00007832#undef WRITE_FIELD
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007833#undef NOBARRIER_WRITE_FIELD
Steve Blocka7e24c12009-10-30 11:49:00 +00007834#undef WRITE_BARRIER
7835#undef CONDITIONAL_WRITE_BARRIER
Steve Blocka7e24c12009-10-30 11:49:00 +00007836#undef READ_DOUBLE_FIELD
7837#undef WRITE_DOUBLE_FIELD
7838#undef READ_INT_FIELD
7839#undef WRITE_INT_FIELD
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007840#undef READ_INTPTR_FIELD
7841#undef WRITE_INTPTR_FIELD
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007842#undef READ_UINT8_FIELD
7843#undef WRITE_UINT8_FIELD
7844#undef READ_INT8_FIELD
7845#undef WRITE_INT8_FIELD
7846#undef READ_UINT16_FIELD
7847#undef WRITE_UINT16_FIELD
7848#undef READ_INT16_FIELD
7849#undef WRITE_INT16_FIELD
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007850#undef READ_UINT32_FIELD
7851#undef WRITE_UINT32_FIELD
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007852#undef READ_INT32_FIELD
7853#undef WRITE_INT32_FIELD
7854#undef READ_FLOAT_FIELD
7855#undef WRITE_FLOAT_FIELD
7856#undef READ_UINT64_FIELD
7857#undef WRITE_UINT64_FIELD
7858#undef READ_INT64_FIELD
7859#undef WRITE_INT64_FIELD
Steve Blocka7e24c12009-10-30 11:49:00 +00007860#undef READ_BYTE_FIELD
7861#undef WRITE_BYTE_FIELD
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007862#undef NOBARRIER_READ_BYTE_FIELD
7863#undef NOBARRIER_WRITE_BYTE_FIELD
Steve Blocka7e24c12009-10-30 11:49:00 +00007864
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007865} // namespace internal
7866} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +00007867
7868#endif // V8_OBJECTS_INL_H_