blob: e00478a6afaf01e2b5f6a68244c701a1859d6f64 [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"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040025#include "src/layout-descriptor-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000026#include "src/lookup.h"
27#include "src/objects.h"
28#include "src/property.h"
29#include "src/prototype.h"
30#include "src/transitions-inl.h"
31#include "src/type-feedback-vector-inl.h"
32#include "src/v8memory.h"
Ben Murdoch592a9fc2012-03-05 11:04:45 +000033
Steve Blocka7e24c12009-10-30 11:49:00 +000034namespace v8 {
35namespace internal {
36
37PropertyDetails::PropertyDetails(Smi* smi) {
38 value_ = smi->value();
39}
40
41
Ben Murdochb8a8cc12014-11-26 15:28:44 +000042Smi* PropertyDetails::AsSmi() const {
43 // Ensure the upper 2 bits have the same value by sign extending it. This is
44 // necessary to be able to use the 31st bit of the property details.
45 int value = value_ << 1;
46 return Smi::FromInt(value >> 1);
Steve Blocka7e24c12009-10-30 11:49:00 +000047}
48
49
Emily Bernierd0a1eb72015-03-24 16:35:39 -040050int PropertyDetails::field_width_in_words() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000051 DCHECK(location() == kField);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040052 if (!FLAG_unbox_double_fields) return 1;
53 if (kDoubleSize == kPointerSize) return 1;
54 return representation().IsDouble() ? kDoubleSize / kPointerSize : 1;
55}
56
Ben Murdoch097c5b22016-05-18 11:27:45 +010057#define TYPE_CHECKER(type, instancetype) \
58 bool HeapObject::Is##type() const { \
59 return map()->instance_type() == instancetype; \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010060 }
61
Ben Murdochb8a8cc12014-11-26 15:28:44 +000062#define CAST_ACCESSOR(type) \
63 type* type::cast(Object* object) { \
64 SLOW_DCHECK(object->Is##type()); \
65 return reinterpret_cast<type*>(object); \
66 } \
67 const type* type::cast(const Object* object) { \
68 SLOW_DCHECK(object->Is##type()); \
69 return reinterpret_cast<const type*>(object); \
Steve Blocka7e24c12009-10-30 11:49:00 +000070 }
71
72
Ben Murdochb8a8cc12014-11-26 15:28:44 +000073#define INT_ACCESSORS(holder, name, offset) \
74 int holder::name() const { return READ_INT_FIELD(this, offset); } \
Steve Blocka7e24c12009-10-30 11:49:00 +000075 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
76
77
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078#define ACCESSORS(holder, name, type, offset) \
79 type* holder::name() const { return type::cast(READ_FIELD(this, offset)); } \
80 void holder::set_##name(type* value, WriteBarrierMode mode) { \
81 WRITE_FIELD(this, offset, value); \
82 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
Steve Blocka7e24c12009-10-30 11:49:00 +000083 }
84
85
Ben Murdoch3ef787d2012-04-12 10:51:47 +010086// Getter that returns a Smi as an int and writes an int as a Smi.
Steve Blocka7e24c12009-10-30 11:49:00 +000087#define SMI_ACCESSORS(holder, name, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000088 int holder::name() const { \
Steve Blocka7e24c12009-10-30 11:49:00 +000089 Object* value = READ_FIELD(this, offset); \
90 return Smi::cast(value)->value(); \
91 } \
92 void holder::set_##name(int value) { \
93 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
94 }
95
Ben Murdochb8a8cc12014-11-26 15:28:44 +000096#define SYNCHRONIZED_SMI_ACCESSORS(holder, name, offset) \
97 int holder::synchronized_##name() const { \
98 Object* value = ACQUIRE_READ_FIELD(this, offset); \
99 return Smi::cast(value)->value(); \
100 } \
101 void holder::synchronized_set_##name(int value) { \
102 RELEASE_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
103 }
104
105#define NOBARRIER_SMI_ACCESSORS(holder, name, offset) \
106 int holder::nobarrier_##name() const { \
107 Object* value = NOBARRIER_READ_FIELD(this, offset); \
108 return Smi::cast(value)->value(); \
109 } \
110 void holder::nobarrier_set_##name(int value) { \
111 NOBARRIER_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
112 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000113
114#define BOOL_GETTER(holder, field, name, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115 bool holder::name() const { \
Steve Blocka7e24c12009-10-30 11:49:00 +0000116 return BooleanBit::get(field(), offset); \
117 } \
118
119
120#define BOOL_ACCESSORS(holder, field, name, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000121 bool holder::name() const { \
Steve Blocka7e24c12009-10-30 11:49:00 +0000122 return BooleanBit::get(field(), offset); \
123 } \
124 void holder::set_##name(bool value) { \
125 set_##field(BooleanBit::set(field(), offset, value)); \
126 }
127
Ben Murdoch097c5b22016-05-18 11:27:45 +0100128bool HeapObject::IsFixedArrayBase() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000129 return IsFixedArray() || IsFixedDoubleArray() || IsFixedTypedArrayBase();
130}
131
Ben Murdoch097c5b22016-05-18 11:27:45 +0100132bool HeapObject::IsFixedArray() const {
133 InstanceType instance_type = map()->instance_type();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134 return instance_type == FIXED_ARRAY_TYPE ||
135 instance_type == TRANSITION_ARRAY_TYPE;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100136}
137
138
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000139// External objects are not extensible, so the map check is enough.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100140bool HeapObject::IsExternal() const {
141 return map() == GetHeap()->external_map();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100142}
143
144
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100145TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000146TYPE_CHECKER(MutableHeapNumber, MUTABLE_HEAP_NUMBER_TYPE)
147TYPE_CHECKER(Symbol, SYMBOL_TYPE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000148TYPE_CHECKER(Simd128Value, SIMD128_VALUE_TYPE)
149
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000150#define SIMD128_TYPE_CHECKER(TYPE, Type, type, lane_count, lane_type) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100151 bool HeapObject::Is##Type() const { return map() == GetHeap()->type##_map(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000152SIMD128_TYPES(SIMD128_TYPE_CHECKER)
153#undef SIMD128_TYPE_CHECKER
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100154
Ben Murdoch097c5b22016-05-18 11:27:45 +0100155#define IS_TYPE_FUNCTION_DEF(type_) \
156 bool Object::Is##type_() const { \
157 return IsHeapObject() && HeapObject::cast(this)->Is##type_(); \
158 }
159HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DEF)
160ODDBALL_LIST(IS_TYPE_FUNCTION_DEF)
161#undef IS_TYPE_FUNCTION_DEF
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100162
Ben Murdoch097c5b22016-05-18 11:27:45 +0100163bool HeapObject::IsString() const {
164 return map()->instance_type() < FIRST_NONSTRING_TYPE;
Steve Blocka7e24c12009-10-30 11:49:00 +0000165}
166
Ben Murdoch097c5b22016-05-18 11:27:45 +0100167bool HeapObject::IsName() const {
168 return map()->instance_type() <= LAST_NAME_TYPE;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000169}
170
Ben Murdoch097c5b22016-05-18 11:27:45 +0100171bool HeapObject::IsUniqueName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172 return IsInternalizedString() || IsSymbol();
173}
174
Ben Murdoch097c5b22016-05-18 11:27:45 +0100175bool Name::IsUniqueName() const {
176 uint32_t type = map()->instance_type();
177 return (type & (kIsNotStringMask | kIsNotInternalizedMask)) !=
178 (kStringTag | kNotInternalizedTag);
179}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180
Ben Murdoch097c5b22016-05-18 11:27:45 +0100181bool HeapObject::IsFunction() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000182 STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100183 return map()->instance_type() >= FIRST_FUNCTION_TYPE;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000184}
185
Ben Murdoch097c5b22016-05-18 11:27:45 +0100186bool HeapObject::IsCallable() const { return map()->is_callable(); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000187
Ben Murdoch097c5b22016-05-18 11:27:45 +0100188bool HeapObject::IsConstructor() const { return map()->is_constructor(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000189
Ben Murdoch097c5b22016-05-18 11:27:45 +0100190bool HeapObject::IsTemplateInfo() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000191 return IsObjectTemplateInfo() || IsFunctionTemplateInfo();
Steve Blocka7e24c12009-10-30 11:49:00 +0000192}
193
Ben Murdoch097c5b22016-05-18 11:27:45 +0100194bool HeapObject::IsInternalizedString() const {
195 uint32_t type = map()->instance_type();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000196 STATIC_ASSERT(kNotInternalizedTag != 0);
197 return (type & (kIsNotStringMask | kIsNotInternalizedMask)) ==
198 (kStringTag | kInternalizedTag);
199}
200
Ben Murdoch097c5b22016-05-18 11:27:45 +0100201bool HeapObject::IsConsString() const {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000202 if (!IsString()) return false;
203 return StringShape(String::cast(this)).IsCons();
204}
205
Ben Murdoch097c5b22016-05-18 11:27:45 +0100206bool HeapObject::IsSlicedString() const {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000207 if (!IsString()) return false;
208 return StringShape(String::cast(this)).IsSliced();
Steve Blocka7e24c12009-10-30 11:49:00 +0000209}
210
Ben Murdoch097c5b22016-05-18 11:27:45 +0100211bool HeapObject::IsSeqString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000212 if (!IsString()) return false;
213 return StringShape(String::cast(this)).IsSequential();
214}
215
Ben Murdoch097c5b22016-05-18 11:27:45 +0100216bool HeapObject::IsSeqOneByteString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000217 if (!IsString()) return false;
218 return StringShape(String::cast(this)).IsSequential() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000219 String::cast(this)->IsOneByteRepresentation();
Steve Blocka7e24c12009-10-30 11:49:00 +0000220}
221
Ben Murdoch097c5b22016-05-18 11:27:45 +0100222bool HeapObject::IsSeqTwoByteString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000223 if (!IsString()) return false;
224 return StringShape(String::cast(this)).IsSequential() &&
225 String::cast(this)->IsTwoByteRepresentation();
226}
227
Ben Murdoch097c5b22016-05-18 11:27:45 +0100228bool HeapObject::IsExternalString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000229 if (!IsString()) return false;
230 return StringShape(String::cast(this)).IsExternal();
231}
232
Ben Murdoch097c5b22016-05-18 11:27:45 +0100233bool HeapObject::IsExternalOneByteString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000234 if (!IsString()) return false;
235 return StringShape(String::cast(this)).IsExternal() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000236 String::cast(this)->IsOneByteRepresentation();
Steve Blocka7e24c12009-10-30 11:49:00 +0000237}
238
Ben Murdoch097c5b22016-05-18 11:27:45 +0100239bool HeapObject::IsExternalTwoByteString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000240 if (!IsString()) return false;
241 return StringShape(String::cast(this)).IsExternal() &&
242 String::cast(this)->IsTwoByteRepresentation();
243}
244
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000245
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000246bool Object::HasValidElements() {
247 // Dictionary is covered under FixedArray.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000248 return IsFixedArray() || IsFixedDoubleArray() || IsFixedTypedArrayBase();
249}
250
251
252bool Object::KeyEquals(Object* second) {
253 Object* first = this;
254 if (second->IsNumber()) {
255 if (first->IsNumber()) return first->Number() == second->Number();
256 Object* temp = first;
257 first = second;
258 second = temp;
259 }
260 if (first->IsNumber()) {
261 DCHECK_LE(0, first->Number());
262 uint32_t expected = static_cast<uint32_t>(first->Number());
263 uint32_t index;
264 return Name::cast(second)->AsArrayIndex(&index) && index == expected;
265 }
266 return Name::cast(first)->Equals(Name::cast(second));
267}
268
269
270bool Object::FilterKey(PropertyFilter filter) {
271 if (IsSymbol()) {
272 if (filter & SKIP_SYMBOLS) return true;
273 if (Symbol::cast(this)->is_private()) return true;
274 } else {
275 if (filter & SKIP_STRINGS) return true;
276 }
277 return false;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000278}
Steve Blocka7e24c12009-10-30 11:49:00 +0000279
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000280
281Handle<Object> Object::NewStorageFor(Isolate* isolate,
282 Handle<Object> object,
283 Representation representation) {
284 if (representation.IsSmi() && object->IsUninitialized()) {
285 return handle(Smi::FromInt(0), isolate);
286 }
287 if (!representation.IsDouble()) return object;
288 double value;
289 if (object->IsUninitialized()) {
290 value = 0;
291 } else if (object->IsMutableHeapNumber()) {
292 value = HeapNumber::cast(*object)->value();
293 } else {
294 value = object->Number();
295 }
296 return isolate->factory()->NewHeapNumber(value, MUTABLE);
297}
298
299
300Handle<Object> Object::WrapForRead(Isolate* isolate,
301 Handle<Object> object,
302 Representation representation) {
303 DCHECK(!object->IsUninitialized());
304 if (!representation.IsDouble()) {
305 DCHECK(object->FitsRepresentation(representation));
306 return object;
307 }
308 return isolate->factory()->NewHeapNumber(HeapNumber::cast(*object)->value());
309}
310
311
312StringShape::StringShape(const String* str)
Steve Blocka7e24c12009-10-30 11:49:00 +0000313 : type_(str->map()->instance_type()) {
314 set_valid();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000315 DCHECK((type_ & kIsNotStringMask) == kStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000316}
317
318
319StringShape::StringShape(Map* map)
320 : type_(map->instance_type()) {
321 set_valid();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000322 DCHECK((type_ & kIsNotStringMask) == kStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000323}
324
325
326StringShape::StringShape(InstanceType t)
327 : type_(static_cast<uint32_t>(t)) {
328 set_valid();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000329 DCHECK((type_ & kIsNotStringMask) == kStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000330}
331
332
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000333bool StringShape::IsInternalized() {
334 DCHECK(valid());
335 STATIC_ASSERT(kNotInternalizedTag != 0);
336 return (type_ & (kIsNotStringMask | kIsNotInternalizedMask)) ==
337 (kStringTag | kInternalizedTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000338}
339
340
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000341bool String::IsOneByteRepresentation() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000342 uint32_t type = map()->instance_type();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000343 return (type & kStringEncodingMask) == kOneByteStringTag;
Steve Blocka7e24c12009-10-30 11:49:00 +0000344}
345
346
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000347bool String::IsTwoByteRepresentation() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000348 uint32_t type = map()->instance_type();
Steve Blocka7e24c12009-10-30 11:49:00 +0000349 return (type & kStringEncodingMask) == kTwoByteStringTag;
350}
351
352
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000353bool String::IsOneByteRepresentationUnderneath() {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000354 uint32_t type = map()->instance_type();
355 STATIC_ASSERT(kIsIndirectStringTag != 0);
356 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000357 DCHECK(IsFlat());
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000358 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000359 case kOneByteStringTag:
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000360 return true;
361 case kTwoByteStringTag:
362 return false;
363 default: // Cons or sliced string. Need to go deeper.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000364 return GetUnderlying()->IsOneByteRepresentation();
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000365 }
366}
367
368
369bool String::IsTwoByteRepresentationUnderneath() {
370 uint32_t type = map()->instance_type();
371 STATIC_ASSERT(kIsIndirectStringTag != 0);
372 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000373 DCHECK(IsFlat());
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000374 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000375 case kOneByteStringTag:
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000376 return false;
377 case kTwoByteStringTag:
378 return true;
379 default: // Cons or sliced string. Need to go deeper.
380 return GetUnderlying()->IsTwoByteRepresentation();
381 }
382}
383
384
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000385bool String::HasOnlyOneByteChars() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100386 uint32_t type = map()->instance_type();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000387 return (type & kOneByteDataHintMask) == kOneByteDataHintTag ||
388 IsOneByteRepresentation();
Steve Block6ded16b2010-05-10 14:33:55 +0100389}
390
391
Steve Blocka7e24c12009-10-30 11:49:00 +0000392bool StringShape::IsCons() {
393 return (type_ & kStringRepresentationMask) == kConsStringTag;
394}
395
396
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000397bool StringShape::IsSliced() {
398 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
399}
400
401
402bool StringShape::IsIndirect() {
403 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
404}
405
406
Steve Blocka7e24c12009-10-30 11:49:00 +0000407bool StringShape::IsExternal() {
408 return (type_ & kStringRepresentationMask) == kExternalStringTag;
409}
410
411
412bool StringShape::IsSequential() {
413 return (type_ & kStringRepresentationMask) == kSeqStringTag;
414}
415
416
417StringRepresentationTag StringShape::representation_tag() {
418 uint32_t tag = (type_ & kStringRepresentationMask);
419 return static_cast<StringRepresentationTag>(tag);
420}
421
422
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000423uint32_t StringShape::encoding_tag() {
424 return type_ & kStringEncodingMask;
425}
426
427
Steve Blocka7e24c12009-10-30 11:49:00 +0000428uint32_t StringShape::full_representation_tag() {
429 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
430}
431
432
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000433STATIC_ASSERT((kStringRepresentationMask | kStringEncodingMask) ==
Steve Blocka7e24c12009-10-30 11:49:00 +0000434 Internals::kFullStringRepresentationMask);
435
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000436STATIC_ASSERT(static_cast<uint32_t>(kStringEncodingMask) ==
437 Internals::kStringEncodingMask);
Steve Blocka7e24c12009-10-30 11:49:00 +0000438
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000439
440bool StringShape::IsSequentialOneByte() {
441 return full_representation_tag() == (kSeqStringTag | kOneByteStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000442}
443
444
445bool StringShape::IsSequentialTwoByte() {
446 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
447}
448
449
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000450bool StringShape::IsExternalOneByte() {
451 return full_representation_tag() == (kExternalStringTag | kOneByteStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000452}
453
454
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000455STATIC_ASSERT((kExternalStringTag | kOneByteStringTag) ==
456 Internals::kExternalOneByteRepresentationTag);
457
458STATIC_ASSERT(v8::String::ONE_BYTE_ENCODING == kOneByteStringTag);
459
460
Steve Blocka7e24c12009-10-30 11:49:00 +0000461bool StringShape::IsExternalTwoByte() {
462 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
463}
464
465
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000466STATIC_ASSERT((kExternalStringTag | kTwoByteStringTag) ==
Steve Blocka7e24c12009-10-30 11:49:00 +0000467 Internals::kExternalTwoByteRepresentationTag);
468
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000469STATIC_ASSERT(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
Steve Blocka7e24c12009-10-30 11:49:00 +0000470
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400471
Steve Blocka7e24c12009-10-30 11:49:00 +0000472uc32 FlatStringReader::Get(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000473 if (is_one_byte_) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400474 return Get<uint8_t>(index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000475 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400476 return Get<uc16>(index);
477 }
478}
479
480
481template <typename Char>
482Char FlatStringReader::Get(int index) {
483 DCHECK_EQ(is_one_byte_, sizeof(Char) == 1);
484 DCHECK(0 <= index && index <= length_);
485 if (sizeof(Char) == 1) {
486 return static_cast<Char>(static_cast<const uint8_t*>(start_)[index]);
487 } else {
488 return static_cast<Char>(static_cast<const uc16*>(start_)[index]);
Steve Blocka7e24c12009-10-30 11:49:00 +0000489 }
490}
491
492
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000493Handle<Object> StringTableShape::AsHandle(Isolate* isolate, HashTableKey* key) {
494 return key->AsHandle(isolate);
495}
496
497
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000498Handle<Object> CompilationCacheShape::AsHandle(Isolate* isolate,
499 HashTableKey* key) {
500 return key->AsHandle(isolate);
501}
502
503
504Handle<Object> CodeCacheHashTableShape::AsHandle(Isolate* isolate,
505 HashTableKey* key) {
506 return key->AsHandle(isolate);
507}
508
509template <typename Char>
510class SequentialStringKey : public HashTableKey {
511 public:
512 explicit SequentialStringKey(Vector<const Char> string, uint32_t seed)
513 : string_(string), hash_field_(0), seed_(seed) { }
514
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000515 uint32_t Hash() override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000516 hash_field_ = StringHasher::HashSequentialString<Char>(string_.start(),
517 string_.length(),
518 seed_);
519
520 uint32_t result = hash_field_ >> String::kHashShift;
521 DCHECK(result != 0); // Ensure that the hash value of 0 is never computed.
522 return result;
523 }
524
525
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000526 uint32_t HashForObject(Object* other) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000527 return String::cast(other)->Hash();
528 }
529
530 Vector<const Char> string_;
531 uint32_t hash_field_;
532 uint32_t seed_;
533};
534
535
536class OneByteStringKey : public SequentialStringKey<uint8_t> {
537 public:
538 OneByteStringKey(Vector<const uint8_t> str, uint32_t seed)
539 : SequentialStringKey<uint8_t>(str, seed) { }
540
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000541 bool IsMatch(Object* string) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000542 return String::cast(string)->IsOneByteEqualTo(string_);
543 }
544
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000545 Handle<Object> AsHandle(Isolate* isolate) override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000546};
547
548
549class SeqOneByteSubStringKey : public HashTableKey {
550 public:
551 SeqOneByteSubStringKey(Handle<SeqOneByteString> string, int from, int length)
552 : string_(string), from_(from), length_(length) {
553 DCHECK(string_->IsSeqOneByteString());
554 }
555
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000556 uint32_t Hash() override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000557 DCHECK(length_ >= 0);
558 DCHECK(from_ + length_ <= string_->length());
559 const uint8_t* chars = string_->GetChars() + from_;
560 hash_field_ = StringHasher::HashSequentialString(
561 chars, length_, string_->GetHeap()->HashSeed());
562 uint32_t result = hash_field_ >> String::kHashShift;
563 DCHECK(result != 0); // Ensure that the hash value of 0 is never computed.
564 return result;
565 }
566
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000567 uint32_t HashForObject(Object* other) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000568 return String::cast(other)->Hash();
569 }
570
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000571 bool IsMatch(Object* string) override;
572 Handle<Object> AsHandle(Isolate* isolate) override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000573
574 private:
575 Handle<SeqOneByteString> string_;
576 int from_;
577 int length_;
578 uint32_t hash_field_;
579};
580
581
582class TwoByteStringKey : public SequentialStringKey<uc16> {
583 public:
584 explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed)
585 : SequentialStringKey<uc16>(str, seed) { }
586
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000587 bool IsMatch(Object* string) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000588 return String::cast(string)->IsTwoByteEqualTo(string_);
589 }
590
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000591 Handle<Object> AsHandle(Isolate* isolate) override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000592};
593
594
595// Utf8StringKey carries a vector of chars as key.
596class Utf8StringKey : public HashTableKey {
597 public:
598 explicit Utf8StringKey(Vector<const char> string, uint32_t seed)
599 : string_(string), hash_field_(0), seed_(seed) { }
600
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000601 bool IsMatch(Object* string) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000602 return String::cast(string)->IsUtf8EqualTo(string_);
603 }
604
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000605 uint32_t Hash() override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000606 if (hash_field_ != 0) return hash_field_ >> String::kHashShift;
607 hash_field_ = StringHasher::ComputeUtf8Hash(string_, seed_, &chars_);
608 uint32_t result = hash_field_ >> String::kHashShift;
609 DCHECK(result != 0); // Ensure that the hash value of 0 is never computed.
610 return result;
611 }
612
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000613 uint32_t HashForObject(Object* other) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000614 return String::cast(other)->Hash();
615 }
616
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000617 Handle<Object> AsHandle(Isolate* isolate) override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000618 if (hash_field_ == 0) Hash();
619 return isolate->factory()->NewInternalizedStringFromUtf8(
620 string_, chars_, hash_field_);
621 }
622
623 Vector<const char> string_;
624 uint32_t hash_field_;
625 int chars_; // Caches the number of characters when computing the hash code.
626 uint32_t seed_;
627};
628
629
630bool Object::IsNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000631 return IsSmi() || IsHeapNumber();
632}
633
634
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100635TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000636TYPE_CHECKER(BytecodeArray, BYTECODE_ARRAY_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100637TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
638
Ben Murdoch097c5b22016-05-18 11:27:45 +0100639bool HeapObject::IsFiller() const {
640 InstanceType instance_type = map()->instance_type();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100641 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
Steve Blocka7e24c12009-10-30 11:49:00 +0000642}
643
644
Steve Block3ce2e202009-11-05 08:53:23 +0000645
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000646#define TYPED_ARRAY_TYPE_CHECKER(Type, type, TYPE, ctype, size) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000647 TYPE_CHECKER(Fixed##Type##Array, FIXED_##TYPE##_ARRAY_TYPE)
648
649TYPED_ARRAYS(TYPED_ARRAY_TYPE_CHECKER)
650#undef TYPED_ARRAY_TYPE_CHECKER
Ben Murdoch257744e2011-11-30 15:57:28 +0000651
Ben Murdoch097c5b22016-05-18 11:27:45 +0100652bool HeapObject::IsFixedTypedArrayBase() const {
653 InstanceType instance_type = map()->instance_type();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000654 return (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE &&
655 instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000656}
657
Ben Murdoch097c5b22016-05-18 11:27:45 +0100658bool HeapObject::IsJSReceiver() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100659 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100660 return map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000661}
662
Ben Murdoch097c5b22016-05-18 11:27:45 +0100663bool HeapObject::IsJSObject() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100664 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100665 return map()->IsJSObjectMap();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000666}
667
Ben Murdoch097c5b22016-05-18 11:27:45 +0100668bool HeapObject::IsJSProxy() const { return map()->IsJSProxyMap(); }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000669
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100670TYPE_CHECKER(JSSet, JS_SET_TYPE)
671TYPE_CHECKER(JSMap, JS_MAP_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000672TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE)
673TYPE_CHECKER(JSMapIterator, JS_MAP_ITERATOR_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100674TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000675TYPE_CHECKER(JSWeakSet, JS_WEAK_SET_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100676TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
677TYPE_CHECKER(Map, MAP_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100678TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400679TYPE_CHECKER(WeakFixedArray, FIXED_ARRAY_TYPE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000680TYPE_CHECKER(TransitionArray, TRANSITION_ARRAY_TYPE)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000681
Ben Murdoch097c5b22016-05-18 11:27:45 +0100682bool HeapObject::IsJSWeakCollection() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000683 return IsJSWeakMap() || IsJSWeakSet();
684}
685
Ben Murdoch097c5b22016-05-18 11:27:45 +0100686bool HeapObject::IsDescriptorArray() const { return IsFixedArray(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000687
Ben Murdoch097c5b22016-05-18 11:27:45 +0100688bool HeapObject::IsArrayList() const { return IsFixedArray(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000689
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400690bool Object::IsLayoutDescriptor() const {
691 return IsSmi() || IsFixedTypedArrayBase();
692}
693
Ben Murdoch097c5b22016-05-18 11:27:45 +0100694bool HeapObject::IsTypeFeedbackVector() const { return IsFixedArray(); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400695
Ben Murdoch097c5b22016-05-18 11:27:45 +0100696bool HeapObject::IsTypeFeedbackMetadata() const { return IsFixedArray(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000697
Ben Murdoch097c5b22016-05-18 11:27:45 +0100698bool HeapObject::IsLiteralsArray() const { return IsFixedArray(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000699
Ben Murdoch097c5b22016-05-18 11:27:45 +0100700bool HeapObject::IsDeoptimizationInputData() const {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100701 // Must be a fixed array.
702 if (!IsFixedArray()) return false;
703
704 // There's no sure way to detect the difference between a fixed array and
705 // a deoptimization data array. Since this is used for asserts we can
706 // check that the length is zero or else the fixed size plus a multiple of
707 // the entry size.
708 int length = FixedArray::cast(this)->length();
709 if (length == 0) return true;
710
711 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000712 return length >= 0 && length % DeoptimizationInputData::kDeoptEntrySize == 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100713}
714
Ben Murdoch097c5b22016-05-18 11:27:45 +0100715bool HeapObject::IsDeoptimizationOutputData() const {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100716 if (!IsFixedArray()) return false;
717 // There's actually no way to see the difference between a fixed array and
718 // a deoptimization data array. Since this is used for asserts we can check
719 // that the length is plausible though.
720 if (FixedArray::cast(this)->length() % 2 != 0) return false;
721 return true;
722}
723
Ben Murdoch097c5b22016-05-18 11:27:45 +0100724bool HeapObject::IsHandlerTable() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000725 if (!IsFixedArray()) return false;
726 // There's actually no way to see the difference between a fixed array and
727 // a handler table array.
728 return true;
729}
730
Ben Murdoch097c5b22016-05-18 11:27:45 +0100731bool HeapObject::IsDependentCode() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100732 if (!IsFixedArray()) return false;
733 // There's actually no way to see the difference between a fixed array and
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000734 // a dependent codes array.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100735 return true;
736}
737
Ben Murdoch097c5b22016-05-18 11:27:45 +0100738bool HeapObject::IsContext() const {
739 Map* map = this->map();
740 Heap* heap = GetHeap();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000741 return (map == heap->function_context_map() ||
742 map == heap->catch_context_map() ||
743 map == heap->with_context_map() ||
744 map == heap->native_context_map() ||
745 map == heap->block_context_map() ||
746 map == heap->module_context_map() ||
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400747 map == heap->script_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 Murdoch097c5b22016-05-18 11:27:45 +0100848bool HeapObject::IsNormalizedMapCache() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000849 return NormalizedMapCache::IsNormalizedMapCache(this);
850}
851
852
853int NormalizedMapCache::GetIndex(Handle<Map> map) {
854 return map->Hash() % NormalizedMapCache::kEntries;
855}
856
Ben Murdoch097c5b22016-05-18 11:27:45 +0100857bool NormalizedMapCache::IsNormalizedMapCache(const HeapObject* obj) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000858 if (!obj->IsFixedArray()) return false;
859 if (FixedArray::cast(obj)->length() != NormalizedMapCache::kEntries) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100860 return false;
861 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000862#ifdef VERIFY_HEAP
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100863 if (FLAG_verify_heap) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100864 reinterpret_cast<NormalizedMapCache*>(const_cast<HeapObject*>(obj))
865 ->NormalizedMapCacheVerify();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100866 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100867#endif
868 return true;
869}
870
Ben Murdoch097c5b22016-05-18 11:27:45 +0100871bool HeapObject::IsCompilationCacheTable() const { return IsHashTable(); }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100872
Ben Murdoch097c5b22016-05-18 11:27:45 +0100873bool HeapObject::IsCodeCacheHashTable() const { return IsHashTable(); }
874
875bool HeapObject::IsPolymorphicCodeCacheHashTable() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000876 return IsHashTable();
877}
878
Ben Murdoch097c5b22016-05-18 11:27:45 +0100879bool HeapObject::IsMapCache() const { return IsHashTable(); }
Steve Blocka7e24c12009-10-30 11:49:00 +0000880
Ben Murdoch097c5b22016-05-18 11:27:45 +0100881bool HeapObject::IsObjectHashTable() const { return IsHashTable(); }
Steve Block6ded16b2010-05-10 14:33:55 +0100882
Ben Murdoch097c5b22016-05-18 11:27:45 +0100883bool HeapObject::IsOrderedHashTable() const {
884 return map() == GetHeap()->ordered_hash_table_map();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000885}
886
887
888bool Object::IsOrderedHashSet() const {
889 return IsOrderedHashTable();
890}
891
892
893bool Object::IsOrderedHashMap() const {
894 return IsOrderedHashTable();
895}
896
897
898bool Object::IsPrimitive() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000899 return IsSmi() || HeapObject::cast(this)->map()->IsPrimitiveMap();
Steve Blocka7e24c12009-10-30 11:49:00 +0000900}
901
Ben Murdoch097c5b22016-05-18 11:27:45 +0100902bool HeapObject::IsJSGlobalProxy() const {
903 bool result = map()->instance_type() == JS_GLOBAL_PROXY_TYPE;
904 DCHECK(!result || map()->is_access_check_needed());
Steve Blocka7e24c12009-10-30 11:49:00 +0000905 return result;
906}
907
908
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100909TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
Steve Blocka7e24c12009-10-30 11:49:00 +0000910
Ben Murdoch097c5b22016-05-18 11:27:45 +0100911bool HeapObject::IsUndetectableObject() const {
912 return map()->is_undetectable();
Steve Blocka7e24c12009-10-30 11:49:00 +0000913}
914
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
1006
1007// static
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001008MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
1009 Handle<Object> object) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001010 if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
1011 return ToObject(isolate, object, isolate->native_context());
Steve Blocka7e24c12009-10-30 11:49:00 +00001012}
1013
1014
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001015// static
1016MaybeHandle<Object> Object::ToPrimitive(Handle<Object> input,
1017 ToPrimitiveHint hint) {
1018 if (input->IsPrimitive()) return input;
1019 return JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input), hint);
1020}
1021
1022
Steve Blocka7e24c12009-10-30 11:49:00 +00001023bool Object::HasSpecificClassOf(String* name) {
1024 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
1025}
1026
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001027MaybeHandle<Object> Object::GetProperty(Handle<Object> object,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001028 Handle<Name> name) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001029 LookupIterator it(object, name);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001030 return GetProperty(&it);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001031}
1032
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001033MaybeHandle<Object> Object::GetElement(Isolate* isolate, Handle<Object> object,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001034 uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001035 LookupIterator it(isolate, object, index);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001036 return GetProperty(&it);
Steve Blocka7e24c12009-10-30 11:49:00 +00001037}
1038
1039
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001040MaybeHandle<Object> Object::SetElement(Isolate* isolate, Handle<Object> object,
1041 uint32_t index, Handle<Object> value,
1042 LanguageMode language_mode) {
1043 LookupIterator it(isolate, object, index);
1044 MAYBE_RETURN_NULL(
1045 SetProperty(&it, value, language_mode, MAY_BE_STORE_FROM_KEYED));
1046 return value;
1047}
1048
Ben Murdoch097c5b22016-05-18 11:27:45 +01001049MaybeHandle<Object> JSReceiver::GetPrototype(Isolate* isolate,
1050 Handle<JSReceiver> receiver) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001051 // We don't expect access checks to be needed on JSProxy objects.
1052 DCHECK(!receiver->IsAccessCheckNeeded() || receiver->IsJSObject());
1053 PrototypeIterator iter(isolate, receiver,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001054 PrototypeIterator::START_AT_RECEIVER,
1055 PrototypeIterator::END_AT_NON_HIDDEN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001056 do {
1057 if (!iter.AdvanceFollowingProxies()) return MaybeHandle<Object>();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001058 } while (!iter.IsAtEnd());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001059 return PrototypeIterator::GetCurrent(iter);
1060}
1061
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001062MaybeHandle<Object> Object::GetProperty(Isolate* isolate, Handle<Object> object,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001063 const char* name) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001064 Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001065 return GetProperty(object, str);
Steve Blocka7e24c12009-10-30 11:49:00 +00001066}
1067
1068
1069#define FIELD_ADDR(p, offset) \
1070 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
1071
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001072#define FIELD_ADDR_CONST(p, offset) \
1073 (reinterpret_cast<const byte*>(p) + offset - kHeapObjectTag)
1074
Steve Blocka7e24c12009-10-30 11:49:00 +00001075#define READ_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001076 (*reinterpret_cast<Object* const*>(FIELD_ADDR_CONST(p, offset)))
1077
1078#define ACQUIRE_READ_FIELD(p, offset) \
1079 reinterpret_cast<Object*>(base::Acquire_Load( \
1080 reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR_CONST(p, offset))))
1081
1082#define NOBARRIER_READ_FIELD(p, offset) \
1083 reinterpret_cast<Object*>(base::NoBarrier_Load( \
1084 reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR_CONST(p, offset))))
Steve Blocka7e24c12009-10-30 11:49:00 +00001085
1086#define WRITE_FIELD(p, offset, value) \
1087 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
1088
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001089#define RELEASE_WRITE_FIELD(p, offset, value) \
1090 base::Release_Store( \
1091 reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
1092 reinterpret_cast<base::AtomicWord>(value));
1093
1094#define NOBARRIER_WRITE_FIELD(p, offset, value) \
1095 base::NoBarrier_Store( \
1096 reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
1097 reinterpret_cast<base::AtomicWord>(value));
1098
Ben Murdoch097c5b22016-05-18 11:27:45 +01001099#define WRITE_BARRIER(heap, object, offset, value) \
1100 heap->incremental_marking()->RecordWrite( \
1101 object, HeapObject::RawField(object, offset), value); \
1102 heap->RecordWrite(object, offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00001103
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001104#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
1105 if (mode != SKIP_WRITE_BARRIER) { \
1106 if (mode == UPDATE_WRITE_BARRIER) { \
1107 heap->incremental_marking()->RecordWrite( \
1108 object, HeapObject::RawField(object, offset), value); \
1109 } \
Ben Murdoch097c5b22016-05-18 11:27:45 +01001110 heap->RecordWrite(object, offset, value); \
Steve Blocka7e24c12009-10-30 11:49:00 +00001111 }
1112
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001113#define READ_DOUBLE_FIELD(p, offset) \
1114 ReadDoubleValue(FIELD_ADDR_CONST(p, offset))
Steve Blocka7e24c12009-10-30 11:49:00 +00001115
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001116#define WRITE_DOUBLE_FIELD(p, offset, value) \
1117 WriteDoubleValue(FIELD_ADDR(p, offset), value)
Steve Blocka7e24c12009-10-30 11:49:00 +00001118
1119#define READ_INT_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001120 (*reinterpret_cast<const int*>(FIELD_ADDR_CONST(p, offset)))
Steve Blocka7e24c12009-10-30 11:49:00 +00001121
1122#define WRITE_INT_FIELD(p, offset, value) \
1123 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
1124
1125#define READ_INTPTR_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001126 (*reinterpret_cast<const intptr_t*>(FIELD_ADDR_CONST(p, offset)))
Steve Blocka7e24c12009-10-30 11:49:00 +00001127
1128#define WRITE_INTPTR_FIELD(p, offset, value) \
1129 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
1130
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001131#define READ_UINT8_FIELD(p, offset) \
1132 (*reinterpret_cast<const uint8_t*>(FIELD_ADDR_CONST(p, offset)))
1133
1134#define WRITE_UINT8_FIELD(p, offset, value) \
1135 (*reinterpret_cast<uint8_t*>(FIELD_ADDR(p, offset)) = value)
1136
1137#define READ_INT8_FIELD(p, offset) \
1138 (*reinterpret_cast<const int8_t*>(FIELD_ADDR_CONST(p, offset)))
1139
1140#define WRITE_INT8_FIELD(p, offset, value) \
1141 (*reinterpret_cast<int8_t*>(FIELD_ADDR(p, offset)) = value)
1142
1143#define READ_UINT16_FIELD(p, offset) \
1144 (*reinterpret_cast<const uint16_t*>(FIELD_ADDR_CONST(p, offset)))
1145
1146#define WRITE_UINT16_FIELD(p, offset, value) \
1147 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
1148
1149#define READ_INT16_FIELD(p, offset) \
1150 (*reinterpret_cast<const int16_t*>(FIELD_ADDR_CONST(p, offset)))
1151
1152#define WRITE_INT16_FIELD(p, offset, value) \
1153 (*reinterpret_cast<int16_t*>(FIELD_ADDR(p, offset)) = value)
1154
Steve Blocka7e24c12009-10-30 11:49:00 +00001155#define READ_UINT32_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001156 (*reinterpret_cast<const uint32_t*>(FIELD_ADDR_CONST(p, offset)))
Steve Blocka7e24c12009-10-30 11:49:00 +00001157
1158#define WRITE_UINT32_FIELD(p, offset, value) \
1159 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
1160
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001161#define READ_INT32_FIELD(p, offset) \
1162 (*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset)))
1163
1164#define WRITE_INT32_FIELD(p, offset, value) \
1165 (*reinterpret_cast<int32_t*>(FIELD_ADDR(p, offset)) = value)
1166
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001167#define READ_FLOAT_FIELD(p, offset) \
1168 (*reinterpret_cast<const float*>(FIELD_ADDR_CONST(p, offset)))
1169
1170#define WRITE_FLOAT_FIELD(p, offset, value) \
1171 (*reinterpret_cast<float*>(FIELD_ADDR(p, offset)) = value)
1172
1173#define READ_UINT64_FIELD(p, offset) \
1174 (*reinterpret_cast<const uint64_t*>(FIELD_ADDR_CONST(p, offset)))
1175
1176#define WRITE_UINT64_FIELD(p, offset, value) \
1177 (*reinterpret_cast<uint64_t*>(FIELD_ADDR(p, offset)) = value)
1178
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001179#define READ_INT64_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001180 (*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset)))
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001181
1182#define WRITE_INT64_FIELD(p, offset, value) \
1183 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
1184
Steve Blocka7e24c12009-10-30 11:49:00 +00001185#define READ_BYTE_FIELD(p, offset) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001186 (*reinterpret_cast<const byte*>(FIELD_ADDR_CONST(p, offset)))
1187
1188#define NOBARRIER_READ_BYTE_FIELD(p, offset) \
1189 static_cast<byte>(base::NoBarrier_Load( \
1190 reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset))))
Steve Blocka7e24c12009-10-30 11:49:00 +00001191
1192#define WRITE_BYTE_FIELD(p, offset, value) \
1193 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
1194
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001195#define NOBARRIER_WRITE_BYTE_FIELD(p, offset, value) \
1196 base::NoBarrier_Store( \
1197 reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset)), \
1198 static_cast<base::Atomic8>(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00001199
1200Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001201 return reinterpret_cast<Object**>(FIELD_ADDR(obj, byte_offset));
Steve Blocka7e24c12009-10-30 11:49:00 +00001202}
1203
1204
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001205MapWord MapWord::FromMap(const Map* map) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001206 return MapWord(reinterpret_cast<uintptr_t>(map));
1207}
1208
1209
1210Map* MapWord::ToMap() {
1211 return reinterpret_cast<Map*>(value_);
1212}
1213
1214
1215bool MapWord::IsForwardingAddress() {
1216 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
1217}
1218
1219
1220MapWord MapWord::FromForwardingAddress(HeapObject* object) {
1221 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1222 return MapWord(reinterpret_cast<uintptr_t>(raw));
1223}
1224
1225
1226HeapObject* MapWord::ToForwardingAddress() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001227 DCHECK(IsForwardingAddress());
Steve Blocka7e24c12009-10-30 11:49:00 +00001228 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
1229}
1230
1231
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001232#ifdef VERIFY_HEAP
Steve Blocka7e24c12009-10-30 11:49:00 +00001233void HeapObject::VerifyObjectField(int offset) {
1234 VerifyPointer(READ_FIELD(this, offset));
1235}
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001236
1237void HeapObject::VerifySmiField(int offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001238 CHECK(READ_FIELD(this, offset)->IsSmi());
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001239}
Steve Blocka7e24c12009-10-30 11:49:00 +00001240#endif
1241
1242
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001243Heap* HeapObject::GetHeap() const {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001244 Heap* heap = MemoryChunk::FromAddress(
1245 reinterpret_cast<Address>(const_cast<HeapObject*>(this)))
1246 ->heap();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001247 SLOW_DCHECK(heap != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001248 return heap;
Steve Block44f0eee2011-05-26 01:26:41 +01001249}
1250
1251
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001252Isolate* HeapObject::GetIsolate() const {
Steve Block44f0eee2011-05-26 01:26:41 +01001253 return GetHeap()->isolate();
1254}
1255
1256
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001257Map* HeapObject::map() const {
1258#ifdef DEBUG
1259 // Clear mark potentially added by PathTracer.
1260 uintptr_t raw_value =
1261 map_word().ToRawValue() & ~static_cast<uintptr_t>(PathTracer::kMarkTag);
1262 return MapWord::FromRawValue(raw_value).ToMap();
1263#else
Steve Blocka7e24c12009-10-30 11:49:00 +00001264 return map_word().ToMap();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001265#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00001266}
1267
1268
1269void HeapObject::set_map(Map* value) {
1270 set_map_word(MapWord::FromMap(value));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001271 if (value != NULL) {
1272 // TODO(1600) We are passing NULL as a slot because maps can never be on
1273 // evacuation candidate.
1274 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1275 }
1276}
1277
1278
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001279Map* HeapObject::synchronized_map() {
1280 return synchronized_map_word().ToMap();
1281}
1282
1283
1284void HeapObject::synchronized_set_map(Map* value) {
1285 synchronized_set_map_word(MapWord::FromMap(value));
1286 if (value != NULL) {
1287 // TODO(1600) We are passing NULL as a slot because maps can never be on
1288 // evacuation candidate.
1289 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1290 }
1291}
1292
1293
1294void HeapObject::synchronized_set_map_no_write_barrier(Map* value) {
1295 synchronized_set_map_word(MapWord::FromMap(value));
1296}
1297
1298
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001299// Unsafe accessor omitting write barrier.
1300void HeapObject::set_map_no_write_barrier(Map* value) {
1301 set_map_word(MapWord::FromMap(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00001302}
1303
1304
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001305MapWord HeapObject::map_word() const {
1306 return MapWord(
1307 reinterpret_cast<uintptr_t>(NOBARRIER_READ_FIELD(this, kMapOffset)));
Steve Blocka7e24c12009-10-30 11:49:00 +00001308}
1309
1310
1311void HeapObject::set_map_word(MapWord map_word) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001312 NOBARRIER_WRITE_FIELD(
1313 this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1314}
1315
1316
1317MapWord HeapObject::synchronized_map_word() const {
1318 return MapWord(
1319 reinterpret_cast<uintptr_t>(ACQUIRE_READ_FIELD(this, kMapOffset)));
1320}
1321
1322
1323void HeapObject::synchronized_set_map_word(MapWord map_word) {
1324 RELEASE_WRITE_FIELD(
1325 this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
Steve Blocka7e24c12009-10-30 11:49:00 +00001326}
1327
1328
Steve Blocka7e24c12009-10-30 11:49:00 +00001329int HeapObject::Size() {
1330 return SizeFromMap(map());
1331}
1332
1333
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001334double HeapNumber::value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00001335 return READ_DOUBLE_FIELD(this, kValueOffset);
1336}
1337
1338
1339void HeapNumber::set_value(double value) {
1340 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1341}
1342
1343
Steve Block6ded16b2010-05-10 14:33:55 +01001344int HeapNumber::get_exponent() {
1345 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1346 kExponentShift) - kExponentBias;
1347}
1348
1349
1350int HeapNumber::get_sign() {
1351 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1352}
1353
1354
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001355bool Simd128Value::Equals(Simd128Value* that) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001356 // TODO(bmeurer): This doesn't match the SIMD.js specification, but it seems
1357 // to be consistent with what the CompareICStub does, and what is tested in
1358 // the current SIMD.js testsuite.
1359 if (this == that) return true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001360#define SIMD128_VALUE(TYPE, Type, type, lane_count, lane_type) \
1361 if (this->Is##Type()) { \
1362 if (!that->Is##Type()) return false; \
1363 return Type::cast(this)->Equals(Type::cast(that)); \
1364 }
1365 SIMD128_TYPES(SIMD128_VALUE)
1366#undef SIMD128_VALUE
1367 return false;
1368}
1369
1370
1371// static
1372bool Simd128Value::Equals(Handle<Simd128Value> one, Handle<Simd128Value> two) {
1373 return one->Equals(*two);
1374}
1375
1376
1377#define SIMD128_VALUE_EQUALS(TYPE, Type, type, lane_count, lane_type) \
1378 bool Type::Equals(Type* that) { \
1379 for (int lane = 0; lane < lane_count; ++lane) { \
1380 if (this->get_lane(lane) != that->get_lane(lane)) return false; \
1381 } \
1382 return true; \
1383 }
1384SIMD128_TYPES(SIMD128_VALUE_EQUALS)
1385#undef SIMD128_VALUE_EQUALS
1386
1387
1388#if defined(V8_TARGET_LITTLE_ENDIAN)
1389#define SIMD128_READ_LANE(lane_type, lane_count, field_type, field_size) \
1390 lane_type value = \
1391 READ_##field_type##_FIELD(this, kValueOffset + lane * field_size);
1392#elif defined(V8_TARGET_BIG_ENDIAN)
1393#define SIMD128_READ_LANE(lane_type, lane_count, field_type, field_size) \
1394 lane_type value = READ_##field_type##_FIELD( \
1395 this, kValueOffset + (lane_count - lane - 1) * field_size);
1396#else
1397#error Unknown byte ordering
1398#endif
1399
1400#if defined(V8_TARGET_LITTLE_ENDIAN)
1401#define SIMD128_WRITE_LANE(lane_count, field_type, field_size, value) \
1402 WRITE_##field_type##_FIELD(this, kValueOffset + lane * field_size, value);
1403#elif defined(V8_TARGET_BIG_ENDIAN)
1404#define SIMD128_WRITE_LANE(lane_count, field_type, field_size, value) \
1405 WRITE_##field_type##_FIELD( \
1406 this, kValueOffset + (lane_count - lane - 1) * field_size, value);
1407#else
1408#error Unknown byte ordering
1409#endif
1410
1411#define SIMD128_NUMERIC_LANE_FNS(type, lane_type, lane_count, field_type, \
1412 field_size) \
1413 lane_type type::get_lane(int lane) const { \
1414 DCHECK(lane < lane_count && lane >= 0); \
1415 SIMD128_READ_LANE(lane_type, lane_count, field_type, field_size) \
1416 return value; \
1417 } \
1418 \
1419 void type::set_lane(int lane, lane_type value) { \
1420 DCHECK(lane < lane_count && lane >= 0); \
1421 SIMD128_WRITE_LANE(lane_count, field_type, field_size, value) \
1422 }
1423
1424SIMD128_NUMERIC_LANE_FNS(Float32x4, float, 4, FLOAT, kFloatSize)
1425SIMD128_NUMERIC_LANE_FNS(Int32x4, int32_t, 4, INT32, kInt32Size)
1426SIMD128_NUMERIC_LANE_FNS(Uint32x4, uint32_t, 4, UINT32, kInt32Size)
1427SIMD128_NUMERIC_LANE_FNS(Int16x8, int16_t, 8, INT16, kShortSize)
1428SIMD128_NUMERIC_LANE_FNS(Uint16x8, uint16_t, 8, UINT16, kShortSize)
1429SIMD128_NUMERIC_LANE_FNS(Int8x16, int8_t, 16, INT8, kCharSize)
1430SIMD128_NUMERIC_LANE_FNS(Uint8x16, uint8_t, 16, UINT8, kCharSize)
1431#undef SIMD128_NUMERIC_LANE_FNS
1432
1433
1434#define SIMD128_BOOLEAN_LANE_FNS(type, lane_type, lane_count, field_type, \
1435 field_size) \
1436 bool type::get_lane(int lane) const { \
1437 DCHECK(lane < lane_count && lane >= 0); \
1438 SIMD128_READ_LANE(lane_type, lane_count, field_type, field_size) \
1439 DCHECK(value == 0 || value == -1); \
1440 return value != 0; \
1441 } \
1442 \
1443 void type::set_lane(int lane, bool value) { \
1444 DCHECK(lane < lane_count && lane >= 0); \
1445 int32_t int_val = value ? -1 : 0; \
1446 SIMD128_WRITE_LANE(lane_count, field_type, field_size, int_val) \
1447 }
1448
1449SIMD128_BOOLEAN_LANE_FNS(Bool32x4, int32_t, 4, INT32, kInt32Size)
1450SIMD128_BOOLEAN_LANE_FNS(Bool16x8, int16_t, 8, INT16, kShortSize)
1451SIMD128_BOOLEAN_LANE_FNS(Bool8x16, int8_t, 16, INT8, kCharSize)
1452#undef SIMD128_BOOLEAN_LANE_FNS
1453
1454#undef SIMD128_READ_LANE
1455#undef SIMD128_WRITE_LANE
1456
1457
1458ACCESSORS(JSReceiver, properties, FixedArray, kPropertiesOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00001459
1460
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001461Object** FixedArray::GetFirstElementAddress() {
1462 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1463}
1464
1465
1466bool FixedArray::ContainsOnlySmisOrHoles() {
1467 Object* the_hole = GetHeap()->the_hole_value();
1468 Object** current = GetFirstElementAddress();
1469 for (int i = 0; i < length(); ++i) {
1470 Object* candidate = *current++;
1471 if (!candidate->IsSmi() && candidate != the_hole) return false;
1472 }
1473 return true;
1474}
1475
1476
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001477FixedArrayBase* JSObject::elements() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00001478 Object* array = READ_FIELD(this, kElementsOffset);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001479 return static_cast<FixedArrayBase*>(array);
Steve Blocka7e24c12009-10-30 11:49:00 +00001480}
1481
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001482
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001483void AllocationSite::Initialize() {
1484 set_transition_info(Smi::FromInt(0));
1485 SetElementsKind(GetInitialFastElementsKind());
1486 set_nested_site(Smi::FromInt(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001487 set_pretenure_data(0);
1488 set_pretenure_create_count(0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001489 set_dependent_code(DependentCode::cast(GetHeap()->empty_fixed_array()),
1490 SKIP_WRITE_BARRIER);
1491}
1492
1493
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001494bool AllocationSite::IsZombie() { return pretenure_decision() == kZombie; }
1495
1496
1497bool AllocationSite::IsMaybeTenure() {
1498 return pretenure_decision() == kMaybeTenure;
1499}
1500
1501
1502bool AllocationSite::PretenuringDecisionMade() {
1503 return pretenure_decision() != kUndecided;
1504}
1505
1506
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001507void AllocationSite::MarkZombie() {
1508 DCHECK(!IsZombie());
1509 Initialize();
1510 set_pretenure_decision(kZombie);
1511}
1512
1513
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001514ElementsKind AllocationSite::GetElementsKind() {
1515 DCHECK(!SitePointsToLiteral());
1516 int value = Smi::cast(transition_info())->value();
1517 return ElementsKindBits::decode(value);
1518}
1519
1520
1521void AllocationSite::SetElementsKind(ElementsKind kind) {
1522 int value = Smi::cast(transition_info())->value();
1523 set_transition_info(Smi::FromInt(ElementsKindBits::update(value, kind)),
1524 SKIP_WRITE_BARRIER);
1525}
1526
1527
1528bool AllocationSite::CanInlineCall() {
1529 int value = Smi::cast(transition_info())->value();
1530 return DoNotInlineBit::decode(value) == 0;
1531}
1532
1533
1534void AllocationSite::SetDoNotInlineCall() {
1535 int value = Smi::cast(transition_info())->value();
1536 set_transition_info(Smi::FromInt(DoNotInlineBit::update(value, true)),
1537 SKIP_WRITE_BARRIER);
1538}
1539
1540
1541bool AllocationSite::SitePointsToLiteral() {
1542 // If transition_info is a smi, then it represents an ElementsKind
1543 // for a constructed array. Otherwise, it must be a boilerplate
1544 // for an object or array literal.
1545 return transition_info()->IsJSArray() || transition_info()->IsJSObject();
1546}
1547
1548
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001549// Heuristic: We only need to create allocation site info if the boilerplate
1550// elements kind is the initial elements kind.
1551AllocationSiteMode AllocationSite::GetMode(
1552 ElementsKind boilerplate_elements_kind) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001553 if (IsFastSmiElementsKind(boilerplate_elements_kind)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001554 return TRACK_ALLOCATION_SITE;
1555 }
1556
1557 return DONT_TRACK_ALLOCATION_SITE;
1558}
1559
1560
1561AllocationSiteMode AllocationSite::GetMode(ElementsKind from,
1562 ElementsKind to) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001563 if (IsFastSmiElementsKind(from) &&
1564 IsMoreGeneralElementsKindTransition(from, to)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001565 return TRACK_ALLOCATION_SITE;
1566 }
1567
1568 return DONT_TRACK_ALLOCATION_SITE;
1569}
1570
1571
1572inline bool AllocationSite::CanTrack(InstanceType type) {
1573 if (FLAG_allocation_site_pretenuring) {
1574 return type == JS_ARRAY_TYPE ||
1575 type == JS_OBJECT_TYPE ||
1576 type < FIRST_NONSTRING_TYPE;
1577 }
1578 return type == JS_ARRAY_TYPE;
1579}
1580
1581
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001582AllocationSite::PretenureDecision AllocationSite::pretenure_decision() {
1583 int value = pretenure_data();
1584 return PretenureDecisionBits::decode(value);
1585}
1586
1587
1588void AllocationSite::set_pretenure_decision(PretenureDecision decision) {
1589 int value = pretenure_data();
1590 set_pretenure_data(PretenureDecisionBits::update(value, decision));
1591}
1592
1593
1594bool AllocationSite::deopt_dependent_code() {
1595 int value = pretenure_data();
1596 return DeoptDependentCodeBit::decode(value);
1597}
1598
1599
1600void AllocationSite::set_deopt_dependent_code(bool deopt) {
1601 int value = pretenure_data();
1602 set_pretenure_data(DeoptDependentCodeBit::update(value, deopt));
1603}
1604
1605
1606int AllocationSite::memento_found_count() {
1607 int value = pretenure_data();
1608 return MementoFoundCountBits::decode(value);
1609}
1610
1611
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001612inline void AllocationSite::set_memento_found_count(int count) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001613 int value = pretenure_data();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001614 // Verify that we can count more mementos than we can possibly find in one
1615 // new space collection.
1616 DCHECK((GetHeap()->MaxSemiSpaceSize() /
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001617 (Heap::kMinObjectSizeInWords * kPointerSize +
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001618 AllocationMemento::kSize)) < MementoFoundCountBits::kMax);
1619 DCHECK(count < MementoFoundCountBits::kMax);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001620 set_pretenure_data(MementoFoundCountBits::update(value, count));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001621}
1622
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001623
1624int AllocationSite::memento_create_count() { return pretenure_create_count(); }
1625
1626
1627void AllocationSite::set_memento_create_count(int count) {
1628 set_pretenure_create_count(count);
1629}
1630
1631
1632bool AllocationSite::IncrementMementoFoundCount(int increment) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001633 if (IsZombie()) return false;
1634
1635 int value = memento_found_count();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001636 set_memento_found_count(value + increment);
1637 return memento_found_count() >= kPretenureMinimumCreated;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001638}
1639
1640
1641inline void AllocationSite::IncrementMementoCreateCount() {
1642 DCHECK(FLAG_allocation_site_pretenuring);
1643 int value = memento_create_count();
1644 set_memento_create_count(value + 1);
1645}
1646
1647
1648inline bool AllocationSite::MakePretenureDecision(
1649 PretenureDecision current_decision,
1650 double ratio,
1651 bool maximum_size_scavenge) {
1652 // Here we just allow state transitions from undecided or maybe tenure
1653 // to don't tenure, maybe tenure, or tenure.
1654 if ((current_decision == kUndecided || current_decision == kMaybeTenure)) {
1655 if (ratio >= kPretenureRatio) {
1656 // We just transition into tenure state when the semi-space was at
1657 // maximum capacity.
1658 if (maximum_size_scavenge) {
1659 set_deopt_dependent_code(true);
1660 set_pretenure_decision(kTenure);
1661 // Currently we just need to deopt when we make a state transition to
1662 // tenure.
1663 return true;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001664 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001665 set_pretenure_decision(kMaybeTenure);
1666 } else {
1667 set_pretenure_decision(kDontTenure);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001668 }
1669 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001670 return false;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001671}
1672
1673
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001674inline bool AllocationSite::DigestPretenuringFeedback(
1675 bool maximum_size_scavenge) {
1676 bool deopt = false;
1677 int create_count = memento_create_count();
1678 int found_count = memento_found_count();
1679 bool minimum_mementos_created = create_count >= kPretenureMinimumCreated;
1680 double ratio =
1681 minimum_mementos_created || FLAG_trace_pretenuring_statistics ?
1682 static_cast<double>(found_count) / create_count : 0.0;
1683 PretenureDecision current_decision = pretenure_decision();
1684
1685 if (minimum_mementos_created) {
1686 deopt = MakePretenureDecision(
1687 current_decision, ratio, maximum_size_scavenge);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001688 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001689
1690 if (FLAG_trace_pretenuring_statistics) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001691 PrintIsolate(GetIsolate(),
1692 "pretenuring: AllocationSite(%p): (created, found, ratio) "
1693 "(%d, %d, %f) %s => %s\n",
1694 this, create_count, found_count, ratio,
1695 PretenureDecisionName(current_decision),
1696 PretenureDecisionName(pretenure_decision()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001697 }
1698
1699 // Clear feedback calculation fields until the next gc.
1700 set_memento_found_count(0);
1701 set_memento_create_count(0);
1702 return deopt;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001703}
1704
1705
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001706bool AllocationMemento::IsValid() {
1707 return allocation_site()->IsAllocationSite() &&
1708 !AllocationSite::cast(allocation_site())->IsZombie();
1709}
1710
1711
1712AllocationSite* AllocationMemento::GetAllocationSite() {
1713 DCHECK(IsValid());
1714 return AllocationSite::cast(allocation_site());
1715}
1716
Ben Murdoch097c5b22016-05-18 11:27:45 +01001717Address AllocationMemento::GetAllocationSiteUnchecked() {
1718 return reinterpret_cast<Address>(allocation_site());
1719}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001720
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001721void JSObject::EnsureCanContainHeapObjectElements(Handle<JSObject> object) {
1722 JSObject::ValidateElements(object);
1723 ElementsKind elements_kind = object->map()->elements_kind();
1724 if (!IsFastObjectElementsKind(elements_kind)) {
1725 if (IsFastHoleyElementsKind(elements_kind)) {
1726 TransitionElementsKind(object, FAST_HOLEY_ELEMENTS);
1727 } else {
1728 TransitionElementsKind(object, FAST_ELEMENTS);
1729 }
1730 }
1731}
1732
1733
1734void JSObject::EnsureCanContainElements(Handle<JSObject> object,
1735 Object** objects,
1736 uint32_t count,
1737 EnsureElementsMode mode) {
1738 ElementsKind current_kind = object->map()->elements_kind();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001739 ElementsKind target_kind = current_kind;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001740 {
1741 DisallowHeapAllocation no_allocation;
1742 DCHECK(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1743 bool is_holey = IsFastHoleyElementsKind(current_kind);
1744 if (current_kind == FAST_HOLEY_ELEMENTS) return;
1745 Heap* heap = object->GetHeap();
1746 Object* the_hole = heap->the_hole_value();
1747 for (uint32_t i = 0; i < count; ++i) {
1748 Object* current = *objects++;
1749 if (current == the_hole) {
1750 is_holey = true;
1751 target_kind = GetHoleyElementsKind(target_kind);
1752 } else if (!current->IsSmi()) {
1753 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && current->IsNumber()) {
1754 if (IsFastSmiElementsKind(target_kind)) {
1755 if (is_holey) {
1756 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
1757 } else {
1758 target_kind = FAST_DOUBLE_ELEMENTS;
1759 }
1760 }
1761 } else if (is_holey) {
1762 target_kind = FAST_HOLEY_ELEMENTS;
1763 break;
1764 } else {
1765 target_kind = FAST_ELEMENTS;
1766 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001767 }
1768 }
1769 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001770 if (target_kind != current_kind) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001771 TransitionElementsKind(object, target_kind);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001772 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001773}
1774
1775
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001776void JSObject::EnsureCanContainElements(Handle<JSObject> object,
1777 Handle<FixedArrayBase> elements,
1778 uint32_t length,
1779 EnsureElementsMode mode) {
1780 Heap* heap = object->GetHeap();
1781 if (elements->map() != heap->fixed_double_array_map()) {
1782 DCHECK(elements->map() == heap->fixed_array_map() ||
1783 elements->map() == heap->fixed_cow_array_map());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001784 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1785 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1786 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001787 Object** objects =
1788 Handle<FixedArray>::cast(elements)->GetFirstElementAddress();
1789 EnsureCanContainElements(object, objects, length, mode);
1790 return;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001791 }
1792
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001793 DCHECK(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1794 if (object->GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) {
1795 TransitionElementsKind(object, FAST_HOLEY_DOUBLE_ELEMENTS);
1796 } else if (object->GetElementsKind() == FAST_SMI_ELEMENTS) {
1797 Handle<FixedDoubleArray> double_array =
1798 Handle<FixedDoubleArray>::cast(elements);
1799 for (uint32_t i = 0; i < length; ++i) {
1800 if (double_array->is_the_hole(i)) {
1801 TransitionElementsKind(object, FAST_HOLEY_DOUBLE_ELEMENTS);
1802 return;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001803 }
1804 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001805 TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001806 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001807}
1808
1809
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001810void JSObject::SetMapAndElements(Handle<JSObject> object,
1811 Handle<Map> new_map,
1812 Handle<FixedArrayBase> value) {
1813 JSObject::MigrateToMap(object, new_map);
1814 DCHECK((object->map()->has_fast_smi_or_object_elements() ||
Ben Murdoch097c5b22016-05-18 11:27:45 +01001815 (*value == object->GetHeap()->empty_fixed_array()) ||
1816 object->map()->has_fast_string_wrapper_elements()) ==
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001817 (value->map() == object->GetHeap()->fixed_array_map() ||
1818 value->map() == object->GetHeap()->fixed_cow_array_map()));
1819 DCHECK((*value == object->GetHeap()->empty_fixed_array()) ||
1820 (object->map()->has_fast_double_elements() ==
1821 value->IsFixedDoubleArray()));
1822 object->set_elements(*value);
1823}
1824
1825
1826void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001827 WRITE_FIELD(this, kElementsOffset, value);
1828 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
1829}
1830
Steve Blocka7e24c12009-10-30 11:49:00 +00001831
Steve Blocka7e24c12009-10-30 11:49:00 +00001832void JSObject::initialize_elements() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001833 FixedArrayBase* elements = map()->GetInitialElements();
1834 WRITE_FIELD(this, kElementsOffset, elements);
Steve Blocka7e24c12009-10-30 11:49:00 +00001835}
1836
1837
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001838InterceptorInfo* JSObject::GetIndexedInterceptor() {
1839 DCHECK(map()->has_indexed_interceptor());
1840 JSFunction* constructor = JSFunction::cast(map()->GetConstructor());
1841 DCHECK(constructor->shared()->IsApiFunction());
1842 Object* result =
1843 constructor->shared()->get_api_func_data()->indexed_property_handler();
1844 return InterceptorInfo::cast(result);
Steve Block8defd9f2010-07-08 12:39:36 +01001845}
1846
1847
Steve Blocka7e24c12009-10-30 11:49:00 +00001848ACCESSORS(Oddball, to_string, String, kToStringOffset)
1849ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001850ACCESSORS(Oddball, type_of, String, kTypeOfOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00001851
1852
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001853byte Oddball::kind() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001854 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
Steve Block44f0eee2011-05-26 01:26:41 +01001855}
1856
1857
1858void Oddball::set_kind(byte value) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001859 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
Steve Block44f0eee2011-05-26 01:26:41 +01001860}
1861
1862
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001863// static
1864Handle<Object> Oddball::ToNumber(Handle<Oddball> input) {
1865 return handle(input->to_number(), input->GetIsolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00001866}
1867
1868
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001869ACCESSORS(Cell, value, Object, kValueOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001870ACCESSORS(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001871ACCESSORS(PropertyCell, property_details_raw, Object, kDetailsOffset)
1872ACCESSORS(PropertyCell, value, Object, kValueOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001873
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001874
1875PropertyDetails PropertyCell::property_details() {
1876 return PropertyDetails(Smi::cast(property_details_raw()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001877}
1878
1879
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001880void PropertyCell::set_property_details(PropertyDetails details) {
1881 set_property_details_raw(details.AsSmi());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001882}
1883
Steve Blocka7e24c12009-10-30 11:49:00 +00001884
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001885Object* WeakCell::value() const { return READ_FIELD(this, kValueOffset); }
1886
1887
1888void WeakCell::clear() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001889 // Either the garbage collector is clearing the cell or we are simply
1890 // initializing the root empty weak cell.
1891 DCHECK(GetHeap()->gc_state() == Heap::MARK_COMPACT ||
1892 this == GetHeap()->empty_weak_cell());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001893 WRITE_FIELD(this, kValueOffset, Smi::FromInt(0));
1894}
1895
1896
1897void WeakCell::initialize(HeapObject* val) {
1898 WRITE_FIELD(this, kValueOffset, val);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001899 Heap* heap = GetHeap();
1900 // We just have to execute the generational barrier here because we never
1901 // mark through a weak cell and collect evacuation candidates when we process
1902 // all weak cells.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001903 heap->RecordWrite(this, kValueOffset, val);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001904}
1905
1906
1907bool WeakCell::cleared() const { return value() == Smi::FromInt(0); }
1908
1909
1910Object* WeakCell::next() const { return READ_FIELD(this, kNextOffset); }
1911
1912
1913void WeakCell::set_next(Object* val, WriteBarrierMode mode) {
1914 WRITE_FIELD(this, kNextOffset, val);
1915 if (mode == UPDATE_WRITE_BARRIER) {
1916 WRITE_BARRIER(GetHeap(), this, kNextOffset, val);
1917 }
1918}
1919
1920
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001921void WeakCell::clear_next(Object* the_hole_value) {
1922 DCHECK_EQ(GetHeap()->the_hole_value(), the_hole_value);
1923 set_next(the_hole_value, SKIP_WRITE_BARRIER);
1924}
1925
1926
1927bool WeakCell::next_cleared() { return next()->IsTheHole(); }
1928
1929
1930int JSObject::GetHeaderSize() { return GetHeaderSize(map()->instance_type()); }
1931
1932
1933int JSObject::GetHeaderSize(InstanceType type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001934 // Check for the most common kind of JavaScript object before
1935 // falling into the generic switch. This speeds up the internal
1936 // field operations considerably on average.
1937 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1938 switch (type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001939 case JS_GENERATOR_OBJECT_TYPE:
1940 return JSGeneratorObject::kSize;
1941 case JS_MODULE_TYPE:
1942 return JSModule::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00001943 case JS_GLOBAL_PROXY_TYPE:
1944 return JSGlobalProxy::kSize;
1945 case JS_GLOBAL_OBJECT_TYPE:
1946 return JSGlobalObject::kSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001947 case JS_BOUND_FUNCTION_TYPE:
1948 return JSBoundFunction::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00001949 case JS_FUNCTION_TYPE:
1950 return JSFunction::kSize;
1951 case JS_VALUE_TYPE:
1952 return JSValue::kSize;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001953 case JS_DATE_TYPE:
1954 return JSDate::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00001955 case JS_ARRAY_TYPE:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001956 return JSArray::kSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001957 case JS_ARRAY_BUFFER_TYPE:
1958 return JSArrayBuffer::kSize;
1959 case JS_TYPED_ARRAY_TYPE:
1960 return JSTypedArray::kSize;
1961 case JS_DATA_VIEW_TYPE:
1962 return JSDataView::kSize;
1963 case JS_SET_TYPE:
1964 return JSSet::kSize;
1965 case JS_MAP_TYPE:
1966 return JSMap::kSize;
1967 case JS_SET_ITERATOR_TYPE:
1968 return JSSetIterator::kSize;
1969 case JS_MAP_ITERATOR_TYPE:
1970 return JSMapIterator::kSize;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001971 case JS_WEAK_MAP_TYPE:
1972 return JSWeakMap::kSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001973 case JS_WEAK_SET_TYPE:
1974 return JSWeakSet::kSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001975 case JS_PROMISE_TYPE:
1976 return JSObject::kHeaderSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00001977 case JS_REGEXP_TYPE:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001978 return JSRegExp::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00001979 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
1980 return JSObject::kHeaderSize;
Steve Block1e0659c2011-05-24 12:43:12 +01001981 case JS_MESSAGE_OBJECT_TYPE:
1982 return JSMessageObject::kSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00001983 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001984 UNREACHABLE();
Steve Blocka7e24c12009-10-30 11:49:00 +00001985 return 0;
1986 }
1987}
1988
1989
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001990int JSObject::GetInternalFieldCount(Map* map) {
1991 int instance_size = map->instance_size();
1992 if (instance_size == kVariableSizeSentinel) return 0;
1993 InstanceType instance_type = map->instance_type();
1994 return ((instance_size - GetHeaderSize(instance_type)) >> kPointerSizeLog2) -
1995 map->GetInObjectProperties();
Steve Blocka7e24c12009-10-30 11:49:00 +00001996}
1997
1998
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001999int JSObject::GetInternalFieldCount() { return GetInternalFieldCount(map()); }
2000
2001
Steve Block44f0eee2011-05-26 01:26:41 +01002002int JSObject::GetInternalFieldOffset(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002003 DCHECK(index < GetInternalFieldCount() && index >= 0);
Steve Block44f0eee2011-05-26 01:26:41 +01002004 return GetHeaderSize() + (kPointerSize * index);
2005}
2006
2007
Steve Blocka7e24c12009-10-30 11:49:00 +00002008Object* JSObject::GetInternalField(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002009 DCHECK(index < GetInternalFieldCount() && index >= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002010 // Internal objects do follow immediately after the header, whereas in-object
2011 // properties are at the end of the object. Therefore there is no need
2012 // to adjust the index here.
2013 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
2014}
2015
2016
2017void JSObject::SetInternalField(int index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002018 DCHECK(index < GetInternalFieldCount() && index >= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002019 // Internal objects do follow immediately after the header, whereas in-object
2020 // properties are at the end of the object. Therefore there is no need
2021 // to adjust the index here.
2022 int offset = GetHeaderSize() + (kPointerSize * index);
2023 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002024 WRITE_BARRIER(GetHeap(), this, offset, value);
2025}
2026
2027
2028void JSObject::SetInternalField(int index, Smi* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002029 DCHECK(index < GetInternalFieldCount() && index >= 0);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002030 // Internal objects do follow immediately after the header, whereas in-object
2031 // properties are at the end of the object. Therefore there is no need
2032 // to adjust the index here.
2033 int offset = GetHeaderSize() + (kPointerSize * index);
2034 WRITE_FIELD(this, offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002035}
2036
2037
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002038bool JSObject::IsUnboxedDoubleField(FieldIndex index) {
2039 if (!FLAG_unbox_double_fields) return false;
2040 return map()->IsUnboxedDoubleField(index);
2041}
2042
2043
2044bool Map::IsUnboxedDoubleField(FieldIndex index) {
2045 if (!FLAG_unbox_double_fields) return false;
2046 if (index.is_hidden_field() || !index.is_inobject()) return false;
2047 return !layout_descriptor()->IsTagged(index.property_index());
2048}
2049
2050
Steve Blocka7e24c12009-10-30 11:49:00 +00002051// Access fast-case object properties at index. The use of these routines
2052// is needed to correctly distinguish between properties stored in-object and
2053// properties stored in the properties array.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002054Object* JSObject::RawFastPropertyAt(FieldIndex index) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002055 DCHECK(!IsUnboxedDoubleField(index));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002056 if (index.is_inobject()) {
2057 return READ_FIELD(this, index.offset());
Steve Blocka7e24c12009-10-30 11:49:00 +00002058 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002059 return properties()->get(index.outobject_array_index());
Steve Blocka7e24c12009-10-30 11:49:00 +00002060 }
2061}
2062
2063
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002064double JSObject::RawFastDoublePropertyAt(FieldIndex index) {
2065 DCHECK(IsUnboxedDoubleField(index));
2066 return READ_DOUBLE_FIELD(this, index.offset());
2067}
2068
2069
2070void JSObject::RawFastPropertyAtPut(FieldIndex index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002071 if (index.is_inobject()) {
2072 int offset = index.offset();
Steve Blocka7e24c12009-10-30 11:49:00 +00002073 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002074 WRITE_BARRIER(GetHeap(), this, offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002075 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002076 properties()->set(index.outobject_array_index(), value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002077 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002078}
2079
2080
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002081void JSObject::RawFastDoublePropertyAtPut(FieldIndex index, double value) {
2082 WRITE_DOUBLE_FIELD(this, index.offset(), value);
2083}
2084
2085
2086void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
2087 if (IsUnboxedDoubleField(index)) {
2088 DCHECK(value->IsMutableHeapNumber());
2089 RawFastDoublePropertyAtPut(index, HeapNumber::cast(value)->value());
2090 } else {
2091 RawFastPropertyAtPut(index, value);
2092 }
2093}
2094
Ben Murdoch097c5b22016-05-18 11:27:45 +01002095void JSObject::WriteToField(int descriptor, PropertyDetails details,
2096 Object* value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002097 DCHECK(details.type() == DATA);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002098 DisallowHeapAllocation no_gc;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002099 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor);
2100 if (details.representation().IsDouble()) {
2101 // Nothing more to be done.
2102 if (value->IsUninitialized()) return;
2103 if (IsUnboxedDoubleField(index)) {
2104 RawFastDoublePropertyAtPut(index, value->Number());
2105 } else {
2106 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index));
2107 DCHECK(box->IsMutableHeapNumber());
2108 box->set_value(value->Number());
2109 }
2110 } else {
2111 RawFastPropertyAtPut(index, value);
2112 }
2113}
2114
Ben Murdoch097c5b22016-05-18 11:27:45 +01002115void JSObject::WriteToField(int descriptor, Object* value) {
2116 DescriptorArray* desc = map()->instance_descriptors();
2117 PropertyDetails details = desc->GetDetails(descriptor);
2118 WriteToField(descriptor, details, value);
2119}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002120
Steve Block44f0eee2011-05-26 01:26:41 +01002121int JSObject::GetInObjectPropertyOffset(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002122 return map()->GetInObjectPropertyOffset(index);
Steve Block44f0eee2011-05-26 01:26:41 +01002123}
2124
2125
Steve Blocka7e24c12009-10-30 11:49:00 +00002126Object* JSObject::InObjectPropertyAt(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002127 int offset = GetInObjectPropertyOffset(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002128 return READ_FIELD(this, offset);
2129}
2130
2131
2132Object* JSObject::InObjectPropertyAtPut(int index,
2133 Object* value,
2134 WriteBarrierMode mode) {
2135 // Adjust for the number of properties stored in the object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002136 int offset = GetInObjectPropertyOffset(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002137 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002138 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002139 return value;
2140}
2141
2142
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002143void JSObject::InitializeBody(Map* map, int start_offset,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002144 Object* pre_allocated_value,
2145 Object* filler_value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002146 DCHECK(!filler_value->IsHeapObject() ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002147 !GetHeap()->InNewSpace(filler_value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002148 DCHECK(!pre_allocated_value->IsHeapObject() ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002149 !GetHeap()->InNewSpace(pre_allocated_value));
2150 int size = map->instance_size();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002151 int offset = start_offset;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002152 if (filler_value != pre_allocated_value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002153 int end_of_pre_allocated_offset =
2154 size - (map->unused_property_fields() * kPointerSize);
2155 DCHECK_LE(kHeaderSize, end_of_pre_allocated_offset);
2156 while (offset < end_of_pre_allocated_offset) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002157 WRITE_FIELD(this, offset, pre_allocated_value);
2158 offset += kPointerSize;
2159 }
2160 }
2161 while (offset < size) {
2162 WRITE_FIELD(this, offset, filler_value);
2163 offset += kPointerSize;
Steve Blocka7e24c12009-10-30 11:49:00 +00002164 }
2165}
2166
2167
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002168bool Map::TooManyFastProperties(StoreFromKeyed store_mode) {
2169 if (unused_property_fields() != 0) return false;
2170 if (is_prototype_map()) return false;
2171 int minimum = store_mode == CERTAINLY_NOT_STORE_FROM_KEYED ? 128 : 12;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002172 int limit = Max(minimum, GetInObjectProperties());
2173 int external = NumberOfFields() - GetInObjectProperties();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002174 return external > limit;
Steve Block8defd9f2010-07-08 12:39:36 +01002175}
2176
2177
Steve Blocka7e24c12009-10-30 11:49:00 +00002178void Struct::InitializeBody(int object_size) {
Steve Block44f0eee2011-05-26 01:26:41 +01002179 Object* value = GetHeap()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00002180 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
2181 WRITE_FIELD(this, offset, value);
2182 }
2183}
2184
2185
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002186bool Object::ToArrayLength(uint32_t* index) { return Object::ToUint32(index); }
2187
2188
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002189bool Object::ToArrayIndex(uint32_t* index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002190 return Object::ToUint32(index) && *index != kMaxUInt32;
Steve Blocka7e24c12009-10-30 11:49:00 +00002191}
2192
2193
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002194void Object::VerifyApiCallResultType() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002195#if DEBUG
2196 if (!(IsSmi() || IsString() || IsSymbol() || IsJSReceiver() ||
2197 IsHeapNumber() || IsSimd128Value() || IsUndefined() || IsTrue() ||
2198 IsFalse() || IsNull())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002199 FATAL("API call returned invalid object");
2200 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002201#endif // DEBUG
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002202}
2203
2204
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002205Object* FixedArray::get(int index) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002206 SLOW_DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00002207 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
2208}
2209
Ben Murdoch097c5b22016-05-18 11:27:45 +01002210Handle<Object> FixedArray::get(FixedArray* array, int index, Isolate* isolate) {
2211 return handle(array->get(index), isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002212}
2213
2214
2215bool FixedArray::is_the_hole(int index) {
2216 return get(index) == GetHeap()->the_hole_value();
2217}
2218
2219
Steve Blocka7e24c12009-10-30 11:49:00 +00002220void FixedArray::set(int index, Smi* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002221 DCHECK(map() != GetHeap()->fixed_cow_array_map());
2222 DCHECK(index >= 0 && index < this->length());
2223 DCHECK(reinterpret_cast<Object*>(value)->IsSmi());
Steve Blocka7e24c12009-10-30 11:49:00 +00002224 int offset = kHeaderSize + index * kPointerSize;
2225 WRITE_FIELD(this, offset, value);
2226}
2227
2228
2229void FixedArray::set(int index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002230 DCHECK_NE(GetHeap()->fixed_cow_array_map(), map());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002231 DCHECK(IsFixedArray());
Ben Murdoch097c5b22016-05-18 11:27:45 +01002232 DCHECK_GE(index, 0);
2233 DCHECK_LT(index, this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00002234 int offset = kHeaderSize + index * kPointerSize;
2235 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002236 WRITE_BARRIER(GetHeap(), this, offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002237}
2238
2239
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002240double FixedDoubleArray::get_scalar(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002241 DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2242 map() != GetHeap()->fixed_array_map());
2243 DCHECK(index >= 0 && index < this->length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002244 DCHECK(!is_the_hole(index));
2245 return READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002246}
2247
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002248
2249uint64_t FixedDoubleArray::get_representation(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002250 DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2251 map() != GetHeap()->fixed_array_map());
2252 DCHECK(index >= 0 && index < this->length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002253 int offset = kHeaderSize + index * kDoubleSize;
2254 return READ_UINT64_FIELD(this, offset);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002255}
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002256
Ben Murdoch097c5b22016-05-18 11:27:45 +01002257Handle<Object> FixedDoubleArray::get(FixedDoubleArray* array, int index,
2258 Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002259 if (array->is_the_hole(index)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002260 return isolate->factory()->the_hole_value();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002261 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002262 return isolate->factory()->NewNumber(array->get_scalar(index));
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002263 }
2264}
2265
2266
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002267void FixedDoubleArray::set(int index, double value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002268 DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2269 map() != GetHeap()->fixed_array_map());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002270 int offset = kHeaderSize + index * kDoubleSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002271 if (std::isnan(value)) {
2272 WRITE_DOUBLE_FIELD(this, offset, std::numeric_limits<double>::quiet_NaN());
2273 } else {
2274 WRITE_DOUBLE_FIELD(this, offset, value);
2275 }
2276 DCHECK(!is_the_hole(index));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002277}
2278
2279
2280void FixedDoubleArray::set_the_hole(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002281 DCHECK(map() != GetHeap()->fixed_cow_array_map() &&
2282 map() != GetHeap()->fixed_array_map());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002283 int offset = kHeaderSize + index * kDoubleSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002284 WRITE_UINT64_FIELD(this, offset, kHoleNanInt64);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002285}
2286
2287
2288bool FixedDoubleArray::is_the_hole(int index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002289 return get_representation(index) == kHoleNanInt64;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002290}
2291
2292
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002293double* FixedDoubleArray::data_start() {
2294 return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
2295}
2296
2297
2298void FixedDoubleArray::FillWithHoles(int from, int to) {
2299 for (int i = from; i < to; i++) {
2300 set_the_hole(i);
2301 }
2302}
2303
2304
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002305Object* WeakFixedArray::Get(int index) const {
2306 Object* raw = FixedArray::cast(this)->get(index + kFirstIndex);
2307 if (raw->IsSmi()) return raw;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002308 DCHECK(raw->IsWeakCell());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002309 return WeakCell::cast(raw)->value();
2310}
2311
2312
2313bool WeakFixedArray::IsEmptySlot(int index) const {
2314 DCHECK(index < Length());
2315 return Get(index)->IsSmi();
2316}
2317
2318
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002319void WeakFixedArray::Clear(int index) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002320 FixedArray::cast(this)->set(index + kFirstIndex, Smi::FromInt(0));
2321}
2322
2323
2324int WeakFixedArray::Length() const {
2325 return FixedArray::cast(this)->length() - kFirstIndex;
2326}
2327
2328
2329int WeakFixedArray::last_used_index() const {
2330 return Smi::cast(FixedArray::cast(this)->get(kLastUsedIndexIndex))->value();
2331}
2332
2333
2334void WeakFixedArray::set_last_used_index(int index) {
2335 FixedArray::cast(this)->set(kLastUsedIndexIndex, Smi::FromInt(index));
2336}
2337
2338
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002339template <class T>
2340T* WeakFixedArray::Iterator::Next() {
2341 if (list_ != NULL) {
2342 // Assert that list did not change during iteration.
2343 DCHECK_EQ(last_used_index_, list_->last_used_index());
2344 while (index_ < list_->Length()) {
2345 Object* item = list_->Get(index_++);
2346 if (item != Empty()) return T::cast(item);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002347 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002348 list_ = NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002349 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002350 return NULL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002351}
2352
2353
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002354int ArrayList::Length() {
2355 if (FixedArray::cast(this)->length() == 0) return 0;
2356 return Smi::cast(FixedArray::cast(this)->get(kLengthIndex))->value();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002357}
2358
2359
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002360void ArrayList::SetLength(int length) {
2361 return FixedArray::cast(this)->set(kLengthIndex, Smi::FromInt(length));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002362}
2363
2364
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002365Object* ArrayList::Get(int index) {
2366 return FixedArray::cast(this)->get(kFirstIndex + index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002367}
2368
2369
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002370Object** ArrayList::Slot(int index) {
2371 return data_start() + kFirstIndex + index;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002372}
2373
2374
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002375void ArrayList::Set(int index, Object* obj) {
2376 FixedArray::cast(this)->set(kFirstIndex + index, obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002377}
2378
2379
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002380void ArrayList::Clear(int index, Object* undefined) {
2381 DCHECK(undefined->IsUndefined());
2382 FixedArray::cast(this)
2383 ->set(kFirstIndex + index, undefined, SKIP_WRITE_BARRIER);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002384}
2385
2386
2387WriteBarrierMode HeapObject::GetWriteBarrierMode(
2388 const DisallowHeapAllocation& promise) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002389 Heap* heap = GetHeap();
2390 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
2391 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
Steve Blocka7e24c12009-10-30 11:49:00 +00002392 return UPDATE_WRITE_BARRIER;
2393}
2394
2395
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002396AllocationAlignment HeapObject::RequiredAlignment() {
2397#ifdef V8_HOST_ARCH_32_BIT
2398 if ((IsFixedFloat64Array() || IsFixedDoubleArray()) &&
2399 FixedArrayBase::cast(this)->length() != 0) {
2400 return kDoubleAligned;
2401 }
2402 if (IsHeapNumber()) return kDoubleUnaligned;
2403 if (IsSimd128Value()) return kSimd128Unaligned;
2404#endif // V8_HOST_ARCH_32_BIT
2405 return kWordAligned;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002406}
2407
2408
Steve Blocka7e24c12009-10-30 11:49:00 +00002409void FixedArray::set(int index,
2410 Object* value,
2411 WriteBarrierMode mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002412 DCHECK(map() != GetHeap()->fixed_cow_array_map());
2413 DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00002414 int offset = kHeaderSize + index * kPointerSize;
2415 WRITE_FIELD(this, offset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002416 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00002417}
2418
2419
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002420void FixedArray::NoWriteBarrierSet(FixedArray* array,
2421 int index,
2422 Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002423 DCHECK(array->map() != array->GetHeap()->fixed_cow_array_map());
2424 DCHECK(index >= 0 && index < array->length());
2425 DCHECK(!array->GetHeap()->InNewSpace(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00002426 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
2427}
2428
2429
2430void FixedArray::set_undefined(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002431 DCHECK(map() != GetHeap()->fixed_cow_array_map());
2432 DCHECK(index >= 0 && index < this->length());
2433 DCHECK(!GetHeap()->InNewSpace(GetHeap()->undefined_value()));
2434 WRITE_FIELD(this,
2435 kHeaderSize + index * kPointerSize,
2436 GetHeap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002437}
2438
2439
2440void FixedArray::set_null(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002441 DCHECK(index >= 0 && index < this->length());
2442 DCHECK(!GetHeap()->InNewSpace(GetHeap()->null_value()));
2443 WRITE_FIELD(this,
2444 kHeaderSize + index * kPointerSize,
2445 GetHeap()->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002446}
2447
2448
2449void FixedArray::set_the_hole(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002450 DCHECK(map() != GetHeap()->fixed_cow_array_map());
2451 DCHECK(index >= 0 && index < this->length());
2452 DCHECK(!GetHeap()->InNewSpace(GetHeap()->the_hole_value()));
Steve Block44f0eee2011-05-26 01:26:41 +01002453 WRITE_FIELD(this,
2454 kHeaderSize + index * kPointerSize,
2455 GetHeap()->the_hole_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002456}
2457
2458
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002459void FixedArray::FillWithHoles(int from, int to) {
2460 for (int i = from; i < to; i++) {
2461 set_the_hole(i);
2462 }
Iain Merrick75681382010-08-19 15:07:18 +01002463}
2464
2465
Steve Block6ded16b2010-05-10 14:33:55 +01002466Object** FixedArray::data_start() {
2467 return HeapObject::RawField(this, kHeaderSize);
2468}
2469
2470
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002471Object** FixedArray::RawFieldOfElementAt(int index) {
2472 return HeapObject::RawField(this, OffsetOfElementAt(index));
2473}
2474
2475
Steve Blocka7e24c12009-10-30 11:49:00 +00002476bool DescriptorArray::IsEmpty() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002477 DCHECK(length() >= kFirstIndex ||
2478 this == GetHeap()->empty_descriptor_array());
2479 return length() < kFirstIndex;
Ben Murdoch257744e2011-11-30 15:57:28 +00002480}
2481
2482
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002483int DescriptorArray::number_of_descriptors() {
2484 DCHECK(length() >= kFirstIndex || IsEmpty());
2485 int len = length();
2486 return len == 0 ? 0 : Smi::cast(get(kDescriptorLengthIndex))->value();
2487}
2488
2489
2490int DescriptorArray::number_of_descriptors_storage() {
2491 int len = length();
2492 return len == 0 ? 0 : (len - kFirstIndex) / kDescriptorSize;
2493}
2494
2495
2496int DescriptorArray::NumberOfSlackDescriptors() {
2497 return number_of_descriptors_storage() - number_of_descriptors();
2498}
2499
2500
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002501void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
2502 WRITE_FIELD(
2503 this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors));
Steve Blocka7e24c12009-10-30 11:49:00 +00002504}
2505
2506
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002507inline int DescriptorArray::number_of_entries() {
2508 return number_of_descriptors();
2509}
2510
2511
2512bool DescriptorArray::HasEnumCache() {
2513 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi();
2514}
2515
2516
2517void DescriptorArray::CopyEnumCacheFrom(DescriptorArray* array) {
2518 set(kEnumCacheIndex, array->get(kEnumCacheIndex));
2519}
2520
2521
2522FixedArray* DescriptorArray::GetEnumCache() {
2523 DCHECK(HasEnumCache());
2524 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
2525 return FixedArray::cast(bridge->get(kEnumCacheBridgeCacheIndex));
2526}
2527
2528
2529bool DescriptorArray::HasEnumIndicesCache() {
2530 if (IsEmpty()) return false;
2531 Object* object = get(kEnumCacheIndex);
2532 if (object->IsSmi()) return false;
2533 FixedArray* bridge = FixedArray::cast(object);
2534 return !bridge->get(kEnumCacheBridgeIndicesCacheIndex)->IsSmi();
2535}
2536
2537
2538FixedArray* DescriptorArray::GetEnumIndicesCache() {
2539 DCHECK(HasEnumIndicesCache());
2540 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
2541 return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex));
2542}
2543
2544
2545Object** DescriptorArray::GetEnumCacheSlot() {
2546 DCHECK(HasEnumCache());
2547 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
2548 kEnumCacheOffset);
2549}
2550
Ben Murdoch097c5b22016-05-18 11:27:45 +01002551// Perform a binary search in a fixed array.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002552template <SearchMode search_mode, typename T>
Ben Murdoch097c5b22016-05-18 11:27:45 +01002553int BinarySearch(T* array, Name* name, int valid_entries,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002554 int* out_insertion_index) {
2555 DCHECK(search_mode == ALL_ENTRIES || out_insertion_index == NULL);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002556 int low = 0;
2557 int high = array->number_of_entries() - 1;
2558 uint32_t hash = name->hash_field();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002559 int limit = high;
2560
2561 DCHECK(low <= high);
2562
2563 while (low != high) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002564 int mid = low + (high - low) / 2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002565 Name* mid_name = array->GetSortedKey(mid);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002566 uint32_t mid_hash = mid_name->hash_field();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002567
2568 if (mid_hash >= hash) {
2569 high = mid;
2570 } else {
2571 low = mid + 1;
2572 }
2573 }
2574
2575 for (; low <= limit; ++low) {
2576 int sort_index = array->GetSortedKeyIndex(low);
2577 Name* entry = array->GetKey(sort_index);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002578 uint32_t current_hash = entry->hash_field();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002579 if (current_hash != hash) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002580 if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002581 *out_insertion_index = sort_index + (current_hash > hash ? 0 : 1);
2582 }
2583 return T::kNotFound;
2584 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002585 if (entry == name) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002586 if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
2587 return sort_index;
2588 }
2589 return T::kNotFound;
2590 }
2591 }
2592
Ben Murdoch097c5b22016-05-18 11:27:45 +01002593 if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
2594 *out_insertion_index = limit + 1;
2595 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002596 return T::kNotFound;
Steve Blocka7e24c12009-10-30 11:49:00 +00002597}
2598
2599
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002600// Perform a linear search in this fixed array. len is the number of entry
2601// indices that are valid.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002602template <SearchMode search_mode, typename T>
Ben Murdoch097c5b22016-05-18 11:27:45 +01002603int LinearSearch(T* array, Name* name, int valid_entries,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002604 int* out_insertion_index) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002605 if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
2606 uint32_t hash = name->hash_field();
2607 int len = array->number_of_entries();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002608 for (int number = 0; number < len; number++) {
2609 int sorted_index = array->GetSortedKeyIndex(number);
2610 Name* entry = array->GetKey(sorted_index);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002611 uint32_t current_hash = entry->hash_field();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002612 if (current_hash > hash) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002613 *out_insertion_index = sorted_index;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002614 return T::kNotFound;
2615 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002616 if (entry == name) return sorted_index;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002617 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002618 *out_insertion_index = len;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002619 return T::kNotFound;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002620 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002621 DCHECK_LE(valid_entries, array->number_of_entries());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002622 DCHECK_NULL(out_insertion_index); // Not supported here.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002623 for (int number = 0; number < valid_entries; number++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002624 if (array->GetKey(number) == name) return number;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002625 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002626 return T::kNotFound;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002627 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002628}
Steve Blocka7e24c12009-10-30 11:49:00 +00002629
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002630
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002631template <SearchMode search_mode, typename T>
2632int Search(T* array, Name* name, int valid_entries, int* out_insertion_index) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002633 SLOW_DCHECK(array->IsSortedNoDuplicates());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002634
Ben Murdoch097c5b22016-05-18 11:27:45 +01002635 if (valid_entries == 0) {
2636 if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
2637 *out_insertion_index = 0;
2638 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002639 return T::kNotFound;
2640 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002641
2642 // Fast case: do linear search for small arrays.
2643 const int kMaxElementsForLinearSearch = 8;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002644 if (valid_entries <= kMaxElementsForLinearSearch) {
2645 return LinearSearch<search_mode>(array, name, valid_entries,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002646 out_insertion_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002647 }
2648
2649 // Slow case: perform binary search.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002650 return BinarySearch<search_mode>(array, name, valid_entries,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002651 out_insertion_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002652}
2653
2654
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002655int DescriptorArray::Search(Name* name, int valid_descriptors) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002656 DCHECK(name->IsUniqueName());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002657 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors, NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002658}
2659
Ben Murdoch097c5b22016-05-18 11:27:45 +01002660int DescriptorArray::SearchWithCache(Isolate* isolate, Name* name, Map* map) {
2661 DCHECK(name->IsUniqueName());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002662 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
2663 if (number_of_own_descriptors == 0) return kNotFound;
2664
Ben Murdoch097c5b22016-05-18 11:27:45 +01002665 DescriptorLookupCache* cache = isolate->descriptor_lookup_cache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002666 int number = cache->Lookup(map, name);
2667
Iain Merrick75681382010-08-19 15:07:18 +01002668 if (number == DescriptorLookupCache::kAbsent) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002669 number = Search(name, number_of_own_descriptors);
2670 cache->Update(map, name, number);
Iain Merrick75681382010-08-19 15:07:18 +01002671 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002672
Iain Merrick75681382010-08-19 15:07:18 +01002673 return number;
2674}
2675
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002676PropertyDetails Map::GetLastDescriptorDetails() {
2677 return instance_descriptors()->GetDetails(LastAdded());
2678}
2679
2680
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002681int Map::LastAdded() {
2682 int number_of_own_descriptors = NumberOfOwnDescriptors();
2683 DCHECK(number_of_own_descriptors > 0);
2684 return number_of_own_descriptors - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002685}
2686
2687
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002688int Map::NumberOfOwnDescriptors() {
2689 return NumberOfOwnDescriptorsBits::decode(bit_field3());
2690}
2691
2692
2693void Map::SetNumberOfOwnDescriptors(int number) {
2694 DCHECK(number <= instance_descriptors()->number_of_descriptors());
2695 set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number));
2696}
2697
2698
2699int Map::EnumLength() { return EnumLengthBits::decode(bit_field3()); }
2700
2701
2702void Map::SetEnumLength(int length) {
2703 if (length != kInvalidEnumCacheSentinel) {
2704 DCHECK(length >= 0);
2705 DCHECK(length == 0 || instance_descriptors()->HasEnumCache());
2706 DCHECK(length <= NumberOfOwnDescriptors());
2707 }
2708 set_bit_field3(EnumLengthBits::update(bit_field3(), length));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002709}
2710
2711
2712FixedArrayBase* Map::GetInitialElements() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002713 if (has_fast_elements() || has_fast_string_wrapper_elements()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002714 DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
2715 return GetHeap()->empty_fixed_array();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002716 } else if (has_fixed_typed_array_elements()) {
2717 FixedTypedArrayBase* empty_array =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002718 GetHeap()->EmptyFixedTypedArrayForMap(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002719 DCHECK(!GetHeap()->InNewSpace(empty_array));
2720 return empty_array;
2721 } else {
2722 UNREACHABLE();
2723 }
2724 return NULL;
2725}
2726
2727
2728Object** DescriptorArray::GetKeySlot(int descriptor_number) {
2729 DCHECK(descriptor_number < number_of_descriptors());
2730 return RawFieldOfElementAt(ToKeyIndex(descriptor_number));
2731}
2732
2733
2734Object** DescriptorArray::GetDescriptorStartSlot(int descriptor_number) {
2735 return GetKeySlot(descriptor_number);
2736}
2737
2738
2739Object** DescriptorArray::GetDescriptorEndSlot(int descriptor_number) {
2740 return GetValueSlot(descriptor_number - 1) + 1;
2741}
2742
2743
2744Name* DescriptorArray::GetKey(int descriptor_number) {
2745 DCHECK(descriptor_number < number_of_descriptors());
2746 return Name::cast(get(ToKeyIndex(descriptor_number)));
2747}
2748
2749
2750int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
2751 return GetDetails(descriptor_number).pointer();
2752}
2753
2754
2755Name* DescriptorArray::GetSortedKey(int descriptor_number) {
2756 return GetKey(GetSortedKeyIndex(descriptor_number));
2757}
2758
2759
2760void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
2761 PropertyDetails details = GetDetails(descriptor_index);
2762 set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi());
2763}
2764
2765
2766void DescriptorArray::SetRepresentation(int descriptor_index,
2767 Representation representation) {
2768 DCHECK(!representation.IsNone());
2769 PropertyDetails details = GetDetails(descriptor_index);
2770 set(ToDetailsIndex(descriptor_index),
2771 details.CopyWithRepresentation(representation).AsSmi());
2772}
2773
2774
2775Object** DescriptorArray::GetValueSlot(int descriptor_number) {
2776 DCHECK(descriptor_number < number_of_descriptors());
2777 return RawFieldOfElementAt(ToValueIndex(descriptor_number));
2778}
2779
2780
2781int DescriptorArray::GetValueOffset(int descriptor_number) {
2782 return OffsetOfElementAt(ToValueIndex(descriptor_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00002783}
2784
2785
2786Object* DescriptorArray::GetValue(int descriptor_number) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002787 DCHECK(descriptor_number < number_of_descriptors());
2788 return get(ToValueIndex(descriptor_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00002789}
2790
2791
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002792void DescriptorArray::SetValue(int descriptor_index, Object* value) {
2793 set(ToValueIndex(descriptor_index), value);
2794}
2795
2796
2797PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
2798 DCHECK(descriptor_number < number_of_descriptors());
2799 Object* details = get(ToDetailsIndex(descriptor_number));
2800 return PropertyDetails(Smi::cast(details));
Steve Blocka7e24c12009-10-30 11:49:00 +00002801}
2802
2803
2804PropertyType DescriptorArray::GetType(int descriptor_number) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002805 return GetDetails(descriptor_number).type();
Steve Blocka7e24c12009-10-30 11:49:00 +00002806}
2807
2808
2809int DescriptorArray::GetFieldIndex(int descriptor_number) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002810 DCHECK(GetDetails(descriptor_number).location() == kField);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002811 return GetDetails(descriptor_number).field_index();
Steve Blocka7e24c12009-10-30 11:49:00 +00002812}
2813
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002814Object* DescriptorArray::GetConstant(int descriptor_number) {
2815 return GetValue(descriptor_number);
Steve Blocka7e24c12009-10-30 11:49:00 +00002816}
2817
2818
2819Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002820 DCHECK(GetType(descriptor_number) == ACCESSOR_CONSTANT);
Steve Blocka7e24c12009-10-30 11:49:00 +00002821 return GetValue(descriptor_number);
2822}
2823
2824
2825AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002826 DCHECK(GetType(descriptor_number) == ACCESSOR_CONSTANT);
Ben Murdoch257744e2011-11-30 15:57:28 +00002827 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002828 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
Steve Blocka7e24c12009-10-30 11:49:00 +00002829}
2830
2831
Steve Blocka7e24c12009-10-30 11:49:00 +00002832void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002833 desc->Init(handle(GetKey(descriptor_number), GetIsolate()),
2834 handle(GetValue(descriptor_number), GetIsolate()),
2835 GetDetails(descriptor_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00002836}
2837
2838
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002839void DescriptorArray::SetDescriptor(int descriptor_number, Descriptor* desc) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002840 // Range check.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002841 DCHECK(descriptor_number < number_of_descriptors());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002842 set(ToKeyIndex(descriptor_number), *desc->GetKey());
2843 set(ToValueIndex(descriptor_number), *desc->GetValue());
2844 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
Steve Blocka7e24c12009-10-30 11:49:00 +00002845}
2846
2847
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002848void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
2849 // Range check.
2850 DCHECK(descriptor_number < number_of_descriptors());
2851
2852 set(ToKeyIndex(descriptor_number), *desc->GetKey());
2853 set(ToValueIndex(descriptor_number), *desc->GetValue());
2854 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
2855}
2856
2857
2858void DescriptorArray::Append(Descriptor* desc) {
2859 DisallowHeapAllocation no_gc;
2860 int descriptor_number = number_of_descriptors();
2861 SetNumberOfDescriptors(descriptor_number + 1);
2862 Set(descriptor_number, desc);
2863
2864 uint32_t hash = desc->GetKey()->Hash();
2865
2866 int insertion;
2867
2868 for (insertion = descriptor_number; insertion > 0; --insertion) {
2869 Name* key = GetSortedKey(insertion - 1);
2870 if (key->Hash() <= hash) break;
2871 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
2872 }
2873
2874 SetSortedKey(insertion, descriptor_number);
2875}
2876
2877
2878void DescriptorArray::SwapSortedKeys(int first, int second) {
2879 int first_key = GetSortedKeyIndex(first);
2880 SetSortedKey(first, GetSortedKeyIndex(second));
2881 SetSortedKey(second, first_key);
Ben Murdoch85b71792012-04-11 18:30:58 +01002882}
2883
2884
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002885PropertyType DescriptorArray::Entry::type() { return descs_->GetType(index_); }
2886
2887
2888Object* DescriptorArray::Entry::GetCallbackObject() {
2889 return descs_->GetValue(index_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002890}
2891
2892
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002893int HashTableBase::NumberOfElements() {
2894 return Smi::cast(get(kNumberOfElementsIndex))->value();
Steve Blocka7e24c12009-10-30 11:49:00 +00002895}
2896
2897
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002898int HashTableBase::NumberOfDeletedElements() {
2899 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
2900}
2901
2902
2903int HashTableBase::Capacity() {
2904 return Smi::cast(get(kCapacityIndex))->value();
2905}
2906
2907
2908void HashTableBase::ElementAdded() {
2909 SetNumberOfElements(NumberOfElements() + 1);
2910}
2911
2912
2913void HashTableBase::ElementRemoved() {
2914 SetNumberOfElements(NumberOfElements() - 1);
2915 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
2916}
2917
2918
2919void HashTableBase::ElementsRemoved(int n) {
2920 SetNumberOfElements(NumberOfElements() - n);
2921 SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
2922}
2923
2924
2925// static
2926int HashTableBase::ComputeCapacity(int at_least_space_for) {
2927 const int kMinCapacity = 4;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002928 int capacity = base::bits::RoundUpToPowerOfTwo32(at_least_space_for * 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002929 return Max(capacity, kMinCapacity);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002930}
2931
2932
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002933bool HashTableBase::IsKey(Object* k) {
2934 return !k->IsTheHole() && !k->IsUndefined();
2935}
2936
2937
2938void HashTableBase::SetNumberOfElements(int nof) {
2939 set(kNumberOfElementsIndex, Smi::FromInt(nof));
2940}
2941
2942
2943void HashTableBase::SetNumberOfDeletedElements(int nod) {
2944 set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod));
2945}
2946
2947
2948template <typename Derived, typename Shape, typename Key>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002949int HashTable<Derived, Shape, Key>::FindEntry(Key key) {
Steve Block44f0eee2011-05-26 01:26:41 +01002950 return FindEntry(GetIsolate(), key);
2951}
2952
2953
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002954template<typename Derived, typename Shape, typename Key>
2955int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002956 return FindEntry(isolate, key, HashTable::Hash(key));
2957}
2958
2959
2960// Find entry for key otherwise return kNotFound.
2961template <typename Derived, typename Shape, typename Key>
2962int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key,
2963 int32_t hash) {
Steve Block44f0eee2011-05-26 01:26:41 +01002964 uint32_t capacity = Capacity();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002965 uint32_t entry = FirstProbe(hash, capacity);
Steve Block44f0eee2011-05-26 01:26:41 +01002966 uint32_t count = 1;
2967 // EnsureCapacity will guarantee the hash table is never full.
2968 while (true) {
2969 Object* element = KeyAt(entry);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002970 // Empty entry. Uses raw unchecked accessors because it is called by the
2971 // string table during bootstrapping.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002972 if (element == isolate->heap()->root(Heap::kUndefinedValueRootIndex)) break;
2973 if (element != isolate->heap()->root(Heap::kTheHoleValueRootIndex) &&
Steve Block44f0eee2011-05-26 01:26:41 +01002974 Shape::IsMatch(key, element)) return entry;
2975 entry = NextProbe(entry, count++, capacity);
2976 }
2977 return kNotFound;
2978}
2979
2980
Ben Murdochc7cc0282012-03-05 14:35:55 +00002981bool SeededNumberDictionary::requires_slow_elements() {
Steve Blocka7e24c12009-10-30 11:49:00 +00002982 Object* max_index_object = get(kMaxNumberKeyIndex);
2983 if (!max_index_object->IsSmi()) return false;
2984 return 0 !=
2985 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2986}
2987
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002988
Ben Murdochc7cc0282012-03-05 14:35:55 +00002989uint32_t SeededNumberDictionary::max_number_key() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002990 DCHECK(!requires_slow_elements());
Steve Blocka7e24c12009-10-30 11:49:00 +00002991 Object* max_index_object = get(kMaxNumberKeyIndex);
2992 if (!max_index_object->IsSmi()) return 0;
2993 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2994 return value >> kRequiresSlowElementsTagSize;
2995}
2996
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002997
Ben Murdochc7cc0282012-03-05 14:35:55 +00002998void SeededNumberDictionary::set_requires_slow_elements() {
Leon Clarke4515c472010-02-03 11:58:03 +00002999 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
Steve Blocka7e24c12009-10-30 11:49:00 +00003000}
3001
3002
3003// ------------------------------------
3004// Cast operations
3005
Ben Murdoch097c5b22016-05-18 11:27:45 +01003006CAST_ACCESSOR(AbstractCode)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003007CAST_ACCESSOR(ArrayList)
3008CAST_ACCESSOR(Bool16x8)
3009CAST_ACCESSOR(Bool32x4)
3010CAST_ACCESSOR(Bool8x16)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003011CAST_ACCESSOR(ByteArray)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003012CAST_ACCESSOR(BytecodeArray)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003013CAST_ACCESSOR(Cell)
3014CAST_ACCESSOR(Code)
3015CAST_ACCESSOR(CodeCacheHashTable)
3016CAST_ACCESSOR(CompilationCacheTable)
3017CAST_ACCESSOR(ConsString)
Ben Murdochb0fe1622011-05-05 13:52:32 +01003018CAST_ACCESSOR(DeoptimizationInputData)
3019CAST_ACCESSOR(DeoptimizationOutputData)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003020CAST_ACCESSOR(DependentCode)
3021CAST_ACCESSOR(DescriptorArray)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003022CAST_ACCESSOR(ExternalOneByteString)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003023CAST_ACCESSOR(ExternalString)
3024CAST_ACCESSOR(ExternalTwoByteString)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003025CAST_ACCESSOR(FixedArray)
3026CAST_ACCESSOR(FixedArrayBase)
3027CAST_ACCESSOR(FixedDoubleArray)
3028CAST_ACCESSOR(FixedTypedArrayBase)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003029CAST_ACCESSOR(Float32x4)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003030CAST_ACCESSOR(Foreign)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003031CAST_ACCESSOR(GlobalDictionary)
3032CAST_ACCESSOR(HandlerTable)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003033CAST_ACCESSOR(HeapObject)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003034CAST_ACCESSOR(Int16x8)
3035CAST_ACCESSOR(Int32x4)
3036CAST_ACCESSOR(Int8x16)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003037CAST_ACCESSOR(JSArray)
3038CAST_ACCESSOR(JSArrayBuffer)
3039CAST_ACCESSOR(JSArrayBufferView)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003040CAST_ACCESSOR(JSBoundFunction)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003041CAST_ACCESSOR(JSDataView)
3042CAST_ACCESSOR(JSDate)
3043CAST_ACCESSOR(JSFunction)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003044CAST_ACCESSOR(JSGeneratorObject)
3045CAST_ACCESSOR(JSGlobalObject)
3046CAST_ACCESSOR(JSGlobalProxy)
3047CAST_ACCESSOR(JSMap)
3048CAST_ACCESSOR(JSMapIterator)
3049CAST_ACCESSOR(JSMessageObject)
3050CAST_ACCESSOR(JSModule)
3051CAST_ACCESSOR(JSObject)
3052CAST_ACCESSOR(JSProxy)
3053CAST_ACCESSOR(JSReceiver)
3054CAST_ACCESSOR(JSRegExp)
3055CAST_ACCESSOR(JSSet)
3056CAST_ACCESSOR(JSSetIterator)
3057CAST_ACCESSOR(JSTypedArray)
3058CAST_ACCESSOR(JSValue)
3059CAST_ACCESSOR(JSWeakMap)
3060CAST_ACCESSOR(JSWeakSet)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003061CAST_ACCESSOR(LayoutDescriptor)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003062CAST_ACCESSOR(Map)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003063CAST_ACCESSOR(Name)
3064CAST_ACCESSOR(NameDictionary)
3065CAST_ACCESSOR(NormalizedMapCache)
3066CAST_ACCESSOR(Object)
3067CAST_ACCESSOR(ObjectHashTable)
3068CAST_ACCESSOR(Oddball)
3069CAST_ACCESSOR(OrderedHashMap)
3070CAST_ACCESSOR(OrderedHashSet)
3071CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
3072CAST_ACCESSOR(PropertyCell)
3073CAST_ACCESSOR(ScopeInfo)
3074CAST_ACCESSOR(SeededNumberDictionary)
3075CAST_ACCESSOR(SeqOneByteString)
3076CAST_ACCESSOR(SeqString)
3077CAST_ACCESSOR(SeqTwoByteString)
3078CAST_ACCESSOR(SharedFunctionInfo)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003079CAST_ACCESSOR(Simd128Value)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003080CAST_ACCESSOR(SlicedString)
3081CAST_ACCESSOR(Smi)
3082CAST_ACCESSOR(String)
3083CAST_ACCESSOR(StringTable)
Steve Blocka7e24c12009-10-30 11:49:00 +00003084CAST_ACCESSOR(Struct)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003085CAST_ACCESSOR(Symbol)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003086CAST_ACCESSOR(Uint16x8)
3087CAST_ACCESSOR(Uint32x4)
3088CAST_ACCESSOR(Uint8x16)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003089CAST_ACCESSOR(UnseededNumberDictionary)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003090CAST_ACCESSOR(WeakCell)
3091CAST_ACCESSOR(WeakFixedArray)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003092CAST_ACCESSOR(WeakHashTable)
3093
3094
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003095// static
3096template <class Traits>
3097STATIC_CONST_MEMBER_DEFINITION const InstanceType
3098 FixedTypedArray<Traits>::kInstanceType;
3099
3100
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003101template <class Traits>
3102FixedTypedArray<Traits>* FixedTypedArray<Traits>::cast(Object* object) {
3103 SLOW_DCHECK(object->IsHeapObject() &&
3104 HeapObject::cast(object)->map()->instance_type() ==
3105 Traits::kInstanceType);
3106 return reinterpret_cast<FixedTypedArray<Traits>*>(object);
3107}
3108
3109
3110template <class Traits>
3111const FixedTypedArray<Traits>*
3112FixedTypedArray<Traits>::cast(const Object* object) {
3113 SLOW_DCHECK(object->IsHeapObject() &&
3114 HeapObject::cast(object)->map()->instance_type() ==
3115 Traits::kInstanceType);
3116 return reinterpret_cast<FixedTypedArray<Traits>*>(object);
3117}
Steve Blocka7e24c12009-10-30 11:49:00 +00003118
3119
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003120#define DEFINE_DEOPT_ELEMENT_ACCESSORS(name, type) \
3121 type* DeoptimizationInputData::name() { \
3122 return type::cast(get(k##name##Index)); \
3123 } \
3124 void DeoptimizationInputData::Set##name(type* value) { \
3125 set(k##name##Index, value); \
3126 }
3127
3128DEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray)
3129DEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi)
3130DEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
3131DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrAstId, Smi)
3132DEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
3133DEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi)
3134DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
3135DEFINE_DEOPT_ELEMENT_ACCESSORS(WeakCellCache, Object)
3136
3137#undef DEFINE_DEOPT_ELEMENT_ACCESSORS
3138
3139
3140#define DEFINE_DEOPT_ENTRY_ACCESSORS(name, type) \
3141 type* DeoptimizationInputData::name(int i) { \
3142 return type::cast(get(IndexForEntry(i) + k##name##Offset)); \
3143 } \
3144 void DeoptimizationInputData::Set##name(int i, type* value) { \
3145 set(IndexForEntry(i) + k##name##Offset, value); \
3146 }
3147
3148DEFINE_DEOPT_ENTRY_ACCESSORS(AstIdRaw, Smi)
3149DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
3150DEFINE_DEOPT_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
3151DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
3152
3153#undef DEFINE_DEOPT_ENTRY_ACCESSORS
3154
3155
3156BailoutId DeoptimizationInputData::AstId(int i) {
3157 return BailoutId(AstIdRaw(i)->value());
3158}
3159
3160
3161void DeoptimizationInputData::SetAstId(int i, BailoutId value) {
3162 SetAstIdRaw(i, Smi::FromInt(value.ToInt()));
3163}
3164
3165
3166int DeoptimizationInputData::DeoptCount() {
3167 return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
3168}
3169
3170
3171int DeoptimizationOutputData::DeoptPoints() { return length() / 2; }
3172
3173
3174BailoutId DeoptimizationOutputData::AstId(int index) {
3175 return BailoutId(Smi::cast(get(index * 2))->value());
3176}
3177
3178
3179void DeoptimizationOutputData::SetAstId(int index, BailoutId id) {
3180 set(index * 2, Smi::FromInt(id.ToInt()));
3181}
3182
3183
3184Smi* DeoptimizationOutputData::PcAndState(int index) {
3185 return Smi::cast(get(1 + index * 2));
3186}
3187
3188
3189void DeoptimizationOutputData::SetPcAndState(int index, Smi* offset) {
3190 set(1 + index * 2, offset);
3191}
3192
3193
3194Object* LiteralsArray::get(int index) const { return FixedArray::get(index); }
3195
3196
3197void LiteralsArray::set(int index, Object* value) {
3198 FixedArray::set(index, value);
3199}
3200
3201
3202void LiteralsArray::set(int index, Smi* value) {
3203 FixedArray::set(index, value);
3204}
3205
3206
3207void LiteralsArray::set(int index, Object* value, WriteBarrierMode mode) {
3208 FixedArray::set(index, value, mode);
3209}
3210
3211
3212LiteralsArray* LiteralsArray::cast(Object* object) {
3213 SLOW_DCHECK(object->IsLiteralsArray());
3214 return reinterpret_cast<LiteralsArray*>(object);
3215}
3216
3217
3218TypeFeedbackVector* LiteralsArray::feedback_vector() const {
3219 return TypeFeedbackVector::cast(get(kVectorIndex));
3220}
3221
3222
3223void LiteralsArray::set_feedback_vector(TypeFeedbackVector* vector) {
3224 set(kVectorIndex, vector);
3225}
3226
3227
3228Object* LiteralsArray::literal(int literal_index) const {
3229 return get(kFirstLiteralIndex + literal_index);
3230}
3231
3232
3233void LiteralsArray::set_literal(int literal_index, Object* literal) {
3234 set(kFirstLiteralIndex + literal_index, literal);
3235}
3236
3237
3238int LiteralsArray::literals_count() const {
3239 return length() - kFirstLiteralIndex;
3240}
3241
Ben Murdoch097c5b22016-05-18 11:27:45 +01003242int HandlerTable::GetRangeStart(int index) const {
3243 return Smi::cast(get(index * kRangeEntrySize + kRangeStartIndex))->value();
3244}
3245
3246int HandlerTable::GetRangeEnd(int index) const {
3247 return Smi::cast(get(index * kRangeEntrySize + kRangeEndIndex))->value();
3248}
3249
3250int HandlerTable::GetRangeHandler(int index) const {
3251 return HandlerOffsetField::decode(
3252 Smi::cast(get(index * kRangeEntrySize + kRangeHandlerIndex))->value());
3253}
3254
3255int HandlerTable::GetRangeData(int index) const {
3256 return Smi::cast(get(index * kRangeEntrySize + kRangeDataIndex))->value();
3257}
3258
3259HandlerTable::CatchPrediction HandlerTable::GetRangePrediction(
3260 int index) const {
3261 return HandlerPredictionField::decode(
3262 Smi::cast(get(index * kRangeEntrySize + kRangeHandlerIndex))->value());
3263}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003264
3265void HandlerTable::SetRangeStart(int index, int value) {
3266 set(index * kRangeEntrySize + kRangeStartIndex, Smi::FromInt(value));
3267}
3268
3269
3270void HandlerTable::SetRangeEnd(int index, int value) {
3271 set(index * kRangeEntrySize + kRangeEndIndex, Smi::FromInt(value));
3272}
3273
3274
3275void HandlerTable::SetRangeHandler(int index, int offset,
3276 CatchPrediction prediction) {
3277 int value = HandlerOffsetField::encode(offset) |
3278 HandlerPredictionField::encode(prediction);
3279 set(index * kRangeEntrySize + kRangeHandlerIndex, Smi::FromInt(value));
3280}
3281
Ben Murdoch097c5b22016-05-18 11:27:45 +01003282void HandlerTable::SetRangeData(int index, int value) {
3283 set(index * kRangeEntrySize + kRangeDataIndex, Smi::FromInt(value));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003284}
3285
3286
3287void HandlerTable::SetReturnOffset(int index, int value) {
3288 set(index * kReturnEntrySize + kReturnOffsetIndex, Smi::FromInt(value));
3289}
3290
3291
3292void HandlerTable::SetReturnHandler(int index, int offset,
3293 CatchPrediction prediction) {
3294 int value = HandlerOffsetField::encode(offset) |
3295 HandlerPredictionField::encode(prediction);
3296 set(index * kReturnEntrySize + kReturnHandlerIndex, Smi::FromInt(value));
3297}
3298
Ben Murdoch097c5b22016-05-18 11:27:45 +01003299int HandlerTable::NumberOfRangeEntries() const {
3300 return length() / kRangeEntrySize;
3301}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003302
Steve Blocka7e24c12009-10-30 11:49:00 +00003303#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
3304 STRUCT_LIST(MAKE_STRUCT_CAST)
3305#undef MAKE_STRUCT_CAST
3306
3307
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003308template <typename Derived, typename Shape, typename Key>
3309HashTable<Derived, Shape, Key>*
3310HashTable<Derived, Shape, Key>::cast(Object* obj) {
3311 SLOW_DCHECK(obj->IsHashTable());
Steve Blocka7e24c12009-10-30 11:49:00 +00003312 return reinterpret_cast<HashTable*>(obj);
3313}
3314
3315
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003316template <typename Derived, typename Shape, typename Key>
3317const HashTable<Derived, Shape, Key>*
3318HashTable<Derived, Shape, Key>::cast(const Object* obj) {
3319 SLOW_DCHECK(obj->IsHashTable());
3320 return reinterpret_cast<const HashTable*>(obj);
3321}
3322
3323
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003324SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003325SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
3326
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003327SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003328NOBARRIER_SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00003329
Steve Block6ded16b2010-05-10 14:33:55 +01003330SMI_ACCESSORS(String, length, kLengthOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003331SYNCHRONIZED_SMI_ACCESSORS(String, length, kLengthOffset)
Steve Blockd0582a62009-12-15 09:54:21 +00003332
3333
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003334int FreeSpace::Size() { return size(); }
3335
3336
3337FreeSpace* FreeSpace::next() {
3338 DCHECK(map() == GetHeap()->root(Heap::kFreeSpaceMapRootIndex) ||
3339 (!GetHeap()->deserialization_complete() && map() == NULL));
3340 DCHECK_LE(kNextOffset + kPointerSize, nobarrier_size());
3341 return reinterpret_cast<FreeSpace*>(
3342 Memory::Address_at(address() + kNextOffset));
3343}
3344
3345
3346void FreeSpace::set_next(FreeSpace* next) {
3347 DCHECK(map() == GetHeap()->root(Heap::kFreeSpaceMapRootIndex) ||
3348 (!GetHeap()->deserialization_complete() && map() == NULL));
3349 DCHECK_LE(kNextOffset + kPointerSize, nobarrier_size());
3350 base::NoBarrier_Store(
3351 reinterpret_cast<base::AtomicWord*>(address() + kNextOffset),
3352 reinterpret_cast<base::AtomicWord>(next));
3353}
3354
3355
3356FreeSpace* FreeSpace::cast(HeapObject* o) {
3357 SLOW_DCHECK(!o->GetHeap()->deserialization_complete() || o->IsFreeSpace());
3358 return reinterpret_cast<FreeSpace*>(o);
3359}
3360
3361
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003362uint32_t Name::hash_field() {
Steve Blockd0582a62009-12-15 09:54:21 +00003363 return READ_UINT32_FIELD(this, kHashFieldOffset);
3364}
3365
3366
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003367void Name::set_hash_field(uint32_t value) {
Steve Blockd0582a62009-12-15 09:54:21 +00003368 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01003369#if V8_HOST_ARCH_64_BIT
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003370#if V8_TARGET_LITTLE_ENDIAN
3371 WRITE_UINT32_FIELD(this, kHashFieldSlot + kIntSize, 0);
3372#else
3373 WRITE_UINT32_FIELD(this, kHashFieldSlot, 0);
3374#endif
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01003375#endif
Steve Blockd0582a62009-12-15 09:54:21 +00003376}
3377
3378
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003379bool Name::Equals(Name* other) {
3380 if (other == this) return true;
3381 if ((this->IsInternalizedString() && other->IsInternalizedString()) ||
3382 this->IsSymbol() || other->IsSymbol()) {
3383 return false;
3384 }
3385 return String::cast(this)->SlowEquals(String::cast(other));
3386}
3387
3388
3389bool Name::Equals(Handle<Name> one, Handle<Name> two) {
3390 if (one.is_identical_to(two)) return true;
3391 if ((one->IsInternalizedString() && two->IsInternalizedString()) ||
3392 one->IsSymbol() || two->IsSymbol()) {
3393 return false;
3394 }
3395 return String::SlowEquals(Handle<String>::cast(one),
3396 Handle<String>::cast(two));
3397}
3398
3399
3400ACCESSORS(Symbol, name, Object, kNameOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003401SMI_ACCESSORS(Symbol, flags, kFlagsOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003402BOOL_ACCESSORS(Symbol, flags, is_private, kPrivateBit)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003403BOOL_ACCESSORS(Symbol, flags, is_well_known_symbol, kWellKnownSymbolBit)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003404
3405
Steve Blocka7e24c12009-10-30 11:49:00 +00003406bool String::Equals(String* other) {
3407 if (other == this) return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003408 if (this->IsInternalizedString() && other->IsInternalizedString()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003409 return false;
3410 }
3411 return SlowEquals(other);
3412}
3413
3414
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003415bool String::Equals(Handle<String> one, Handle<String> two) {
3416 if (one.is_identical_to(two)) return true;
3417 if (one->IsInternalizedString() && two->IsInternalizedString()) {
3418 return false;
3419 }
3420 return SlowEquals(one, two);
Steve Blocka7e24c12009-10-30 11:49:00 +00003421}
3422
3423
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003424Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) {
3425 if (!string->IsConsString()) return string;
3426 Handle<ConsString> cons = Handle<ConsString>::cast(string);
3427 if (cons->IsFlat()) return handle(cons->first());
3428 return SlowFlatten(cons, pretenure);
Leon Clarkef7060e22010-06-03 12:02:55 +01003429}
3430
3431
Steve Blocka7e24c12009-10-30 11:49:00 +00003432uint16_t String::Get(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003433 DCHECK(index >= 0 && index < length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003434 switch (StringShape(this).full_representation_tag()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003435 case kSeqStringTag | kOneByteStringTag:
3436 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00003437 case kSeqStringTag | kTwoByteStringTag:
3438 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003439 case kConsStringTag | kOneByteStringTag:
Steve Blocka7e24c12009-10-30 11:49:00 +00003440 case kConsStringTag | kTwoByteStringTag:
3441 return ConsString::cast(this)->ConsStringGet(index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003442 case kExternalStringTag | kOneByteStringTag:
3443 return ExternalOneByteString::cast(this)->ExternalOneByteStringGet(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00003444 case kExternalStringTag | kTwoByteStringTag:
3445 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003446 case kSlicedStringTag | kOneByteStringTag:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003447 case kSlicedStringTag | kTwoByteStringTag:
3448 return SlicedString::cast(this)->SlicedStringGet(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00003449 default:
3450 break;
3451 }
3452
3453 UNREACHABLE();
3454 return 0;
3455}
3456
3457
3458void String::Set(int index, uint16_t value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003459 DCHECK(index >= 0 && index < length());
3460 DCHECK(StringShape(this).IsSequential());
Steve Blocka7e24c12009-10-30 11:49:00 +00003461
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003462 return this->IsOneByteRepresentation()
3463 ? SeqOneByteString::cast(this)->SeqOneByteStringSet(index, value)
Steve Blocka7e24c12009-10-30 11:49:00 +00003464 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
3465}
3466
3467
3468bool String::IsFlat() {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003469 if (!StringShape(this).IsCons()) return true;
3470 return ConsString::cast(this)->second()->length() == 0;
3471}
3472
3473
3474String* String::GetUnderlying() {
3475 // Giving direct access to underlying string only makes sense if the
3476 // wrapping string is already flattened.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003477 DCHECK(this->IsFlat());
3478 DCHECK(StringShape(this).IsIndirect());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003479 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
3480 const int kUnderlyingOffset = SlicedString::kParentOffset;
3481 return String::cast(READ_FIELD(this, kUnderlyingOffset));
Steve Blocka7e24c12009-10-30 11:49:00 +00003482}
3483
3484
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003485template<class Visitor>
3486ConsString* String::VisitFlat(Visitor* visitor,
3487 String* string,
3488 const int offset) {
3489 int slice_offset = offset;
3490 const int length = string->length();
3491 DCHECK(offset <= length);
3492 while (true) {
3493 int32_t type = string->map()->instance_type();
3494 switch (type & (kStringRepresentationMask | kStringEncodingMask)) {
3495 case kSeqStringTag | kOneByteStringTag:
3496 visitor->VisitOneByteString(
3497 SeqOneByteString::cast(string)->GetChars() + slice_offset,
3498 length - offset);
3499 return NULL;
3500
3501 case kSeqStringTag | kTwoByteStringTag:
3502 visitor->VisitTwoByteString(
3503 SeqTwoByteString::cast(string)->GetChars() + slice_offset,
3504 length - offset);
3505 return NULL;
3506
3507 case kExternalStringTag | kOneByteStringTag:
3508 visitor->VisitOneByteString(
3509 ExternalOneByteString::cast(string)->GetChars() + slice_offset,
3510 length - offset);
3511 return NULL;
3512
3513 case kExternalStringTag | kTwoByteStringTag:
3514 visitor->VisitTwoByteString(
3515 ExternalTwoByteString::cast(string)->GetChars() + slice_offset,
3516 length - offset);
3517 return NULL;
3518
3519 case kSlicedStringTag | kOneByteStringTag:
3520 case kSlicedStringTag | kTwoByteStringTag: {
3521 SlicedString* slicedString = SlicedString::cast(string);
3522 slice_offset += slicedString->offset();
3523 string = slicedString->parent();
3524 continue;
3525 }
3526
3527 case kConsStringTag | kOneByteStringTag:
3528 case kConsStringTag | kTwoByteStringTag:
3529 return ConsString::cast(string);
3530
3531 default:
3532 UNREACHABLE();
3533 return NULL;
3534 }
3535 }
3536}
3537
3538
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003539template <>
3540inline Vector<const uint8_t> String::GetCharVector() {
3541 String::FlatContent flat = GetFlatContent();
3542 DCHECK(flat.IsOneByte());
3543 return flat.ToOneByteVector();
3544}
3545
3546
3547template <>
3548inline Vector<const uc16> String::GetCharVector() {
3549 String::FlatContent flat = GetFlatContent();
3550 DCHECK(flat.IsTwoByte());
3551 return flat.ToUC16Vector();
3552}
3553
3554
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003555uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
3556 DCHECK(index >= 0 && index < length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003557 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
3558}
3559
3560
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003561void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) {
3562 DCHECK(index >= 0 && index < length() && value <= kMaxOneByteCharCode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003563 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
3564 static_cast<byte>(value));
3565}
3566
3567
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003568Address SeqOneByteString::GetCharsAddress() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003569 return FIELD_ADDR(this, kHeaderSize);
3570}
3571
3572
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003573uint8_t* SeqOneByteString::GetChars() {
3574 return reinterpret_cast<uint8_t*>(GetCharsAddress());
Steve Blocka7e24c12009-10-30 11:49:00 +00003575}
3576
3577
3578Address SeqTwoByteString::GetCharsAddress() {
3579 return FIELD_ADDR(this, kHeaderSize);
3580}
3581
3582
3583uc16* SeqTwoByteString::GetChars() {
3584 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
3585}
3586
3587
3588uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003589 DCHECK(index >= 0 && index < length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003590 return READ_UINT16_FIELD(this, kHeaderSize + index * kShortSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00003591}
3592
3593
3594void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003595 DCHECK(index >= 0 && index < length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003596 WRITE_UINT16_FIELD(this, kHeaderSize + index * kShortSize, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003597}
3598
3599
3600int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
Steve Block6ded16b2010-05-10 14:33:55 +01003601 return SizeFor(length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003602}
3603
3604
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003605int SeqOneByteString::SeqOneByteStringSize(InstanceType instance_type) {
Steve Block6ded16b2010-05-10 14:33:55 +01003606 return SizeFor(length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003607}
3608
3609
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003610String* SlicedString::parent() {
3611 return String::cast(READ_FIELD(this, kParentOffset));
3612}
3613
3614
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003615void SlicedString::set_parent(String* parent, WriteBarrierMode mode) {
3616 DCHECK(parent->IsSeqString() || parent->IsExternalString());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003617 WRITE_FIELD(this, kParentOffset, parent);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003618 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kParentOffset, parent, mode);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003619}
3620
3621
3622SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
3623
3624
Steve Blocka7e24c12009-10-30 11:49:00 +00003625String* ConsString::first() {
3626 return String::cast(READ_FIELD(this, kFirstOffset));
3627}
3628
3629
3630Object* ConsString::unchecked_first() {
3631 return READ_FIELD(this, kFirstOffset);
3632}
3633
3634
3635void ConsString::set_first(String* value, WriteBarrierMode mode) {
3636 WRITE_FIELD(this, kFirstOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003637 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003638}
3639
3640
3641String* ConsString::second() {
3642 return String::cast(READ_FIELD(this, kSecondOffset));
3643}
3644
3645
3646Object* ConsString::unchecked_second() {
3647 return READ_FIELD(this, kSecondOffset);
3648}
3649
3650
3651void ConsString::set_second(String* value, WriteBarrierMode mode) {
3652 WRITE_FIELD(this, kSecondOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003653 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00003654}
3655
3656
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003657bool ExternalString::is_short() {
3658 InstanceType type = map()->instance_type();
3659 return (type & kShortExternalStringMask) == kShortExternalStringTag;
3660}
3661
3662
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003663const ExternalOneByteString::Resource* ExternalOneByteString::resource() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003664 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
3665}
3666
3667
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003668void ExternalOneByteString::update_data_cache() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003669 if (is_short()) return;
3670 const char** data_field =
3671 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
3672 *data_field = resource()->data();
3673}
3674
3675
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003676void ExternalOneByteString::set_resource(
3677 const ExternalOneByteString::Resource* resource) {
3678 DCHECK(IsAligned(reinterpret_cast<intptr_t>(resource), kPointerSize));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003679 *reinterpret_cast<const Resource**>(
3680 FIELD_ADDR(this, kResourceOffset)) = resource;
3681 if (resource != NULL) update_data_cache();
Steve Blocka7e24c12009-10-30 11:49:00 +00003682}
3683
3684
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003685const uint8_t* ExternalOneByteString::GetChars() {
3686 return reinterpret_cast<const uint8_t*>(resource()->data());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003687}
3688
3689
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003690uint16_t ExternalOneByteString::ExternalOneByteStringGet(int index) {
3691 DCHECK(index >= 0 && index < length());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003692 return GetChars()[index];
3693}
3694
3695
3696const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
Steve Blocka7e24c12009-10-30 11:49:00 +00003697 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
3698}
3699
3700
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003701void ExternalTwoByteString::update_data_cache() {
3702 if (is_short()) return;
3703 const uint16_t** data_field =
3704 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
3705 *data_field = resource()->data();
3706}
3707
3708
Steve Blocka7e24c12009-10-30 11:49:00 +00003709void ExternalTwoByteString::set_resource(
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003710 const ExternalTwoByteString::Resource* resource) {
3711 *reinterpret_cast<const Resource**>(
3712 FIELD_ADDR(this, kResourceOffset)) = resource;
3713 if (resource != NULL) update_data_cache();
3714}
3715
3716
3717const uint16_t* ExternalTwoByteString::GetChars() {
3718 return resource()->data();
3719}
3720
3721
3722uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003723 DCHECK(index >= 0 && index < length());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003724 return GetChars()[index];
3725}
3726
3727
3728const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
3729 unsigned start) {
3730 return GetChars() + start;
Steve Blocka7e24c12009-10-30 11:49:00 +00003731}
3732
3733
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003734int ConsStringIterator::OffsetForDepth(int depth) { return depth & kDepthMask; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003735
3736
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003737void ConsStringIterator::PushLeft(ConsString* string) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003738 frames_[depth_++ & kDepthMask] = string;
3739}
3740
3741
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003742void ConsStringIterator::PushRight(ConsString* string) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003743 // Inplace update.
3744 frames_[(depth_-1) & kDepthMask] = string;
3745}
3746
3747
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003748void ConsStringIterator::AdjustMaximumDepth() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003749 if (depth_ > maximum_depth_) maximum_depth_ = depth_;
3750}
3751
3752
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003753void ConsStringIterator::Pop() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003754 DCHECK(depth_ > 0);
3755 DCHECK(depth_ <= maximum_depth_);
3756 depth_--;
3757}
3758
3759
3760uint16_t StringCharacterStream::GetNext() {
3761 DCHECK(buffer8_ != NULL && end_ != NULL);
3762 // Advance cursor if needed.
3763 if (buffer8_ == end_) HasMore();
3764 DCHECK(buffer8_ < end_);
3765 return is_one_byte_ ? *buffer8_++ : *buffer16_++;
3766}
3767
3768
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003769StringCharacterStream::StringCharacterStream(String* string, int offset)
3770 : is_one_byte_(false) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003771 Reset(string, offset);
3772}
3773
3774
3775void StringCharacterStream::Reset(String* string, int offset) {
3776 buffer8_ = NULL;
3777 end_ = NULL;
3778 ConsString* cons_string = String::VisitFlat(this, string, offset);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003779 iter_.Reset(cons_string, offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003780 if (cons_string != NULL) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003781 string = iter_.Next(&offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003782 if (string != NULL) String::VisitFlat(this, string, offset);
3783 }
3784}
3785
3786
3787bool StringCharacterStream::HasMore() {
3788 if (buffer8_ != end_) return true;
3789 int offset;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003790 String* string = iter_.Next(&offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003791 DCHECK_EQ(offset, 0);
3792 if (string == NULL) return false;
3793 String::VisitFlat(this, string);
3794 DCHECK(buffer8_ != end_);
3795 return true;
3796}
3797
3798
3799void StringCharacterStream::VisitOneByteString(
3800 const uint8_t* chars, int length) {
3801 is_one_byte_ = true;
3802 buffer8_ = chars;
3803 end_ = chars + length;
3804}
3805
3806
3807void StringCharacterStream::VisitTwoByteString(
3808 const uint16_t* chars, int length) {
3809 is_one_byte_ = false;
3810 buffer16_ = chars;
3811 end_ = reinterpret_cast<const uint8_t*>(chars + length);
3812}
3813
3814
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003815int ByteArray::Size() { return RoundUp(length() + kHeaderSize, kPointerSize); }
Ben Murdochb8e0da22011-05-16 14:20:40 +01003816
3817
Steve Blocka7e24c12009-10-30 11:49:00 +00003818byte ByteArray::get(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003819 DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003820 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
3821}
3822
3823
3824void ByteArray::set(int index, byte value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003825 DCHECK(index >= 0 && index < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003826 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
3827}
3828
3829
3830int ByteArray::get_int(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003831 DCHECK(index >= 0 && (index * kIntSize) < this->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00003832 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
3833}
3834
3835
3836ByteArray* ByteArray::FromDataStartAddress(Address address) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003837 DCHECK_TAG_ALIGNED(address);
Steve Blocka7e24c12009-10-30 11:49:00 +00003838 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
3839}
3840
3841
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003842int ByteArray::ByteArraySize() { return SizeFor(this->length()); }
3843
3844
Steve Blocka7e24c12009-10-30 11:49:00 +00003845Address ByteArray::GetDataStartAddress() {
3846 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
3847}
3848
3849
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003850byte BytecodeArray::get(int index) {
3851 DCHECK(index >= 0 && index < this->length());
3852 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00003853}
3854
3855
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003856void BytecodeArray::set(int index, byte value) {
3857 DCHECK(index >= 0 && index < this->length());
3858 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00003859}
3860
3861
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003862void BytecodeArray::set_frame_size(int frame_size) {
3863 DCHECK_GE(frame_size, 0);
3864 DCHECK(IsAligned(frame_size, static_cast<unsigned>(kPointerSize)));
3865 WRITE_INT_FIELD(this, kFrameSizeOffset, frame_size);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003866}
3867
3868
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003869int BytecodeArray::frame_size() const {
3870 return READ_INT_FIELD(this, kFrameSizeOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00003871}
3872
3873
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003874int BytecodeArray::register_count() const {
3875 return frame_size() / kPointerSize;
3876}
3877
3878
3879void BytecodeArray::set_parameter_count(int number_of_parameters) {
3880 DCHECK_GE(number_of_parameters, 0);
3881 // Parameter count is stored as the size on stack of the parameters to allow
3882 // it to be used directly by generated code.
3883 WRITE_INT_FIELD(this, kParameterSizeOffset,
3884 (number_of_parameters << kPointerSizeLog2));
3885}
3886
Ben Murdoch097c5b22016-05-18 11:27:45 +01003887int BytecodeArray::interrupt_budget() const {
3888 return READ_INT_FIELD(this, kInterruptBudgetOffset);
3889}
3890
3891void BytecodeArray::set_interrupt_budget(int interrupt_budget) {
3892 DCHECK_GE(interrupt_budget, 0);
3893 WRITE_INT_FIELD(this, kInterruptBudgetOffset, interrupt_budget);
3894}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003895
3896int BytecodeArray::parameter_count() const {
3897 // Parameter count is stored as the size on stack of the parameters to allow
3898 // it to be used directly by generated code.
3899 return READ_INT_FIELD(this, kParameterSizeOffset) >> kPointerSizeLog2;
3900}
3901
3902
3903ACCESSORS(BytecodeArray, constant_pool, FixedArray, kConstantPoolOffset)
Ben Murdoch097c5b22016-05-18 11:27:45 +01003904ACCESSORS(BytecodeArray, handler_table, FixedArray, kHandlerTableOffset)
3905ACCESSORS(BytecodeArray, source_position_table, FixedArray,
3906 kSourcePositionTableOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003907
3908
3909Address BytecodeArray::GetFirstBytecodeAddress() {
3910 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
3911}
3912
3913
3914int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); }
3915
3916
3917ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset)
3918
3919
3920void* FixedTypedArrayBase::external_pointer() const {
Steve Block3ce2e202009-11-05 08:53:23 +00003921 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
3922 return reinterpret_cast<void*>(ptr);
3923}
3924
3925
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003926void FixedTypedArrayBase::set_external_pointer(void* value,
3927 WriteBarrierMode mode) {
Steve Block3ce2e202009-11-05 08:53:23 +00003928 intptr_t ptr = reinterpret_cast<intptr_t>(value);
3929 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
3930}
3931
3932
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003933void* FixedTypedArrayBase::DataPtr() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003934 return reinterpret_cast<void*>(
3935 reinterpret_cast<intptr_t>(base_pointer()) +
3936 reinterpret_cast<intptr_t>(external_pointer()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003937}
3938
3939
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003940int FixedTypedArrayBase::ElementSize(InstanceType type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003941 int element_size;
3942 switch (type) {
3943#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
3944 case FIXED_##TYPE##_ARRAY_TYPE: \
3945 element_size = size; \
3946 break;
3947
3948 TYPED_ARRAYS(TYPED_ARRAY_CASE)
3949#undef TYPED_ARRAY_CASE
3950 default:
3951 UNREACHABLE();
3952 return 0;
3953 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003954 return element_size;
3955}
3956
3957
3958int FixedTypedArrayBase::DataSize(InstanceType type) {
3959 if (base_pointer() == Smi::FromInt(0)) return 0;
3960 return length() * ElementSize(type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003961}
3962
3963
3964int FixedTypedArrayBase::DataSize() {
3965 return DataSize(map()->instance_type());
3966}
3967
3968
3969int FixedTypedArrayBase::size() {
3970 return OBJECT_POINTER_ALIGN(kDataOffset + DataSize());
3971}
3972
3973
3974int FixedTypedArrayBase::TypedArraySize(InstanceType type) {
3975 return OBJECT_POINTER_ALIGN(kDataOffset + DataSize(type));
3976}
3977
3978
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003979int FixedTypedArrayBase::TypedArraySize(InstanceType type, int length) {
3980 return OBJECT_POINTER_ALIGN(kDataOffset + length * ElementSize(type));
3981}
3982
3983
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003984uint8_t Uint8ArrayTraits::defaultValue() { return 0; }
3985
3986
3987uint8_t Uint8ClampedArrayTraits::defaultValue() { return 0; }
3988
3989
3990int8_t Int8ArrayTraits::defaultValue() { return 0; }
3991
3992
3993uint16_t Uint16ArrayTraits::defaultValue() { return 0; }
3994
3995
3996int16_t Int16ArrayTraits::defaultValue() { return 0; }
3997
3998
3999uint32_t Uint32ArrayTraits::defaultValue() { return 0; }
4000
4001
4002int32_t Int32ArrayTraits::defaultValue() { return 0; }
4003
4004
4005float Float32ArrayTraits::defaultValue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004006 return std::numeric_limits<float>::quiet_NaN();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004007}
4008
4009
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004010double Float64ArrayTraits::defaultValue() {
4011 return std::numeric_limits<double>::quiet_NaN();
4012}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004013
4014
4015template <class Traits>
4016typename Traits::ElementType FixedTypedArray<Traits>::get_scalar(int index) {
4017 DCHECK((index >= 0) && (index < this->length()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004018 ElementType* ptr = reinterpret_cast<ElementType*>(DataPtr());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004019 return ptr[index];
4020}
4021
4022
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004023template <class Traits>
4024void FixedTypedArray<Traits>::set(int index, ElementType value) {
4025 DCHECK((index >= 0) && (index < this->length()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004026 ElementType* ptr = reinterpret_cast<ElementType*>(DataPtr());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004027 ptr[index] = value;
4028}
4029
4030
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004031template <class Traits>
4032typename Traits::ElementType FixedTypedArray<Traits>::from_int(int value) {
4033 return static_cast<ElementType>(value);
4034}
4035
4036
4037template <> inline
4038uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from_int(int value) {
4039 if (value < 0) return 0;
4040 if (value > 0xFF) return 0xFF;
4041 return static_cast<uint8_t>(value);
4042}
4043
4044
4045template <class Traits>
4046typename Traits::ElementType FixedTypedArray<Traits>::from_double(
4047 double value) {
4048 return static_cast<ElementType>(DoubleToInt32(value));
4049}
4050
4051
4052template<> inline
4053uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from_double(double value) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004054 // Handle NaNs and less than zero values which clamp to zero.
4055 if (!(value > 0)) return 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004056 if (value > 0xFF) return 0xFF;
4057 return static_cast<uint8_t>(lrint(value));
4058}
4059
4060
4061template<> inline
4062float FixedTypedArray<Float32ArrayTraits>::from_double(double value) {
4063 return static_cast<float>(value);
4064}
4065
4066
4067template<> inline
4068double FixedTypedArray<Float64ArrayTraits>::from_double(double value) {
4069 return value;
4070}
4071
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004072template <class Traits>
Ben Murdoch097c5b22016-05-18 11:27:45 +01004073Handle<Object> FixedTypedArray<Traits>::get(FixedTypedArray<Traits>* array,
4074 int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004075 return Traits::ToHandle(array->GetIsolate(), array->get_scalar(index));
4076}
4077
4078
4079template <class Traits>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004080void FixedTypedArray<Traits>::SetValue(uint32_t index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004081 ElementType cast_value = Traits::defaultValue();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004082 if (value->IsSmi()) {
4083 int int_value = Smi::cast(value)->value();
4084 cast_value = from_int(int_value);
4085 } else if (value->IsHeapNumber()) {
4086 double double_value = HeapNumber::cast(value)->value();
4087 cast_value = from_double(double_value);
4088 } else {
4089 // Clamp undefined to the default value. All other types have been
4090 // converted to a number type further up in the call chain.
4091 DCHECK(value->IsUndefined());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004092 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004093 set(index, cast_value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004094}
4095
4096
4097Handle<Object> Uint8ArrayTraits::ToHandle(Isolate* isolate, uint8_t scalar) {
4098 return handle(Smi::FromInt(scalar), isolate);
4099}
4100
4101
4102Handle<Object> Uint8ClampedArrayTraits::ToHandle(Isolate* isolate,
4103 uint8_t scalar) {
4104 return handle(Smi::FromInt(scalar), isolate);
4105}
4106
4107
4108Handle<Object> Int8ArrayTraits::ToHandle(Isolate* isolate, int8_t scalar) {
4109 return handle(Smi::FromInt(scalar), isolate);
4110}
4111
4112
4113Handle<Object> Uint16ArrayTraits::ToHandle(Isolate* isolate, uint16_t scalar) {
4114 return handle(Smi::FromInt(scalar), isolate);
4115}
4116
4117
4118Handle<Object> Int16ArrayTraits::ToHandle(Isolate* isolate, int16_t scalar) {
4119 return handle(Smi::FromInt(scalar), isolate);
4120}
4121
4122
4123Handle<Object> Uint32ArrayTraits::ToHandle(Isolate* isolate, uint32_t scalar) {
4124 return isolate->factory()->NewNumberFromUint(scalar);
4125}
4126
4127
4128Handle<Object> Int32ArrayTraits::ToHandle(Isolate* isolate, int32_t scalar) {
4129 return isolate->factory()->NewNumberFromInt(scalar);
4130}
4131
4132
4133Handle<Object> Float32ArrayTraits::ToHandle(Isolate* isolate, float scalar) {
4134 return isolate->factory()->NewNumber(scalar);
4135}
4136
4137
4138Handle<Object> Float64ArrayTraits::ToHandle(Isolate* isolate, double scalar) {
4139 return isolate->factory()->NewNumber(scalar);
4140}
4141
4142
Iain Merrick9ac36c92010-09-13 15:29:50 +01004143int Map::visitor_id() {
4144 return READ_BYTE_FIELD(this, kVisitorIdOffset);
4145}
4146
4147
4148void Map::set_visitor_id(int id) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004149 DCHECK(0 <= id && id < 256);
Iain Merrick9ac36c92010-09-13 15:29:50 +01004150 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
4151}
4152
Steve Block3ce2e202009-11-05 08:53:23 +00004153
Steve Blocka7e24c12009-10-30 11:49:00 +00004154int Map::instance_size() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004155 return NOBARRIER_READ_BYTE_FIELD(
4156 this, kInstanceSizeOffset) << kPointerSizeLog2;
Steve Blocka7e24c12009-10-30 11:49:00 +00004157}
4158
4159
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004160int Map::inobject_properties_or_constructor_function_index() {
4161 return READ_BYTE_FIELD(this,
4162 kInObjectPropertiesOrConstructorFunctionIndexOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00004163}
4164
4165
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004166void Map::set_inobject_properties_or_constructor_function_index(int value) {
4167 DCHECK(0 <= value && value < 256);
4168 WRITE_BYTE_FIELD(this, kInObjectPropertiesOrConstructorFunctionIndexOffset,
4169 static_cast<byte>(value));
4170}
4171
4172
4173int Map::GetInObjectProperties() {
4174 DCHECK(IsJSObjectMap());
4175 return inobject_properties_or_constructor_function_index();
4176}
4177
4178
4179void Map::SetInObjectProperties(int value) {
4180 DCHECK(IsJSObjectMap());
4181 set_inobject_properties_or_constructor_function_index(value);
4182}
4183
4184
4185int Map::GetConstructorFunctionIndex() {
4186 DCHECK(IsPrimitiveMap());
4187 return inobject_properties_or_constructor_function_index();
4188}
4189
4190
4191void Map::SetConstructorFunctionIndex(int value) {
4192 DCHECK(IsPrimitiveMap());
4193 set_inobject_properties_or_constructor_function_index(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004194}
4195
4196
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004197int Map::GetInObjectPropertyOffset(int index) {
4198 // Adjust for the number of properties stored in the object.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004199 index -= GetInObjectProperties();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004200 DCHECK(index <= 0);
4201 return instance_size() + (index * kPointerSize);
4202}
4203
4204
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004205Handle<Map> Map::AddMissingTransitionsForTesting(
4206 Handle<Map> split_map, Handle<DescriptorArray> descriptors,
4207 Handle<LayoutDescriptor> full_layout_descriptor) {
4208 return AddMissingTransitions(split_map, descriptors, full_layout_descriptor);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004209}
4210
4211
Steve Blocka7e24c12009-10-30 11:49:00 +00004212int HeapObject::SizeFromMap(Map* map) {
Steve Block791712a2010-08-27 10:21:07 +01004213 int instance_size = map->instance_size();
4214 if (instance_size != kVariableSizeSentinel) return instance_size;
Steve Blocka7e24c12009-10-30 11:49:00 +00004215 // Only inline the most frequent cases.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004216 InstanceType instance_type = map->instance_type();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004217 if (instance_type == FIXED_ARRAY_TYPE ||
4218 instance_type == TRANSITION_ARRAY_TYPE) {
4219 return FixedArray::SizeFor(
4220 reinterpret_cast<FixedArray*>(this)->synchronized_length());
Steve Blocka7e24c12009-10-30 11:49:00 +00004221 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004222 if (instance_type == ONE_BYTE_STRING_TYPE ||
4223 instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004224 // Strings may get concurrently truncated, hence we have to access its
4225 // length synchronized.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004226 return SeqOneByteString::SizeFor(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004227 reinterpret_cast<SeqOneByteString*>(this)->synchronized_length());
Steve Block791712a2010-08-27 10:21:07 +01004228 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004229 if (instance_type == BYTE_ARRAY_TYPE) {
4230 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
4231 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004232 if (instance_type == BYTECODE_ARRAY_TYPE) {
4233 return reinterpret_cast<BytecodeArray*>(this)->BytecodeArraySize();
4234 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004235 if (instance_type == FREE_SPACE_TYPE) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004236 return reinterpret_cast<FreeSpace*>(this)->nobarrier_size();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004237 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004238 if (instance_type == STRING_TYPE ||
4239 instance_type == INTERNALIZED_STRING_TYPE) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004240 // Strings may get concurrently truncated, hence we have to access its
4241 // length synchronized.
Steve Block791712a2010-08-27 10:21:07 +01004242 return SeqTwoByteString::SizeFor(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004243 reinterpret_cast<SeqTwoByteString*>(this)->synchronized_length());
Steve Block791712a2010-08-27 10:21:07 +01004244 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004245 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
4246 return FixedDoubleArray::SizeFor(
4247 reinterpret_cast<FixedDoubleArray*>(this)->length());
4248 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004249 if (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE &&
4250 instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE) {
4251 return reinterpret_cast<FixedTypedArrayBase*>(
4252 this)->TypedArraySize(instance_type);
4253 }
4254 DCHECK(instance_type == CODE_TYPE);
Steve Block791712a2010-08-27 10:21:07 +01004255 return reinterpret_cast<Code*>(this)->CodeSize();
Steve Blocka7e24c12009-10-30 11:49:00 +00004256}
4257
4258
4259void Map::set_instance_size(int value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004260 DCHECK_EQ(0, value & (kPointerSize - 1));
Steve Blocka7e24c12009-10-30 11:49:00 +00004261 value >>= kPointerSizeLog2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004262 DCHECK(0 <= value && value < 256);
4263 NOBARRIER_WRITE_BYTE_FIELD(
4264 this, kInstanceSizeOffset, static_cast<byte>(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00004265}
4266
4267
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004268void Map::clear_unused() { WRITE_BYTE_FIELD(this, kUnusedOffset, 0); }
Steve Blocka7e24c12009-10-30 11:49:00 +00004269
4270
4271InstanceType Map::instance_type() {
4272 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
4273}
4274
4275
4276void Map::set_instance_type(InstanceType value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004277 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
4278}
4279
4280
4281int Map::unused_property_fields() {
4282 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
4283}
4284
4285
4286void Map::set_unused_property_fields(int value) {
4287 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
4288}
4289
4290
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004291byte Map::bit_field() const { return READ_BYTE_FIELD(this, kBitFieldOffset); }
Steve Blocka7e24c12009-10-30 11:49:00 +00004292
4293
4294void Map::set_bit_field(byte value) {
4295 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
4296}
4297
4298
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004299byte Map::bit_field2() const { return READ_BYTE_FIELD(this, kBitField2Offset); }
Steve Blocka7e24c12009-10-30 11:49:00 +00004300
4301
4302void Map::set_bit_field2(byte value) {
4303 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
4304}
4305
4306
4307void Map::set_non_instance_prototype(bool value) {
4308 if (value) {
4309 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
4310 } else {
4311 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
4312 }
4313}
4314
4315
4316bool Map::has_non_instance_prototype() {
4317 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
4318}
4319
4320
Ben Murdoch097c5b22016-05-18 11:27:45 +01004321void Map::set_is_constructor(bool value) {
4322 if (value) {
4323 set_bit_field(bit_field() | (1 << kIsConstructor));
4324 } else {
4325 set_bit_field(bit_field() & ~(1 << kIsConstructor));
4326 }
Steve Block6ded16b2010-05-10 14:33:55 +01004327}
4328
4329
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004330bool Map::is_constructor() const {
4331 return ((1 << kIsConstructor) & bit_field()) != 0;
4332}
4333
Ben Murdoch097c5b22016-05-18 11:27:45 +01004334void Map::set_has_hidden_prototype(bool value) {
4335 set_bit_field3(HasHiddenPrototype::update(bit_field3(), value));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004336}
4337
Ben Murdoch097c5b22016-05-18 11:27:45 +01004338bool Map::has_hidden_prototype() const {
4339 return HasHiddenPrototype::decode(bit_field3());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004340}
4341
4342
4343void Map::set_has_indexed_interceptor() {
4344 set_bit_field(bit_field() | (1 << kHasIndexedInterceptor));
4345}
4346
4347
4348bool Map::has_indexed_interceptor() {
4349 return ((1 << kHasIndexedInterceptor) & bit_field()) != 0;
4350}
4351
4352
4353void Map::set_is_undetectable() {
4354 set_bit_field(bit_field() | (1 << kIsUndetectable));
4355}
4356
4357
4358bool Map::is_undetectable() {
4359 return ((1 << kIsUndetectable) & bit_field()) != 0;
4360}
4361
4362
4363void Map::set_is_observed() { set_bit_field(bit_field() | (1 << kIsObserved)); }
4364
4365bool Map::is_observed() { return ((1 << kIsObserved) & bit_field()) != 0; }
4366
4367
4368void Map::set_has_named_interceptor() {
4369 set_bit_field(bit_field() | (1 << kHasNamedInterceptor));
4370}
4371
4372
4373bool Map::has_named_interceptor() {
4374 return ((1 << kHasNamedInterceptor) & bit_field()) != 0;
Steve Block6ded16b2010-05-10 14:33:55 +01004375}
4376
4377
Steve Blocka7e24c12009-10-30 11:49:00 +00004378void Map::set_is_access_check_needed(bool access_check_needed) {
4379 if (access_check_needed) {
4380 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
4381 } else {
4382 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
4383 }
4384}
4385
4386
4387bool Map::is_access_check_needed() {
4388 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
4389}
4390
4391
Steve Block8defd9f2010-07-08 12:39:36 +01004392void Map::set_is_extensible(bool value) {
4393 if (value) {
4394 set_bit_field2(bit_field2() | (1 << kIsExtensible));
4395 } else {
4396 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
4397 }
4398}
4399
4400bool Map::is_extensible() {
4401 return ((1 << kIsExtensible) & bit_field2()) != 0;
4402}
4403
4404
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004405void Map::set_is_prototype_map(bool value) {
4406 set_bit_field2(IsPrototypeMapBits::update(bit_field2(), value));
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004407}
4408
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004409bool Map::is_prototype_map() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004410 return IsPrototypeMapBits::decode(bit_field2());
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004411}
4412
4413
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004414void Map::set_elements_kind(ElementsKind elements_kind) {
4415 DCHECK(static_cast<int>(elements_kind) < kElementsKindCount);
4416 DCHECK(kElementsKindCount <= (1 << Map::ElementsKindBits::kSize));
4417 set_bit_field2(Map::ElementsKindBits::update(bit_field2(), elements_kind));
4418 DCHECK(this->elements_kind() == elements_kind);
4419}
4420
4421
4422ElementsKind Map::elements_kind() {
4423 return Map::ElementsKindBits::decode(bit_field2());
4424}
4425
4426
4427bool Map::has_fast_smi_elements() {
4428 return IsFastSmiElementsKind(elements_kind());
4429}
4430
4431bool Map::has_fast_object_elements() {
4432 return IsFastObjectElementsKind(elements_kind());
4433}
4434
4435bool Map::has_fast_smi_or_object_elements() {
4436 return IsFastSmiOrObjectElementsKind(elements_kind());
4437}
4438
4439bool Map::has_fast_double_elements() {
4440 return IsFastDoubleElementsKind(elements_kind());
4441}
4442
4443bool Map::has_fast_elements() { return IsFastElementsKind(elements_kind()); }
4444
4445bool Map::has_sloppy_arguments_elements() {
4446 return IsSloppyArgumentsElements(elements_kind());
4447}
4448
Ben Murdoch097c5b22016-05-18 11:27:45 +01004449bool Map::has_fast_string_wrapper_elements() {
4450 return elements_kind() == FAST_STRING_WRAPPER_ELEMENTS;
4451}
4452
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004453bool Map::has_fixed_typed_array_elements() {
4454 return IsFixedTypedArrayElementsKind(elements_kind());
4455}
4456
4457bool Map::has_dictionary_elements() {
4458 return IsDictionaryElementsKind(elements_kind());
4459}
4460
4461
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004462void Map::set_dictionary_map(bool value) {
4463 uint32_t new_bit_field3 = DictionaryMap::update(bit_field3(), value);
4464 new_bit_field3 = IsUnstable::update(new_bit_field3, value);
4465 set_bit_field3(new_bit_field3);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004466}
4467
4468
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004469bool Map::is_dictionary_map() {
4470 return DictionaryMap::decode(bit_field3());
Kristian Monsen0d5e1162010-09-30 15:31:59 +01004471}
4472
Steve Block8defd9f2010-07-08 12:39:36 +01004473
Steve Blocka7e24c12009-10-30 11:49:00 +00004474Code::Flags Code::flags() {
4475 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
4476}
4477
4478
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004479void Map::set_owns_descriptors(bool owns_descriptors) {
4480 set_bit_field3(OwnsDescriptors::update(bit_field3(), owns_descriptors));
4481}
4482
4483
4484bool Map::owns_descriptors() {
4485 return OwnsDescriptors::decode(bit_field3());
4486}
4487
4488
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004489void Map::set_is_callable() { set_bit_field(bit_field() | (1 << kIsCallable)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004490
4491
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004492bool Map::is_callable() const {
4493 return ((1 << kIsCallable) & bit_field()) != 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004494}
4495
4496
4497void Map::deprecate() {
4498 set_bit_field3(Deprecated::update(bit_field3(), true));
4499}
4500
4501
4502bool Map::is_deprecated() {
4503 return Deprecated::decode(bit_field3());
4504}
4505
4506
4507void Map::set_migration_target(bool value) {
4508 set_bit_field3(IsMigrationTarget::update(bit_field3(), value));
4509}
4510
4511
4512bool Map::is_migration_target() {
4513 return IsMigrationTarget::decode(bit_field3());
4514}
4515
4516
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004517void Map::set_is_strong() {
4518 set_bit_field3(IsStrong::update(bit_field3(), true));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004519}
4520
4521
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004522bool Map::is_strong() {
4523 return IsStrong::decode(bit_field3());
4524}
4525
4526
4527void Map::set_new_target_is_base(bool value) {
4528 set_bit_field3(NewTargetIsBase::update(bit_field3(), value));
4529}
4530
4531
4532bool Map::new_target_is_base() { return NewTargetIsBase::decode(bit_field3()); }
4533
4534
4535void Map::set_construction_counter(int value) {
4536 set_bit_field3(ConstructionCounter::update(bit_field3(), value));
4537}
4538
4539
4540int Map::construction_counter() {
4541 return ConstructionCounter::decode(bit_field3());
4542}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004543
4544
4545void Map::mark_unstable() {
4546 set_bit_field3(IsUnstable::update(bit_field3(), true));
4547}
4548
4549
4550bool Map::is_stable() {
4551 return !IsUnstable::decode(bit_field3());
4552}
4553
4554
4555bool Map::has_code_cache() {
4556 return code_cache() != GetIsolate()->heap()->empty_fixed_array();
4557}
4558
4559
4560bool Map::CanBeDeprecated() {
4561 int descriptor = LastAdded();
4562 for (int i = 0; i <= descriptor; i++) {
4563 PropertyDetails details = instance_descriptors()->GetDetails(i);
4564 if (details.representation().IsNone()) return true;
4565 if (details.representation().IsSmi()) return true;
4566 if (details.representation().IsDouble()) return true;
4567 if (details.representation().IsHeapObject()) return true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004568 if (details.type() == DATA_CONSTANT) return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004569 }
4570 return false;
4571}
4572
4573
4574void Map::NotifyLeafMapLayoutChange() {
4575 if (is_stable()) {
4576 mark_unstable();
4577 dependent_code()->DeoptimizeDependentCodeGroup(
4578 GetIsolate(),
4579 DependentCode::kPrototypeCheckGroup);
4580 }
4581}
4582
4583
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004584bool Map::CanTransition() {
4585 // Only JSObject and subtypes have map transitions and back pointers.
4586 STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE);
4587 return instance_type() >= FIRST_JS_OBJECT_TYPE;
4588}
4589
4590
4591bool Map::IsBooleanMap() { return this == GetHeap()->boolean_map(); }
4592bool Map::IsPrimitiveMap() {
4593 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE);
4594 return instance_type() <= LAST_PRIMITIVE_TYPE;
4595}
4596bool Map::IsJSReceiverMap() {
4597 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
4598 return instance_type() >= FIRST_JS_RECEIVER_TYPE;
4599}
4600bool Map::IsJSObjectMap() {
4601 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
4602 return instance_type() >= FIRST_JS_OBJECT_TYPE;
4603}
4604bool Map::IsJSArrayMap() { return instance_type() == JS_ARRAY_TYPE; }
4605bool Map::IsJSFunctionMap() { return instance_type() == JS_FUNCTION_TYPE; }
4606bool Map::IsStringMap() { return instance_type() < FIRST_NONSTRING_TYPE; }
4607bool Map::IsJSProxyMap() { return instance_type() == JS_PROXY_TYPE; }
4608bool Map::IsJSGlobalProxyMap() {
4609 return instance_type() == JS_GLOBAL_PROXY_TYPE;
4610}
4611bool Map::IsJSGlobalObjectMap() {
4612 return instance_type() == JS_GLOBAL_OBJECT_TYPE;
4613}
4614bool Map::IsJSTypedArrayMap() { return instance_type() == JS_TYPED_ARRAY_TYPE; }
4615bool Map::IsJSDataViewMap() { return instance_type() == JS_DATA_VIEW_TYPE; }
4616
4617
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004618bool Map::CanOmitMapChecks() {
4619 return is_stable() && FLAG_omit_map_checks_for_leaf_maps;
4620}
4621
4622
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004623DependentCode* DependentCode::next_link() {
4624 return DependentCode::cast(get(kNextLinkIndex));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004625}
4626
4627
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004628void DependentCode::set_next_link(DependentCode* next) {
4629 set(kNextLinkIndex, next);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004630}
4631
4632
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004633int DependentCode::flags() { return Smi::cast(get(kFlagsIndex))->value(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004634
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004635
4636void DependentCode::set_flags(int flags) {
4637 set(kFlagsIndex, Smi::FromInt(flags));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004638}
4639
4640
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004641int DependentCode::count() { return CountField::decode(flags()); }
4642
4643void DependentCode::set_count(int value) {
4644 set_flags(CountField::update(flags(), value));
4645}
4646
4647
4648DependentCode::DependencyGroup DependentCode::group() {
4649 return static_cast<DependencyGroup>(GroupField::decode(flags()));
4650}
4651
4652
4653void DependentCode::set_group(DependentCode::DependencyGroup group) {
4654 set_flags(GroupField::update(flags(), static_cast<int>(group)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004655}
4656
4657
4658void DependentCode::set_object_at(int i, Object* object) {
4659 set(kCodesStartIndex + i, object);
4660}
4661
4662
4663Object* DependentCode::object_at(int i) {
4664 return get(kCodesStartIndex + i);
4665}
4666
4667
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004668void DependentCode::clear_at(int i) {
4669 set_undefined(kCodesStartIndex + i);
4670}
4671
4672
4673void DependentCode::copy(int from, int to) {
4674 set(kCodesStartIndex + to, get(kCodesStartIndex + from));
4675}
4676
4677
Steve Blocka7e24c12009-10-30 11:49:00 +00004678void Code::set_flags(Code::Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00004679 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
Steve Blocka7e24c12009-10-30 11:49:00 +00004680 WRITE_INT_FIELD(this, kFlagsOffset, flags);
4681}
4682
4683
4684Code::Kind Code::kind() {
4685 return ExtractKindFromFlags(flags());
4686}
4687
4688
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004689bool Code::IsCodeStubOrIC() {
4690 return kind() == STUB || kind() == HANDLER || kind() == LOAD_IC ||
4691 kind() == KEYED_LOAD_IC || kind() == CALL_IC || kind() == STORE_IC ||
4692 kind() == KEYED_STORE_IC || kind() == BINARY_OP_IC ||
4693 kind() == COMPARE_IC || kind() == COMPARE_NIL_IC ||
4694 kind() == TO_BOOLEAN_IC;
4695}
4696
4697
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004698bool Code::IsJavaScriptCode() {
4699 return kind() == FUNCTION || kind() == OPTIMIZED_FUNCTION ||
4700 is_interpreter_entry_trampoline();
4701}
4702
4703
Steve Blocka7e24c12009-10-30 11:49:00 +00004704InlineCacheState Code::ic_state() {
4705 InlineCacheState result = ExtractICStateFromFlags(flags());
4706 // Only allow uninitialized or debugger states for non-IC code
4707 // objects. This is used in the debugger to determine whether or not
4708 // a call to code object has been replaced with a debug break call.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004709 DCHECK(is_inline_cache_stub() ||
Steve Blocka7e24c12009-10-30 11:49:00 +00004710 result == UNINITIALIZED ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004711 result == DEBUG_STUB);
Steve Blocka7e24c12009-10-30 11:49:00 +00004712 return result;
4713}
4714
4715
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004716ExtraICState Code::extra_ic_state() {
4717 DCHECK(is_inline_cache_stub() || ic_state() == DEBUG_STUB);
Ben Murdochb8e0da22011-05-16 14:20:40 +01004718 return ExtractExtraICStateFromFlags(flags());
4719}
4720
4721
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004722Code::StubType Code::type() {
Steve Blocka7e24c12009-10-30 11:49:00 +00004723 return ExtractTypeFromFlags(flags());
4724}
4725
4726
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004727// For initialization.
4728void Code::set_raw_kind_specific_flags1(int value) {
4729 WRITE_INT_FIELD(this, kKindSpecificFlags1Offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004730}
4731
4732
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004733void Code::set_raw_kind_specific_flags2(int value) {
4734 WRITE_INT_FIELD(this, kKindSpecificFlags2Offset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004735}
4736
4737
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004738inline bool Code::is_crankshafted() {
4739 return IsCrankshaftedField::decode(
4740 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
Steve Blocka7e24c12009-10-30 11:49:00 +00004741}
4742
4743
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004744inline bool Code::is_hydrogen_stub() {
4745 return is_crankshafted() && kind() != OPTIMIZED_FUNCTION;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004746}
4747
4748
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004749inline bool Code::is_interpreter_entry_trampoline() {
4750 Handle<Code> interpreter_entry =
4751 GetIsolate()->builtins()->InterpreterEntryTrampoline();
4752 return interpreter_entry.location() != nullptr && *interpreter_entry == this;
4753}
4754
Ben Murdoch097c5b22016-05-18 11:27:45 +01004755inline bool Code::is_interpreter_enter_bytecode_dispatch() {
4756 Handle<Code> interpreter_handler =
4757 GetIsolate()->builtins()->InterpreterEnterBytecodeDispatch();
4758 return interpreter_handler.location() != nullptr &&
4759 *interpreter_handler == this;
4760}
4761
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004762inline void Code::set_is_crankshafted(bool value) {
4763 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4764 int updated = IsCrankshaftedField::update(previous, value);
4765 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
4766}
4767
4768
4769inline bool Code::is_turbofanned() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004770 return IsTurbofannedField::decode(
4771 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
4772}
4773
4774
4775inline void Code::set_is_turbofanned(bool value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004776 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4777 int updated = IsTurbofannedField::update(previous, value);
4778 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004779}
4780
4781
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004782inline bool Code::can_have_weak_objects() {
4783 DCHECK(kind() == OPTIMIZED_FUNCTION);
4784 return CanHaveWeakObjectsField::decode(
4785 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
Ben Murdochb0fe1622011-05-05 13:52:32 +01004786}
4787
4788
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004789inline void Code::set_can_have_weak_objects(bool value) {
4790 DCHECK(kind() == OPTIMIZED_FUNCTION);
4791 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4792 int updated = CanHaveWeakObjectsField::update(previous, value);
4793 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004794}
4795
4796
4797bool Code::has_deoptimization_support() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004798 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004799 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004800 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004801}
4802
4803
4804void Code::set_has_deoptimization_support(bool value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004805 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004806 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004807 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004808 WRITE_UINT32_FIELD(this, kFullCodeFlags, flags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004809}
4810
4811
4812bool Code::has_debug_break_slots() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004813 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004814 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004815 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
4816}
4817
4818
4819void Code::set_has_debug_break_slots(bool value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004820 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004821 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Ben Murdoch589d6972011-11-30 16:04:58 +00004822 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004823 WRITE_UINT32_FIELD(this, kFullCodeFlags, flags);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004824}
4825
4826
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004827bool Code::has_reloc_info_for_serialization() {
4828 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004829 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004830 return FullCodeFlagsHasRelocInfoForSerialization::decode(flags);
4831}
4832
4833
4834void Code::set_has_reloc_info_for_serialization(bool value) {
4835 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004836 unsigned flags = READ_UINT32_FIELD(this, kFullCodeFlags);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004837 flags = FullCodeFlagsHasRelocInfoForSerialization::update(flags, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004838 WRITE_UINT32_FIELD(this, kFullCodeFlags, flags);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004839}
4840
4841
Ben Murdochb0fe1622011-05-05 13:52:32 +01004842int Code::allow_osr_at_loop_nesting_level() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004843 DCHECK_EQ(FUNCTION, kind());
4844 int fields = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4845 return AllowOSRAtLoopNestingLevelField::decode(fields);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004846}
4847
4848
4849void Code::set_allow_osr_at_loop_nesting_level(int level) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004850 DCHECK_EQ(FUNCTION, kind());
4851 DCHECK(level >= 0 && level <= kMaxLoopNestingMarker);
4852 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4853 int updated = AllowOSRAtLoopNestingLevelField::update(previous, level);
4854 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004855}
4856
4857
Ben Murdoch8f9999f2012-04-23 10:39:17 +01004858int Code::profiler_ticks() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004859 DCHECK_EQ(FUNCTION, kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004860 return ProfilerTicksField::decode(
4861 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
Ben Murdoch8f9999f2012-04-23 10:39:17 +01004862}
4863
4864
4865void Code::set_profiler_ticks(int ticks) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004866 if (kind() == FUNCTION) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004867 unsigned previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4868 unsigned updated = ProfilerTicksField::update(previous, ticks);
4869 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004870 }
4871}
4872
4873
4874int Code::builtin_index() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004875 return READ_INT32_FIELD(this, kKindSpecificFlags1Offset);
4876}
4877
4878
4879void Code::set_builtin_index(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004880 WRITE_INT32_FIELD(this, kKindSpecificFlags1Offset, index);
Ben Murdoch8f9999f2012-04-23 10:39:17 +01004881}
4882
4883
Ben Murdochb0fe1622011-05-05 13:52:32 +01004884unsigned Code::stack_slots() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004885 DCHECK(is_crankshafted());
4886 return StackSlotsField::decode(
4887 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
Ben Murdochb0fe1622011-05-05 13:52:32 +01004888}
4889
4890
4891void Code::set_stack_slots(unsigned slots) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004892 CHECK(slots <= (1 << kStackSlotsBitCount));
4893 DCHECK(is_crankshafted());
4894 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4895 int updated = StackSlotsField::update(previous, slots);
4896 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004897}
4898
4899
Steve Block1e0659c2011-05-24 12:43:12 +01004900unsigned Code::safepoint_table_offset() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004901 DCHECK(is_crankshafted());
4902 return SafepointTableOffsetField::decode(
4903 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
Ben Murdochb0fe1622011-05-05 13:52:32 +01004904}
4905
4906
Steve Block1e0659c2011-05-24 12:43:12 +01004907void Code::set_safepoint_table_offset(unsigned offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004908 CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
4909 DCHECK(is_crankshafted());
4910 DCHECK(IsAligned(offset, static_cast<unsigned>(kIntSize)));
4911 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4912 int updated = SafepointTableOffsetField::update(previous, offset);
4913 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004914}
4915
4916
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004917unsigned Code::back_edge_table_offset() {
4918 DCHECK_EQ(FUNCTION, kind());
4919 return BackEdgeTableOffsetField::decode(
4920 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset)) << kPointerSizeLog2;
Ben Murdochb0fe1622011-05-05 13:52:32 +01004921}
4922
4923
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004924void Code::set_back_edge_table_offset(unsigned offset) {
4925 DCHECK_EQ(FUNCTION, kind());
4926 DCHECK(IsAligned(offset, static_cast<unsigned>(kPointerSize)));
4927 offset = offset >> kPointerSizeLog2;
4928 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
4929 int updated = BackEdgeTableOffsetField::update(previous, offset);
4930 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
Ben Murdochb0fe1622011-05-05 13:52:32 +01004931}
4932
4933
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004934bool Code::back_edges_patched_for_osr() {
4935 DCHECK_EQ(FUNCTION, kind());
4936 return allow_osr_at_loop_nesting_level() > 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +01004937}
4938
4939
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004940uint16_t Code::to_boolean_state() { return extra_ic_state(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004941
4942
4943bool Code::marked_for_deoptimization() {
4944 DCHECK(kind() == OPTIMIZED_FUNCTION);
4945 return MarkedForDeoptimizationField::decode(
4946 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
4947}
4948
4949
4950void Code::set_marked_for_deoptimization(bool flag) {
4951 DCHECK(kind() == OPTIMIZED_FUNCTION);
4952 DCHECK(!flag || AllowDeoptimization::IsAllowed(GetIsolate()));
4953 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4954 int updated = MarkedForDeoptimizationField::update(previous, flag);
4955 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
4956}
4957
4958
Steve Blocka7e24c12009-10-30 11:49:00 +00004959bool Code::is_inline_cache_stub() {
4960 Kind kind = this->kind();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004961 switch (kind) {
4962#define CASE(name) case name: return true;
4963 IC_KIND_LIST(CASE)
4964#undef CASE
4965 default: return false;
4966 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004967}
4968
4969
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004970bool Code::is_keyed_stub() {
4971 return is_keyed_load_stub() || is_keyed_store_stub();
4972}
4973
4974
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004975bool Code::is_debug_stub() { return ic_state() == DEBUG_STUB; }
4976bool Code::is_handler() { return kind() == HANDLER; }
4977bool Code::is_load_stub() { return kind() == LOAD_IC; }
4978bool Code::is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
4979bool Code::is_store_stub() { return kind() == STORE_IC; }
4980bool Code::is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
4981bool Code::is_call_stub() { return kind() == CALL_IC; }
4982bool Code::is_binary_op_stub() { return kind() == BINARY_OP_IC; }
4983bool Code::is_compare_ic_stub() { return kind() == COMPARE_IC; }
4984bool Code::is_compare_nil_ic_stub() { return kind() == COMPARE_NIL_IC; }
4985bool Code::is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; }
4986bool Code::is_optimized_code() { return kind() == OPTIMIZED_FUNCTION; }
4987
4988
4989bool Code::embeds_maps_weakly() {
4990 Kind k = kind();
4991 return (k == LOAD_IC || k == STORE_IC || k == KEYED_LOAD_IC ||
4992 k == KEYED_STORE_IC || k == COMPARE_NIL_IC) &&
4993 ic_state() == MONOMORPHIC;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004994}
4995
4996
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004997Address Code::constant_pool() {
4998 Address constant_pool = NULL;
4999 if (FLAG_enable_embedded_constant_pool) {
5000 int offset = constant_pool_offset();
5001 if (offset < instruction_size()) {
5002 constant_pool = FIELD_ADDR(this, kHeaderSize + offset);
5003 }
5004 }
5005 return constant_pool;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005006}
5007
5008
5009Code::Flags Code::ComputeFlags(Kind kind, InlineCacheState ic_state,
5010 ExtraICState extra_ic_state, StubType type,
5011 CacheHolderFlag holder) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005012 // Compute the bit mask.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005013 unsigned int bits = KindField::encode(kind)
Ben Murdoch589d6972011-11-30 16:04:58 +00005014 | ICStateField::encode(ic_state)
5015 | TypeField::encode(type)
5016 | ExtraICStateField::encode(extra_ic_state)
Ben Murdoch589d6972011-11-30 16:04:58 +00005017 | CacheHolderField::encode(holder);
5018 return static_cast<Flags>(bits);
Steve Blocka7e24c12009-10-30 11:49:00 +00005019}
5020
5021
5022Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
Ben Murdochb8e0da22011-05-16 14:20:40 +01005023 ExtraICState extra_ic_state,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005024 CacheHolderFlag holder,
5025 StubType type) {
5026 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, holder);
5027}
5028
5029
5030Code::Flags Code::ComputeHandlerFlags(Kind handler_kind, StubType type,
5031 CacheHolderFlag holder) {
5032 return ComputeFlags(Code::HANDLER, MONOMORPHIC, handler_kind, type, holder);
Steve Blocka7e24c12009-10-30 11:49:00 +00005033}
5034
5035
5036Code::Kind Code::ExtractKindFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005037 return KindField::decode(flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005038}
5039
5040
5041InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005042 return ICStateField::decode(flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005043}
5044
5045
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005046ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005047 return ExtraICStateField::decode(flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005048}
5049
5050
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005051Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005052 return TypeField::decode(flags);
Steve Blocka7e24c12009-10-30 11:49:00 +00005053}
5054
5055
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005056CacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005057 return CacheHolderField::decode(flags);
Steve Block8defd9f2010-07-08 12:39:36 +01005058}
5059
5060
Steve Blocka7e24c12009-10-30 11:49:00 +00005061Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
Ben Murdoch589d6972011-11-30 16:04:58 +00005062 int bits = flags & ~TypeField::kMask;
Steve Blocka7e24c12009-10-30 11:49:00 +00005063 return static_cast<Flags>(bits);
5064}
5065
5066
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005067Code::Flags Code::RemoveTypeAndHolderFromFlags(Flags flags) {
5068 int bits = flags & ~TypeField::kMask & ~CacheHolderField::kMask;
5069 return static_cast<Flags>(bits);
5070}
5071
5072
Steve Blocka7e24c12009-10-30 11:49:00 +00005073Code* Code::GetCodeFromTargetAddress(Address address) {
5074 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
5075 // GetCodeFromTargetAddress might be called when marking objects during mark
5076 // sweep. reinterpret_cast is therefore used instead of the more appropriate
5077 // Code::cast. Code::cast does not work when the object's map is
5078 // marked.
5079 Code* result = reinterpret_cast<Code*>(code);
5080 return result;
5081}
5082
5083
Steve Block791712a2010-08-27 10:21:07 +01005084Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
5085 return HeapObject::
5086 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
5087}
5088
5089
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005090bool Code::CanContainWeakObjects() {
5091 return is_optimized_code() && can_have_weak_objects();
5092}
5093
5094
5095bool Code::IsWeakObject(Object* object) {
5096 return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object));
5097}
5098
5099
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005100bool Code::IsWeakObjectInOptimizedCode(Object* object) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005101 if (object->IsMap()) {
5102 return Map::cast(object)->CanTransition() &&
5103 FLAG_weak_embedded_maps_in_optimized_code;
5104 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005105 if (object->IsCell()) {
5106 object = Cell::cast(object)->value();
5107 } else if (object->IsPropertyCell()) {
5108 object = PropertyCell::cast(object)->value();
5109 }
5110 if (object->IsJSReceiver()) {
5111 return FLAG_weak_embedded_objects_in_optimized_code;
5112 }
5113 if (object->IsContext()) {
5114 // Contexts of inlined functions are embedded in optimized code.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005115 return FLAG_weak_embedded_objects_in_optimized_code;
5116 }
5117 return false;
5118}
5119
5120
5121class Code::FindAndReplacePattern {
5122 public:
5123 FindAndReplacePattern() : count_(0) { }
5124 void Add(Handle<Map> map_to_find, Handle<Object> obj_to_replace) {
5125 DCHECK(count_ < kMaxCount);
5126 find_[count_] = map_to_find;
5127 replace_[count_] = obj_to_replace;
5128 ++count_;
5129 }
5130 private:
5131 static const int kMaxCount = 4;
5132 int count_;
5133 Handle<Map> find_[kMaxCount];
5134 Handle<Object> replace_[kMaxCount];
5135 friend class Code;
5136};
5137
Ben Murdoch097c5b22016-05-18 11:27:45 +01005138int AbstractCode::Size() {
5139 if (IsCode()) {
5140 return GetCode()->instruction_size();
5141 } else {
5142 return GetBytecodeArray()->length();
5143 }
5144}
5145
5146Code* AbstractCode::GetCode() { return Code::cast(this); }
5147
5148BytecodeArray* AbstractCode::GetBytecodeArray() {
5149 return BytecodeArray::cast(this);
5150}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005151
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005152Object* Map::prototype() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005153 return READ_FIELD(this, kPrototypeOffset);
5154}
5155
5156
5157void Map::set_prototype(Object* value, WriteBarrierMode mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005158 DCHECK(value->IsNull() || value->IsJSReceiver());
Steve Blocka7e24c12009-10-30 11:49:00 +00005159 WRITE_FIELD(this, kPrototypeOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005160 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
Steve Block1e0659c2011-05-24 12:43:12 +01005161}
5162
5163
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005164LayoutDescriptor* Map::layout_descriptor_gc_safe() {
5165 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
5166 return LayoutDescriptor::cast_gc_safe(layout_desc);
5167}
5168
5169
5170bool Map::HasFastPointerLayout() const {
5171 Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
5172 return LayoutDescriptor::IsFastPointerLayout(layout_desc);
5173}
5174
5175
5176void Map::UpdateDescriptors(DescriptorArray* descriptors,
5177 LayoutDescriptor* layout_desc) {
5178 set_instance_descriptors(descriptors);
5179 if (FLAG_unbox_double_fields) {
5180 if (layout_descriptor()->IsSlowLayout()) {
5181 set_layout_descriptor(layout_desc);
5182 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005183#ifdef VERIFY_HEAP
5184 // TODO(ishell): remove these checks from VERIFY_HEAP mode.
5185 if (FLAG_verify_heap) {
5186 CHECK(layout_descriptor()->IsConsistentWithMap(this));
5187 CHECK(visitor_id() == Heap::GetStaticVisitorIdForMap(this));
5188 }
5189#else
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005190 SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005191 DCHECK(visitor_id() == Heap::GetStaticVisitorIdForMap(this));
5192#endif
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005193 }
5194}
5195
5196
5197void Map::InitializeDescriptors(DescriptorArray* descriptors,
5198 LayoutDescriptor* layout_desc) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005199 int len = descriptors->number_of_descriptors();
5200 set_instance_descriptors(descriptors);
5201 SetNumberOfOwnDescriptors(len);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005202
5203 if (FLAG_unbox_double_fields) {
5204 set_layout_descriptor(layout_desc);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005205#ifdef VERIFY_HEAP
5206 // TODO(ishell): remove these checks from VERIFY_HEAP mode.
5207 if (FLAG_verify_heap) {
5208 CHECK(layout_descriptor()->IsConsistentWithMap(this));
5209 }
5210#else
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005211 SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005212#endif
5213 set_visitor_id(Heap::GetStaticVisitorIdForMap(this));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005214 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005215}
5216
5217
5218ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005219ACCESSORS(Map, layout_descriptor, LayoutDescriptor, kLayoutDecriptorOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005220
5221
5222void Map::set_bit_field3(uint32_t bits) {
5223 if (kInt32Size != kPointerSize) {
5224 WRITE_UINT32_FIELD(this, kBitField3Offset + kInt32Size, 0);
5225 }
5226 WRITE_UINT32_FIELD(this, kBitField3Offset, bits);
5227}
5228
5229
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005230uint32_t Map::bit_field3() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005231 return READ_UINT32_FIELD(this, kBitField3Offset);
5232}
5233
5234
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005235LayoutDescriptor* Map::GetLayoutDescriptor() {
5236 return FLAG_unbox_double_fields ? layout_descriptor()
5237 : LayoutDescriptor::FastPointerLayout();
5238}
5239
5240
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005241void Map::AppendDescriptor(Descriptor* desc) {
5242 DescriptorArray* descriptors = instance_descriptors();
5243 int number_of_own_descriptors = NumberOfOwnDescriptors();
5244 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors);
5245 descriptors->Append(desc);
5246 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005247
5248// This function does not support appending double field descriptors and
5249// it should never try to (otherwise, layout descriptor must be updated too).
5250#ifdef DEBUG
5251 PropertyDetails details = desc->GetDetails();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005252 CHECK(details.type() != DATA || !details.representation().IsDouble());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005253#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005254}
5255
5256
5257Object* Map::GetBackPointer() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005258 Object* object = constructor_or_backpointer();
5259 if (object->IsMap()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005260 return object;
5261 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005262 return GetIsolate()->heap()->undefined_value();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005263}
5264
5265
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005266Map* Map::ElementsTransitionMap() {
5267 return TransitionArray::SearchSpecial(
5268 this, GetHeap()->elements_transition_symbol());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005269}
5270
5271
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005272ACCESSORS(Map, raw_transitions, Object, kTransitionsOrPrototypeInfoOffset)
5273
5274
5275Object* Map::prototype_info() const {
5276 DCHECK(is_prototype_map());
5277 return READ_FIELD(this, Map::kTransitionsOrPrototypeInfoOffset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005278}
5279
5280
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005281void Map::set_prototype_info(Object* value, WriteBarrierMode mode) {
5282 DCHECK(is_prototype_map());
5283 WRITE_FIELD(this, Map::kTransitionsOrPrototypeInfoOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005284 CONDITIONAL_WRITE_BARRIER(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005285 GetHeap(), this, Map::kTransitionsOrPrototypeInfoOffset, value, mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005286}
5287
5288
5289void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
5290 DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005291 DCHECK((value->IsMap() && GetBackPointer()->IsUndefined()));
5292 DCHECK(!value->IsMap() ||
5293 Map::cast(value)->GetConstructor() == constructor_or_backpointer());
5294 set_constructor_or_backpointer(value, mode);
Ben Murdoch257744e2011-11-30 15:57:28 +00005295}
5296
5297
Steve Block6ded16b2010-05-10 14:33:55 +01005298ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005299ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005300ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset)
5301ACCESSORS(Map, constructor_or_backpointer, Object,
5302 kConstructorOrBackPointerOffset)
5303
5304
5305Object* Map::GetConstructor() const {
5306 Object* maybe_constructor = constructor_or_backpointer();
5307 // Follow any back pointers.
5308 while (maybe_constructor->IsMap()) {
5309 maybe_constructor =
5310 Map::cast(maybe_constructor)->constructor_or_backpointer();
5311 }
5312 return maybe_constructor;
5313}
5314
5315
5316void Map::SetConstructor(Object* constructor, WriteBarrierMode mode) {
5317 // Never overwrite a back pointer with a constructor.
5318 DCHECK(!constructor_or_backpointer()->IsMap());
5319 set_constructor_or_backpointer(constructor, mode);
5320}
5321
5322
5323Handle<Map> Map::CopyInitialMap(Handle<Map> map) {
5324 return CopyInitialMap(map, map->instance_size(), map->GetInObjectProperties(),
5325 map->unused_property_fields());
5326}
5327
5328
5329ACCESSORS(JSBoundFunction, length, Object, kLengthOffset)
5330ACCESSORS(JSBoundFunction, name, Object, kNameOffset)
5331ACCESSORS(JSBoundFunction, bound_target_function, JSReceiver,
5332 kBoundTargetFunctionOffset)
5333ACCESSORS(JSBoundFunction, bound_this, Object, kBoundThisOffset)
5334ACCESSORS(JSBoundFunction, bound_arguments, FixedArray, kBoundArgumentsOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005335
5336ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005337ACCESSORS(JSFunction, literals, LiteralsArray, kLiteralsOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005338ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005339
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005340ACCESSORS(JSGlobalObject, native_context, Context, kNativeContextOffset)
5341ACCESSORS(JSGlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005342
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005343ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
5344ACCESSORS(JSGlobalProxy, hash, Object, kHashOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005345
Steve Blocka7e24c12009-10-30 11:49:00 +00005346ACCESSORS(AccessorInfo, name, Object, kNameOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005347SMI_ACCESSORS(AccessorInfo, flag, kFlagOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005348ACCESSORS(AccessorInfo, expected_receiver_type, Object,
5349 kExpectedReceiverTypeOffset)
5350
Ben Murdoch097c5b22016-05-18 11:27:45 +01005351ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
5352ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
5353ACCESSORS(AccessorInfo, data, Object, kDataOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005354
5355ACCESSORS(Box, value, Object, kValueOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005356
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005357ACCESSORS(PrototypeInfo, prototype_users, Object, kPrototypeUsersOffset)
5358SMI_ACCESSORS(PrototypeInfo, registry_slot, kRegistrySlotOffset)
5359ACCESSORS(PrototypeInfo, validity_cell, Object, kValidityCellOffset)
5360
5361ACCESSORS(SloppyBlockWithEvalContextExtension, scope_info, ScopeInfo,
5362 kScopeInfoOffset)
5363ACCESSORS(SloppyBlockWithEvalContextExtension, extension, JSObject,
5364 kExtensionOffset)
5365
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005366ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
5367ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
Ben Murdochc7cc0282012-03-05 14:35:55 +00005368
Steve Blocka7e24c12009-10-30 11:49:00 +00005369ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
5370ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005371ACCESSORS(AccessCheckInfo, callback, Object, kCallbackOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005372ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
5373
5374ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
5375ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
5376ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
5377ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
5378ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
5379ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005380SMI_ACCESSORS(InterceptorInfo, flags, kFlagsOffset)
5381BOOL_ACCESSORS(InterceptorInfo, flags, can_intercept_symbols,
5382 kCanInterceptSymbolsBit)
5383BOOL_ACCESSORS(InterceptorInfo, flags, all_can_read, kAllCanReadBit)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005384BOOL_ACCESSORS(InterceptorInfo, flags, non_masking, kNonMasking)
Steve Blocka7e24c12009-10-30 11:49:00 +00005385
5386ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
5387ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005388ACCESSORS(CallHandlerInfo, fast_handler, Object, kFastHandlerOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005389
5390ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005391ACCESSORS(TemplateInfo, serial_number, Object, kSerialNumberOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005392SMI_ACCESSORS(TemplateInfo, number_of_properties, kNumberOfProperties)
Steve Blocka7e24c12009-10-30 11:49:00 +00005393ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005394ACCESSORS(TemplateInfo, property_accessors, Object, kPropertyAccessorsOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005395
Steve Blocka7e24c12009-10-30 11:49:00 +00005396ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005397ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
5398 kPrototypeTemplateOffset)
5399ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
5400ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
5401 kNamedPropertyHandlerOffset)
5402ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
5403 kIndexedPropertyHandlerOffset)
5404ACCESSORS(FunctionTemplateInfo, instance_template, Object,
5405 kInstanceTemplateOffset)
5406ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
5407ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
5408ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
5409 kInstanceCallHandlerOffset)
5410ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
5411 kAccessCheckInfoOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005412SMI_ACCESSORS(FunctionTemplateInfo, flag, kFlagOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005413
5414ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
5415ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
5416 kInternalFieldCountOffset)
5417
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005418ACCESSORS(AllocationSite, transition_info, Object, kTransitionInfoOffset)
5419ACCESSORS(AllocationSite, nested_site, Object, kNestedSiteOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005420SMI_ACCESSORS(AllocationSite, pretenure_data, kPretenureDataOffset)
5421SMI_ACCESSORS(AllocationSite, pretenure_create_count,
5422 kPretenureCreateCountOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005423ACCESSORS(AllocationSite, dependent_code, DependentCode,
5424 kDependentCodeOffset)
5425ACCESSORS(AllocationSite, weak_next, Object, kWeakNextOffset)
5426ACCESSORS(AllocationMemento, allocation_site, Object, kAllocationSiteOffset)
5427
Steve Blocka7e24c12009-10-30 11:49:00 +00005428ACCESSORS(Script, source, Object, kSourceOffset)
5429ACCESSORS(Script, name, Object, kNameOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005430SMI_ACCESSORS(Script, id, kIdOffset)
5431SMI_ACCESSORS(Script, line_offset, kLineOffsetOffset)
5432SMI_ACCESSORS(Script, column_offset, kColumnOffsetOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005433ACCESSORS(Script, context_data, Object, kContextOffset)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005434ACCESSORS(Script, wrapper, HeapObject, kWrapperOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005435SMI_ACCESSORS(Script, type, kTypeOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005436ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
Steve Blockd0582a62009-12-15 09:54:21 +00005437ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005438SMI_ACCESSORS(Script, eval_from_instructions_offset,
5439 kEvalFrominstructionsOffsetOffset)
5440ACCESSORS(Script, shared_function_infos, Object, kSharedFunctionInfosOffset)
5441SMI_ACCESSORS(Script, flags, kFlagsOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005442ACCESSORS(Script, source_url, Object, kSourceUrlOffset)
5443ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005444
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005445Script::CompilationType Script::compilation_type() {
5446 return BooleanBit::get(flags(), kCompilationTypeBit) ?
5447 COMPILATION_TYPE_EVAL : COMPILATION_TYPE_HOST;
5448}
5449void Script::set_compilation_type(CompilationType type) {
5450 set_flags(BooleanBit::set(flags(), kCompilationTypeBit,
5451 type == COMPILATION_TYPE_EVAL));
5452}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005453bool Script::hide_source() { return BooleanBit::get(flags(), kHideSourceBit); }
5454void Script::set_hide_source(bool value) {
5455 set_flags(BooleanBit::set(flags(), kHideSourceBit, value));
5456}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005457Script::CompilationState Script::compilation_state() {
5458 return BooleanBit::get(flags(), kCompilationStateBit) ?
5459 COMPILATION_STATE_COMPILED : COMPILATION_STATE_INITIAL;
5460}
5461void Script::set_compilation_state(CompilationState state) {
5462 set_flags(BooleanBit::set(flags(), kCompilationStateBit,
5463 state == COMPILATION_STATE_COMPILED));
5464}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005465ScriptOriginOptions Script::origin_options() {
5466 return ScriptOriginOptions((flags() & kOriginOptionsMask) >>
5467 kOriginOptionsShift);
5468}
5469void Script::set_origin_options(ScriptOriginOptions origin_options) {
5470 DCHECK(!(origin_options.Flags() & ~((1 << kOriginOptionsSize) - 1)));
5471 set_flags((flags() & ~kOriginOptionsMask) |
5472 (origin_options.Flags() << kOriginOptionsShift));
5473}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005474
5475
Steve Blocka7e24c12009-10-30 11:49:00 +00005476ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005477ACCESSORS(DebugInfo, abstract_code, AbstractCode, kAbstractCodeIndex)
Steve Blocka7e24c12009-10-30 11:49:00 +00005478ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
5479
Ben Murdoch097c5b22016-05-18 11:27:45 +01005480BytecodeArray* DebugInfo::original_bytecode_array() {
5481 return shared()->bytecode_array();
5482}
5483
5484SMI_ACCESSORS(BreakPointInfo, code_offset, kCodeOffsetIndex)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005485SMI_ACCESSORS(BreakPointInfo, source_position, kSourcePositionIndex)
5486SMI_ACCESSORS(BreakPointInfo, statement_position, kStatementPositionIndex)
Steve Blocka7e24c12009-10-30 11:49:00 +00005487ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
Steve Blocka7e24c12009-10-30 11:49:00 +00005488
Steve Blocka7e24c12009-10-30 11:49:00 +00005489ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005490ACCESSORS(SharedFunctionInfo, optimized_code_map, FixedArray,
5491 kOptimizedCodeMapOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005492ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005493ACCESSORS(SharedFunctionInfo, feedback_vector, TypeFeedbackVector,
5494 kFeedbackVectorOffset)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005495#if TRACE_MAPS
5496SMI_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset)
5497#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00005498ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
5499 kInstanceClassNameOffset)
Steve Block6ded16b2010-05-10 14:33:55 +01005500ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005501ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
5502ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
5503ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005504
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005505
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005506SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00005507BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
5508 kHiddenPrototypeBit)
5509BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
5510BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
5511 kNeedsAccessCheckBit)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005512BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
5513 kReadOnlyPrototypeBit)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005514BOOL_ACCESSORS(FunctionTemplateInfo, flag, remove_prototype,
5515 kRemovePrototypeBit)
5516BOOL_ACCESSORS(FunctionTemplateInfo, flag, do_not_cache,
5517 kDoNotCacheBit)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005518BOOL_ACCESSORS(FunctionTemplateInfo, flag, instantiated, kInstantiatedBit)
5519BOOL_ACCESSORS(FunctionTemplateInfo, flag, accept_any_receiver,
5520 kAcceptAnyReceiver)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005521BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_named_expression,
5522 kIsNamedExpressionBit)
Steve Blocka7e24c12009-10-30 11:49:00 +00005523BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
5524 kIsTopLevelBit)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005525
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005526BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, allows_lazy_compilation,
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005527 kAllowLazyCompilation)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005528BOOL_ACCESSORS(SharedFunctionInfo,
5529 compiler_hints,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005530 allows_lazy_compilation_without_context,
5531 kAllowLazyCompilationWithoutContext)
5532BOOL_ACCESSORS(SharedFunctionInfo,
5533 compiler_hints,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005534 uses_arguments,
5535 kUsesArguments)
5536BOOL_ACCESSORS(SharedFunctionInfo,
5537 compiler_hints,
5538 has_duplicate_parameters,
5539 kHasDuplicateParameters)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005540BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, asm_function, kIsAsmFunction)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005541BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, deserialized, kDeserialized)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005542BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, never_compiled,
5543 kNeverCompiled)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005544BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_declaration,
5545 kIsDeclaration)
Iain Merrick75681382010-08-19 15:07:18 +01005546
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005547#if V8_HOST_ARCH_32_BIT
5548SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005549SMI_ACCESSORS(SharedFunctionInfo, internal_formal_parameter_count,
Steve Blocka7e24c12009-10-30 11:49:00 +00005550 kFormalParameterCountOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005551SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
Steve Blocka7e24c12009-10-30 11:49:00 +00005552 kExpectedNofPropertiesOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005553SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
5554SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
Steve Blocka7e24c12009-10-30 11:49:00 +00005555 kStartPositionAndTypeOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005556SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
5557SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
Steve Blocka7e24c12009-10-30 11:49:00 +00005558 kFunctionTokenPositionOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005559SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
Steve Blocka7e24c12009-10-30 11:49:00 +00005560 kCompilerHintsOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005561SMI_ACCESSORS(SharedFunctionInfo, opt_count_and_bailout_reason,
5562 kOptCountAndBailoutReasonOffset)
5563SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005564SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005565SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
5566
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005567#else
Steve Blocka7e24c12009-10-30 11:49:00 +00005568
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005569#if V8_TARGET_LITTLE_ENDIAN
5570#define PSEUDO_SMI_LO_ALIGN 0
5571#define PSEUDO_SMI_HI_ALIGN kIntSize
5572#else
5573#define PSEUDO_SMI_LO_ALIGN kIntSize
5574#define PSEUDO_SMI_HI_ALIGN 0
5575#endif
5576
5577#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
5578 STATIC_ASSERT(holder::offset % kPointerSize == PSEUDO_SMI_LO_ALIGN); \
5579 int holder::name() const { \
5580 int value = READ_INT_FIELD(this, offset); \
5581 DCHECK(kHeapObjectTag == 1); \
5582 DCHECK((value & kHeapObjectTag) == 0); \
5583 return value >> 1; \
5584 } \
5585 void holder::set_##name(int value) { \
5586 DCHECK(kHeapObjectTag == 1); \
5587 DCHECK((value & 0xC0000000) == 0xC0000000 || (value & 0xC0000000) == 0x0); \
5588 WRITE_INT_FIELD(this, offset, (value << 1) & ~kHeapObjectTag); \
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005589 }
5590
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005591#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
5592 STATIC_ASSERT(holder::offset % kPointerSize == PSEUDO_SMI_HI_ALIGN); \
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005593 INT_ACCESSORS(holder, name, offset)
5594
5595
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005596PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005597PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, internal_formal_parameter_count,
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005598 kFormalParameterCountOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005599
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005600PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5601 expected_nof_properties,
5602 kExpectedNofPropertiesOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005603PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
5604
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005605PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
5606PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5607 start_position_and_type,
5608 kStartPositionAndTypeOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005609
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005610PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5611 function_token_position,
5612 kFunctionTokenPositionOffset)
5613PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5614 compiler_hints,
5615 kCompilerHintsOffset)
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005616
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08005617PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005618 opt_count_and_bailout_reason,
5619 kOptCountAndBailoutReasonOffset)
5620PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, counters, kCountersOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005621
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005622PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
5623 ast_node_count,
5624 kAstNodeCountOffset)
5625PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
5626 profiler_ticks,
5627 kProfilerTicksOffset)
5628
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01005629#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00005630
Kristian Monsen0d5e1162010-09-30 15:31:59 +01005631
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005632BOOL_GETTER(SharedFunctionInfo,
5633 compiler_hints,
5634 optimization_disabled,
5635 kOptimizationDisabled)
Ben Murdochb0fe1622011-05-05 13:52:32 +01005636
5637
5638void SharedFunctionInfo::set_optimization_disabled(bool disable) {
5639 set_compiler_hints(BooleanBit::set(compiler_hints(),
5640 kOptimizationDisabled,
5641 disable));
Ben Murdochb0fe1622011-05-05 13:52:32 +01005642}
5643
5644
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005645LanguageMode SharedFunctionInfo::language_mode() {
5646 STATIC_ASSERT(LANGUAGE_END == 3);
5647 return construct_language_mode(
5648 BooleanBit::get(compiler_hints(), kStrictModeFunction),
5649 BooleanBit::get(compiler_hints(), kStrongModeFunction));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005650}
5651
5652
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005653void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
5654 STATIC_ASSERT(LANGUAGE_END == 3);
5655 // We only allow language mode transitions that set the same language mode
5656 // again or go up in the chain:
5657 DCHECK(is_sloppy(this->language_mode()) || is_strict(language_mode));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005658 int hints = compiler_hints();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005659 hints = BooleanBit::set(hints, kStrictModeFunction, is_strict(language_mode));
5660 hints = BooleanBit::set(hints, kStrongModeFunction, is_strong(language_mode));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005661 set_compiler_hints(hints);
5662}
5663
5664
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005665FunctionKind SharedFunctionInfo::kind() {
5666 return FunctionKindBits::decode(compiler_hints());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005667}
5668
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005669
5670void SharedFunctionInfo::set_kind(FunctionKind kind) {
5671 DCHECK(IsValidFunctionKind(kind));
5672 int hints = compiler_hints();
5673 hints = FunctionKindBits::update(hints, kind);
5674 set_compiler_hints(hints);
5675}
5676
5677
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005678BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, needs_home_object,
5679 kNeedsHomeObject)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005680BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005681BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, force_inline, kForceInline)
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005682BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
5683 name_should_print_as_anonymous,
5684 kNameShouldPrintAsAnonymous)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005685BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous_expression,
5686 kIsAnonymousExpression)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005687BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005688BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_crankshaft,
5689 kDontCrankshaft)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005690BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_flush, kDontFlush)
5691BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_arrow, kIsArrow)
5692BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator)
5693BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_concise_method,
5694 kIsConciseMethod)
Ben Murdoch097c5b22016-05-18 11:27:45 +01005695BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_getter_function,
5696 kIsGetterFunction)
5697BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_setter_function,
5698 kIsSetterFunction)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005699BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_default_constructor,
5700 kIsDefaultConstructor)
Ben Murdoch257744e2011-11-30 15:57:28 +00005701
Steve Block6ded16b2010-05-10 14:33:55 +01005702ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
5703ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
5704
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005705ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
5706
Steve Block3ce2e202009-11-05 08:53:23 +00005707bool Script::HasValidSource() {
5708 Object* src = this->source();
5709 if (!src->IsString()) return true;
5710 String* src_str = String::cast(src);
5711 if (!StringShape(src_str).IsExternal()) return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005712 if (src_str->IsOneByteRepresentation()) {
5713 return ExternalOneByteString::cast(src)->resource() != NULL;
Steve Block3ce2e202009-11-05 08:53:23 +00005714 } else if (src_str->IsTwoByteRepresentation()) {
5715 return ExternalTwoByteString::cast(src)->resource() != NULL;
5716 }
5717 return true;
5718}
5719
5720
Steve Blocka7e24c12009-10-30 11:49:00 +00005721void SharedFunctionInfo::DontAdaptArguments() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005722 DCHECK(code()->kind() == Code::BUILTIN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005723 set_internal_formal_parameter_count(kDontAdaptArgumentsSentinel);
Steve Blocka7e24c12009-10-30 11:49:00 +00005724}
5725
5726
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005727int SharedFunctionInfo::start_position() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005728 return start_position_and_type() >> kStartPositionShift;
5729}
5730
5731
5732void SharedFunctionInfo::set_start_position(int start_position) {
5733 set_start_position_and_type((start_position << kStartPositionShift)
5734 | (start_position_and_type() & ~kStartPositionMask));
5735}
5736
5737
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005738Code* SharedFunctionInfo::code() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005739 return Code::cast(READ_FIELD(this, kCodeOffset));
5740}
5741
5742
5743void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005744 DCHECK(value->kind() != Code::OPTIMIZED_FUNCTION);
Steve Blocka7e24c12009-10-30 11:49:00 +00005745 WRITE_FIELD(this, kCodeOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005746 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
Steve Blocka7e24c12009-10-30 11:49:00 +00005747}
5748
5749
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005750void SharedFunctionInfo::ReplaceCode(Code* value) {
5751 // If the GC metadata field is already used then the function was
5752 // enqueued as a code flushing candidate and we remove it now.
5753 if (code()->gc_metadata() != NULL) {
5754 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
5755 flusher->EvictCandidate(this);
5756 }
5757
5758 DCHECK(code()->gc_metadata() == NULL && value->gc_metadata() == NULL);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005759#ifdef DEBUG
5760 Code::VerifyRecompiledCode(code(), value);
5761#endif // DEBUG
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005762
5763 set_code(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005764
5765 if (is_compiled()) set_never_compiled(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005766}
5767
5768
5769ScopeInfo* SharedFunctionInfo::scope_info() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005770 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005771}
5772
5773
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005774void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005775 WriteBarrierMode mode) {
5776 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005777 CONDITIONAL_WRITE_BARRIER(GetHeap(),
5778 this,
5779 kScopeInfoOffset,
5780 reinterpret_cast<Object*>(value),
5781 mode);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01005782}
5783
5784
Steve Blocka7e24c12009-10-30 11:49:00 +00005785bool SharedFunctionInfo::is_compiled() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005786 Builtins* builtins = GetIsolate()->builtins();
5787 DCHECK(code() != builtins->builtin(Builtins::kCompileOptimizedConcurrent));
5788 DCHECK(code() != builtins->builtin(Builtins::kCompileOptimized));
5789 return code() != builtins->builtin(Builtins::kCompileLazy);
5790}
5791
5792
5793bool SharedFunctionInfo::has_simple_parameters() {
5794 return scope_info()->HasSimpleParameters();
5795}
5796
5797
5798bool SharedFunctionInfo::HasDebugInfo() {
5799 bool has_debug_info = debug_info()->IsStruct();
5800 DCHECK(!has_debug_info || HasDebugCode());
5801 return has_debug_info;
5802}
5803
5804
5805DebugInfo* SharedFunctionInfo::GetDebugInfo() {
5806 DCHECK(HasDebugInfo());
5807 return DebugInfo::cast(debug_info());
5808}
5809
5810
5811bool SharedFunctionInfo::HasDebugCode() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01005812 return HasBytecodeArray() ||
5813 (code()->kind() == Code::FUNCTION && code()->has_debug_break_slots());
Steve Blocka7e24c12009-10-30 11:49:00 +00005814}
5815
5816
Steve Block6ded16b2010-05-10 14:33:55 +01005817bool SharedFunctionInfo::IsApiFunction() {
5818 return function_data()->IsFunctionTemplateInfo();
5819}
5820
5821
5822FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005823 DCHECK(IsApiFunction());
Steve Block6ded16b2010-05-10 14:33:55 +01005824 return FunctionTemplateInfo::cast(function_data());
5825}
5826
5827
Ben Murdochb0fe1622011-05-05 13:52:32 +01005828bool SharedFunctionInfo::HasBuiltinFunctionId() {
Kristian Monsen25f61362010-05-21 11:50:48 +01005829 return function_data()->IsSmi();
5830}
5831
5832
Ben Murdochb0fe1622011-05-05 13:52:32 +01005833BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005834 DCHECK(HasBuiltinFunctionId());
Ben Murdochb0fe1622011-05-05 13:52:32 +01005835 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
Steve Blocka7e24c12009-10-30 11:49:00 +00005836}
5837
5838
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005839bool SharedFunctionInfo::HasBytecodeArray() {
5840 return function_data()->IsBytecodeArray();
5841}
5842
5843
5844BytecodeArray* SharedFunctionInfo::bytecode_array() {
5845 DCHECK(HasBytecodeArray());
5846 return BytecodeArray::cast(function_data());
5847}
5848
5849
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005850int SharedFunctionInfo::ic_age() {
5851 return ICAgeBits::decode(counters());
Iain Merrick75681382010-08-19 15:07:18 +01005852}
5853
5854
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005855void SharedFunctionInfo::set_ic_age(int ic_age) {
5856 set_counters(ICAgeBits::update(counters(), ic_age));
5857}
5858
5859
5860int SharedFunctionInfo::deopt_count() {
5861 return DeoptCountBits::decode(counters());
5862}
5863
5864
5865void SharedFunctionInfo::set_deopt_count(int deopt_count) {
5866 set_counters(DeoptCountBits::update(counters(), deopt_count));
5867}
5868
5869
5870void SharedFunctionInfo::increment_deopt_count() {
5871 int value = counters();
5872 int deopt_count = DeoptCountBits::decode(value);
5873 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
5874 set_counters(DeoptCountBits::update(value, deopt_count));
5875}
5876
5877
5878int SharedFunctionInfo::opt_reenable_tries() {
5879 return OptReenableTriesBits::decode(counters());
5880}
5881
5882
5883void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
5884 set_counters(OptReenableTriesBits::update(counters(), tries));
5885}
5886
5887
5888int SharedFunctionInfo::opt_count() {
5889 return OptCountBits::decode(opt_count_and_bailout_reason());
5890}
5891
5892
5893void SharedFunctionInfo::set_opt_count(int opt_count) {
5894 set_opt_count_and_bailout_reason(
5895 OptCountBits::update(opt_count_and_bailout_reason(), opt_count));
5896}
5897
5898
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005899BailoutReason SharedFunctionInfo::disable_optimization_reason() {
5900 return static_cast<BailoutReason>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005901 DisabledOptimizationReasonBits::decode(opt_count_and_bailout_reason()));
Iain Merrick75681382010-08-19 15:07:18 +01005902}
5903
5904
Ben Murdochb0fe1622011-05-05 13:52:32 +01005905bool SharedFunctionInfo::has_deoptimization_support() {
5906 Code* code = this->code();
5907 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
5908}
5909
5910
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005911void SharedFunctionInfo::TryReenableOptimization() {
5912 int tries = opt_reenable_tries();
5913 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
5914 // We reenable optimization whenever the number of tries is a large
5915 // enough power of 2.
5916 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
5917 set_optimization_disabled(false);
5918 set_opt_count(0);
5919 set_deopt_count(0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005920 }
5921}
5922
5923
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005924void SharedFunctionInfo::set_disable_optimization_reason(BailoutReason reason) {
5925 set_opt_count_and_bailout_reason(DisabledOptimizationReasonBits::update(
5926 opt_count_and_bailout_reason(), reason));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005927}
5928
5929
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005930bool SharedFunctionInfo::IsBuiltin() {
5931 Object* script_obj = script();
5932 if (script_obj->IsUndefined()) return true;
5933 Script* script = Script::cast(script_obj);
5934 Script::Type type = static_cast<Script::Type>(script->type());
5935 return type != Script::TYPE_NORMAL;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005936}
5937
5938
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005939bool SharedFunctionInfo::IsSubjectToDebugging() { return !IsBuiltin(); }
5940
5941
5942bool SharedFunctionInfo::OptimizedCodeMapIsCleared() const {
5943 return optimized_code_map() == GetHeap()->cleared_optimized_code_map();
Steve Blocka7e24c12009-10-30 11:49:00 +00005944}
5945
5946
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005947// static
5948void SharedFunctionInfo::AddToOptimizedCodeMap(
5949 Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
5950 Handle<Code> code, Handle<LiteralsArray> literals, BailoutId osr_ast_id) {
5951 AddToOptimizedCodeMapInternal(shared, native_context, code, literals,
5952 osr_ast_id);
5953}
5954
5955
5956// static
5957void SharedFunctionInfo::AddLiteralsToOptimizedCodeMap(
5958 Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
5959 Handle<LiteralsArray> literals) {
5960 Isolate* isolate = shared->GetIsolate();
5961 Handle<Oddball> undefined = isolate->factory()->undefined_value();
5962 AddToOptimizedCodeMapInternal(shared, native_context, undefined, literals,
5963 BailoutId::None());
Ben Murdochb0fe1622011-05-05 13:52:32 +01005964}
5965
5966
5967bool JSFunction::IsOptimized() {
5968 return code()->kind() == Code::OPTIMIZED_FUNCTION;
5969}
5970
5971
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005972bool JSFunction::IsMarkedForOptimization() {
5973 return code() == GetIsolate()->builtins()->builtin(
5974 Builtins::kCompileOptimized);
5975}
5976
5977
5978bool JSFunction::IsMarkedForConcurrentOptimization() {
5979 return code() == GetIsolate()->builtins()->builtin(
5980 Builtins::kCompileOptimizedConcurrent);
5981}
5982
5983
5984bool JSFunction::IsInOptimizationQueue() {
5985 return code() == GetIsolate()->builtins()->builtin(
5986 Builtins::kInOptimizationQueue);
5987}
5988
5989
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005990void JSFunction::CompleteInobjectSlackTrackingIfActive() {
5991 if (has_initial_map() && initial_map()->IsInobjectSlackTrackingInProgress()) {
5992 initial_map()->CompleteInobjectSlackTracking();
5993 }
5994}
5995
5996
5997bool Map::IsInobjectSlackTrackingInProgress() {
5998 return construction_counter() != Map::kNoSlackTracking;
5999}
6000
6001
6002void Map::InobjectSlackTrackingStep() {
6003 if (!IsInobjectSlackTrackingInProgress()) return;
6004 int counter = construction_counter();
6005 set_construction_counter(counter - 1);
6006 if (counter == kSlackTrackingCounterEnd) {
6007 CompleteInobjectSlackTracking();
6008 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01006009}
6010
6011
Steve Blocka7e24c12009-10-30 11:49:00 +00006012Code* JSFunction::code() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006013 return Code::cast(
Steve Block791712a2010-08-27 10:21:07 +01006014 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
Steve Blocka7e24c12009-10-30 11:49:00 +00006015}
6016
6017
6018void JSFunction::set_code(Code* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006019 DCHECK(!GetHeap()->InNewSpace(value));
Steve Block791712a2010-08-27 10:21:07 +01006020 Address entry = value->entry();
6021 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006022 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
6023 this,
6024 HeapObject::RawField(this, kCodeEntryOffset),
6025 value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006026}
6027
6028
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006029void JSFunction::set_code_no_write_barrier(Code* value) {
6030 DCHECK(!GetHeap()->InNewSpace(value));
6031 Address entry = value->entry();
6032 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
6033}
6034
6035
Ben Murdochb0fe1622011-05-05 13:52:32 +01006036void JSFunction::ReplaceCode(Code* code) {
6037 bool was_optimized = IsOptimized();
6038 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
6039
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006040 if (was_optimized && is_optimized) {
6041 shared()->EvictFromOptimizedCodeMap(this->code(),
6042 "Replacing with another optimized code");
6043 }
6044
Ben Murdochb0fe1622011-05-05 13:52:32 +01006045 set_code(code);
6046
6047 // Add/remove the function from the list of optimized functions for this
6048 // context based on the state change.
6049 if (!was_optimized && is_optimized) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006050 context()->native_context()->AddOptimizedFunction(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01006051 }
6052 if (was_optimized && !is_optimized) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006053 // TODO(titzer): linear in the number of optimized functions; fix!
6054 context()->native_context()->RemoveOptimizedFunction(this);
Ben Murdochb0fe1622011-05-05 13:52:32 +01006055 }
6056}
6057
6058
Steve Blocka7e24c12009-10-30 11:49:00 +00006059Context* JSFunction::context() {
6060 return Context::cast(READ_FIELD(this, kContextOffset));
6061}
6062
6063
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006064JSObject* JSFunction::global_proxy() {
6065 return context()->global_proxy();
Iain Merrick75681382010-08-19 15:07:18 +01006066}
6067
6068
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006069Context* JSFunction::native_context() { return context()->native_context(); }
6070
6071
Steve Blocka7e24c12009-10-30 11:49:00 +00006072void JSFunction::set_context(Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006073 DCHECK(value->IsUndefined() || value->IsContext());
Steve Blocka7e24c12009-10-30 11:49:00 +00006074 WRITE_FIELD(this, kContextOffset, value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006075 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006076}
6077
6078ACCESSORS(JSFunction, prototype_or_initial_map, Object,
6079 kPrototypeOrInitialMapOffset)
6080
6081
6082Map* JSFunction::initial_map() {
6083 return Map::cast(prototype_or_initial_map());
6084}
6085
6086
Steve Blocka7e24c12009-10-30 11:49:00 +00006087bool JSFunction::has_initial_map() {
6088 return prototype_or_initial_map()->IsMap();
6089}
6090
6091
6092bool JSFunction::has_instance_prototype() {
6093 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
6094}
6095
6096
6097bool JSFunction::has_prototype() {
6098 return map()->has_non_instance_prototype() || has_instance_prototype();
6099}
6100
6101
6102Object* JSFunction::instance_prototype() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006103 DCHECK(has_instance_prototype());
Steve Blocka7e24c12009-10-30 11:49:00 +00006104 if (has_initial_map()) return initial_map()->prototype();
6105 // When there is no initial map and the prototype is a JSObject, the
6106 // initial map field is used for the prototype field.
6107 return prototype_or_initial_map();
6108}
6109
6110
6111Object* JSFunction::prototype() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006112 DCHECK(has_prototype());
Steve Blocka7e24c12009-10-30 11:49:00 +00006113 // If the function's prototype property has been set to a non-JSObject
6114 // value, that value is stored in the constructor field of the map.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006115 if (map()->has_non_instance_prototype()) {
6116 Object* prototype = map()->GetConstructor();
6117 // The map must have a prototype in that field, not a back pointer.
6118 DCHECK(!prototype->IsMap());
6119 return prototype;
6120 }
Steve Blocka7e24c12009-10-30 11:49:00 +00006121 return instance_prototype();
6122}
6123
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006124
Steve Blocka7e24c12009-10-30 11:49:00 +00006125bool JSFunction::is_compiled() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006126 Builtins* builtins = GetIsolate()->builtins();
6127 return code() != builtins->builtin(Builtins::kCompileLazy) &&
6128 code() != builtins->builtin(Builtins::kCompileOptimized) &&
6129 code() != builtins->builtin(Builtins::kCompileOptimizedConcurrent);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006130}
6131
6132
Steve Blocka7e24c12009-10-30 11:49:00 +00006133int JSFunction::NumberOfLiterals() {
6134 return literals()->length();
6135}
6136
6137
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006138ACCESSORS(JSProxy, target, JSReceiver, kTargetOffset)
Ben Murdoch257744e2011-11-30 15:57:28 +00006139ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006140ACCESSORS(JSProxy, hash, Object, kHashOffset)
Ben Murdoch589d6972011-11-30 16:04:58 +00006141
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006142bool JSProxy::IsRevoked() const { return !handler()->IsJSReceiver(); }
Ben Murdoch257744e2011-11-30 15:57:28 +00006143
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006144ACCESSORS(JSCollection, table, Object, kTableOffset)
6145
6146
6147#define ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(name, type, offset) \
6148 template<class Derived, class TableType> \
6149 type* OrderedHashTableIterator<Derived, TableType>::name() const { \
6150 return type::cast(READ_FIELD(this, offset)); \
6151 } \
6152 template<class Derived, class TableType> \
6153 void OrderedHashTableIterator<Derived, TableType>::set_##name( \
6154 type* value, WriteBarrierMode mode) { \
6155 WRITE_FIELD(this, offset, value); \
6156 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
6157 }
6158
6159ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(table, Object, kTableOffset)
6160ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(index, Object, kIndexOffset)
6161ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(kind, Object, kKindOffset)
6162
6163#undef ORDERED_HASH_TABLE_ITERATOR_ACCESSORS
6164
6165
6166ACCESSORS(JSWeakCollection, table, Object, kTableOffset)
6167ACCESSORS(JSWeakCollection, next, Object, kNextOffset)
Ben Murdoch69a99ed2011-11-30 16:03:39 +00006168
6169
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006170Address Foreign::foreign_address() {
6171 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
Ben Murdoch69a99ed2011-11-30 16:03:39 +00006172}
6173
6174
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006175void Foreign::set_foreign_address(Address value) {
6176 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00006177}
6178
6179
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006180ACCESSORS(JSGeneratorObject, function, JSFunction, kFunctionOffset)
6181ACCESSORS(JSGeneratorObject, context, Context, kContextOffset)
6182ACCESSORS(JSGeneratorObject, receiver, Object, kReceiverOffset)
Ben Murdoch097c5b22016-05-18 11:27:45 +01006183ACCESSORS(JSGeneratorObject, input, Object, kInputOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006184SMI_ACCESSORS(JSGeneratorObject, continuation, kContinuationOffset)
6185ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006186
6187bool JSGeneratorObject::is_suspended() {
6188 DCHECK_LT(kGeneratorExecuting, kGeneratorClosed);
6189 DCHECK_EQ(kGeneratorClosed, 0);
6190 return continuation() > 0;
6191}
6192
6193bool JSGeneratorObject::is_closed() {
6194 return continuation() == kGeneratorClosed;
6195}
6196
6197bool JSGeneratorObject::is_executing() {
6198 return continuation() == kGeneratorExecuting;
6199}
6200
6201ACCESSORS(JSModule, context, Object, kContextOffset)
6202ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
6203
6204
Steve Blocka7e24c12009-10-30 11:49:00 +00006205ACCESSORS(JSValue, value, Object, kValueOffset)
6206
6207
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006208HeapNumber* HeapNumber::cast(Object* object) {
6209 SLOW_DCHECK(object->IsHeapNumber() || object->IsMutableHeapNumber());
6210 return reinterpret_cast<HeapNumber*>(object);
6211}
6212
6213
6214const HeapNumber* HeapNumber::cast(const Object* object) {
6215 SLOW_DCHECK(object->IsHeapNumber() || object->IsMutableHeapNumber());
6216 return reinterpret_cast<const HeapNumber*>(object);
Steve Blocka7e24c12009-10-30 11:49:00 +00006217}
6218
6219
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006220ACCESSORS(JSDate, value, Object, kValueOffset)
6221ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
6222ACCESSORS(JSDate, year, Object, kYearOffset)
6223ACCESSORS(JSDate, month, Object, kMonthOffset)
6224ACCESSORS(JSDate, day, Object, kDayOffset)
6225ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
6226ACCESSORS(JSDate, hour, Object, kHourOffset)
6227ACCESSORS(JSDate, min, Object, kMinOffset)
6228ACCESSORS(JSDate, sec, Object, kSecOffset)
6229
6230
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006231SMI_ACCESSORS(JSMessageObject, type, kTypeOffset)
6232ACCESSORS(JSMessageObject, argument, Object, kArgumentsOffset)
Steve Block1e0659c2011-05-24 12:43:12 +01006233ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
Steve Block1e0659c2011-05-24 12:43:12 +01006234ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
6235SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
6236SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
6237
6238
Steve Blocka7e24c12009-10-30 11:49:00 +00006239INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006240INT_ACCESSORS(Code, prologue_offset, kPrologueOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006241INT_ACCESSORS(Code, constant_pool_offset, kConstantPoolOffset)
Leon Clarkeac952652010-07-15 11:15:24 +01006242ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006243ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
Ben Murdochb0fe1622011-05-05 13:52:32 +01006244ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006245ACCESSORS(Code, raw_type_feedback_info, Object, kTypeFeedbackInfoOffset)
6246ACCESSORS(Code, next_code_link, Object, kNextCodeLinkOffset)
6247
6248
6249void Code::WipeOutHeader() {
6250 WRITE_FIELD(this, kRelocationInfoOffset, NULL);
6251 WRITE_FIELD(this, kHandlerTableOffset, NULL);
6252 WRITE_FIELD(this, kDeoptimizationDataOffset, NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006253 // Do not wipe out major/minor keys on a code stub or IC
6254 if (!READ_FIELD(this, kTypeFeedbackInfoOffset)->IsSmi()) {
6255 WRITE_FIELD(this, kTypeFeedbackInfoOffset, NULL);
6256 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006257 WRITE_FIELD(this, kNextCodeLinkOffset, NULL);
6258 WRITE_FIELD(this, kGCMetadataOffset, NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006259}
6260
6261
6262Object* Code::type_feedback_info() {
6263 DCHECK(kind() == FUNCTION);
6264 return raw_type_feedback_info();
6265}
6266
6267
6268void Code::set_type_feedback_info(Object* value, WriteBarrierMode mode) {
6269 DCHECK(kind() == FUNCTION);
6270 set_raw_type_feedback_info(value, mode);
6271 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kTypeFeedbackInfoOffset,
6272 value, mode);
6273}
6274
6275
6276uint32_t Code::stub_key() {
6277 DCHECK(IsCodeStubOrIC());
6278 Smi* smi_key = Smi::cast(raw_type_feedback_info());
6279 return static_cast<uint32_t>(smi_key->value());
6280}
6281
6282
6283void Code::set_stub_key(uint32_t key) {
6284 DCHECK(IsCodeStubOrIC());
6285 set_raw_type_feedback_info(Smi::FromInt(key));
6286}
6287
6288
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006289ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
6290INT_ACCESSORS(Code, ic_age, kICAgeOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00006291
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006292
Steve Blocka7e24c12009-10-30 11:49:00 +00006293byte* Code::instruction_start() {
6294 return FIELD_ADDR(this, kHeaderSize);
6295}
6296
6297
Leon Clarkeac952652010-07-15 11:15:24 +01006298byte* Code::instruction_end() {
6299 return instruction_start() + instruction_size();
6300}
6301
6302
Steve Blocka7e24c12009-10-30 11:49:00 +00006303int Code::body_size() {
Leon Clarkeac952652010-07-15 11:15:24 +01006304 return RoundUp(instruction_size(), kObjectAlignment);
6305}
6306
6307
6308ByteArray* Code::unchecked_relocation_info() {
6309 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
Steve Blocka7e24c12009-10-30 11:49:00 +00006310}
6311
6312
6313byte* Code::relocation_start() {
Leon Clarkeac952652010-07-15 11:15:24 +01006314 return unchecked_relocation_info()->GetDataStartAddress();
6315}
6316
6317
6318int Code::relocation_size() {
6319 return unchecked_relocation_info()->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00006320}
6321
6322
6323byte* Code::entry() {
6324 return instruction_start();
6325}
6326
6327
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006328bool Code::contains(byte* inner_pointer) {
6329 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
Steve Blocka7e24c12009-10-30 11:49:00 +00006330}
6331
6332
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006333int Code::ExecutableSize() {
6334 // Check that the assumptions about the layout of the code object holds.
6335 DCHECK_EQ(static_cast<int>(instruction_start() - address()),
6336 Code::kHeaderSize);
6337 return instruction_size() + Code::kHeaderSize;
6338}
6339
6340
6341int Code::CodeSize() { return SizeFor(body_size()); }
6342
6343
Steve Blocka7e24c12009-10-30 11:49:00 +00006344ACCESSORS(JSArray, length, Object, kLengthOffset)
6345
6346
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006347void* JSArrayBuffer::backing_store() const {
6348 intptr_t ptr = READ_INTPTR_FIELD(this, kBackingStoreOffset);
6349 return reinterpret_cast<void*>(ptr);
6350}
6351
6352
6353void JSArrayBuffer::set_backing_store(void* value, WriteBarrierMode mode) {
6354 intptr_t ptr = reinterpret_cast<intptr_t>(value);
6355 WRITE_INTPTR_FIELD(this, kBackingStoreOffset, ptr);
6356}
6357
6358
6359ACCESSORS(JSArrayBuffer, byte_length, Object, kByteLengthOffset)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006360
6361
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006362void JSArrayBuffer::set_bit_field(uint32_t bits) {
6363 if (kInt32Size != kPointerSize) {
6364#if V8_TARGET_LITTLE_ENDIAN
6365 WRITE_UINT32_FIELD(this, kBitFieldSlot + kInt32Size, 0);
6366#else
6367 WRITE_UINT32_FIELD(this, kBitFieldSlot, 0);
6368#endif
6369 }
6370 WRITE_UINT32_FIELD(this, kBitFieldOffset, bits);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006371}
6372
6373
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006374uint32_t JSArrayBuffer::bit_field() const {
6375 return READ_UINT32_FIELD(this, kBitFieldOffset);
6376}
6377
6378
6379bool JSArrayBuffer::is_external() { return IsExternal::decode(bit_field()); }
6380
6381
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006382void JSArrayBuffer::set_is_external(bool value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006383 set_bit_field(IsExternal::update(bit_field(), value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006384}
6385
6386
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006387bool JSArrayBuffer::is_neuterable() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006388 return IsNeuterable::decode(bit_field());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006389}
6390
6391
6392void JSArrayBuffer::set_is_neuterable(bool value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006393 set_bit_field(IsNeuterable::update(bit_field(), value));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006394}
6395
6396
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006397bool JSArrayBuffer::was_neutered() { return WasNeutered::decode(bit_field()); }
6398
6399
6400void JSArrayBuffer::set_was_neutered(bool value) {
6401 set_bit_field(WasNeutered::update(bit_field(), value));
6402}
6403
6404
6405bool JSArrayBuffer::is_shared() { return IsShared::decode(bit_field()); }
6406
6407
6408void JSArrayBuffer::set_is_shared(bool value) {
6409 set_bit_field(IsShared::update(bit_field(), value));
6410}
6411
6412
6413Object* JSArrayBufferView::byte_offset() const {
6414 if (WasNeutered()) return Smi::FromInt(0);
6415 return Object::cast(READ_FIELD(this, kByteOffsetOffset));
6416}
6417
6418
6419void JSArrayBufferView::set_byte_offset(Object* value, WriteBarrierMode mode) {
6420 WRITE_FIELD(this, kByteOffsetOffset, value);
6421 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kByteOffsetOffset, value, mode);
6422}
6423
6424
6425Object* JSArrayBufferView::byte_length() const {
6426 if (WasNeutered()) return Smi::FromInt(0);
6427 return Object::cast(READ_FIELD(this, kByteLengthOffset));
6428}
6429
6430
6431void JSArrayBufferView::set_byte_length(Object* value, WriteBarrierMode mode) {
6432 WRITE_FIELD(this, kByteLengthOffset, value);
6433 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kByteLengthOffset, value, mode);
6434}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006435
6436
6437ACCESSORS(JSArrayBufferView, buffer, Object, kBufferOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006438#ifdef VERIFY_HEAP
6439ACCESSORS(JSArrayBufferView, raw_byte_offset, Object, kByteOffsetOffset)
6440ACCESSORS(JSArrayBufferView, raw_byte_length, Object, kByteLengthOffset)
6441#endif
6442
6443
6444bool JSArrayBufferView::WasNeutered() const {
6445 return JSArrayBuffer::cast(buffer())->was_neutered();
6446}
6447
6448
6449Object* JSTypedArray::length() const {
6450 if (WasNeutered()) return Smi::FromInt(0);
6451 return Object::cast(READ_FIELD(this, kLengthOffset));
6452}
6453
6454
6455uint32_t JSTypedArray::length_value() const {
6456 if (WasNeutered()) return 0;
6457 uint32_t index = 0;
6458 CHECK(Object::cast(READ_FIELD(this, kLengthOffset))->ToArrayLength(&index));
6459 return index;
6460}
6461
6462
6463void JSTypedArray::set_length(Object* value, WriteBarrierMode mode) {
6464 WRITE_FIELD(this, kLengthOffset, value);
6465 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kLengthOffset, value, mode);
6466}
6467
6468
6469#ifdef VERIFY_HEAP
6470ACCESSORS(JSTypedArray, raw_length, Object, kLengthOffset)
6471#endif
6472
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006473
Steve Blocka7e24c12009-10-30 11:49:00 +00006474ACCESSORS(JSRegExp, data, Object, kDataOffset)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006475ACCESSORS(JSRegExp, flags, Object, kFlagsOffset)
6476ACCESSORS(JSRegExp, source, Object, kSourceOffset)
Steve Blocka7e24c12009-10-30 11:49:00 +00006477
6478
6479JSRegExp::Type JSRegExp::TypeTag() {
6480 Object* data = this->data();
6481 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
6482 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
6483 return static_cast<JSRegExp::Type>(smi->value());
6484}
6485
6486
6487int JSRegExp::CaptureCount() {
6488 switch (TypeTag()) {
6489 case ATOM:
6490 return 0;
6491 case IRREGEXP:
6492 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
6493 default:
6494 UNREACHABLE();
6495 return -1;
6496 }
6497}
6498
6499
6500JSRegExp::Flags JSRegExp::GetFlags() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006501 DCHECK(this->data()->IsFixedArray());
Steve Blocka7e24c12009-10-30 11:49:00 +00006502 Object* data = this->data();
6503 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
6504 return Flags(smi->value());
6505}
6506
6507
6508String* JSRegExp::Pattern() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006509 DCHECK(this->data()->IsFixedArray());
Steve Blocka7e24c12009-10-30 11:49:00 +00006510 Object* data = this->data();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006511 String* pattern = String::cast(FixedArray::cast(data)->get(kSourceIndex));
Steve Blocka7e24c12009-10-30 11:49:00 +00006512 return pattern;
6513}
6514
6515
6516Object* JSRegExp::DataAt(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006517 DCHECK(TypeTag() != NOT_COMPILED);
Steve Blocka7e24c12009-10-30 11:49:00 +00006518 return FixedArray::cast(data())->get(index);
6519}
6520
6521
6522void JSRegExp::SetDataAt(int index, Object* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006523 DCHECK(TypeTag() != NOT_COMPILED);
6524 DCHECK(index >= kDataIndex); // Only implementation data can be set this way.
Steve Blocka7e24c12009-10-30 11:49:00 +00006525 FixedArray::cast(data())->set(index, value);
6526}
6527
6528
Ben Murdoch589d6972011-11-30 16:04:58 +00006529ElementsKind JSObject::GetElementsKind() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006530 ElementsKind kind = map()->elements_kind();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006531#if VERIFY_HEAP && DEBUG
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006532 FixedArrayBase* fixed_array =
6533 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006534
6535 // If a GC was caused while constructing this object, the elements
6536 // pointer may point to a one pointer filler map.
6537 if (ElementsAreSafeToExamine()) {
6538 Map* map = fixed_array->map();
6539 DCHECK((IsFastSmiOrObjectElementsKind(kind) &&
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006540 (map == GetHeap()->fixed_array_map() ||
6541 map == GetHeap()->fixed_cow_array_map())) ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006542 (IsFastDoubleElementsKind(kind) &&
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006543 (fixed_array->IsFixedDoubleArray() ||
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006544 fixed_array == GetHeap()->empty_fixed_array())) ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006545 (kind == DICTIONARY_ELEMENTS &&
6546 fixed_array->IsFixedArray() &&
6547 fixed_array->IsDictionary()) ||
6548 (kind > DICTIONARY_ELEMENTS));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006549 DCHECK(!IsSloppyArgumentsElements(kind) ||
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006550 (elements()->IsFixedArray() && elements()->length() >= 2));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006551 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006552#endif
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006553 return kind;
Steve Blocka7e24c12009-10-30 11:49:00 +00006554}
6555
6556
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006557bool JSObject::HasFastObjectElements() {
6558 return IsFastObjectElementsKind(GetElementsKind());
Steve Blocka7e24c12009-10-30 11:49:00 +00006559}
6560
6561
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006562bool JSObject::HasFastSmiElements() {
6563 return IsFastSmiElementsKind(GetElementsKind());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006564}
6565
6566
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006567bool JSObject::HasFastSmiOrObjectElements() {
6568 return IsFastSmiOrObjectElementsKind(GetElementsKind());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006569}
6570
6571
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006572bool JSObject::HasFastDoubleElements() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006573 return IsFastDoubleElementsKind(GetElementsKind());
6574}
6575
6576
6577bool JSObject::HasFastHoleyElements() {
6578 return IsFastHoleyElementsKind(GetElementsKind());
6579}
6580
6581
6582bool JSObject::HasFastElements() {
6583 return IsFastElementsKind(GetElementsKind());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006584}
6585
6586
Steve Blocka7e24c12009-10-30 11:49:00 +00006587bool JSObject::HasDictionaryElements() {
6588 return GetElementsKind() == DICTIONARY_ELEMENTS;
6589}
6590
6591
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006592bool JSObject::HasFastArgumentsElements() {
6593 return GetElementsKind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
6594}
6595
6596
6597bool JSObject::HasSlowArgumentsElements() {
6598 return GetElementsKind() == SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
6599}
6600
6601
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006602bool JSObject::HasSloppyArgumentsElements() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006603 return IsSloppyArgumentsElements(GetElementsKind());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006604}
6605
Ben Murdoch097c5b22016-05-18 11:27:45 +01006606bool JSObject::HasStringWrapperElements() {
6607 return IsStringWrapperElementsKind(GetElementsKind());
6608}
6609
6610bool JSObject::HasFastStringWrapperElements() {
6611 return GetElementsKind() == FAST_STRING_WRAPPER_ELEMENTS;
6612}
6613
6614bool JSObject::HasSlowStringWrapperElements() {
6615 return GetElementsKind() == SLOW_STRING_WRAPPER_ELEMENTS;
6616}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006617
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006618bool JSObject::HasFixedTypedArrayElements() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01006619 DCHECK_NOT_NULL(elements());
6620 return map()->has_fixed_typed_array_elements();
Steve Block3ce2e202009-11-05 08:53:23 +00006621}
6622
Ben Murdoch097c5b22016-05-18 11:27:45 +01006623#define FIXED_TYPED_ELEMENTS_CHECK(Type, type, TYPE, ctype, size) \
6624 bool JSObject::HasFixed##Type##Elements() { \
6625 HeapObject* array = elements(); \
6626 DCHECK(array != NULL); \
6627 if (!array->IsHeapObject()) return false; \
6628 return array->map()->instance_type() == FIXED_##TYPE##_ARRAY_TYPE; \
6629 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006630
6631TYPED_ARRAYS(FIXED_TYPED_ELEMENTS_CHECK)
6632
6633#undef FIXED_TYPED_ELEMENTS_CHECK
Steve Block3ce2e202009-11-05 08:53:23 +00006634
6635
Steve Blocka7e24c12009-10-30 11:49:00 +00006636bool JSObject::HasNamedInterceptor() {
6637 return map()->has_named_interceptor();
6638}
6639
6640
6641bool JSObject::HasIndexedInterceptor() {
6642 return map()->has_indexed_interceptor();
6643}
6644
6645
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006646GlobalDictionary* JSObject::global_dictionary() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006647 DCHECK(!HasFastProperties());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006648 DCHECK(IsJSGlobalObject());
6649 return GlobalDictionary::cast(properties());
Steve Blocka7e24c12009-10-30 11:49:00 +00006650}
6651
6652
Ben Murdochc7cc0282012-03-05 14:35:55 +00006653SeededNumberDictionary* JSObject::element_dictionary() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01006654 DCHECK(HasDictionaryElements() || HasSlowStringWrapperElements());
Ben Murdochc7cc0282012-03-05 14:35:55 +00006655 return SeededNumberDictionary::cast(elements());
Steve Blocka7e24c12009-10-30 11:49:00 +00006656}
6657
6658
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006659bool Name::IsHashFieldComputed(uint32_t field) {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006660 return (field & kHashNotComputedMask) == 0;
6661}
6662
6663
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006664bool Name::HasHashCode() {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006665 return IsHashFieldComputed(hash_field());
Steve Blocka7e24c12009-10-30 11:49:00 +00006666}
6667
6668
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006669uint32_t Name::Hash() {
Steve Blocka7e24c12009-10-30 11:49:00 +00006670 // Fast case: has hash code already been computed?
Steve Blockd0582a62009-12-15 09:54:21 +00006671 uint32_t field = hash_field();
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006672 if (IsHashFieldComputed(field)) return field >> kHashShift;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006673 // Slow case: compute hash code and set it. Has to be a string.
6674 return String::cast(this)->ComputeAndSetHash();
6675}
6676
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006677
6678bool Name::IsPrivate() {
6679 return this->IsSymbol() && Symbol::cast(this)->is_private();
Steve Blocka7e24c12009-10-30 11:49:00 +00006680}
6681
6682
Ben Murdochc7cc0282012-03-05 14:35:55 +00006683StringHasher::StringHasher(int length, uint32_t seed)
Steve Blocka7e24c12009-10-30 11:49:00 +00006684 : length_(length),
Ben Murdochc7cc0282012-03-05 14:35:55 +00006685 raw_running_hash_(seed),
Steve Blocka7e24c12009-10-30 11:49:00 +00006686 array_index_(0),
6687 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006688 is_first_char_(true) {
6689 DCHECK(FLAG_randomize_hashes || raw_running_hash_ == 0);
Ben Murdochc7cc0282012-03-05 14:35:55 +00006690}
Steve Blocka7e24c12009-10-30 11:49:00 +00006691
6692
6693bool StringHasher::has_trivial_hash() {
Steve Blockd0582a62009-12-15 09:54:21 +00006694 return length_ > String::kMaxHashCalcLength;
Steve Blocka7e24c12009-10-30 11:49:00 +00006695}
6696
6697
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006698uint32_t StringHasher::AddCharacterCore(uint32_t running_hash, uint16_t c) {
6699 running_hash += c;
6700 running_hash += (running_hash << 10);
6701 running_hash ^= (running_hash >> 6);
6702 return running_hash;
6703}
6704
6705
6706uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
6707 running_hash += (running_hash << 3);
6708 running_hash ^= (running_hash >> 11);
6709 running_hash += (running_hash << 15);
6710 if ((running_hash & String::kHashBitMask) == 0) {
6711 return kZeroHash;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006712 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006713 return running_hash;
6714}
6715
6716
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006717uint32_t StringHasher::ComputeRunningHash(uint32_t running_hash,
6718 const uc16* chars, int length) {
6719 DCHECK_NOT_NULL(chars);
6720 DCHECK(length >= 0);
6721 for (int i = 0; i < length; ++i) {
6722 running_hash = AddCharacterCore(running_hash, *chars++);
6723 }
6724 return running_hash;
6725}
6726
6727
6728uint32_t StringHasher::ComputeRunningHashOneByte(uint32_t running_hash,
6729 const char* chars,
6730 int length) {
6731 DCHECK_NOT_NULL(chars);
6732 DCHECK(length >= 0);
6733 for (int i = 0; i < length; ++i) {
6734 uint16_t c = static_cast<uint16_t>(*chars++);
6735 running_hash = AddCharacterCore(running_hash, c);
6736 }
6737 return running_hash;
6738}
6739
6740
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006741void StringHasher::AddCharacter(uint16_t c) {
Steve Blocka7e24c12009-10-30 11:49:00 +00006742 // Use the Jenkins one-at-a-time hash function to update the hash
6743 // for the given character.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006744 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c);
6745}
6746
6747
6748bool StringHasher::UpdateIndex(uint16_t c) {
6749 DCHECK(is_array_index_);
6750 if (c < '0' || c > '9') {
6751 is_array_index_ = false;
6752 return false;
6753 }
6754 int d = c - '0';
6755 if (is_first_char_) {
6756 is_first_char_ = false;
6757 if (c == '0' && length_ > 1) {
Steve Blocka7e24c12009-10-30 11:49:00 +00006758 is_array_index_ = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006759 return false;
6760 }
6761 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006762 if (array_index_ > 429496729U - ((d + 3) >> 3)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006763 is_array_index_ = false;
6764 return false;
6765 }
6766 array_index_ = array_index_ * 10 + d;
6767 return true;
6768}
6769
6770
6771template<typename Char>
6772inline void StringHasher::AddCharacters(const Char* chars, int length) {
6773 DCHECK(sizeof(Char) == 1 || sizeof(Char) == 2);
6774 int i = 0;
6775 if (is_array_index_) {
6776 for (; i < length; i++) {
6777 AddCharacter(chars[i]);
6778 if (!UpdateIndex(chars[i])) {
6779 i++;
6780 break;
Steve Blocka7e24c12009-10-30 11:49:00 +00006781 }
6782 }
6783 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006784 for (; i < length; i++) {
6785 DCHECK(!is_array_index_);
6786 AddCharacter(chars[i]);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006787 }
Steve Blocka7e24c12009-10-30 11:49:00 +00006788}
6789
6790
Steve Block44f0eee2011-05-26 01:26:41 +01006791template <typename schar>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006792uint32_t StringHasher::HashSequentialString(const schar* chars,
6793 int length,
6794 uint32_t seed) {
Ben Murdochc7cc0282012-03-05 14:35:55 +00006795 StringHasher hasher(length, seed);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006796 if (!hasher.has_trivial_hash()) hasher.AddCharacters(chars, length);
6797 return hasher.GetHashField();
6798}
6799
6800
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006801IteratingStringHasher::IteratingStringHasher(int len, uint32_t seed)
6802 : StringHasher(len, seed) {}
6803
6804
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006805uint32_t IteratingStringHasher::Hash(String* string, uint32_t seed) {
6806 IteratingStringHasher hasher(string->length(), seed);
6807 // Nothing to do.
6808 if (hasher.has_trivial_hash()) return hasher.GetHashField();
6809 ConsString* cons_string = String::VisitFlat(&hasher, string);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006810 if (cons_string == nullptr) return hasher.GetHashField();
6811 hasher.VisitConsString(cons_string);
Steve Block44f0eee2011-05-26 01:26:41 +01006812 return hasher.GetHashField();
6813}
6814
6815
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006816void IteratingStringHasher::VisitOneByteString(const uint8_t* chars,
6817 int length) {
6818 AddCharacters(chars, length);
6819}
6820
6821
6822void IteratingStringHasher::VisitTwoByteString(const uint16_t* chars,
6823 int length) {
6824 AddCharacters(chars, length);
6825}
6826
6827
6828bool Name::AsArrayIndex(uint32_t* index) {
6829 return IsString() && String::cast(this)->AsArrayIndex(index);
6830}
6831
6832
Steve Blocka7e24c12009-10-30 11:49:00 +00006833bool String::AsArrayIndex(uint32_t* index) {
Steve Blockd0582a62009-12-15 09:54:21 +00006834 uint32_t field = hash_field();
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01006835 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
6836 return false;
6837 }
Steve Blocka7e24c12009-10-30 11:49:00 +00006838 return SlowAsArrayIndex(index);
6839}
6840
6841
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006842void String::SetForwardedInternalizedString(String* canonical) {
6843 DCHECK(IsInternalizedString());
6844 DCHECK(HasHashCode());
6845 if (canonical == this) return; // No need to forward.
6846 DCHECK(SlowEquals(canonical));
6847 DCHECK(canonical->IsInternalizedString());
6848 DCHECK(canonical->HasHashCode());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006849 WRITE_FIELD(this, kHashFieldSlot, canonical);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006850 // Setting the hash field to a tagged value sets the LSB, causing the hash
6851 // code to be interpreted as uninitialized. We use this fact to recognize
6852 // that we have a forwarded string.
6853 DCHECK(!HasHashCode());
Steve Blocka7e24c12009-10-30 11:49:00 +00006854}
6855
6856
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006857String* String::GetForwardedInternalizedString() {
6858 DCHECK(IsInternalizedString());
6859 if (HasHashCode()) return this;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006860 String* canonical = String::cast(READ_FIELD(this, kHashFieldSlot));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006861 DCHECK(canonical->IsInternalizedString());
6862 DCHECK(SlowEquals(canonical));
6863 DCHECK(canonical->HasHashCode());
6864 return canonical;
6865}
6866
6867
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006868// static
Ben Murdoch097c5b22016-05-18 11:27:45 +01006869Maybe<bool> Object::GreaterThan(Handle<Object> x, Handle<Object> y) {
6870 Maybe<ComparisonResult> result = Compare(x, y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006871 if (result.IsJust()) {
6872 switch (result.FromJust()) {
6873 case ComparisonResult::kGreaterThan:
6874 return Just(true);
6875 case ComparisonResult::kLessThan:
6876 case ComparisonResult::kEqual:
6877 case ComparisonResult::kUndefined:
6878 return Just(false);
6879 }
6880 }
6881 return Nothing<bool>();
6882}
6883
6884
6885// static
Ben Murdoch097c5b22016-05-18 11:27:45 +01006886Maybe<bool> Object::GreaterThanOrEqual(Handle<Object> x, Handle<Object> y) {
6887 Maybe<ComparisonResult> result = Compare(x, y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006888 if (result.IsJust()) {
6889 switch (result.FromJust()) {
6890 case ComparisonResult::kEqual:
6891 case ComparisonResult::kGreaterThan:
6892 return Just(true);
6893 case ComparisonResult::kLessThan:
6894 case ComparisonResult::kUndefined:
6895 return Just(false);
6896 }
6897 }
6898 return Nothing<bool>();
6899}
6900
6901
6902// static
Ben Murdoch097c5b22016-05-18 11:27:45 +01006903Maybe<bool> Object::LessThan(Handle<Object> x, Handle<Object> y) {
6904 Maybe<ComparisonResult> result = Compare(x, y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006905 if (result.IsJust()) {
6906 switch (result.FromJust()) {
6907 case ComparisonResult::kLessThan:
6908 return Just(true);
6909 case ComparisonResult::kEqual:
6910 case ComparisonResult::kGreaterThan:
6911 case ComparisonResult::kUndefined:
6912 return Just(false);
6913 }
6914 }
6915 return Nothing<bool>();
6916}
6917
6918
6919// static
Ben Murdoch097c5b22016-05-18 11:27:45 +01006920Maybe<bool> Object::LessThanOrEqual(Handle<Object> x, Handle<Object> y) {
6921 Maybe<ComparisonResult> result = Compare(x, y);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006922 if (result.IsJust()) {
6923 switch (result.FromJust()) {
6924 case ComparisonResult::kEqual:
6925 case ComparisonResult::kLessThan:
6926 return Just(true);
6927 case ComparisonResult::kGreaterThan:
6928 case ComparisonResult::kUndefined:
6929 return Just(false);
6930 }
6931 }
6932 return Nothing<bool>();
6933}
6934
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006935MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> object,
Ben Murdoch097c5b22016-05-18 11:27:45 +01006936 Handle<Name> name) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006937 LookupIterator it =
6938 LookupIterator::PropertyOrElement(name->GetIsolate(), object, name);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006939 return GetProperty(&it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006940}
6941
Ben Murdoch097c5b22016-05-18 11:27:45 +01006942MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> receiver,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006943 Handle<Name> name,
Ben Murdoch097c5b22016-05-18 11:27:45 +01006944 Handle<JSReceiver> holder) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006945 LookupIterator it = LookupIterator::PropertyOrElement(
6946 name->GetIsolate(), receiver, name, holder);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006947 return GetProperty(&it);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006948}
6949
6950
6951void JSReceiver::initialize_properties() {
6952 DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
6953 DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_properties_dictionary()));
6954 if (map()->is_dictionary_map()) {
6955 WRITE_FIELD(this, kPropertiesOffset,
6956 GetHeap()->empty_properties_dictionary());
6957 } else {
6958 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
6959 }
6960}
6961
6962
6963bool JSReceiver::HasFastProperties() {
6964 DCHECK(properties()->IsDictionary() == map()->is_dictionary_map());
6965 return !properties()->IsDictionary();
6966}
6967
6968
6969NameDictionary* JSReceiver::property_dictionary() {
6970 DCHECK(!HasFastProperties());
6971 DCHECK(!IsJSGlobalObject());
6972 return NameDictionary::cast(properties());
6973}
6974
6975
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006976Maybe<bool> JSReceiver::HasProperty(Handle<JSReceiver> object,
6977 Handle<Name> name) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006978 LookupIterator it =
6979 LookupIterator::PropertyOrElement(object->GetIsolate(), object, name);
6980 return HasProperty(&it);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006981}
6982
6983
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006984Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object,
6985 Handle<Name> name) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006986 if (object->IsJSObject()) { // Shortcut
6987 LookupIterator it = LookupIterator::PropertyOrElement(
6988 object->GetIsolate(), object, name, LookupIterator::HIDDEN);
6989 return HasProperty(&it);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006990 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006991
6992 Maybe<PropertyAttributes> attributes =
6993 JSReceiver::GetOwnPropertyAttributes(object, name);
6994 MAYBE_RETURN(attributes, Nothing<bool>());
6995 return Just(attributes.FromJust() != ABSENT);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006996}
6997
6998
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006999Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007000 Handle<JSReceiver> object, Handle<Name> name) {
7001 LookupIterator it =
7002 LookupIterator::PropertyOrElement(name->GetIsolate(), object, name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007003 return GetPropertyAttributes(&it);
Steve Blockd0582a62009-12-15 09:54:21 +00007004}
7005
7006
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007007Maybe<PropertyAttributes> JSReceiver::GetOwnPropertyAttributes(
7008 Handle<JSReceiver> object, Handle<Name> name) {
7009 LookupIterator it = LookupIterator::PropertyOrElement(
7010 name->GetIsolate(), object, name, LookupIterator::HIDDEN);
7011 return GetPropertyAttributes(&it);
7012}
7013
7014
7015Maybe<bool> JSReceiver::HasElement(Handle<JSReceiver> object, uint32_t index) {
7016 LookupIterator it(object->GetIsolate(), object, index);
7017 return HasProperty(&it);
7018}
7019
7020
7021Maybe<PropertyAttributes> JSReceiver::GetElementAttributes(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007022 Handle<JSReceiver> object, uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007023 Isolate* isolate = object->GetIsolate();
7024 LookupIterator it(isolate, object, index);
7025 return GetPropertyAttributes(&it);
7026}
7027
7028
7029Maybe<PropertyAttributes> JSReceiver::GetOwnElementAttributes(
7030 Handle<JSReceiver> object, uint32_t index) {
7031 Isolate* isolate = object->GetIsolate();
7032 LookupIterator it(isolate, object, index, LookupIterator::HIDDEN);
7033 return GetPropertyAttributes(&it);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007034}
7035
7036
7037bool JSGlobalObject::IsDetached() {
7038 return JSGlobalProxy::cast(global_proxy())->IsDetachedFrom(this);
7039}
7040
7041
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007042bool JSGlobalProxy::IsDetachedFrom(JSGlobalObject* global) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007043 const PrototypeIterator iter(this->GetIsolate(),
7044 const_cast<JSGlobalProxy*>(this));
7045 return iter.GetCurrent() != global;
7046}
7047
7048
7049Handle<Smi> JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver> object) {
7050 return object->IsJSProxy()
7051 ? JSProxy::GetOrCreateIdentityHash(Handle<JSProxy>::cast(object))
7052 : JSObject::GetOrCreateIdentityHash(Handle<JSObject>::cast(object));
7053}
7054
7055
7056Object* JSReceiver::GetIdentityHash() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007057 return IsJSProxy()
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007058 ? JSProxy::cast(this)->GetIdentityHash()
7059 : JSObject::cast(this)->GetIdentityHash();
Steve Blockd0582a62009-12-15 09:54:21 +00007060}
7061
7062
Steve Blocka7e24c12009-10-30 11:49:00 +00007063bool AccessorInfo::all_can_read() {
7064 return BooleanBit::get(flag(), kAllCanReadBit);
7065}
7066
7067
7068void AccessorInfo::set_all_can_read(bool value) {
7069 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
7070}
7071
7072
7073bool AccessorInfo::all_can_write() {
7074 return BooleanBit::get(flag(), kAllCanWriteBit);
7075}
7076
7077
7078void AccessorInfo::set_all_can_write(bool value) {
7079 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
7080}
7081
7082
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007083bool AccessorInfo::is_special_data_property() {
7084 return BooleanBit::get(flag(), kSpecialDataProperty);
7085}
7086
7087
7088void AccessorInfo::set_is_special_data_property(bool value) {
7089 set_flag(BooleanBit::set(flag(), kSpecialDataProperty, value));
7090}
7091
7092
Steve Blocka7e24c12009-10-30 11:49:00 +00007093PropertyAttributes AccessorInfo::property_attributes() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007094 return AttributesField::decode(static_cast<uint32_t>(flag()));
Steve Blocka7e24c12009-10-30 11:49:00 +00007095}
7096
7097
7098void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007099 set_flag(AttributesField::update(flag(), attributes));
Steve Blocka7e24c12009-10-30 11:49:00 +00007100}
7101
Ben Murdoch8b112d22011-06-08 16:22:53 +01007102
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007103bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
7104 if (!HasExpectedReceiverType()) return true;
7105 if (!receiver->IsJSObject()) return false;
7106 return FunctionTemplateInfo::cast(expected_receiver_type())
7107 ->IsTemplateFor(JSObject::cast(receiver)->map());
7108}
7109
7110
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007111bool AccessorInfo::HasExpectedReceiverType() {
7112 return expected_receiver_type()->IsFunctionTemplateInfo();
7113}
7114
7115
7116Object* AccessorPair::get(AccessorComponent component) {
7117 return component == ACCESSOR_GETTER ? getter() : setter();
7118}
7119
7120
7121void AccessorPair::set(AccessorComponent component, Object* value) {
7122 if (component == ACCESSOR_GETTER) {
7123 set_getter(value);
7124 } else {
7125 set_setter(value);
7126 }
7127}
7128
7129
7130void AccessorPair::SetComponents(Object* getter, Object* setter) {
7131 if (!getter->IsNull()) set_getter(getter);
7132 if (!setter->IsNull()) set_setter(setter);
7133}
7134
7135
7136bool AccessorPair::Equals(AccessorPair* pair) {
7137 return (this == pair) || pair->Equals(getter(), setter());
7138}
7139
7140
7141bool AccessorPair::Equals(Object* getter_value, Object* setter_value) {
7142 return (getter() == getter_value) && (setter() == setter_value);
7143}
7144
7145
7146bool AccessorPair::ContainsAccessor() {
7147 return IsJSAccessor(getter()) || IsJSAccessor(setter());
7148}
7149
7150
7151bool AccessorPair::IsJSAccessor(Object* obj) {
7152 return obj->IsCallable() || obj->IsUndefined();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007153}
7154
7155
7156template<typename Derived, typename Shape, typename Key>
7157void Dictionary<Derived, Shape, Key>::SetEntry(int entry,
7158 Handle<Object> key,
7159 Handle<Object> value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007160 this->SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
Ben Murdoch8b112d22011-06-08 16:22:53 +01007161}
7162
7163
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007164template<typename Derived, typename Shape, typename Key>
7165void Dictionary<Derived, Shape, Key>::SetEntry(int entry,
7166 Handle<Object> key,
7167 Handle<Object> value,
7168 PropertyDetails details) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007169 Shape::SetEntry(static_cast<Derived*>(this), entry, key, value, details);
7170}
7171
7172
7173template <typename Key>
7174template <typename Dictionary>
7175void BaseDictionaryShape<Key>::SetEntry(Dictionary* dict, int entry,
7176 Handle<Object> key,
7177 Handle<Object> value,
7178 PropertyDetails details) {
7179 STATIC_ASSERT(Dictionary::kEntrySize == 3);
7180 DCHECK(!key->IsName() || details.dictionary_index() > 0);
7181 int index = dict->EntryToIndex(entry);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007182 DisallowHeapAllocation no_gc;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007183 WriteBarrierMode mode = dict->GetWriteBarrierMode(no_gc);
7184 dict->set(index, *key, mode);
7185 dict->set(index + 1, *value, mode);
7186 dict->set(index + 2, details.AsSmi());
7187}
7188
7189
7190template <typename Dictionary>
7191void GlobalDictionaryShape::SetEntry(Dictionary* dict, int entry,
7192 Handle<Object> key, Handle<Object> value,
7193 PropertyDetails details) {
7194 STATIC_ASSERT(Dictionary::kEntrySize == 2);
7195 DCHECK(!key->IsName() || details.dictionary_index() > 0);
7196 DCHECK(value->IsPropertyCell());
7197 int index = dict->EntryToIndex(entry);
7198 DisallowHeapAllocation no_gc;
7199 WriteBarrierMode mode = dict->GetWriteBarrierMode(no_gc);
7200 dict->set(index, *key, mode);
7201 dict->set(index + 1, *value, mode);
7202 PropertyCell::cast(*value)->set_property_details(details);
Steve Blocka7e24c12009-10-30 11:49:00 +00007203}
7204
7205
Steve Block44f0eee2011-05-26 01:26:41 +01007206bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007207 DCHECK(other->IsNumber());
Steve Block44f0eee2011-05-26 01:26:41 +01007208 return key == static_cast<uint32_t>(other->Number());
7209}
7210
7211
Ben Murdochc7cc0282012-03-05 14:35:55 +00007212uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
7213 return ComputeIntegerHash(key, 0);
Steve Block44f0eee2011-05-26 01:26:41 +01007214}
7215
7216
Ben Murdochc7cc0282012-03-05 14:35:55 +00007217uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
7218 Object* other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007219 DCHECK(other->IsNumber());
Ben Murdochc7cc0282012-03-05 14:35:55 +00007220 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
Steve Block44f0eee2011-05-26 01:26:41 +01007221}
7222
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007223
Ben Murdochc7cc0282012-03-05 14:35:55 +00007224uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
7225 return ComputeIntegerHash(key, seed);
7226}
7227
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007228
Ben Murdochc7cc0282012-03-05 14:35:55 +00007229uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
7230 uint32_t seed,
7231 Object* other) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007232 DCHECK(other->IsNumber());
Ben Murdochc7cc0282012-03-05 14:35:55 +00007233 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
7234}
Steve Block44f0eee2011-05-26 01:26:41 +01007235
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007236
7237Handle<Object> NumberDictionaryShape::AsHandle(Isolate* isolate, uint32_t key) {
7238 return isolate->factory()->NewNumberFromUint(key);
Steve Block44f0eee2011-05-26 01:26:41 +01007239}
7240
7241
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007242bool NameDictionaryShape::IsMatch(Handle<Name> key, Object* other) {
Steve Block44f0eee2011-05-26 01:26:41 +01007243 // We know that all entries in a hash table had their hash keys created.
7244 // Use that knowledge to have fast failure.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007245 if (key->Hash() != Name::cast(other)->Hash()) return false;
7246 return key->Equals(Name::cast(other));
Steve Block44f0eee2011-05-26 01:26:41 +01007247}
7248
7249
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007250uint32_t NameDictionaryShape::Hash(Handle<Name> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01007251 return key->Hash();
7252}
7253
7254
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007255uint32_t NameDictionaryShape::HashForObject(Handle<Name> key, Object* other) {
7256 return Name::cast(other)->Hash();
Steve Block44f0eee2011-05-26 01:26:41 +01007257}
7258
7259
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007260Handle<Object> NameDictionaryShape::AsHandle(Isolate* isolate,
7261 Handle<Name> key) {
7262 DCHECK(key->IsUniqueName());
Steve Block44f0eee2011-05-26 01:26:41 +01007263 return key;
7264}
7265
7266
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007267Handle<FixedArray> NameDictionary::DoGenerateNewEnumerationIndices(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007268 Handle<NameDictionary> dictionary) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007269 return DerivedDictionary::GenerateNewEnumerationIndices(dictionary);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007270}
7271
7272
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007273template <typename Dictionary>
7274PropertyDetails GlobalDictionaryShape::DetailsAt(Dictionary* dict, int entry) {
7275 DCHECK(entry >= 0); // Not found is -1, which is not caught by get().
7276 Object* raw_value = dict->ValueAt(entry);
7277 DCHECK(raw_value->IsPropertyCell());
7278 PropertyCell* cell = PropertyCell::cast(raw_value);
7279 return cell->property_details();
7280}
7281
7282
7283template <typename Dictionary>
7284void GlobalDictionaryShape::DetailsAtPut(Dictionary* dict, int entry,
7285 PropertyDetails value) {
7286 DCHECK(entry >= 0); // Not found is -1, which is not caught by get().
7287 Object* raw_value = dict->ValueAt(entry);
7288 DCHECK(raw_value->IsPropertyCell());
7289 PropertyCell* cell = PropertyCell::cast(raw_value);
7290 cell->set_property_details(value);
7291}
7292
7293
7294template <typename Dictionary>
7295bool GlobalDictionaryShape::IsDeleted(Dictionary* dict, int entry) {
7296 DCHECK(dict->ValueAt(entry)->IsPropertyCell());
7297 return PropertyCell::cast(dict->ValueAt(entry))->value()->IsTheHole();
7298}
7299
7300
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007301bool ObjectHashTableShape::IsMatch(Handle<Object> key, Object* other) {
7302 return key->SameValue(other);
7303}
7304
7305
7306uint32_t ObjectHashTableShape::Hash(Handle<Object> key) {
7307 return Smi::cast(key->GetHash())->value();
7308}
7309
7310
7311uint32_t ObjectHashTableShape::HashForObject(Handle<Object> key,
7312 Object* other) {
7313 return Smi::cast(other->GetHash())->value();
7314}
7315
7316
7317Handle<Object> ObjectHashTableShape::AsHandle(Isolate* isolate,
7318 Handle<Object> key) {
7319 return key;
7320}
7321
7322
7323Handle<ObjectHashTable> ObjectHashTable::Shrink(
7324 Handle<ObjectHashTable> table, Handle<Object> key) {
7325 return DerivedHashTable::Shrink(table, key);
7326}
7327
7328
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007329Object* OrderedHashMap::ValueAt(int entry) {
7330 return get(EntryToIndex(entry) + kValueOffset);
7331}
7332
7333
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007334template <int entrysize>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007335bool WeakHashTableShape<entrysize>::IsMatch(Handle<Object> key, Object* other) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007336 if (other->IsWeakCell()) other = WeakCell::cast(other)->value();
7337 return key->IsWeakCell() ? WeakCell::cast(*key)->value() == other
7338 : *key == other;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007339}
7340
7341
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007342template <int entrysize>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007343uint32_t WeakHashTableShape<entrysize>::Hash(Handle<Object> key) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007344 intptr_t hash =
7345 key->IsWeakCell()
7346 ? reinterpret_cast<intptr_t>(WeakCell::cast(*key)->value())
7347 : reinterpret_cast<intptr_t>(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007348 return (uint32_t)(hash & 0xFFFFFFFF);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007349}
7350
7351
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007352template <int entrysize>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007353uint32_t WeakHashTableShape<entrysize>::HashForObject(Handle<Object> key,
7354 Object* other) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007355 if (other->IsWeakCell()) other = WeakCell::cast(other)->value();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007356 intptr_t hash = reinterpret_cast<intptr_t>(other);
7357 return (uint32_t)(hash & 0xFFFFFFFF);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007358}
7359
7360
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007361template <int entrysize>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007362Handle<Object> WeakHashTableShape<entrysize>::AsHandle(Isolate* isolate,
7363 Handle<Object> key) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007364 return key;
7365}
7366
7367
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007368bool ScopeInfo::IsAsmModule() { return AsmModuleField::decode(Flags()); }
7369
7370
7371bool ScopeInfo::IsAsmFunction() { return AsmFunctionField::decode(Flags()); }
7372
7373
7374bool ScopeInfo::HasSimpleParameters() {
7375 return HasSimpleParametersField::decode(Flags());
7376}
7377
7378
7379#define SCOPE_INFO_FIELD_ACCESSORS(name) \
7380 void ScopeInfo::Set##name(int value) { set(k##name, Smi::FromInt(value)); } \
7381 int ScopeInfo::name() { \
7382 if (length() > 0) { \
7383 return Smi::cast(get(k##name))->value(); \
7384 } else { \
7385 return 0; \
7386 } \
7387 }
7388FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(SCOPE_INFO_FIELD_ACCESSORS)
7389#undef SCOPE_INFO_FIELD_ACCESSORS
7390
7391
Steve Block44f0eee2011-05-26 01:26:41 +01007392void Map::ClearCodeCache(Heap* heap) {
Steve Blocka7e24c12009-10-30 11:49:00 +00007393 // No write barrier is needed since empty_fixed_array is not in new space.
7394 // Please note this function is used during marking:
7395 // - MarkCompactCollector::MarkUnmarkedObject
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007396 // - IncrementalMarking::Step
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007397 DCHECK(!heap->InNewSpace(heap->empty_fixed_array()));
7398 WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array());
Steve Blocka7e24c12009-10-30 11:49:00 +00007399}
7400
7401
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007402int Map::SlackForArraySize(int old_size, int size_limit) {
7403 const int max_slack = size_limit - old_size;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007404 CHECK_LE(0, max_slack);
7405 if (old_size < 4) {
7406 DCHECK_LE(1, max_slack);
7407 return 1;
Steve Blockd0582a62009-12-15 09:54:21 +00007408 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007409 return Min(max_slack, old_size / 4);
Steve Blocka7e24c12009-10-30 11:49:00 +00007410}
7411
7412
Leon Clarke4515c472010-02-03 11:58:03 +00007413void JSArray::set_length(Smi* length) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007414 // Don't need a write barrier for a Smi.
Leon Clarke4515c472010-02-03 11:58:03 +00007415 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
7416}
7417
7418
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007419bool JSArray::SetLengthWouldNormalize(Heap* heap, uint32_t new_length) {
7420 // If the new array won't fit in a some non-trivial fraction of the max old
7421 // space size, then force it to go dictionary mode.
7422 uint32_t max_fast_array_size =
7423 static_cast<uint32_t>((heap->MaxOldGenerationSize() / kDoubleSize) / 4);
7424 return new_length >= max_fast_array_size;
7425}
7426
7427
7428bool JSArray::AllowsSetLength() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007429 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007430 DCHECK(result == !HasFixedTypedArrayElements());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007431 return result;
7432}
7433
7434
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007435void JSArray::SetContent(Handle<JSArray> array,
7436 Handle<FixedArrayBase> storage) {
7437 EnsureCanContainElements(array, storage, storage->length(),
7438 ALLOW_COPIED_DOUBLE_ELEMENTS);
7439
7440 DCHECK((storage->map() == array->GetHeap()->fixed_double_array_map() &&
7441 IsFastDoubleElementsKind(array->GetElementsKind())) ||
7442 ((storage->map() != array->GetHeap()->fixed_double_array_map()) &&
7443 (IsFastObjectElementsKind(array->GetElementsKind()) ||
7444 (IsFastSmiElementsKind(array->GetElementsKind()) &&
7445 Handle<FixedArray>::cast(storage)->ContainsOnlySmisOrHoles()))));
7446 array->set_elements(*storage);
7447 array->set_length(Smi::FromInt(storage->length()));
Steve Blocka7e24c12009-10-30 11:49:00 +00007448}
7449
7450
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007451int TypeFeedbackInfo::ic_total_count() {
7452 int current = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7453 return ICTotalCountField::decode(current);
Steve Block44f0eee2011-05-26 01:26:41 +01007454}
7455
7456
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007457void TypeFeedbackInfo::set_ic_total_count(int count) {
7458 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7459 value = ICTotalCountField::update(value,
7460 ICTotalCountField::decode(count));
7461 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007462}
7463
7464
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007465int TypeFeedbackInfo::ic_with_type_info_count() {
7466 int current = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7467 return ICsWithTypeInfoCountField::decode(current);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007468}
7469
7470
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007471void TypeFeedbackInfo::change_ic_with_type_info_count(int delta) {
7472 if (delta == 0) return;
7473 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7474 int new_count = ICsWithTypeInfoCountField::decode(value) + delta;
7475 // We can get negative count here when the type-feedback info is
7476 // shared between two code objects. The can only happen when
7477 // the debugger made a shallow copy of code object (see Heap::CopyCode).
7478 // Since we do not optimize when the debugger is active, we can skip
7479 // this counter update.
7480 if (new_count >= 0) {
7481 new_count &= ICsWithTypeInfoCountField::kMask;
7482 value = ICsWithTypeInfoCountField::update(value, new_count);
7483 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
7484 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007485}
7486
7487
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007488int TypeFeedbackInfo::ic_generic_count() {
7489 return Smi::cast(READ_FIELD(this, kStorage3Offset))->value();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007490}
7491
7492
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007493void TypeFeedbackInfo::change_ic_generic_count(int delta) {
7494 if (delta == 0) return;
7495 int new_count = ic_generic_count() + delta;
7496 if (new_count >= 0) {
7497 new_count &= ~Smi::kMinValue;
7498 WRITE_FIELD(this, kStorage3Offset, Smi::FromInt(new_count));
7499 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007500}
7501
7502
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007503void TypeFeedbackInfo::initialize_storage() {
7504 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(0));
7505 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(0));
7506 WRITE_FIELD(this, kStorage3Offset, Smi::FromInt(0));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007507}
7508
7509
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007510void TypeFeedbackInfo::change_own_type_change_checksum() {
7511 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7512 int checksum = OwnTypeChangeChecksum::decode(value);
7513 checksum = (checksum + 1) % (1 << kTypeChangeChecksumBits);
7514 value = OwnTypeChangeChecksum::update(value, checksum);
7515 // Ensure packed bit field is in Smi range.
7516 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
7517 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
7518 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007519}
7520
7521
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007522void TypeFeedbackInfo::set_inlined_type_change_checksum(int checksum) {
7523 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7524 int mask = (1 << kTypeChangeChecksumBits) - 1;
7525 value = InlinedTypeChangeChecksum::update(value, checksum & mask);
7526 // Ensure packed bit field is in Smi range.
7527 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
7528 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
7529 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007530}
7531
7532
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007533int TypeFeedbackInfo::own_type_change_checksum() {
7534 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
7535 return OwnTypeChangeChecksum::decode(value);
7536}
7537
7538
7539bool TypeFeedbackInfo::matches_inlined_type_change_checksum(int checksum) {
7540 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
7541 int mask = (1 << kTypeChangeChecksumBits) - 1;
7542 return InlinedTypeChangeChecksum::decode(value) == (checksum & mask);
7543}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007544
7545
7546SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
7547
7548
Steve Block44f0eee2011-05-26 01:26:41 +01007549Relocatable::Relocatable(Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +01007550 isolate_ = isolate;
7551 prev_ = isolate->relocatable_top();
7552 isolate->set_relocatable_top(this);
7553}
7554
7555
7556Relocatable::~Relocatable() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007557 DCHECK_EQ(isolate_->relocatable_top(), this);
Steve Block44f0eee2011-05-26 01:26:41 +01007558 isolate_->set_relocatable_top(prev_);
Steve Blocka7e24c12009-10-30 11:49:00 +00007559}
7560
7561
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007562template<class Derived, class TableType>
7563Object* OrderedHashTableIterator<Derived, TableType>::CurrentKey() {
7564 TableType* table(TableType::cast(this->table()));
7565 int index = Smi::cast(this->index())->value();
7566 Object* key = table->KeyAt(index);
7567 DCHECK(!key->IsTheHole());
7568 return key;
7569}
7570
7571
7572void JSSetIterator::PopulateValueArray(FixedArray* array) {
7573 array->set(0, CurrentKey());
7574}
7575
7576
7577void JSMapIterator::PopulateValueArray(FixedArray* array) {
7578 array->set(0, CurrentKey());
7579 array->set(1, CurrentValue());
7580}
7581
7582
7583Object* JSMapIterator::CurrentValue() {
7584 OrderedHashMap* table(OrderedHashMap::cast(this->table()));
7585 int index = Smi::cast(this->index())->value();
7586 Object* value = table->ValueAt(index);
7587 DCHECK(!value->IsTheHole());
7588 return value;
7589}
7590
Iain Merrick75681382010-08-19 15:07:18 +01007591
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007592String::SubStringRange::SubStringRange(String* string, int first, int length)
7593 : string_(string),
7594 first_(first),
7595 length_(length == -1 ? string->length() : length) {}
7596
7597
7598class String::SubStringRange::iterator final {
7599 public:
7600 typedef std::forward_iterator_tag iterator_category;
7601 typedef int difference_type;
7602 typedef uc16 value_type;
7603 typedef uc16* pointer;
7604 typedef uc16& reference;
7605
7606 iterator(const iterator& other)
7607 : content_(other.content_), offset_(other.offset_) {}
7608
7609 uc16 operator*() { return content_.Get(offset_); }
7610 bool operator==(const iterator& other) const {
7611 return content_.UsesSameString(other.content_) && offset_ == other.offset_;
7612 }
7613 bool operator!=(const iterator& other) const {
7614 return !content_.UsesSameString(other.content_) || offset_ != other.offset_;
7615 }
7616 iterator& operator++() {
7617 ++offset_;
7618 return *this;
7619 }
7620 iterator operator++(int);
7621
7622 private:
7623 friend class String;
7624 iterator(String* from, int offset)
7625 : content_(from->GetFlatContent()), offset_(offset) {}
7626 String::FlatContent content_;
7627 int offset_;
7628};
7629
7630
7631String::SubStringRange::iterator String::SubStringRange::begin() {
7632 return String::SubStringRange::iterator(string_, first_);
7633}
7634
7635
7636String::SubStringRange::iterator String::SubStringRange::end() {
7637 return String::SubStringRange::iterator(string_, first_ + length_);
7638}
7639
7640
7641// Predictably converts HeapObject* or Address to uint32 by calculating
7642// offset of the address in respective MemoryChunk.
7643static inline uint32_t ObjectAddressForHashing(void* object) {
7644 uint32_t value = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(object));
7645 return value & MemoryChunk::kAlignmentMask;
7646}
7647
7648
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007649#undef TYPE_CHECKER
Steve Blocka7e24c12009-10-30 11:49:00 +00007650#undef CAST_ACCESSOR
7651#undef INT_ACCESSORS
Ben Murdoch85b71792012-04-11 18:30:58 +01007652#undef ACCESSORS
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007653#undef SMI_ACCESSORS
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007654#undef SYNCHRONIZED_SMI_ACCESSORS
7655#undef NOBARRIER_SMI_ACCESSORS
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007656#undef BOOL_GETTER
7657#undef BOOL_ACCESSORS
Steve Blocka7e24c12009-10-30 11:49:00 +00007658#undef FIELD_ADDR
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007659#undef FIELD_ADDR_CONST
Steve Blocka7e24c12009-10-30 11:49:00 +00007660#undef READ_FIELD
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007661#undef NOBARRIER_READ_FIELD
Steve Blocka7e24c12009-10-30 11:49:00 +00007662#undef WRITE_FIELD
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007663#undef NOBARRIER_WRITE_FIELD
Steve Blocka7e24c12009-10-30 11:49:00 +00007664#undef WRITE_BARRIER
7665#undef CONDITIONAL_WRITE_BARRIER
Steve Blocka7e24c12009-10-30 11:49:00 +00007666#undef READ_DOUBLE_FIELD
7667#undef WRITE_DOUBLE_FIELD
7668#undef READ_INT_FIELD
7669#undef WRITE_INT_FIELD
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007670#undef READ_INTPTR_FIELD
7671#undef WRITE_INTPTR_FIELD
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007672#undef READ_UINT8_FIELD
7673#undef WRITE_UINT8_FIELD
7674#undef READ_INT8_FIELD
7675#undef WRITE_INT8_FIELD
7676#undef READ_UINT16_FIELD
7677#undef WRITE_UINT16_FIELD
7678#undef READ_INT16_FIELD
7679#undef WRITE_INT16_FIELD
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007680#undef READ_UINT32_FIELD
7681#undef WRITE_UINT32_FIELD
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007682#undef READ_INT32_FIELD
7683#undef WRITE_INT32_FIELD
7684#undef READ_FLOAT_FIELD
7685#undef WRITE_FLOAT_FIELD
7686#undef READ_UINT64_FIELD
7687#undef WRITE_UINT64_FIELD
7688#undef READ_INT64_FIELD
7689#undef WRITE_INT64_FIELD
Steve Blocka7e24c12009-10-30 11:49:00 +00007690#undef READ_BYTE_FIELD
7691#undef WRITE_BYTE_FIELD
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007692#undef NOBARRIER_READ_BYTE_FIELD
7693#undef NOBARRIER_WRITE_BYTE_FIELD
Steve Blocka7e24c12009-10-30 11:49:00 +00007694
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007695} // namespace internal
7696} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +00007697
7698#endif // V8_OBJECTS_INL_H_