blob: a14fccb073fb7936f1efe9f83bf9d33ddad1646a [file] [log] [blame]
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000038#include "elements.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000039#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040#include "contexts.h"
41#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000042#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000043#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000045#include "spaces.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000046#include "store-buffer.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000047#include "v8memory.h"
danno@chromium.orgfa458e42012-02-01 10:48:36 +000048#include "factory.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000049#include "incremental-marking.h"
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000050#include "transitions-inl.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000051
kasperl@chromium.org71affb52009-05-26 05:44:31 +000052namespace v8 {
53namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000054
55PropertyDetails::PropertyDetails(Smi* smi) {
56 value_ = smi->value();
57}
58
59
60Smi* PropertyDetails::AsSmi() {
61 return Smi::FromInt(value_);
62}
63
64
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000065PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000066 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000067 return PropertyDetails(smi);
68}
69
70
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000071#define TYPE_CHECKER(type, instancetype) \
72 bool Object::Is##type() { \
73 return Object::IsHeapObject() && \
74 HeapObject::cast(this)->map()->instance_type() == instancetype; \
75 }
76
77
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078#define CAST_ACCESSOR(type) \
79 type* type::cast(Object* object) { \
80 ASSERT(object->Is##type()); \
81 return reinterpret_cast<type*>(object); \
82 }
83
84
85#define INT_ACCESSORS(holder, name, offset) \
86 int holder::name() { return READ_INT_FIELD(this, offset); } \
87 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
88
89
90#define ACCESSORS(holder, name, type, offset) \
91 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000092 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000093 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000094 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000095 }
96
97
rossberg@chromium.org2c067b12012-03-19 11:01:52 +000098// Getter that returns a tagged Smi and setter that writes a tagged Smi.
99#define ACCESSORS_TO_SMI(holder, name, offset) \
100 Smi* holder::name() { return Smi::cast(READ_FIELD(this, offset)); } \
101 void holder::set_##name(Smi* value, WriteBarrierMode mode) { \
102 WRITE_FIELD(this, offset, value); \
103 }
104
105
106// Getter that returns a Smi as an int and writes an int as a Smi.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000107#define SMI_ACCESSORS(holder, name, offset) \
108 int holder::name() { \
109 Object* value = READ_FIELD(this, offset); \
110 return Smi::cast(value)->value(); \
111 } \
112 void holder::set_##name(int value) { \
113 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
114 }
115
116
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000117#define BOOL_GETTER(holder, field, name, offset) \
118 bool holder::name() { \
119 return BooleanBit::get(field(), offset); \
120 } \
121
122
123#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000124 bool holder::name() { \
125 return BooleanBit::get(field(), offset); \
126 } \
127 void holder::set_##name(bool value) { \
128 set_##field(BooleanBit::set(field(), offset, value)); \
129 }
130
131
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000132bool Object::IsFixedArrayBase() {
133 return IsFixedArray() || IsFixedDoubleArray();
134}
135
136
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000137// External objects are not extensible, so the map check is enough.
138bool Object::IsExternal() {
139 return Object::IsHeapObject() &&
140 HeapObject::cast(this)->map() ==
141 HeapObject::cast(this)->GetHeap()->external_map();
142}
143
144
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000145bool Object::IsAccessorInfo() {
146 return IsExecutableAccessorInfo() || IsDeclaredAccessorInfo();
147}
148
149
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000150bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
151 // There is a constraint on the object; check.
152 if (!this->IsJSObject()) return false;
153 // Fetch the constructor function of the object.
154 Object* cons_obj = JSObject::cast(this)->map()->constructor();
155 if (!cons_obj->IsJSFunction()) return false;
156 JSFunction* fun = JSFunction::cast(cons_obj);
157 // Iterate through the chain of inheriting function templates to
158 // see if the required one occurs.
159 for (Object* type = fun->shared()->function_data();
160 type->IsFunctionTemplateInfo();
161 type = FunctionTemplateInfo::cast(type)->parent_template()) {
162 if (type == expected) return true;
163 }
164 // Didn't find the required type in the inheritance chain.
165 return false;
166}
167
168
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000169bool Object::IsSmi() {
170 return HAS_SMI_TAG(this);
171}
172
173
174bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000175 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000176}
177
178
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000179bool Object::NonFailureIsHeapObject() {
180 ASSERT(!this->IsFailure());
181 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
182}
183
184
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000185TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000186TYPE_CHECKER(Symbol, SYMBOL_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000187
188
189bool Object::IsString() {
190 return Object::IsHeapObject()
191 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
192}
193
194
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000195bool Object::IsName() {
196 return IsString() || IsSymbol();
197}
198
199
200bool Object::IsUniqueName() {
201 return IsInternalizedString() || IsSymbol();
202}
203
204
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000205bool Object::IsSpecObject() {
206 return Object::IsHeapObject()
207 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
208}
209
210
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000211bool Object::IsSpecFunction() {
212 if (!Object::IsHeapObject()) return false;
213 InstanceType type = HeapObject::cast(this)->map()->instance_type();
214 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
215}
216
217
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000218bool Object::IsInternalizedString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000219 if (!this->IsHeapObject()) return false;
220 uint32_t type = HeapObject::cast(this)->map()->instance_type();
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000221 // Because the internalized tag is non-zero and no non-string types have the
222 // internalized bit set we can test for internalized strings with a very
223 // simple test operation.
224 STATIC_ASSERT(kInternalizedTag != 0);
225 ASSERT(kNotStringTag + kIsInternalizedMask > LAST_TYPE);
226 return (type & kIsInternalizedMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000227}
228
229
230bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000231 if (!IsString()) return false;
232 return StringShape(String::cast(this)).IsCons();
233}
234
235
236bool Object::IsSlicedString() {
237 if (!IsString()) return false;
238 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000239}
240
241
ager@chromium.org870a0b62008-11-04 11:43:05 +0000242bool Object::IsSeqString() {
243 if (!IsString()) return false;
244 return StringShape(String::cast(this)).IsSequential();
245}
246
247
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000248bool Object::IsSeqOneByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000249 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000250 return StringShape(String::cast(this)).IsSequential() &&
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000251 String::cast(this)->IsOneByteRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000252}
253
254
255bool Object::IsSeqTwoByteString() {
256 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000257 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000258 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000259}
260
261
262bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000263 if (!IsString()) return false;
264 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000265}
266
267
268bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000269 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000270 return StringShape(String::cast(this)).IsExternal() &&
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000271 String::cast(this)->IsOneByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000272}
273
274
275bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000276 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000277 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000278 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000279}
280
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000281bool Object::HasValidElements() {
282 // Dictionary is covered under FixedArray.
283 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
284}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000285
ager@chromium.org870a0b62008-11-04 11:43:05 +0000286StringShape::StringShape(String* str)
287 : type_(str->map()->instance_type()) {
288 set_valid();
289 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000290}
291
292
ager@chromium.org870a0b62008-11-04 11:43:05 +0000293StringShape::StringShape(Map* map)
294 : type_(map->instance_type()) {
295 set_valid();
296 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000297}
298
299
ager@chromium.org870a0b62008-11-04 11:43:05 +0000300StringShape::StringShape(InstanceType t)
301 : type_(static_cast<uint32_t>(t)) {
302 set_valid();
303 ASSERT((type_ & kIsNotStringMask) == kStringTag);
304}
305
306
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000307bool StringShape::IsInternalized() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000308 ASSERT(valid());
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000309 STATIC_ASSERT(kInternalizedTag != 0);
310 return (type_ & kIsInternalizedMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000311}
312
313
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000314bool String::IsOneByteRepresentation() {
ager@chromium.org5ec48922009-05-05 07:25:34 +0000315 uint32_t type = map()->instance_type();
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000316 return (type & kStringEncodingMask) == kOneByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000317}
318
319
ager@chromium.org5ec48922009-05-05 07:25:34 +0000320bool String::IsTwoByteRepresentation() {
321 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000322 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000323}
324
325
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000326bool String::IsOneByteRepresentationUnderneath() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000327 uint32_t type = map()->instance_type();
328 STATIC_ASSERT(kIsIndirectStringTag != 0);
329 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
330 ASSERT(IsFlat());
331 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000332 case kOneByteStringTag:
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000333 return true;
334 case kTwoByteStringTag:
335 return false;
336 default: // Cons or sliced string. Need to go deeper.
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000337 return GetUnderlying()->IsOneByteRepresentation();
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000338 }
339}
340
341
342bool String::IsTwoByteRepresentationUnderneath() {
343 uint32_t type = map()->instance_type();
344 STATIC_ASSERT(kIsIndirectStringTag != 0);
345 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
346 ASSERT(IsFlat());
347 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000348 case kOneByteStringTag:
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000349 return false;
350 case kTwoByteStringTag:
351 return true;
352 default: // Cons or sliced string. Need to go deeper.
353 return GetUnderlying()->IsTwoByteRepresentation();
354 }
355}
356
357
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000358bool String::HasOnlyAsciiChars() {
359 uint32_t type = map()->instance_type();
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000360 return (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000361}
362
363
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000364bool String::IsOneByteConvertible() {
365 return HasOnlyAsciiChars() || IsOneByteRepresentation();
366}
367
368
ager@chromium.org870a0b62008-11-04 11:43:05 +0000369bool StringShape::IsCons() {
370 return (type_ & kStringRepresentationMask) == kConsStringTag;
371}
372
373
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000374bool StringShape::IsSliced() {
375 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
376}
377
378
379bool StringShape::IsIndirect() {
380 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
381}
382
383
ager@chromium.org870a0b62008-11-04 11:43:05 +0000384bool StringShape::IsExternal() {
385 return (type_ & kStringRepresentationMask) == kExternalStringTag;
386}
387
388
389bool StringShape::IsSequential() {
390 return (type_ & kStringRepresentationMask) == kSeqStringTag;
391}
392
393
394StringRepresentationTag StringShape::representation_tag() {
395 uint32_t tag = (type_ & kStringRepresentationMask);
396 return static_cast<StringRepresentationTag>(tag);
397}
398
399
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000400uint32_t StringShape::encoding_tag() {
401 return type_ & kStringEncodingMask;
402}
403
404
ager@chromium.org870a0b62008-11-04 11:43:05 +0000405uint32_t StringShape::full_representation_tag() {
406 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
407}
408
409
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000410STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
411 Internals::kFullStringRepresentationMask);
412
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000413STATIC_CHECK(static_cast<uint32_t>(kStringEncodingMask) ==
414 Internals::kStringEncodingMask);
415
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000416
ager@chromium.org870a0b62008-11-04 11:43:05 +0000417bool StringShape::IsSequentialAscii() {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000418 return full_representation_tag() == (kSeqStringTag | kOneByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000419}
420
421
422bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000423 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000424}
425
426
427bool StringShape::IsExternalAscii() {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000428 return full_representation_tag() == (kExternalStringTag | kOneByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000429}
430
431
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000432STATIC_CHECK((kExternalStringTag | kOneByteStringTag) ==
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000433 Internals::kExternalAsciiRepresentationTag);
434
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000435STATIC_CHECK(v8::String::ASCII_ENCODING == kOneByteStringTag);
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000436
437
ager@chromium.org870a0b62008-11-04 11:43:05 +0000438bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000439 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000440}
441
442
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000443STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
444 Internals::kExternalTwoByteRepresentationTag);
445
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000446STATIC_CHECK(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000447
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000448uc32 FlatStringReader::Get(int index) {
449 ASSERT(0 <= index && index <= length_);
450 if (is_ascii_) {
451 return static_cast<const byte*>(start_)[index];
452 } else {
453 return static_cast<const uc16*>(start_)[index];
454 }
455}
456
457
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000458bool Object::IsNumber() {
459 return IsSmi() || IsHeapNumber();
460}
461
462
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000463TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
464TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000465
466
467bool Object::IsFiller() {
468 if (!Object::IsHeapObject()) return false;
469 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
470 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
471}
472
473
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000474TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000475
476
ager@chromium.org3811b432009-10-28 14:53:37 +0000477bool Object::IsExternalArray() {
478 if (!Object::IsHeapObject())
479 return false;
480 InstanceType instance_type =
481 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000482 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
483 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000484}
485
486
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000487TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
488TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
489TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
490TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
491TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
492TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
493TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
494TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000495
496
lrn@chromium.org303ada72010-10-27 09:33:13 +0000497bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000498 return HAS_FAILURE_TAG(this);
499}
500
501
lrn@chromium.org303ada72010-10-27 09:33:13 +0000502bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000503 return HAS_FAILURE_TAG(this)
504 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
505}
506
507
lrn@chromium.org303ada72010-10-27 09:33:13 +0000508bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000509 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000510 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000511}
512
513
lrn@chromium.org303ada72010-10-27 09:33:13 +0000514bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000515 return this == Failure::Exception();
516}
517
518
lrn@chromium.org303ada72010-10-27 09:33:13 +0000519bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000520 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000521}
522
523
524Failure* Failure::cast(MaybeObject* obj) {
525 ASSERT(HAS_FAILURE_TAG(obj));
526 return reinterpret_cast<Failure*>(obj);
527}
528
529
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000530bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000531 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000532 return IsHeapObject() &&
533 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
534}
535
536
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000537bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000538 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
539 return IsHeapObject() &&
540 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000541}
542
543
544bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000545 if (!Object::IsHeapObject()) return false;
546 InstanceType type = HeapObject::cast(this)->map()->instance_type();
547 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000548}
549
550
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000551TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
552TYPE_CHECKER(JSSet, JS_SET_TYPE)
553TYPE_CHECKER(JSMap, JS_MAP_TYPE)
554TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
555TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
556TYPE_CHECKER(Map, MAP_TYPE)
557TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
558TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000559
560
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000561bool Object::IsDescriptorArray() {
562 return IsFixedArray();
563}
564
565
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000566bool Object::IsTransitionArray() {
567 return IsFixedArray();
568}
569
570
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000571bool Object::IsDeoptimizationInputData() {
572 // Must be a fixed array.
573 if (!IsFixedArray()) return false;
574
575 // There's no sure way to detect the difference between a fixed array and
576 // a deoptimization data array. Since this is used for asserts we can
577 // check that the length is zero or else the fixed size plus a multiple of
578 // the entry size.
579 int length = FixedArray::cast(this)->length();
580 if (length == 0) return true;
581
582 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
583 return length >= 0 &&
584 length % DeoptimizationInputData::kDeoptEntrySize == 0;
585}
586
587
588bool Object::IsDeoptimizationOutputData() {
589 if (!IsFixedArray()) return false;
590 // There's actually no way to see the difference between a fixed array and
591 // a deoptimization data array. Since this is used for asserts we can check
592 // that the length is plausible though.
593 if (FixedArray::cast(this)->length() % 2 != 0) return false;
594 return true;
595}
596
597
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000598bool Object::IsDependentCode() {
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000599 if (!IsFixedArray()) return false;
600 // There's actually no way to see the difference between a fixed array and
601 // a dependent codes array.
602 return true;
603}
604
605
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000606bool Object::IsTypeFeedbackCells() {
607 if (!IsFixedArray()) return false;
608 // There's actually no way to see the difference between a fixed array and
609 // a cache cells array. Since this is used for asserts we can check that
610 // the length is plausible though.
611 if (FixedArray::cast(this)->length() % 2 != 0) return false;
612 return true;
613}
614
615
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616bool Object::IsContext() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000617 if (!Object::IsHeapObject()) return false;
618 Map* map = HeapObject::cast(this)->map();
619 Heap* heap = map->GetHeap();
620 return (map == heap->function_context_map() ||
621 map == heap->catch_context_map() ||
622 map == heap->with_context_map() ||
623 map == heap->native_context_map() ||
624 map == heap->block_context_map() ||
625 map == heap->module_context_map() ||
626 map == heap->global_context_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000627}
628
629
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000630bool Object::IsNativeContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000631 return Object::IsHeapObject() &&
632 HeapObject::cast(this)->map() ==
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000633 HeapObject::cast(this)->GetHeap()->native_context_map();
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000634}
635
636
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000637bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000638 return Object::IsHeapObject() &&
639 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000640 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000641}
642
643
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000644TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000645
646
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000647template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000648 return obj->IsJSFunction();
649}
650
651
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000652TYPE_CHECKER(Code, CODE_TYPE)
653TYPE_CHECKER(Oddball, ODDBALL_TYPE)
654TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
655TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000656TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000657TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000658TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000659TYPE_CHECKER(JSDate, JS_DATE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000660TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000661
662
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000663bool Object::IsStringWrapper() {
664 return IsJSValue() && JSValue::cast(this)->value()->IsString();
665}
666
667
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000668TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000669
670
671bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000672 return IsOddball() &&
673 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000674}
675
676
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000677TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000678TYPE_CHECKER(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000679TYPE_CHECKER(JSTypedArray, JS_TYPED_ARRAY_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000680TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000681
682
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000683template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000684 return obj->IsJSArray();
685}
686
687
688bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000689 return Object::IsHeapObject() &&
690 HeapObject::cast(this)->map() ==
691 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000692}
693
694
695bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000696 return IsHashTable() &&
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000697 this != HeapObject::cast(this)->GetHeap()->string_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000698}
699
700
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000701bool Object::IsStringTable() {
danno@chromium.org72204d52012-10-31 10:02:10 +0000702 return IsHashTable() &&
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000703 this == HeapObject::cast(this)->GetHeap()->raw_unchecked_string_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000704}
705
706
ager@chromium.orgac091b72010-05-05 07:34:42 +0000707bool Object::IsJSFunctionResultCache() {
708 if (!IsFixedArray()) return false;
709 FixedArray* self = FixedArray::cast(this);
710 int length = self->length();
711 if (length < JSFunctionResultCache::kEntriesIndex) return false;
712 if ((length - JSFunctionResultCache::kEntriesIndex)
713 % JSFunctionResultCache::kEntrySize != 0) {
714 return false;
715 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +0000716#ifdef VERIFY_HEAP
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000717 if (FLAG_verify_heap) {
718 reinterpret_cast<JSFunctionResultCache*>(this)->
719 JSFunctionResultCacheVerify();
720 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000721#endif
722 return true;
723}
724
725
ricow@chromium.org65fae842010-08-25 15:26:24 +0000726bool Object::IsNormalizedMapCache() {
727 if (!IsFixedArray()) return false;
728 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
729 return false;
730 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +0000731#ifdef VERIFY_HEAP
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000732 if (FLAG_verify_heap) {
733 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
734 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000735#endif
736 return true;
737}
738
739
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000740bool Object::IsCompilationCacheTable() {
741 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000742}
743
744
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000745bool Object::IsCodeCacheHashTable() {
746 return IsHashTable();
747}
748
749
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000750bool Object::IsPolymorphicCodeCacheHashTable() {
751 return IsHashTable();
752}
753
754
ager@chromium.org236ad962008-09-25 09:45:57 +0000755bool Object::IsMapCache() {
756 return IsHashTable();
757}
758
759
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000760bool Object::IsObjectHashTable() {
761 return IsHashTable();
762}
763
764
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000765bool Object::IsPrimitive() {
766 return IsOddball() || IsNumber() || IsString();
767}
768
769
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000770bool Object::IsJSGlobalProxy() {
771 bool result = IsHeapObject() &&
772 (HeapObject::cast(this)->map()->instance_type() ==
773 JS_GLOBAL_PROXY_TYPE);
774 ASSERT(!result || IsAccessCheckNeeded());
775 return result;
776}
777
778
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000779bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000780 if (!IsHeapObject()) return false;
781
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000782 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000783 return type == JS_GLOBAL_OBJECT_TYPE ||
784 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000785}
786
787
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000788TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
789TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000790
791
792bool Object::IsUndetectableObject() {
793 return IsHeapObject()
794 && HeapObject::cast(this)->map()->is_undetectable();
795}
796
797
798bool Object::IsAccessCheckNeeded() {
799 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000800 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000801}
802
803
804bool Object::IsStruct() {
805 if (!IsHeapObject()) return false;
806 switch (HeapObject::cast(this)->map()->instance_type()) {
807#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
808 STRUCT_LIST(MAKE_STRUCT_CASE)
809#undef MAKE_STRUCT_CASE
810 default: return false;
811 }
812}
813
814
815#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
816 bool Object::Is##Name() { \
817 return Object::IsHeapObject() \
818 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
819 }
820 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
821#undef MAKE_STRUCT_PREDICATE
822
823
824bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000825 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000826}
827
828
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000829bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000830 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
831}
832
833
834bool Object::IsTheHole() {
835 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000836}
837
838
839bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000840 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000841}
842
843
844bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000845 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000846}
847
848
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000849bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000850 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000851}
852
853
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000854double Object::Number() {
855 ASSERT(IsNumber());
856 return IsSmi()
857 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
858 : reinterpret_cast<HeapNumber*>(this)->value();
859}
860
861
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000862bool Object::IsNaN() {
ulan@chromium.org77ca49a2013-04-22 09:43:56 +0000863 return this->IsHeapNumber() && std::isnan(HeapNumber::cast(this)->value());
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000864}
865
866
lrn@chromium.org303ada72010-10-27 09:33:13 +0000867MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000868 if (IsSmi()) return this;
869 if (IsHeapNumber()) {
870 double value = HeapNumber::cast(this)->value();
871 int int_value = FastD2I(value);
872 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
873 return Smi::FromInt(int_value);
874 }
875 }
876 return Failure::Exception();
877}
878
879
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000880bool Object::HasSpecificClassOf(String* name) {
881 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
882}
883
884
lrn@chromium.org303ada72010-10-27 09:33:13 +0000885MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000886 // GetElement can trigger a getter which can cause allocation.
887 // This was not always the case. This ASSERT is here to catch
888 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000889 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000890 return GetElementWithReceiver(this, index);
891}
892
893
lrn@chromium.org303ada72010-10-27 09:33:13 +0000894Object* Object::GetElementNoExceptionThrown(uint32_t index) {
895 MaybeObject* maybe = GetElementWithReceiver(this, index);
896 ASSERT(!maybe->IsFailure());
897 Object* result = NULL; // Initialization to please compiler.
898 maybe->ToObject(&result);
899 return result;
900}
901
902
ulan@chromium.org750145a2013-03-07 15:14:13 +0000903MaybeObject* Object::GetProperty(Name* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000904 PropertyAttributes attributes;
905 return GetPropertyWithReceiver(this, key, &attributes);
906}
907
908
ulan@chromium.org750145a2013-03-07 15:14:13 +0000909MaybeObject* Object::GetProperty(Name* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000910 return GetPropertyWithReceiver(this, key, attributes);
911}
912
913
914#define FIELD_ADDR(p, offset) \
915 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
916
917#define READ_FIELD(p, offset) \
918 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
919
920#define WRITE_FIELD(p, offset, value) \
921 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
922
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000923#define WRITE_BARRIER(heap, object, offset, value) \
924 heap->incremental_marking()->RecordWrite( \
925 object, HeapObject::RawField(object, offset), value); \
926 if (heap->InNewSpace(value)) { \
927 heap->RecordWrite(object->address(), offset); \
928 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000929
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000930#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
931 if (mode == UPDATE_WRITE_BARRIER) { \
932 heap->incremental_marking()->RecordWrite( \
933 object, HeapObject::RawField(object, offset), value); \
934 if (heap->InNewSpace(value)) { \
935 heap->RecordWrite(object->address(), offset); \
936 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000937 }
938
lrn@chromium.org7516f052011-03-30 08:52:27 +0000939#ifndef V8_TARGET_ARCH_MIPS
940 #define READ_DOUBLE_FIELD(p, offset) \
941 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
942#else // V8_TARGET_ARCH_MIPS
943 // Prevent gcc from using load-double (mips ldc1) on (possibly)
944 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000945 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000946 union conversion {
947 double d;
948 uint32_t u[2];
949 } c;
950 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
951 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
952 return c.d;
953 }
954 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
955#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000956
lrn@chromium.org7516f052011-03-30 08:52:27 +0000957#ifndef V8_TARGET_ARCH_MIPS
958 #define WRITE_DOUBLE_FIELD(p, offset, value) \
959 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
960#else // V8_TARGET_ARCH_MIPS
961 // Prevent gcc from using store-double (mips sdc1) on (possibly)
962 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000963 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000964 double value) {
965 union conversion {
966 double d;
967 uint32_t u[2];
968 } c;
969 c.d = value;
970 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
971 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
972 }
973 #define WRITE_DOUBLE_FIELD(p, offset, value) \
974 write_double_field(p, offset, value)
975#endif // V8_TARGET_ARCH_MIPS
976
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000977
978#define READ_INT_FIELD(p, offset) \
979 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
980
981#define WRITE_INT_FIELD(p, offset, value) \
982 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
983
ager@chromium.org3e875802009-06-29 08:26:34 +0000984#define READ_INTPTR_FIELD(p, offset) \
985 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
986
987#define WRITE_INTPTR_FIELD(p, offset, value) \
988 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
989
ager@chromium.org7c537e22008-10-16 08:43:32 +0000990#define READ_UINT32_FIELD(p, offset) \
991 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
992
993#define WRITE_UINT32_FIELD(p, offset, value) \
994 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
995
danno@chromium.org88aa0582012-03-23 15:11:57 +0000996#define READ_INT64_FIELD(p, offset) \
997 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
998
999#define WRITE_INT64_FIELD(p, offset, value) \
1000 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
1001
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001002#define READ_SHORT_FIELD(p, offset) \
1003 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
1004
1005#define WRITE_SHORT_FIELD(p, offset, value) \
1006 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
1007
1008#define READ_BYTE_FIELD(p, offset) \
1009 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
1010
1011#define WRITE_BYTE_FIELD(p, offset, value) \
1012 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
1013
1014
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00001015Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
1016 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001017}
1018
1019
1020int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00001021 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001022}
1023
1024
1025Smi* Smi::FromInt(int value) {
1026 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001027 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +00001028 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001029 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +00001030 return reinterpret_cast<Smi*>(tagged_value);
1031}
1032
1033
1034Smi* Smi::FromIntptr(intptr_t value) {
1035 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001036 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1037 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001038}
1039
1040
1041Failure::Type Failure::type() const {
1042 return static_cast<Type>(value() & kFailureTypeTagMask);
1043}
1044
1045
1046bool Failure::IsInternalError() const {
1047 return type() == INTERNAL_ERROR;
1048}
1049
1050
1051bool Failure::IsOutOfMemoryException() const {
1052 return type() == OUT_OF_MEMORY_EXCEPTION;
1053}
1054
1055
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001056AllocationSpace Failure::allocation_space() const {
1057 ASSERT_EQ(RETRY_AFTER_GC, type());
1058 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1059 & kSpaceTagMask);
1060}
1061
1062
1063Failure* Failure::InternalError() {
1064 return Construct(INTERNAL_ERROR);
1065}
1066
1067
1068Failure* Failure::Exception() {
1069 return Construct(EXCEPTION);
1070}
1071
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001072
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00001073Failure* Failure::OutOfMemoryException(intptr_t value) {
1074 return Construct(OUT_OF_MEMORY_EXCEPTION, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001075}
1076
1077
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001078intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001079 return static_cast<intptr_t>(
1080 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001081}
1082
1083
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001084Failure* Failure::RetryAfterGC() {
1085 return RetryAfterGC(NEW_SPACE);
1086}
1087
1088
1089Failure* Failure::RetryAfterGC(AllocationSpace space) {
1090 ASSERT((space & ~kSpaceTagMask) == 0);
1091 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001092}
1093
1094
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001095Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001096 uintptr_t info =
1097 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001098 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +00001099 // Fill the unused bits with a pattern that's easy to recognize in crash
1100 // dumps.
1101 static const int kFailureMagicPattern = 0x0BAD0000;
1102 return reinterpret_cast<Failure*>(
1103 (info << kFailureTagSize) | kFailureTag | kFailureMagicPattern);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001104}
1105
1106
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001107bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001108#ifdef DEBUG
1109 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1110#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001111
1112#ifdef V8_TARGET_ARCH_X64
1113 // To be representable as a long smi, the value must be a 32-bit integer.
1114 bool result = (value == static_cast<int32_t>(value));
1115#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001116 // To be representable as an tagged small integer, the two
1117 // most-significant bits of 'value' must be either 00 or 11 due to
1118 // sign-extension. To check this we add 01 to the two
1119 // most-significant bits, and check if the most-significant bit is 0
1120 //
1121 // CAUTION: The original code below:
1122 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1123 // may lead to incorrect results according to the C language spec, and
1124 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1125 // compiler may produce undefined results in case of signed integer
1126 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001127 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001128#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001129 ASSERT(result == in_range);
1130 return result;
1131}
1132
1133
kasper.lund7276f142008-07-30 08:49:36 +00001134MapWord MapWord::FromMap(Map* map) {
1135 return MapWord(reinterpret_cast<uintptr_t>(map));
1136}
1137
1138
1139Map* MapWord::ToMap() {
1140 return reinterpret_cast<Map*>(value_);
1141}
1142
1143
1144bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001145 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001146}
1147
1148
1149MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001150 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1151 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001152}
1153
1154
1155HeapObject* MapWord::ToForwardingAddress() {
1156 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001157 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001158}
1159
1160
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001161#ifdef VERIFY_HEAP
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001162void HeapObject::VerifyObjectField(int offset) {
1163 VerifyPointer(READ_FIELD(this, offset));
1164}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001165
1166void HeapObject::VerifySmiField(int offset) {
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001167 CHECK(READ_FIELD(this, offset)->IsSmi());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001168}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001169#endif
1170
1171
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001172Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001173 Heap* heap =
1174 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1175 ASSERT(heap != NULL);
1176 ASSERT(heap->isolate() == Isolate::Current());
1177 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001178}
1179
1180
1181Isolate* HeapObject::GetIsolate() {
1182 return GetHeap()->isolate();
1183}
1184
1185
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001186Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001187 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001188}
1189
1190
1191void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001192 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001193 if (value != NULL) {
1194 // TODO(1600) We are passing NULL as a slot because maps can never be on
1195 // evacuation candidate.
1196 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1197 }
1198}
1199
1200
1201// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001202void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001203 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001204}
1205
1206
kasper.lund7276f142008-07-30 08:49:36 +00001207MapWord HeapObject::map_word() {
1208 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1209}
1210
1211
1212void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001213 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001214 // here.
1215 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1216}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001217
1218
1219HeapObject* HeapObject::FromAddress(Address address) {
1220 ASSERT_TAG_ALIGNED(address);
1221 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1222}
1223
1224
1225Address HeapObject::address() {
1226 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1227}
1228
1229
1230int HeapObject::Size() {
1231 return SizeFromMap(map());
1232}
1233
1234
1235void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1236 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1237 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1238}
1239
1240
1241void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1242 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1243}
1244
1245
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001246double HeapNumber::value() {
1247 return READ_DOUBLE_FIELD(this, kValueOffset);
1248}
1249
1250
1251void HeapNumber::set_value(double value) {
1252 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1253}
1254
1255
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001256int HeapNumber::get_exponent() {
1257 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1258 kExponentShift) - kExponentBias;
1259}
1260
1261
1262int HeapNumber::get_sign() {
1263 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1264}
1265
1266
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001267ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001268
1269
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001270Object** FixedArray::GetFirstElementAddress() {
1271 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1272}
1273
1274
1275bool FixedArray::ContainsOnlySmisOrHoles() {
1276 Object* the_hole = GetHeap()->the_hole_value();
1277 Object** current = GetFirstElementAddress();
1278 for (int i = 0; i < length(); ++i) {
1279 Object* candidate = *current++;
1280 if (!candidate->IsSmi() && candidate != the_hole) return false;
1281 }
1282 return true;
1283}
1284
1285
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001286FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001287 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001288 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001289}
1290
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001291
1292void JSObject::ValidateElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001293#if DEBUG
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001294 if (FLAG_enable_slow_asserts) {
1295 ElementsAccessor* accessor = GetElementsAccessor();
1296 accessor->Validate(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001297 }
1298#endif
1299}
1300
1301
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001302MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001303 ValidateElements();
1304 ElementsKind elements_kind = map()->elements_kind();
1305 if (!IsFastObjectElementsKind(elements_kind)) {
1306 if (IsFastHoleyElementsKind(elements_kind)) {
1307 return TransitionElementsKind(FAST_HOLEY_ELEMENTS);
1308 } else {
1309 return TransitionElementsKind(FAST_ELEMENTS);
1310 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001311 }
1312 return this;
1313}
1314
1315
1316MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001317 uint32_t count,
1318 EnsureElementsMode mode) {
1319 ElementsKind current_kind = map()->elements_kind();
1320 ElementsKind target_kind = current_kind;
1321 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001322 bool is_holey = IsFastHoleyElementsKind(current_kind);
1323 if (current_kind == FAST_HOLEY_ELEMENTS) return this;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001324 Heap* heap = GetHeap();
1325 Object* the_hole = heap->the_hole_value();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001326 for (uint32_t i = 0; i < count; ++i) {
1327 Object* current = *objects++;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001328 if (current == the_hole) {
1329 is_holey = true;
1330 target_kind = GetHoleyElementsKind(target_kind);
1331 } else if (!current->IsSmi()) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001332 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && current->IsNumber()) {
1333 if (IsFastSmiElementsKind(target_kind)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001334 if (is_holey) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001335 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001336 } else {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001337 target_kind = FAST_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001338 }
1339 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001340 } else if (is_holey) {
1341 target_kind = FAST_HOLEY_ELEMENTS;
1342 break;
1343 } else {
1344 target_kind = FAST_ELEMENTS;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001345 }
1346 }
1347 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001348
1349 if (target_kind != current_kind) {
1350 return TransitionElementsKind(target_kind);
1351 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001352 return this;
1353}
1354
1355
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001356MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001357 uint32_t length,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001358 EnsureElementsMode mode) {
1359 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1360 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1361 elements->map() == GetHeap()->fixed_cow_array_map());
1362 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1363 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1364 }
1365 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001366 return EnsureCanContainElements(objects, length, mode);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001367 }
1368
1369 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001370 if (GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) {
1371 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1372 } else if (GetElementsKind() == FAST_SMI_ELEMENTS) {
1373 FixedDoubleArray* double_array = FixedDoubleArray::cast(elements);
1374 for (uint32_t i = 0; i < length; ++i) {
1375 if (double_array->is_the_hole(i)) {
1376 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1377 }
1378 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001379 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1380 }
1381
1382 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001383}
1384
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001385
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001386MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1387 ElementsKind to_kind) {
1388 Map* current_map = map();
1389 ElementsKind from_kind = current_map->elements_kind();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001390 if (from_kind == to_kind) return current_map;
1391
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001392 Context* native_context = isolate->context()->native_context();
1393 Object* maybe_array_maps = native_context->js_array_maps();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001394 if (maybe_array_maps->IsFixedArray()) {
1395 FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
1396 if (array_maps->get(from_kind) == current_map) {
1397 Object* maybe_transitioned_map = array_maps->get(to_kind);
1398 if (maybe_transitioned_map->IsMap()) {
1399 return Map::cast(maybe_transitioned_map);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001400 }
1401 }
1402 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001403
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001404 return GetElementsTransitionMapSlow(to_kind);
1405}
1406
1407
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001408void JSObject::set_map_and_elements(Map* new_map,
1409 FixedArrayBase* value,
1410 WriteBarrierMode mode) {
1411 ASSERT(value->HasValidElements());
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001412 if (new_map != NULL) {
1413 if (mode == UPDATE_WRITE_BARRIER) {
1414 set_map(new_map);
1415 } else {
1416 ASSERT(mode == SKIP_WRITE_BARRIER);
1417 set_map_no_write_barrier(new_map);
1418 }
1419 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001420 ASSERT((map()->has_fast_smi_or_object_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001421 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001422 (value->map() == GetHeap()->fixed_array_map() ||
1423 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001424 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1425 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001426 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001427 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001428}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001429
1430
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001431void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1432 set_map_and_elements(NULL, value, mode);
1433}
1434
1435
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001436void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001437 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1438 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001439}
1440
1441
1442void JSObject::initialize_elements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001443 ASSERT(map()->has_fast_smi_or_object_elements() ||
danno@chromium.org2c26cb12012-05-03 09:06:43 +00001444 map()->has_fast_double_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001445 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1446 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001447}
1448
1449
lrn@chromium.org303ada72010-10-27 09:33:13 +00001450MaybeObject* JSObject::ResetElements() {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001451 if (map()->is_observed()) {
1452 // Maintain invariant that observed elements are always in dictionary mode.
1453 SeededNumberDictionary* dictionary;
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001454 MaybeObject* maybe = SeededNumberDictionary::Allocate(GetHeap(), 0);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001455 if (!maybe->To(&dictionary)) return maybe;
1456 if (map() == GetHeap()->non_strict_arguments_elements_map()) {
1457 FixedArray::cast(elements())->set(1, dictionary);
1458 } else {
1459 set_elements(dictionary);
1460 }
1461 return this;
1462 }
1463
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001464 ElementsKind elements_kind = GetInitialFastElementsKind();
1465 if (!FLAG_smi_only_arrays) {
1466 elements_kind = FastSmiToObjectElementsKind(elements_kind);
1467 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001468 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind);
1469 Map* map;
1470 if (!maybe->To(&map)) return maybe;
1471 set_map(map);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001472 initialize_elements();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001473
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001474 return this;
1475}
1476
1477
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00001478MaybeObject* JSObject::AddFastPropertyUsingMap(Map* map) {
1479 ASSERT(this->map()->NumberOfOwnDescriptors() + 1 ==
1480 map->NumberOfOwnDescriptors());
1481 if (this->map()->unused_property_fields() == 0) {
1482 int new_size = properties()->length() + map->unused_property_fields() + 1;
1483 FixedArray* new_properties;
1484 MaybeObject* maybe_properties = properties()->CopySize(new_size);
1485 if (!maybe_properties->To(&new_properties)) return maybe_properties;
1486 set_properties(new_properties);
1487 }
1488 set_map(map);
1489 return this;
1490}
1491
1492
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001493MaybeObject* JSObject::TransitionToMap(Map* map) {
1494 ASSERT(this->map()->inobject_properties() == map->inobject_properties());
1495 ElementsKind expected_kind = this->map()->elements_kind();
1496 if (map->elements_kind() != expected_kind) {
1497 MaybeObject* maybe_map = map->AsElementsKind(expected_kind);
1498 if (!maybe_map->To(&map)) return maybe_map;
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001499 }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001500 int total_size =
1501 map->NumberOfOwnDescriptors() + map->unused_property_fields();
1502 int out_of_object = total_size - map->inobject_properties();
1503 if (out_of_object != properties()->length()) {
1504 FixedArray* new_properties;
1505 MaybeObject* maybe_properties = properties()->CopySize(out_of_object);
1506 if (!maybe_properties->To(&new_properties)) return maybe_properties;
1507 set_properties(new_properties);
1508 }
1509 set_map(map);
1510 return this;
1511}
1512
1513
1514Handle<String> JSObject::ExpectedTransitionKey(Handle<Map> map) {
1515 AssertNoAllocation no_gc;
1516 if (!map->HasTransitionArray()) return Handle<String>::null();
1517 TransitionArray* transitions = map->transitions();
1518 if (!transitions->IsSimpleTransition()) return Handle<String>::null();
1519 int transition = TransitionArray::kSimpleTransitionIndex;
1520 PropertyDetails details = transitions->GetTargetDetails(transition);
1521 Name* name = transitions->GetKey(transition);
1522 if (details.type() != FIELD) return Handle<String>::null();
1523 if (details.attributes() != NONE) return Handle<String>::null();
1524 if (!name->IsString()) return Handle<String>::null();
1525 return Handle<String>(String::cast(name));
1526}
1527
1528
1529Handle<Map> JSObject::ExpectedTransitionTarget(Handle<Map> map) {
1530 ASSERT(!ExpectedTransitionKey(map).is_null());
1531 return Handle<Map>(map->transitions()->GetTarget(
1532 TransitionArray::kSimpleTransitionIndex));
1533}
1534
1535
1536Handle<Map> JSObject::FindTransitionToField(Handle<Map> map, Handle<Name> key) {
1537 AssertNoAllocation no_allocation;
1538 if (!map->HasTransitionArray()) return Handle<Map>::null();
1539 TransitionArray* transitions = map->transitions();
1540 int transition = transitions->Search(*key);
1541 if (transition == TransitionArray::kNotFound) return Handle<Map>::null();
1542 PropertyDetails target_details = transitions->GetTargetDetails(transition);
1543 if (target_details.type() != FIELD) return Handle<Map>::null();
1544 if (target_details.attributes() != NONE) return Handle<Map>::null();
1545 return Handle<Map>(transitions->GetTarget(transition));
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00001546}
1547
1548
1549int JSObject::LastAddedFieldIndex() {
1550 Map* map = this->map();
1551 int last_added = map->LastAdded();
1552 return map->instance_descriptors()->GetFieldIndex(last_added);
1553}
1554
1555
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001556ACCESSORS(Oddball, to_string, String, kToStringOffset)
1557ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1558
1559
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001560byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001561 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001562}
1563
1564
1565void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001566 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001567}
1568
1569
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001570Object* JSGlobalPropertyCell::value() {
1571 return READ_FIELD(this, kValueOffset);
1572}
1573
1574
1575void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1576 // The write barrier is not used for global property cells.
1577 ASSERT(!val->IsJSGlobalPropertyCell());
1578 WRITE_FIELD(this, kValueOffset, val);
1579}
1580
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001581
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001582int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001583 InstanceType type = map()->instance_type();
1584 // Check for the most common kind of JavaScript object before
1585 // falling into the generic switch. This speeds up the internal
1586 // field operations considerably on average.
1587 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1588 switch (type) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001589 case JS_GENERATOR_OBJECT_TYPE:
1590 return JSGeneratorObject::kSize;
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001591 case JS_MODULE_TYPE:
1592 return JSModule::kSize;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001593 case JS_GLOBAL_PROXY_TYPE:
1594 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001595 case JS_GLOBAL_OBJECT_TYPE:
1596 return JSGlobalObject::kSize;
1597 case JS_BUILTINS_OBJECT_TYPE:
1598 return JSBuiltinsObject::kSize;
1599 case JS_FUNCTION_TYPE:
1600 return JSFunction::kSize;
1601 case JS_VALUE_TYPE:
1602 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001603 case JS_DATE_TYPE:
1604 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001606 return JSArray::kSize;
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001607 case JS_ARRAY_BUFFER_TYPE:
1608 return JSArrayBuffer::kSize;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001609 case JS_TYPED_ARRAY_TYPE:
1610 return JSTypedArray::kSize;
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001611 case JS_SET_TYPE:
1612 return JSSet::kSize;
1613 case JS_MAP_TYPE:
1614 return JSMap::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001615 case JS_WEAK_MAP_TYPE:
1616 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001617 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001618 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001619 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001620 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001621 case JS_MESSAGE_OBJECT_TYPE:
1622 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001623 default:
1624 UNREACHABLE();
1625 return 0;
1626 }
1627}
1628
1629
1630int JSObject::GetInternalFieldCount() {
1631 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001632 // Make sure to adjust for the number of in-object properties. These
1633 // properties do contribute to the size, but are not internal fields.
1634 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1635 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001636}
1637
1638
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001639int JSObject::GetInternalFieldOffset(int index) {
1640 ASSERT(index < GetInternalFieldCount() && index >= 0);
1641 return GetHeaderSize() + (kPointerSize * index);
1642}
1643
1644
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001645Object* JSObject::GetInternalField(int index) {
1646 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001647 // Internal objects do follow immediately after the header, whereas in-object
1648 // properties are at the end of the object. Therefore there is no need
1649 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001650 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1651}
1652
1653
1654void JSObject::SetInternalField(int index, Object* value) {
1655 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001656 // Internal objects do follow immediately after the header, whereas in-object
1657 // properties are at the end of the object. Therefore there is no need
1658 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001659 int offset = GetHeaderSize() + (kPointerSize * index);
1660 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001661 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001662}
1663
1664
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001665void JSObject::SetInternalField(int index, Smi* value) {
1666 ASSERT(index < GetInternalFieldCount() && index >= 0);
1667 // Internal objects do follow immediately after the header, whereas in-object
1668 // properties are at the end of the object. Therefore there is no need
1669 // to adjust the index here.
1670 int offset = GetHeaderSize() + (kPointerSize * index);
1671 WRITE_FIELD(this, offset, value);
1672}
1673
1674
ager@chromium.org7c537e22008-10-16 08:43:32 +00001675// Access fast-case object properties at index. The use of these routines
1676// is needed to correctly distinguish between properties stored in-object and
1677// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001678Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001679 // Adjust for the number of properties stored in the object.
1680 index -= map()->inobject_properties();
1681 if (index < 0) {
1682 int offset = map()->instance_size() + (index * kPointerSize);
1683 return READ_FIELD(this, offset);
1684 } else {
1685 ASSERT(index < properties()->length());
1686 return properties()->get(index);
1687 }
1688}
1689
1690
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001691Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001692 // Adjust for the number of properties stored in the object.
1693 index -= map()->inobject_properties();
1694 if (index < 0) {
1695 int offset = map()->instance_size() + (index * kPointerSize);
1696 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001697 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001698 } else {
1699 ASSERT(index < properties()->length());
1700 properties()->set(index, value);
1701 }
1702 return value;
1703}
1704
1705
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001706int JSObject::GetInObjectPropertyOffset(int index) {
1707 // Adjust for the number of properties stored in the object.
1708 index -= map()->inobject_properties();
1709 ASSERT(index < 0);
1710 return map()->instance_size() + (index * kPointerSize);
1711}
1712
1713
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001714Object* JSObject::InObjectPropertyAt(int index) {
1715 // Adjust for the number of properties stored in the object.
1716 index -= map()->inobject_properties();
1717 ASSERT(index < 0);
1718 int offset = map()->instance_size() + (index * kPointerSize);
1719 return READ_FIELD(this, offset);
1720}
1721
1722
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001723Object* JSObject::InObjectPropertyAtPut(int index,
1724 Object* value,
1725 WriteBarrierMode mode) {
1726 // Adjust for the number of properties stored in the object.
1727 index -= map()->inobject_properties();
1728 ASSERT(index < 0);
1729 int offset = map()->instance_size() + (index * kPointerSize);
1730 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001731 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001732 return value;
1733}
1734
1735
1736
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001737void JSObject::InitializeBody(Map* map,
1738 Object* pre_allocated_value,
1739 Object* filler_value) {
1740 ASSERT(!filler_value->IsHeapObject() ||
1741 !GetHeap()->InNewSpace(filler_value));
1742 ASSERT(!pre_allocated_value->IsHeapObject() ||
1743 !GetHeap()->InNewSpace(pre_allocated_value));
1744 int size = map->instance_size();
1745 int offset = kHeaderSize;
1746 if (filler_value != pre_allocated_value) {
1747 int pre_allocated = map->pre_allocated_property_fields();
1748 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1749 for (int i = 0; i < pre_allocated; i++) {
1750 WRITE_FIELD(this, offset, pre_allocated_value);
1751 offset += kPointerSize;
1752 }
1753 }
1754 while (offset < size) {
1755 WRITE_FIELD(this, offset, filler_value);
1756 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001757 }
1758}
1759
1760
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001761bool JSObject::HasFastProperties() {
erik.corry@gmail.com88767242012-08-08 14:43:45 +00001762 ASSERT(properties()->IsDictionary() == map()->is_dictionary_map());
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001763 return !properties()->IsDictionary();
1764}
1765
1766
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001767bool JSObject::TooManyFastProperties(int properties,
1768 JSObject::StoreFromKeyed store_mode) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001769 // Allow extra fast properties if the object has more than
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001770 // kFastPropertiesSoftLimit in-object properties. When this is the case,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001771 // it is very unlikely that the object is being used as a dictionary
1772 // and there is a good chance that allowing more map transitions
1773 // will be worth it.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001774 int inobject = map()->inobject_properties();
1775
1776 int limit;
ulan@chromium.orgf6a0c412012-06-15 12:31:06 +00001777 if (store_mode == CERTAINLY_NOT_STORE_FROM_KEYED) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001778 limit = Max(inobject, kMaxFastProperties);
1779 } else {
1780 limit = Max(inobject, kFastPropertiesSoftLimit);
1781 }
1782 return properties > limit;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001783}
1784
1785
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001786void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001787 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001788 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001789 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001790 }
1791}
1792
1793
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001794bool Object::ToArrayIndex(uint32_t* index) {
1795 if (IsSmi()) {
1796 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001797 if (value < 0) return false;
1798 *index = value;
1799 return true;
1800 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001801 if (IsHeapNumber()) {
1802 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001803 uint32_t uint_value = static_cast<uint32_t>(value);
1804 if (value == static_cast<double>(uint_value)) {
1805 *index = uint_value;
1806 return true;
1807 }
1808 }
1809 return false;
1810}
1811
1812
1813bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1814 if (!this->IsJSValue()) return false;
1815
1816 JSValue* js_value = JSValue::cast(this);
1817 if (!js_value->value()->IsString()) return false;
1818
1819 String* str = String::cast(js_value->value());
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00001820 if (index >= static_cast<uint32_t>(str->length())) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001821
1822 return true;
1823}
1824
1825
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00001826
1827void Object::VerifyApiCallResultType() {
1828#if ENABLE_EXTRA_CHECKS
1829 if (!(IsSmi() ||
1830 IsString() ||
1831 IsSpecObject() ||
1832 IsHeapNumber() ||
1833 IsUndefined() ||
1834 IsTrue() ||
1835 IsFalse() ||
1836 IsNull())) {
1837 FATAL("API call returned invalid object");
1838 }
1839#endif // ENABLE_EXTRA_CHECKS
1840}
1841
1842
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001843FixedArrayBase* FixedArrayBase::cast(Object* object) {
1844 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1845 return reinterpret_cast<FixedArrayBase*>(object);
1846}
1847
1848
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001849Object* FixedArray::get(int index) {
1850 ASSERT(index >= 0 && index < this->length());
1851 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1852}
1853
1854
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001855bool FixedArray::is_the_hole(int index) {
1856 return get(index) == GetHeap()->the_hole_value();
1857}
1858
1859
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001860void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001861 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001862 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001863 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1864 int offset = kHeaderSize + index * kPointerSize;
1865 WRITE_FIELD(this, offset, value);
1866}
1867
1868
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001869void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001870 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001871 ASSERT(index >= 0 && index < this->length());
1872 int offset = kHeaderSize + index * kPointerSize;
1873 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001874 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001875}
1876
1877
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001878inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1879 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1880}
1881
1882
1883inline double FixedDoubleArray::hole_nan_as_double() {
1884 return BitCast<double, uint64_t>(kHoleNanInt64);
1885}
1886
1887
1888inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1889 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1890 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1891 return OS::nan_value();
1892}
1893
1894
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001895double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001896 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1897 map() != HEAP->fixed_array_map());
1898 ASSERT(index >= 0 && index < this->length());
1899 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1900 ASSERT(!is_the_hole_nan(result));
1901 return result;
1902}
1903
danno@chromium.org88aa0582012-03-23 15:11:57 +00001904int64_t FixedDoubleArray::get_representation(int index) {
1905 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1906 map() != HEAP->fixed_array_map());
1907 ASSERT(index >= 0 && index < this->length());
1908 return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1909}
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001910
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001911MaybeObject* FixedDoubleArray::get(int index) {
1912 if (is_the_hole(index)) {
1913 return GetHeap()->the_hole_value();
1914 } else {
1915 return GetHeap()->NumberFromDouble(get_scalar(index));
1916 }
1917}
1918
1919
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001920void FixedDoubleArray::set(int index, double value) {
1921 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1922 map() != HEAP->fixed_array_map());
1923 int offset = kHeaderSize + index * kDoubleSize;
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00001924 if (std::isnan(value)) value = canonical_not_the_hole_nan_as_double();
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001925 WRITE_DOUBLE_FIELD(this, offset, value);
1926}
1927
1928
1929void FixedDoubleArray::set_the_hole(int index) {
1930 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1931 map() != HEAP->fixed_array_map());
1932 int offset = kHeaderSize + index * kDoubleSize;
1933 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1934}
1935
1936
1937bool FixedDoubleArray::is_the_hole(int index) {
1938 int offset = kHeaderSize + index * kDoubleSize;
1939 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1940}
1941
1942
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001943WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001944 Heap* heap = GetHeap();
1945 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1946 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001947 return UPDATE_WRITE_BARRIER;
1948}
1949
1950
1951void FixedArray::set(int index,
1952 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001953 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001954 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001955 ASSERT(index >= 0 && index < this->length());
1956 int offset = kHeaderSize + index * kPointerSize;
1957 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001958 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001959}
1960
1961
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001962void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1963 int index,
1964 Object* value) {
danno@chromium.org72204d52012-10-31 10:02:10 +00001965 ASSERT(array->map() != HEAP->fixed_cow_array_map());
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001966 ASSERT(index >= 0 && index < array->length());
1967 int offset = kHeaderSize + index * kPointerSize;
1968 WRITE_FIELD(array, offset, value);
1969 Heap* heap = array->GetHeap();
1970 if (heap->InNewSpace(value)) {
1971 heap->RecordWrite(array->address(), offset);
1972 }
1973}
1974
1975
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001976void FixedArray::NoWriteBarrierSet(FixedArray* array,
1977 int index,
1978 Object* value) {
danno@chromium.org72204d52012-10-31 10:02:10 +00001979 ASSERT(array->map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001980 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001981 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001982 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1983}
1984
1985
1986void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001987 ASSERT(map() != HEAP->fixed_cow_array_map());
1988 set_undefined(GetHeap(), index);
1989}
1990
1991
1992void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001993 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001994 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001995 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001996 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001997}
1998
1999
ager@chromium.org236ad962008-09-25 09:45:57 +00002000void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002001 set_null(GetHeap(), index);
2002}
2003
2004
2005void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00002006 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002007 ASSERT(!heap->InNewSpace(heap->null_value()));
2008 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002009}
2010
2011
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002012void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002013 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002014 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002015 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
2016 WRITE_FIELD(this,
2017 kHeaderSize + index * kPointerSize,
2018 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002019}
2020
2021
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002022void FixedArray::set_unchecked(int index, Smi* value) {
2023 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
2024 int offset = kHeaderSize + index * kPointerSize;
2025 WRITE_FIELD(this, offset, value);
2026}
2027
2028
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002029void FixedArray::set_unchecked(Heap* heap,
2030 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002031 Object* value,
2032 WriteBarrierMode mode) {
2033 int offset = kHeaderSize + index * kPointerSize;
2034 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002035 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00002036}
2037
2038
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002039void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002040 ASSERT(index >= 0 && index < this->length());
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00002041 ASSERT(!heap->InNewSpace(heap->null_value()));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002042 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002043}
2044
2045
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002046double* FixedDoubleArray::data_start() {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00002047 return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002048}
2049
2050
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002051Object** FixedArray::data_start() {
2052 return HeapObject::RawField(this, kHeaderSize);
2053}
2054
2055
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00002056bool DescriptorArray::IsEmpty() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002057 ASSERT(length() >= kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002058 this == HEAP->empty_descriptor_array());
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002059 return length() < kFirstIndex;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002060}
2061
2062
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002063void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
2064 WRITE_FIELD(
2065 this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors));
2066}
2067
2068
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002069// Perform a binary search in a fixed array. Low and high are entry indices. If
2070// there are three entries in this array it should be called with low=0 and
2071// high=2.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002072template<SearchMode search_mode, typename T>
ulan@chromium.org750145a2013-03-07 15:14:13 +00002073int BinarySearch(T* array, Name* name, int low, int high, int valid_entries) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002074 uint32_t hash = name->Hash();
2075 int limit = high;
2076
2077 ASSERT(low <= high);
2078
2079 while (low != high) {
2080 int mid = (low + high) / 2;
ulan@chromium.org750145a2013-03-07 15:14:13 +00002081 Name* mid_name = array->GetSortedKey(mid);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002082 uint32_t mid_hash = mid_name->Hash();
2083
2084 if (mid_hash >= hash) {
2085 high = mid;
2086 } else {
2087 low = mid + 1;
2088 }
2089 }
2090
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002091 for (; low <= limit; ++low) {
2092 int sort_index = array->GetSortedKeyIndex(low);
ulan@chromium.org750145a2013-03-07 15:14:13 +00002093 Name* entry = array->GetKey(sort_index);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002094 if (entry->Hash() != hash) break;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002095 if (entry->Equals(name)) {
2096 if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
2097 return sort_index;
2098 }
2099 return T::kNotFound;
2100 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002101 }
2102
2103 return T::kNotFound;
2104}
2105
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002106
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002107// Perform a linear search in this fixed array. len is the number of entry
2108// indices that are valid.
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002109template<SearchMode search_mode, typename T>
ulan@chromium.org750145a2013-03-07 15:14:13 +00002110int LinearSearch(T* array, Name* name, int len, int valid_entries) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002111 uint32_t hash = name->Hash();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002112 if (search_mode == ALL_ENTRIES) {
2113 for (int number = 0; number < len; number++) {
2114 int sorted_index = array->GetSortedKeyIndex(number);
ulan@chromium.org750145a2013-03-07 15:14:13 +00002115 Name* entry = array->GetKey(sorted_index);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002116 uint32_t current_hash = entry->Hash();
2117 if (current_hash > hash) break;
2118 if (current_hash == hash && entry->Equals(name)) return sorted_index;
2119 }
2120 } else {
2121 ASSERT(len >= valid_entries);
2122 for (int number = 0; number < valid_entries; number++) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002123 Name* entry = array->GetKey(number);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002124 uint32_t current_hash = entry->Hash();
2125 if (current_hash == hash && entry->Equals(name)) return number;
2126 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002127 }
2128 return T::kNotFound;
2129}
2130
2131
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002132template<SearchMode search_mode, typename T>
ulan@chromium.org750145a2013-03-07 15:14:13 +00002133int Search(T* array, Name* name, int valid_entries) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002134 if (search_mode == VALID_ENTRIES) {
2135 SLOW_ASSERT(array->IsSortedNoDuplicates(valid_entries));
2136 } else {
2137 SLOW_ASSERT(array->IsSortedNoDuplicates());
2138 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002139
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002140 int nof = array->number_of_entries();
2141 if (nof == 0) return T::kNotFound;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002142
2143 // Fast case: do linear search for small arrays.
2144 const int kMaxElementsForLinearSearch = 8;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002145 if ((search_mode == ALL_ENTRIES &&
2146 nof <= kMaxElementsForLinearSearch) ||
2147 (search_mode == VALID_ENTRIES &&
2148 valid_entries <= (kMaxElementsForLinearSearch * 3))) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002149 return LinearSearch<search_mode>(array, name, nof, valid_entries);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002150 }
2151
2152 // Slow case: perform binary search.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002153 return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002154}
2155
2156
ulan@chromium.org750145a2013-03-07 15:14:13 +00002157int DescriptorArray::Search(Name* name, int valid_descriptors) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002158 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002159}
2160
2161
ulan@chromium.org750145a2013-03-07 15:14:13 +00002162int DescriptorArray::SearchWithCache(Name* name, Map* map) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002163 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
2164 if (number_of_own_descriptors == 0) return kNotFound;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002165
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002166 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002167 int number = cache->Lookup(map, name);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002168
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002169 if (number == DescriptorLookupCache::kAbsent) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002170 number = Search(name, number_of_own_descriptors);
2171 cache->Update(map, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002172 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002173
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002174 return number;
2175}
2176
2177
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002178void Map::LookupDescriptor(JSObject* holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +00002179 Name* name,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002180 LookupResult* result) {
2181 DescriptorArray* descriptors = this->instance_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002182 int number = descriptors->SearchWithCache(name, this);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002183 if (number == DescriptorArray::kNotFound) return result->NotFound();
2184 result->DescriptorResult(holder, descriptors->GetDetails(number), number);
2185}
2186
2187
2188void Map::LookupTransition(JSObject* holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +00002189 Name* name,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002190 LookupResult* result) {
2191 if (HasTransitionArray()) {
2192 TransitionArray* transition_array = transitions();
2193 int number = transition_array->Search(name);
2194 if (number != TransitionArray::kNotFound) {
2195 return result->TransitionResult(holder, number);
2196 }
2197 }
2198 result->NotFound();
2199}
2200
2201
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002202Object** DescriptorArray::GetKeySlot(int descriptor_number) {
2203 ASSERT(descriptor_number < number_of_descriptors());
2204 return HeapObject::RawField(
2205 reinterpret_cast<HeapObject*>(this),
2206 OffsetOfElementAt(ToKeyIndex(descriptor_number)));
2207}
2208
2209
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00002210Object** DescriptorArray::GetDescriptorStartSlot(int descriptor_number) {
2211 return GetKeySlot(descriptor_number);
2212}
2213
2214
2215Object** DescriptorArray::GetDescriptorEndSlot(int descriptor_number) {
2216 return GetValueSlot(descriptor_number - 1) + 1;
2217}
2218
2219
ulan@chromium.org750145a2013-03-07 15:14:13 +00002220Name* DescriptorArray::GetKey(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002221 ASSERT(descriptor_number < number_of_descriptors());
ulan@chromium.org750145a2013-03-07 15:14:13 +00002222 return Name::cast(get(ToKeyIndex(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002223}
2224
2225
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002226int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
2227 return GetDetails(descriptor_number).pointer();
2228}
2229
2230
ulan@chromium.org750145a2013-03-07 15:14:13 +00002231Name* DescriptorArray::GetSortedKey(int descriptor_number) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002232 return GetKey(GetSortedKeyIndex(descriptor_number));
2233}
2234
2235
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002236void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
2237 PropertyDetails details = GetDetails(descriptor_index);
2238 set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi());
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002239}
2240
2241
verwaest@chromium.org37141392012-05-31 13:27:02 +00002242Object** DescriptorArray::GetValueSlot(int descriptor_number) {
2243 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002244 return HeapObject::RawField(
2245 reinterpret_cast<HeapObject*>(this),
2246 OffsetOfElementAt(ToValueIndex(descriptor_number)));
verwaest@chromium.org37141392012-05-31 13:27:02 +00002247}
2248
2249
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002250Object* DescriptorArray::GetValue(int descriptor_number) {
2251 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002252 return get(ToValueIndex(descriptor_number));
2253}
2254
2255
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002256PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002257 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002258 Object* details = get(ToDetailsIndex(descriptor_number));
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002259 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002260}
2261
2262
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002263PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002264 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002265}
2266
2267
2268int DescriptorArray::GetFieldIndex(int descriptor_number) {
2269 return Descriptor::IndexFromValue(GetValue(descriptor_number));
2270}
2271
2272
2273JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
2274 return JSFunction::cast(GetValue(descriptor_number));
2275}
2276
2277
2278Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
2279 ASSERT(GetType(descriptor_number) == CALLBACKS);
2280 return GetValue(descriptor_number);
2281}
2282
2283
2284AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
2285 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002286 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002287 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002288}
2289
2290
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002291void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2292 desc->Init(GetKey(descriptor_number),
2293 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002294 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002295}
2296
2297
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002298void DescriptorArray::Set(int descriptor_number,
2299 Descriptor* desc,
2300 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002301 // Range check.
2302 ASSERT(descriptor_number < number_of_descriptors());
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002303 ASSERT(desc->GetDetails().descriptor_index() <=
2304 number_of_descriptors());
2305 ASSERT(desc->GetDetails().descriptor_index() > 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002306
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002307 NoIncrementalWriteBarrierSet(this,
2308 ToKeyIndex(descriptor_number),
2309 desc->GetKey());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002310 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002311 ToValueIndex(descriptor_number),
2312 desc->GetValue());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002313 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002314 ToDetailsIndex(descriptor_number),
2315 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002316}
2317
2318
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002319void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
2320 // Range check.
2321 ASSERT(descriptor_number < number_of_descriptors());
2322 ASSERT(desc->GetDetails().descriptor_index() <=
2323 number_of_descriptors());
2324 ASSERT(desc->GetDetails().descriptor_index() > 0);
2325
2326 set(ToKeyIndex(descriptor_number), desc->GetKey());
2327 set(ToValueIndex(descriptor_number), desc->GetValue());
2328 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
2329}
2330
2331
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002332void DescriptorArray::Append(Descriptor* desc,
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002333 const WhitenessWitness& witness) {
2334 int descriptor_number = number_of_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002335 int enumeration_index = descriptor_number + 1;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002336 SetNumberOfDescriptors(descriptor_number + 1);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002337 desc->SetEnumerationIndex(enumeration_index);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002338 Set(descriptor_number, desc, witness);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002339
2340 uint32_t hash = desc->GetKey()->Hash();
2341
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002342 int insertion;
2343
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002344 for (insertion = descriptor_number; insertion > 0; --insertion) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002345 Name* key = GetSortedKey(insertion - 1);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002346 if (key->Hash() <= hash) break;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002347 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002348 }
2349
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002350 SetSortedKey(insertion, descriptor_number);
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002351}
2352
2353
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002354void DescriptorArray::Append(Descriptor* desc) {
2355 int descriptor_number = number_of_descriptors();
2356 int enumeration_index = descriptor_number + 1;
2357 SetNumberOfDescriptors(descriptor_number + 1);
2358 desc->SetEnumerationIndex(enumeration_index);
2359 Set(descriptor_number, desc);
2360
2361 uint32_t hash = desc->GetKey()->Hash();
2362
2363 int insertion;
2364
2365 for (insertion = descriptor_number; insertion > 0; --insertion) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002366 Name* key = GetSortedKey(insertion - 1);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002367 if (key->Hash() <= hash) break;
2368 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
2369 }
2370
2371 SetSortedKey(insertion, descriptor_number);
2372}
2373
2374
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002375void DescriptorArray::SwapSortedKeys(int first, int second) {
2376 int first_key = GetSortedKeyIndex(first);
2377 SetSortedKey(first, GetSortedKeyIndex(second));
2378 SetSortedKey(second, first_key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002379}
2380
2381
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002382DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002383 : marking_(array->GetHeap()->incremental_marking()) {
2384 marking_->EnterNoMarkingScope();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002385 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002386}
2387
2388
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002389DescriptorArray::WhitenessWitness::~WhitenessWitness() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002390 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002391}
2392
2393
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002394template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002395int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2396 const int kMinCapacity = 32;
2397 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2398 if (capacity < kMinCapacity) {
2399 capacity = kMinCapacity; // Guarantee min capacity.
2400 }
2401 return capacity;
2402}
2403
2404
2405template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002406int HashTable<Shape, Key>::FindEntry(Key key) {
2407 return FindEntry(GetIsolate(), key);
2408}
2409
2410
2411// Find entry for key otherwise return kNotFound.
2412template<typename Shape, typename Key>
2413int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2414 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002415 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002416 uint32_t count = 1;
2417 // EnsureCapacity will guarantee the hash table is never full.
2418 while (true) {
2419 Object* element = KeyAt(entry);
danno@chromium.org72204d52012-10-31 10:02:10 +00002420 // Empty entry. Uses raw unchecked accessors because it is called by the
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002421 // string table during bootstrapping.
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002422 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2423 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002424 Shape::IsMatch(key, element)) return entry;
2425 entry = NextProbe(entry, count++, capacity);
2426 }
2427 return kNotFound;
2428}
2429
2430
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002431bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002432 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002433 if (!max_index_object->IsSmi()) return false;
2434 return 0 !=
2435 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2436}
2437
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002438uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002439 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002440 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002441 if (!max_index_object->IsSmi()) return 0;
2442 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2443 return value >> kRequiresSlowElementsTagSize;
2444}
2445
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002446void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002447 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002448}
2449
2450
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002451// ------------------------------------
2452// Cast operations
2453
2454
2455CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002456CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002457CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002458CAST_ACCESSOR(DeoptimizationInputData)
2459CAST_ACCESSOR(DeoptimizationOutputData)
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002460CAST_ACCESSOR(DependentCode)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002461CAST_ACCESSOR(TypeFeedbackCells)
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002462CAST_ACCESSOR(StringTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002463CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002464CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002465CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002466CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002467CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002468CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002469CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002470CAST_ACCESSOR(String)
2471CAST_ACCESSOR(SeqString)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002472CAST_ACCESSOR(SeqOneByteString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002473CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002474CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002475CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002476CAST_ACCESSOR(ExternalString)
2477CAST_ACCESSOR(ExternalAsciiString)
2478CAST_ACCESSOR(ExternalTwoByteString)
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002479CAST_ACCESSOR(Symbol)
ulan@chromium.org750145a2013-03-07 15:14:13 +00002480CAST_ACCESSOR(Name)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002481CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002482CAST_ACCESSOR(JSObject)
2483CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002484CAST_ACCESSOR(HeapObject)
2485CAST_ACCESSOR(HeapNumber)
2486CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002487CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002488CAST_ACCESSOR(SharedFunctionInfo)
2489CAST_ACCESSOR(Map)
2490CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002491CAST_ACCESSOR(GlobalObject)
2492CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002493CAST_ACCESSOR(JSGlobalObject)
2494CAST_ACCESSOR(JSBuiltinsObject)
2495CAST_ACCESSOR(Code)
2496CAST_ACCESSOR(JSArray)
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00002497CAST_ACCESSOR(JSArrayBuffer)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002498CAST_ACCESSOR(JSTypedArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002499CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002500CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002501CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002502CAST_ACCESSOR(JSSet)
2503CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002504CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002505CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002506CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002507CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002508CAST_ACCESSOR(ExternalArray)
2509CAST_ACCESSOR(ExternalByteArray)
2510CAST_ACCESSOR(ExternalUnsignedByteArray)
2511CAST_ACCESSOR(ExternalShortArray)
2512CAST_ACCESSOR(ExternalUnsignedShortArray)
2513CAST_ACCESSOR(ExternalIntArray)
2514CAST_ACCESSOR(ExternalUnsignedIntArray)
2515CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002516CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002517CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002518CAST_ACCESSOR(Struct)
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002519CAST_ACCESSOR(AccessorInfo)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002520
2521
2522#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2523 STRUCT_LIST(MAKE_STRUCT_CAST)
2524#undef MAKE_STRUCT_CAST
2525
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002526
2527template <typename Shape, typename Key>
2528HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002529 ASSERT(obj->IsHashTable());
2530 return reinterpret_cast<HashTable*>(obj);
2531}
2532
2533
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002534SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002535SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002536
ager@chromium.orgac091b72010-05-05 07:34:42 +00002537SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002538
2539
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002540uint32_t Name::hash_field() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002541 return READ_UINT32_FIELD(this, kHashFieldOffset);
2542}
2543
2544
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002545void Name::set_hash_field(uint32_t value) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002546 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002547#if V8_HOST_ARCH_64_BIT
2548 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2549#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002550}
2551
2552
ulan@chromium.org750145a2013-03-07 15:14:13 +00002553bool Name::Equals(Name* other) {
2554 if (other == this) return true;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002555 if ((this->IsInternalizedString() && other->IsInternalizedString()) ||
2556 this->IsSymbol() || other->IsSymbol()) {
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00002557 return false;
2558 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00002559 return String::cast(this)->SlowEquals(String::cast(other));
2560}
2561
2562
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00002563ACCESSORS(Symbol, name, Object, kNameOffset)
2564
2565
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002566bool String::Equals(String* other) {
2567 if (other == this) return true;
ulan@chromium.org750145a2013-03-07 15:14:13 +00002568 if (this->IsInternalizedString() && other->IsInternalizedString()) {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002569 return false;
2570 }
2571 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002572}
2573
2574
lrn@chromium.org303ada72010-10-27 09:33:13 +00002575MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002576 if (!StringShape(this).IsCons()) return this;
2577 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002578 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002579 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002580}
2581
2582
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002583String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002584 MaybeObject* flat = TryFlatten(pretenure);
2585 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002586 if (!flat->ToObject(&successfully_flattened)) return this;
2587 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002588}
2589
2590
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002591uint16_t String::Get(int index) {
2592 ASSERT(index >= 0 && index < length());
2593 switch (StringShape(this).full_representation_tag()) {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002594 case kSeqStringTag | kOneByteStringTag:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002595 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002596 case kSeqStringTag | kTwoByteStringTag:
2597 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002598 case kConsStringTag | kOneByteStringTag:
ager@chromium.org870a0b62008-11-04 11:43:05 +00002599 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002600 return ConsString::cast(this)->ConsStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002601 case kExternalStringTag | kOneByteStringTag:
ager@chromium.org870a0b62008-11-04 11:43:05 +00002602 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2603 case kExternalStringTag | kTwoByteStringTag:
2604 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002605 case kSlicedStringTag | kOneByteStringTag:
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002606 case kSlicedStringTag | kTwoByteStringTag:
2607 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002608 default:
2609 break;
2610 }
2611
2612 UNREACHABLE();
2613 return 0;
2614}
2615
2616
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002617void String::Set(int index, uint16_t value) {
2618 ASSERT(index >= 0 && index < length());
2619 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002620
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00002621 return this->IsOneByteRepresentation()
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002622 ? SeqOneByteString::cast(this)->SeqOneByteStringSet(index, value)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002623 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002624}
2625
2626
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002627bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002628 if (!StringShape(this).IsCons()) return true;
2629 return ConsString::cast(this)->second()->length() == 0;
2630}
2631
2632
2633String* String::GetUnderlying() {
2634 // Giving direct access to underlying string only makes sense if the
2635 // wrapping string is already flattened.
2636 ASSERT(this->IsFlat());
2637 ASSERT(StringShape(this).IsIndirect());
2638 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2639 const int kUnderlyingOffset = SlicedString::kParentOffset;
2640 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002641}
2642
2643
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002644template<class Visitor, class ConsOp>
2645void String::Visit(
2646 String* string,
2647 unsigned offset,
2648 Visitor& visitor,
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002649 ConsOp& cons_op,
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002650 int32_t type,
2651 unsigned length) {
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002652 ASSERT(length == static_cast<unsigned>(string->length()));
2653 ASSERT(offset <= length);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002654 unsigned slice_offset = offset;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002655 while (true) {
2656 ASSERT(type == string->map()->instance_type());
2657
2658 switch (type & (kStringRepresentationMask | kStringEncodingMask)) {
2659 case kSeqStringTag | kOneByteStringTag:
2660 visitor.VisitOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002661 SeqOneByteString::cast(string)->GetChars() + slice_offset,
2662 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002663 return;
2664
2665 case kSeqStringTag | kTwoByteStringTag:
2666 visitor.VisitTwoByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002667 SeqTwoByteString::cast(string)->GetChars() + slice_offset,
2668 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002669 return;
2670
2671 case kExternalStringTag | kOneByteStringTag:
2672 visitor.VisitOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002673 ExternalAsciiString::cast(string)->GetChars() + slice_offset,
2674 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002675 return;
2676
2677 case kExternalStringTag | kTwoByteStringTag:
2678 visitor.VisitTwoByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002679 ExternalTwoByteString::cast(string)->GetChars() + slice_offset,
2680 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002681 return;
2682
2683 case kSlicedStringTag | kOneByteStringTag:
2684 case kSlicedStringTag | kTwoByteStringTag: {
2685 SlicedString* slicedString = SlicedString::cast(string);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002686 slice_offset += slicedString->offset();
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002687 string = slicedString->parent();
2688 type = string->map()->instance_type();
2689 continue;
2690 }
2691
2692 case kConsStringTag | kOneByteStringTag:
2693 case kConsStringTag | kTwoByteStringTag:
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002694 string = cons_op.Operate(string, &offset, &type, &length);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002695 if (string == NULL) return;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002696 slice_offset = offset;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002697 ASSERT(length == static_cast<unsigned>(string->length()));
2698 continue;
2699
2700 default:
2701 UNREACHABLE();
2702 return;
2703 }
2704 }
2705}
2706
2707
ulan@chromium.org750145a2013-03-07 15:14:13 +00002708// TODO(dcarney): Remove this class after conversion to VisitFlat.
2709class ConsStringCaptureOp {
2710 public:
2711 inline ConsStringCaptureOp() : cons_string_(NULL) {}
2712 inline String* Operate(String* string, unsigned*, int32_t*, unsigned*) {
2713 cons_string_ = ConsString::cast(string);
2714 return NULL;
2715 }
2716 ConsString* cons_string_;
2717};
2718
2719
2720template<class Visitor>
2721ConsString* String::VisitFlat(Visitor* visitor,
2722 String* string,
2723 int offset,
2724 int length,
2725 int32_t type) {
2726 ASSERT(length >= 0 && length == string->length());
2727 ASSERT(offset >= 0 && offset <= length);
2728 ConsStringCaptureOp op;
2729 Visit(string, offset, *visitor, op, type, static_cast<unsigned>(length));
2730 return op.cons_string_;
2731}
2732
2733
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002734uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002735 ASSERT(index >= 0 && index < length());
2736 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2737}
2738
2739
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002740void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002741 ASSERT(index >= 0 && index < length() && value <= kMaxOneByteCharCode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002742 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2743 static_cast<byte>(value));
2744}
2745
2746
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002747Address SeqOneByteString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002748 return FIELD_ADDR(this, kHeaderSize);
2749}
2750
2751
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002752uint8_t* SeqOneByteString::GetChars() {
2753 return reinterpret_cast<uint8_t*>(GetCharsAddress());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002754}
2755
2756
ager@chromium.org7c537e22008-10-16 08:43:32 +00002757Address SeqTwoByteString::GetCharsAddress() {
2758 return FIELD_ADDR(this, kHeaderSize);
2759}
2760
2761
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002762uc16* SeqTwoByteString::GetChars() {
2763 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2764}
2765
2766
ager@chromium.org7c537e22008-10-16 08:43:32 +00002767uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002768 ASSERT(index >= 0 && index < length());
2769 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2770}
2771
2772
ager@chromium.org7c537e22008-10-16 08:43:32 +00002773void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002774 ASSERT(index >= 0 && index < length());
2775 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2776}
2777
2778
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002779int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002780 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002781}
2782
2783
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002784int SeqOneByteString::SeqOneByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002785 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002786}
2787
2788
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002789String* SlicedString::parent() {
2790 return String::cast(READ_FIELD(this, kParentOffset));
2791}
2792
2793
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002794void SlicedString::set_parent(String* parent, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002795 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002796 WRITE_FIELD(this, kParentOffset, parent);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002797 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kParentOffset, parent, mode);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002798}
2799
2800
2801SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2802
2803
ager@chromium.org870a0b62008-11-04 11:43:05 +00002804String* ConsString::first() {
2805 return String::cast(READ_FIELD(this, kFirstOffset));
2806}
2807
2808
2809Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002810 return READ_FIELD(this, kFirstOffset);
2811}
2812
2813
ager@chromium.org870a0b62008-11-04 11:43:05 +00002814void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002815 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002816 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002817}
2818
2819
ager@chromium.org870a0b62008-11-04 11:43:05 +00002820String* ConsString::second() {
2821 return String::cast(READ_FIELD(this, kSecondOffset));
2822}
2823
2824
2825Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002826 return READ_FIELD(this, kSecondOffset);
2827}
2828
2829
ager@chromium.org870a0b62008-11-04 11:43:05 +00002830void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002831 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002832 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002833}
2834
2835
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002836bool ExternalString::is_short() {
2837 InstanceType type = map()->instance_type();
2838 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002839}
2840
2841
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002842const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002843 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2844}
2845
2846
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002847void ExternalAsciiString::update_data_cache() {
2848 if (is_short()) return;
2849 const char** data_field =
2850 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2851 *data_field = resource()->data();
2852}
2853
2854
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002855void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002856 const ExternalAsciiString::Resource* resource) {
2857 *reinterpret_cast<const Resource**>(
2858 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002859 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002860}
2861
2862
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002863const uint8_t* ExternalAsciiString::GetChars() {
2864 return reinterpret_cast<const uint8_t*>(resource()->data());
erikcorry0ad885c2011-11-21 13:51:57 +00002865}
2866
2867
2868uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2869 ASSERT(index >= 0 && index < length());
2870 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002871}
2872
2873
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002874const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002875 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2876}
2877
2878
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002879void ExternalTwoByteString::update_data_cache() {
2880 if (is_short()) return;
2881 const uint16_t** data_field =
2882 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2883 *data_field = resource()->data();
2884}
2885
2886
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002887void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002888 const ExternalTwoByteString::Resource* resource) {
2889 *reinterpret_cast<const Resource**>(
2890 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002891 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002892}
2893
2894
2895const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002896 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002897}
2898
2899
2900uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2901 ASSERT(index >= 0 && index < length());
2902 return GetChars()[index];
2903}
2904
2905
2906const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2907 unsigned start) {
2908 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002909}
2910
2911
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002912String* ConsStringNullOp::Operate(String*, unsigned*, int32_t*, unsigned*) {
2913 return NULL;
2914}
2915
2916
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002917unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) {
2918 return depth & kDepthMask;
2919}
2920
2921
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002922void ConsStringIteratorOp::PushLeft(ConsString* string) {
2923 frames_[depth_++ & kDepthMask] = string;
2924}
2925
2926
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002927void ConsStringIteratorOp::PushRight(ConsString* string) {
2928 // Inplace update.
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002929 frames_[(depth_-1) & kDepthMask] = string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002930}
2931
2932
2933void ConsStringIteratorOp::AdjustMaximumDepth() {
2934 if (depth_ > maximum_depth_) maximum_depth_ = depth_;
2935}
2936
2937
2938void ConsStringIteratorOp::Pop() {
2939 ASSERT(depth_ > 0);
2940 ASSERT(depth_ <= maximum_depth_);
2941 depth_--;
2942}
2943
2944
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002945bool ConsStringIteratorOp::HasMore() {
2946 return depth_ != 0;
2947}
2948
2949
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002950void ConsStringIteratorOp::Reset() {
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002951 depth_ = 0;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002952}
2953
2954
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002955String* ConsStringIteratorOp::ContinueOperation(int32_t* type_out,
2956 unsigned* length_out) {
2957 bool blew_stack = false;
2958 String* string = NextLeaf(&blew_stack, type_out, length_out);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002959 // String found.
2960 if (string != NULL) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002961 // Verify output.
2962 ASSERT(*length_out == static_cast<unsigned>(string->length()));
2963 ASSERT(*type_out == string->map()->instance_type());
2964 return string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002965 }
2966 // Traversal complete.
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002967 if (!blew_stack) return NULL;
2968 // Restart search from root.
2969 unsigned offset_out;
2970 string = Search(&offset_out, type_out, length_out);
2971 // Verify output.
2972 ASSERT(string == NULL || offset_out == 0);
2973 ASSERT(string == NULL ||
2974 *length_out == static_cast<unsigned>(string->length()));
2975 ASSERT(string == NULL || *type_out == string->map()->instance_type());
2976 return string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002977}
2978
2979
2980uint16_t StringCharacterStream::GetNext() {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002981 ASSERT(buffer8_ != NULL && end_ != NULL);
2982 // Advance cursor if needed.
2983 // TODO(dcarney): Ensure uses of the api call HasMore first and avoid this.
2984 if (buffer8_ == end_) HasMore();
2985 ASSERT(buffer8_ < end_);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002986 return is_one_byte_ ? *buffer8_++ : *buffer16_++;
2987}
2988
2989
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002990StringCharacterStream::StringCharacterStream(String* string,
2991 ConsStringIteratorOp* op,
2992 unsigned offset)
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002993 : is_one_byte_(false),
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002994 op_(op) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002995 Reset(string, offset);
2996}
2997
2998
2999void StringCharacterStream::Reset(String* string, unsigned offset) {
3000 op_->Reset();
3001 buffer8_ = NULL;
3002 end_ = NULL;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003003 int32_t type = string->map()->instance_type();
3004 unsigned length = string->length();
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00003005 String::Visit(string, offset, *this, *op_, type, length);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00003006}
3007
3008
3009bool StringCharacterStream::HasMore() {
3010 if (buffer8_ != end_) return true;
3011 if (!op_->HasMore()) return false;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003012 unsigned length;
3013 int32_t type;
3014 String* string = op_->ContinueOperation(&type, &length);
3015 if (string == NULL) return false;
3016 ASSERT(!string->IsConsString());
3017 ASSERT(string->length() != 0);
3018 ConsStringNullOp null_op;
3019 String::Visit(string, 0, *this, null_op, type, length);
3020 ASSERT(buffer8_ != end_);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00003021 return true;
3022}
3023
3024
3025void StringCharacterStream::VisitOneByteString(
3026 const uint8_t* chars, unsigned length) {
3027 is_one_byte_ = true;
3028 buffer8_ = chars;
3029 end_ = chars + length;
3030}
3031
3032
3033void StringCharacterStream::VisitTwoByteString(
3034 const uint16_t* chars, unsigned length) {
3035 is_one_byte_ = false;
3036 buffer16_ = chars;
3037 end_ = reinterpret_cast<const uint8_t*>(chars + length);
3038}
3039
3040
ager@chromium.orgac091b72010-05-05 07:34:42 +00003041void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003042 set_finger_index(kEntriesIndex);
3043 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00003044}
3045
3046
3047void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003048 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00003049 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00003050 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003051 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00003052 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00003053 MakeZeroSize();
3054}
3055
3056
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003057int JSFunctionResultCache::size() {
3058 return Smi::cast(get(kCacheSizeIndex))->value();
3059}
3060
3061
3062void JSFunctionResultCache::set_size(int size) {
3063 set(kCacheSizeIndex, Smi::FromInt(size));
3064}
3065
3066
3067int JSFunctionResultCache::finger_index() {
3068 return Smi::cast(get(kFingerIndex))->value();
3069}
3070
3071
3072void JSFunctionResultCache::set_finger_index(int finger_index) {
3073 set(kFingerIndex, Smi::FromInt(finger_index));
3074}
3075
3076
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003077byte ByteArray::get(int index) {
3078 ASSERT(index >= 0 && index < this->length());
3079 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
3080}
3081
3082
3083void ByteArray::set(int index, byte value) {
3084 ASSERT(index >= 0 && index < this->length());
3085 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
3086}
3087
3088
3089int ByteArray::get_int(int index) {
3090 ASSERT(index >= 0 && (index * kIntSize) < this->length());
3091 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
3092}
3093
3094
3095ByteArray* ByteArray::FromDataStartAddress(Address address) {
3096 ASSERT_TAG_ALIGNED(address);
3097 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
3098}
3099
3100
3101Address ByteArray::GetDataStartAddress() {
3102 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
3103}
3104
3105
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003106uint8_t* ExternalPixelArray::external_pixel_pointer() {
3107 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003108}
3109
3110
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003111uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003112 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003113 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003114 return ptr[index];
3115}
3116
3117
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003118MaybeObject* ExternalPixelArray::get(int index) {
3119 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3120}
3121
3122
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003123void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003124 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003125 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003126 ptr[index] = value;
3127}
3128
3129
ager@chromium.org3811b432009-10-28 14:53:37 +00003130void* ExternalArray::external_pointer() {
3131 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
3132 return reinterpret_cast<void*>(ptr);
3133}
3134
3135
3136void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
3137 intptr_t ptr = reinterpret_cast<intptr_t>(value);
3138 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
3139}
3140
3141
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003142int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003143 ASSERT((index >= 0) && (index < this->length()));
3144 int8_t* ptr = static_cast<int8_t*>(external_pointer());
3145 return ptr[index];
3146}
3147
3148
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003149MaybeObject* ExternalByteArray::get(int index) {
3150 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3151}
3152
3153
ager@chromium.org3811b432009-10-28 14:53:37 +00003154void ExternalByteArray::set(int index, int8_t value) {
3155 ASSERT((index >= 0) && (index < this->length()));
3156 int8_t* ptr = static_cast<int8_t*>(external_pointer());
3157 ptr[index] = value;
3158}
3159
3160
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003161uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003162 ASSERT((index >= 0) && (index < this->length()));
3163 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
3164 return ptr[index];
3165}
3166
3167
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003168MaybeObject* ExternalUnsignedByteArray::get(int index) {
3169 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3170}
3171
3172
ager@chromium.org3811b432009-10-28 14:53:37 +00003173void ExternalUnsignedByteArray::set(int index, uint8_t value) {
3174 ASSERT((index >= 0) && (index < this->length()));
3175 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
3176 ptr[index] = value;
3177}
3178
3179
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003180int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003181 ASSERT((index >= 0) && (index < this->length()));
3182 int16_t* ptr = static_cast<int16_t*>(external_pointer());
3183 return ptr[index];
3184}
3185
3186
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003187MaybeObject* ExternalShortArray::get(int index) {
3188 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3189}
3190
3191
ager@chromium.org3811b432009-10-28 14:53:37 +00003192void ExternalShortArray::set(int index, int16_t value) {
3193 ASSERT((index >= 0) && (index < this->length()));
3194 int16_t* ptr = static_cast<int16_t*>(external_pointer());
3195 ptr[index] = value;
3196}
3197
3198
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003199uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003200 ASSERT((index >= 0) && (index < this->length()));
3201 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
3202 return ptr[index];
3203}
3204
3205
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003206MaybeObject* ExternalUnsignedShortArray::get(int index) {
3207 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3208}
3209
3210
ager@chromium.org3811b432009-10-28 14:53:37 +00003211void ExternalUnsignedShortArray::set(int index, uint16_t value) {
3212 ASSERT((index >= 0) && (index < this->length()));
3213 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
3214 ptr[index] = value;
3215}
3216
3217
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003218int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003219 ASSERT((index >= 0) && (index < this->length()));
3220 int32_t* ptr = static_cast<int32_t*>(external_pointer());
3221 return ptr[index];
3222}
3223
3224
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003225MaybeObject* ExternalIntArray::get(int index) {
3226 return GetHeap()->NumberFromInt32(get_scalar(index));
3227}
3228
3229
ager@chromium.org3811b432009-10-28 14:53:37 +00003230void ExternalIntArray::set(int index, int32_t value) {
3231 ASSERT((index >= 0) && (index < this->length()));
3232 int32_t* ptr = static_cast<int32_t*>(external_pointer());
3233 ptr[index] = value;
3234}
3235
3236
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003237uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003238 ASSERT((index >= 0) && (index < this->length()));
3239 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
3240 return ptr[index];
3241}
3242
3243
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003244MaybeObject* ExternalUnsignedIntArray::get(int index) {
3245 return GetHeap()->NumberFromUint32(get_scalar(index));
3246}
3247
3248
ager@chromium.org3811b432009-10-28 14:53:37 +00003249void ExternalUnsignedIntArray::set(int index, uint32_t value) {
3250 ASSERT((index >= 0) && (index < this->length()));
3251 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
3252 ptr[index] = value;
3253}
3254
3255
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003256float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003257 ASSERT((index >= 0) && (index < this->length()));
3258 float* ptr = static_cast<float*>(external_pointer());
3259 return ptr[index];
3260}
3261
3262
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003263MaybeObject* ExternalFloatArray::get(int index) {
3264 return GetHeap()->NumberFromDouble(get_scalar(index));
3265}
3266
3267
ager@chromium.org3811b432009-10-28 14:53:37 +00003268void ExternalFloatArray::set(int index, float value) {
3269 ASSERT((index >= 0) && (index < this->length()));
3270 float* ptr = static_cast<float*>(external_pointer());
3271 ptr[index] = value;
3272}
3273
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00003274
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003275double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003276 ASSERT((index >= 0) && (index < this->length()));
3277 double* ptr = static_cast<double*>(external_pointer());
3278 return ptr[index];
3279}
3280
3281
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003282MaybeObject* ExternalDoubleArray::get(int index) {
3283 return GetHeap()->NumberFromDouble(get_scalar(index));
3284}
3285
3286
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003287void ExternalDoubleArray::set(int index, double value) {
3288 ASSERT((index >= 0) && (index < this->length()));
3289 double* ptr = static_cast<double*>(external_pointer());
3290 ptr[index] = value;
3291}
3292
3293
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00003294int Map::visitor_id() {
3295 return READ_BYTE_FIELD(this, kVisitorIdOffset);
3296}
3297
3298
3299void Map::set_visitor_id(int id) {
3300 ASSERT(0 <= id && id < 256);
3301 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
3302}
3303
ager@chromium.org3811b432009-10-28 14:53:37 +00003304
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003305int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00003306 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
3307}
3308
3309
3310int Map::inobject_properties() {
3311 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003312}
3313
3314
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003315int Map::pre_allocated_property_fields() {
3316 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
3317}
3318
3319
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003320int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003321 int instance_size = map->instance_size();
3322 if (instance_size != kVariableSizeSentinel) return instance_size;
ulan@chromium.org750145a2013-03-07 15:14:13 +00003323 // We can ignore the "internalized" bit because it is only set for strings
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00003324 // and thus implies a string type.
3325 int instance_type =
3326 static_cast<int>(map->instance_type()) & ~kIsInternalizedMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003327 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003328 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003329 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003330 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003331 if (instance_type == ASCII_STRING_TYPE) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003332 return SeqOneByteString::SizeFor(
3333 reinterpret_cast<SeqOneByteString*>(this)->length());
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003334 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003335 if (instance_type == BYTE_ARRAY_TYPE) {
3336 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
3337 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003338 if (instance_type == FREE_SPACE_TYPE) {
3339 return reinterpret_cast<FreeSpace*>(this)->size();
3340 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003341 if (instance_type == STRING_TYPE) {
3342 return SeqTwoByteString::SizeFor(
3343 reinterpret_cast<SeqTwoByteString*>(this)->length());
3344 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003345 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
3346 return FixedDoubleArray::SizeFor(
3347 reinterpret_cast<FixedDoubleArray*>(this)->length());
3348 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003349 ASSERT(instance_type == CODE_TYPE);
3350 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003351}
3352
3353
3354void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003355 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003356 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003357 ASSERT(0 <= value && value < 256);
3358 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
3359}
3360
3361
ager@chromium.org7c537e22008-10-16 08:43:32 +00003362void Map::set_inobject_properties(int value) {
3363 ASSERT(0 <= value && value < 256);
3364 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
3365}
3366
3367
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003368void Map::set_pre_allocated_property_fields(int value) {
3369 ASSERT(0 <= value && value < 256);
3370 WRITE_BYTE_FIELD(this,
3371 kPreAllocatedPropertyFieldsOffset,
3372 static_cast<byte>(value));
3373}
3374
3375
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003376InstanceType Map::instance_type() {
3377 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
3378}
3379
3380
3381void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003382 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
3383}
3384
3385
3386int Map::unused_property_fields() {
3387 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
3388}
3389
3390
3391void Map::set_unused_property_fields(int value) {
3392 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
3393}
3394
3395
3396byte Map::bit_field() {
3397 return READ_BYTE_FIELD(this, kBitFieldOffset);
3398}
3399
3400
3401void Map::set_bit_field(byte value) {
3402 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
3403}
3404
3405
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00003406byte Map::bit_field2() {
3407 return READ_BYTE_FIELD(this, kBitField2Offset);
3408}
3409
3410
3411void Map::set_bit_field2(byte value) {
3412 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
3413}
3414
3415
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003416void Map::set_non_instance_prototype(bool value) {
3417 if (value) {
3418 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
3419 } else {
3420 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
3421 }
3422}
3423
3424
3425bool Map::has_non_instance_prototype() {
3426 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
3427}
3428
3429
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003430void Map::set_function_with_prototype(bool value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003431 set_bit_field3(FunctionWithPrototype::update(bit_field3(), value));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003432}
3433
3434
3435bool Map::function_with_prototype() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003436 return FunctionWithPrototype::decode(bit_field3());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003437}
3438
3439
ager@chromium.org870a0b62008-11-04 11:43:05 +00003440void Map::set_is_access_check_needed(bool access_check_needed) {
3441 if (access_check_needed) {
3442 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
3443 } else {
3444 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
3445 }
3446}
3447
3448
3449bool Map::is_access_check_needed() {
3450 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
3451}
3452
3453
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003454void Map::set_is_extensible(bool value) {
3455 if (value) {
3456 set_bit_field2(bit_field2() | (1 << kIsExtensible));
3457 } else {
3458 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
3459 }
3460}
3461
3462bool Map::is_extensible() {
3463 return ((1 << kIsExtensible) & bit_field2()) != 0;
3464}
3465
3466
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003467void Map::set_attached_to_shared_function_info(bool value) {
3468 if (value) {
3469 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
3470 } else {
3471 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
3472 }
3473}
3474
3475bool Map::attached_to_shared_function_info() {
3476 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
3477}
3478
3479
3480void Map::set_is_shared(bool value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003481 set_bit_field3(IsShared::update(bit_field3(), value));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003482}
3483
erik.corry@gmail.com88767242012-08-08 14:43:45 +00003484
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003485bool Map::is_shared() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003486 return IsShared::decode(bit_field3());
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003487}
3488
3489
erik.corry@gmail.com88767242012-08-08 14:43:45 +00003490void Map::set_dictionary_map(bool value) {
3491 set_bit_field3(DictionaryMap::update(bit_field3(), value));
3492}
3493
3494
3495bool Map::is_dictionary_map() {
3496 return DictionaryMap::decode(bit_field3());
3497}
3498
3499
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003500JSFunction* Map::unchecked_constructor() {
3501 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
3502}
3503
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003504
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003505Code::Flags Code::flags() {
3506 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
3507}
3508
3509
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00003510inline bool Map::CanTrackAllocationSite() {
3511 return instance_type() == JS_ARRAY_TYPE;
3512}
3513
3514
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00003515void Map::set_owns_descriptors(bool is_shared) {
3516 set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
3517}
3518
3519
3520bool Map::owns_descriptors() {
3521 return OwnsDescriptors::decode(bit_field3());
3522}
3523
3524
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00003525void Map::set_is_observed(bool is_observed) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003526 ASSERT(instance_type() < FIRST_JS_OBJECT_TYPE ||
3527 instance_type() > LAST_JS_OBJECT_TYPE ||
3528 has_slow_elements_kind() || has_external_array_elements());
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00003529 set_bit_field3(IsObserved::update(bit_field3(), is_observed));
3530}
3531
3532
3533bool Map::is_observed() {
3534 return IsObserved::decode(bit_field3());
3535}
3536
3537
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003538void Map::NotifyLeafMapLayoutChange() {
3539 dependent_code()->DeoptimizeDependentCodeGroup(
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003540 GetIsolate(),
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003541 DependentCode::kPrototypeCheckGroup);
3542}
3543
3544
3545bool Map::CanOmitPrototypeChecks() {
3546 return !HasTransitionArray() && !is_dictionary_map() &&
3547 FLAG_omit_prototype_checks_for_leaf_maps;
3548}
3549
3550
3551void Map::AddDependentCode(DependentCode::DependencyGroup group,
3552 Handle<Code> code) {
3553 Handle<DependentCode> codes =
3554 DependentCode::Insert(Handle<DependentCode>(dependent_code()),
3555 group, code);
3556 if (*codes != dependent_code()) {
3557 set_dependent_code(*codes);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003558 }
3559}
3560
3561
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003562int DependentCode::number_of_entries(DependencyGroup group) {
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003563 if (length() == 0) return 0;
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003564 return Smi::cast(get(group))->value();
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003565}
3566
3567
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003568void DependentCode::set_number_of_entries(DependencyGroup group, int value) {
3569 set(group, Smi::FromInt(value));
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003570}
3571
3572
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003573Code* DependentCode::code_at(int i) {
3574 return Code::cast(get(kCodesStartIndex + i));
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003575}
3576
3577
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003578void DependentCode::set_code_at(int i, Code* value) {
3579 set(kCodesStartIndex + i, value);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003580}
3581
3582
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003583Object** DependentCode::code_slot_at(int i) {
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003584 return HeapObject::RawField(
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003585 this, FixedArray::OffsetOfElementAt(kCodesStartIndex + i));
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003586}
3587
3588
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003589void DependentCode::clear_code_at(int i) {
3590 set_undefined(kCodesStartIndex + i);
3591}
3592
3593
3594void DependentCode::ExtendGroup(DependencyGroup group) {
3595 GroupStartIndexes starts(this);
3596 for (int g = kGroupCount - 1; g > group; g--) {
3597 if (starts.at(g) < starts.at(g + 1)) {
3598 set_code_at(starts.at(g + 1), code_at(starts.at(g)));
3599 }
3600 }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003601}
3602
3603
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003604void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003605 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003606 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003607 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
3608 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003609 ExtractArgumentsCountFromFlags(flags) >= 0);
3610 WRITE_INT_FIELD(this, kFlagsOffset, flags);
3611}
3612
3613
3614Code::Kind Code::kind() {
3615 return ExtractKindFromFlags(flags());
3616}
3617
3618
kasper.lund7276f142008-07-30 08:49:36 +00003619InlineCacheState Code::ic_state() {
3620 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003621 // Only allow uninitialized or debugger states for non-IC code
3622 // objects. This is used in the debugger to determine whether or not
3623 // a call to code object has been replaced with a debug break call.
3624 ASSERT(is_inline_cache_stub() ||
3625 result == UNINITIALIZED ||
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003626 result == DEBUG_STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003627 return result;
3628}
3629
3630
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003631Code::ExtraICState Code::extra_ic_state() {
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003632 ASSERT(is_inline_cache_stub() || ic_state() == DEBUG_STUB);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003633 return ExtractExtraICStateFromFlags(flags());
3634}
3635
3636
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003637Code::StubType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003638 return ExtractTypeFromFlags(flags());
3639}
3640
3641
3642int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003643 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003644 return ExtractArgumentsCountFromFlags(flags());
3645}
3646
3647
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00003648inline bool Code::is_crankshafted() {
3649 return IsCrankshaftedField::decode(
3650 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
3651}
3652
3653
3654inline void Code::set_is_crankshafted(bool value) {
3655 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3656 int updated = IsCrankshaftedField::update(previous, value);
3657 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
3658}
3659
3660
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003661int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003662 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003663 kind() == UNARY_OP_IC ||
3664 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003665 kind() == COMPARE_IC ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00003666 kind() == LOAD_IC ||
3667 kind() == KEYED_LOAD_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003668 kind() == TO_BOOLEAN_IC);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003669 return StubMajorKeyField::decode(
3670 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasper.lund7276f142008-07-30 08:49:36 +00003671}
3672
3673
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003674void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003675 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003676 kind() == UNARY_OP_IC ||
3677 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003678 kind() == COMPARE_IC ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00003679 kind() == LOAD_IC ||
3680 kind() == KEYED_LOAD_IC ||
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00003681 kind() == STORE_IC ||
3682 kind() == KEYED_STORE_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003683 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003684 ASSERT(0 <= major && major < 256);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003685 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3686 int updated = StubMajorKeyField::update(previous, major);
3687 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003688}
3689
3690
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003691bool Code::is_pregenerated() {
3692 return kind() == STUB && IsPregeneratedField::decode(flags());
3693}
3694
3695
3696void Code::set_is_pregenerated(bool value) {
3697 ASSERT(kind() == STUB);
3698 Flags f = flags();
3699 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3700 set_flags(f);
3701}
3702
3703
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003704bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003705 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003706 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3707}
3708
3709
3710void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003711 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003712 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3713}
3714
3715
3716bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003717 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003718 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3719 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003720}
3721
3722
3723void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003724 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003725 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3726 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3727 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3728}
3729
3730
3731bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003732 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003733 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3734 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3735}
3736
3737
3738void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003739 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003740 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3741 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3742 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003743}
3744
3745
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003746bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003747 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003748 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3749 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3750}
3751
3752
3753void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003754 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003755 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3756 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3757 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3758}
3759
3760
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003761int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003762 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003763 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3764}
3765
3766
3767void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003768 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003769 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3770 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3771}
3772
3773
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003774int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003775 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003776 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3777}
3778
3779
3780void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003781 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003782 ASSERT(ticks < 256);
3783 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3784}
3785
3786
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003787unsigned Code::stack_slots() {
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00003788 ASSERT(is_crankshafted());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003789 return StackSlotsField::decode(
3790 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003791}
3792
3793
3794void Code::set_stack_slots(unsigned slots) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003795 CHECK(slots <= (1 << kStackSlotsBitCount));
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00003796 ASSERT(is_crankshafted());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003797 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3798 int updated = StackSlotsField::update(previous, slots);
3799 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003800}
3801
3802
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003803unsigned Code::safepoint_table_offset() {
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00003804 ASSERT(is_crankshafted());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003805 return SafepointTableOffsetField::decode(
3806 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003807}
3808
3809
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003810void Code::set_safepoint_table_offset(unsigned offset) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003811 CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00003812 ASSERT(is_crankshafted());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003813 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003814 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3815 int updated = SafepointTableOffsetField::update(previous, offset);
3816 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003817}
3818
3819
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003820unsigned Code::back_edge_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003821 ASSERT_EQ(FUNCTION, kind());
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003822 return BackEdgeTableOffsetField::decode(
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003823 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003824}
3825
3826
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003827void Code::set_back_edge_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003828 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003829 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003830 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003831 int updated = BackEdgeTableOffsetField::update(previous, offset);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003832 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003833}
3834
3835
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003836bool Code::back_edges_patched_for_osr() {
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00003837 ASSERT_EQ(FUNCTION, kind());
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003838 return BackEdgesPatchedForOSRField::decode(
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00003839 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
3840}
3841
3842
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003843void Code::set_back_edges_patched_for_osr(bool value) {
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00003844 ASSERT_EQ(FUNCTION, kind());
3845 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003846 int updated = BackEdgesPatchedForOSRField::update(previous, value);
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00003847 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
3848}
3849
3850
3851
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003852CheckType Code::check_type() {
3853 ASSERT(is_call_stub() || is_keyed_call_stub());
3854 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3855 return static_cast<CheckType>(type);
3856}
3857
3858
3859void Code::set_check_type(CheckType value) {
3860 ASSERT(is_call_stub() || is_keyed_call_stub());
3861 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3862}
3863
3864
danno@chromium.org40cb8782011-05-25 07:58:50 +00003865byte Code::unary_op_type() {
3866 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003867 return UnaryOpTypeField::decode(
3868 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003869}
3870
3871
danno@chromium.org40cb8782011-05-25 07:58:50 +00003872void Code::set_unary_op_type(byte value) {
3873 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003874 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3875 int updated = UnaryOpTypeField::update(previous, value);
3876 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003877}
3878
3879
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003880byte Code::to_boolean_state() {
3881 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003882 return ToBooleanStateField::decode(
3883 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003884}
3885
3886
3887void Code::set_to_boolean_state(byte value) {
3888 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003889 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3890 int updated = ToBooleanStateField::update(previous, value);
3891 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003892}
3893
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003894
3895bool Code::has_function_cache() {
3896 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003897 return HasFunctionCacheField::decode(
3898 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003899}
3900
3901
3902void Code::set_has_function_cache(bool flag) {
3903 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003904 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3905 int updated = HasFunctionCacheField::update(previous, flag);
3906 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003907}
3908
3909
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003910bool Code::marked_for_deoptimization() {
3911 ASSERT(kind() == OPTIMIZED_FUNCTION);
3912 return MarkedForDeoptimizationField::decode(
3913 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
3914}
3915
3916
3917void Code::set_marked_for_deoptimization(bool flag) {
3918 ASSERT(kind() == OPTIMIZED_FUNCTION);
3919 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3920 int updated = MarkedForDeoptimizationField::update(previous, flag);
3921 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
3922}
3923
3924
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003925bool Code::is_inline_cache_stub() {
3926 Kind kind = this->kind();
3927 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3928}
3929
3930
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003931bool Code::is_debug_break() {
3932 return ic_state() == DEBUG_STUB && extra_ic_state() == DEBUG_BREAK;
3933}
3934
3935
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003936Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003937 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003938 ExtraICState extra_ic_state,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003939 StubType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003940 int argc,
3941 InlineCacheHolderFlag holder) {
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003942 ASSERT(argc <= Code::kMaxArguments);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003943 // Compute the bit mask.
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003944 unsigned int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003945 | ICStateField::encode(ic_state)
3946 | TypeField::encode(type)
3947 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003948 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003949 | CacheHolderField::encode(holder);
3950 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003951}
3952
3953
3954Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003955 ExtraICState extra_ic_state,
hpayer@chromium.org8432c912013-02-28 15:55:26 +00003956 StubType type,
3957 int argc,
3958 InlineCacheHolderFlag holder) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003959 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003960}
3961
3962
3963Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003964 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003965}
3966
3967
kasper.lund7276f142008-07-30 08:49:36 +00003968InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003969 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003970}
3971
3972
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003973Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003974 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003975}
3976
3977
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003978Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003979 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003980}
3981
3982
3983int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003984 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003985}
3986
3987
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003988InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003989 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003990}
3991
3992
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003993Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003994 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003995 return static_cast<Flags>(bits);
3996}
3997
3998
ager@chromium.org8bb60582008-12-11 12:02:20 +00003999Code* Code::GetCodeFromTargetAddress(Address address) {
4000 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
4001 // GetCodeFromTargetAddress might be called when marking objects during mark
4002 // sweep. reinterpret_cast is therefore used instead of the more appropriate
4003 // Code::cast. Code::cast does not work when the object's map is
4004 // marked.
4005 Code* result = reinterpret_cast<Code*>(code);
4006 return result;
4007}
4008
4009
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004010Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
4011 return HeapObject::
4012 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
4013}
4014
4015
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004016Object* Map::prototype() {
4017 return READ_FIELD(this, kPrototypeOffset);
4018}
4019
4020
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004021void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004022 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004023 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004024 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00004025}
4026
4027
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004028// If the descriptor is using the empty transition array, install a new empty
4029// transition array that will have place for an element transition.
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004030static MaybeObject* EnsureHasTransitionArray(Map* map) {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004031 TransitionArray* transitions;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004032 MaybeObject* maybe_transitions;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004033 if (!map->HasTransitionArray()) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004034 maybe_transitions = TransitionArray::Allocate(0);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004035 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
4036 transitions->set_back_pointer_storage(map->GetBackPointer());
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004037 } else if (!map->transitions()->IsFullTransitionArray()) {
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004038 maybe_transitions = map->transitions()->ExtendToFullTransitionArray();
4039 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
4040 } else {
4041 return map;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004042 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004043 map->set_transitions(transitions);
4044 return transitions;
4045}
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004046
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004047
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004048void Map::InitializeDescriptors(DescriptorArray* descriptors) {
verwaest@chromium.org652f4fa2012-10-08 08:48:51 +00004049 int len = descriptors->number_of_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00004050#ifdef DEBUG
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004051 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004052
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004053 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors];
4054 for (int i = 0; i < len; ++i) used_indices[i] = false;
4055
4056 // Ensure that all enumeration indexes between 1 and length occur uniquely in
4057 // the descriptor array.
4058 for (int i = 0; i < len; ++i) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004059 int enum_index = descriptors->GetDetails(i).descriptor_index() -
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004060 PropertyDetails::kInitialIndex;
4061 ASSERT(0 <= enum_index && enum_index < len);
4062 ASSERT(!used_indices[enum_index]);
4063 used_indices[enum_index] = true;
4064 }
4065#endif
4066
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004067 set_instance_descriptors(descriptors);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00004068 SetNumberOfOwnDescriptors(len);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004069}
4070
4071
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004072ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004073SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)
danno@chromium.org40cb8782011-05-25 07:58:50 +00004074
4075
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004076void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004077 Object* back_pointer = GetBackPointer();
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00004078
4079 if (Heap::ShouldZapGarbage() && HasTransitionArray()) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004080 ZapTransitions();
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00004081 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00004082
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004083 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004084 CONDITIONAL_WRITE_BARRIER(
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004085 heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode);
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00004086}
4087
4088
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004089void Map::AppendDescriptor(Descriptor* desc,
4090 const DescriptorArray::WhitenessWitness& witness) {
4091 DescriptorArray* descriptors = instance_descriptors();
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004092 int number_of_own_descriptors = NumberOfOwnDescriptors();
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004093 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
4094 descriptors->Append(desc, witness);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004095 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004096}
4097
danno@chromium.org40cb8782011-05-25 07:58:50 +00004098
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004099Object* Map::GetBackPointer() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004100 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004101 if (object->IsDescriptorArray()) {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004102 return TransitionArray::cast(object)->back_pointer_storage();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004103 } else {
4104 ASSERT(object->IsMap() || object->IsUndefined());
4105 return object;
4106 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004107}
4108
4109
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004110bool Map::HasElementsTransition() {
4111 return HasTransitionArray() && transitions()->HasElementsTransition();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004112}
4113
4114
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004115bool Map::HasTransitionArray() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004116 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4117 return object->IsTransitionArray();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004118}
4119
4120
4121Map* Map::elements_transition_map() {
4122 return transitions()->elements_transition();
4123}
4124
4125
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +00004126bool Map::CanHaveMoreTransitions() {
4127 if (!HasTransitionArray()) return true;
4128 return FixedArray::SizeFor(transitions()->length() +
4129 TransitionArray::kTransitionSize)
4130 <= Page::kMaxNonCodeHeapObjectSize;
4131}
4132
4133
ulan@chromium.org750145a2013-03-07 15:14:13 +00004134MaybeObject* Map::AddTransition(Name* key,
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004135 Map* target,
4136 SimpleTransitionFlag flag) {
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004137 if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004138 return TransitionArray::NewWith(flag, key, target, GetBackPointer());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004139}
4140
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004141
4142void Map::SetTransition(int transition_index, Map* target) {
4143 transitions()->SetTarget(transition_index, target);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00004144}
4145
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004146
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00004147Map* Map::GetTransition(int transition_index) {
4148 return transitions()->GetTarget(transition_index);
4149}
4150
4151
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004152MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004153 MaybeObject* allow_elements = EnsureHasTransitionArray(this);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004154 if (allow_elements->IsFailure()) return allow_elements;
4155 transitions()->set_elements_transition(transitioned_map);
4156 return this;
4157}
4158
4159
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004160FixedArray* Map::GetPrototypeTransitions() {
4161 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
4162 if (!transitions()->HasPrototypeTransitions()) {
4163 return GetHeap()->empty_fixed_array();
4164 }
4165 return transitions()->GetPrototypeTransitions();
4166}
4167
4168
4169MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004170 MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004171 if (allow_prototype->IsFailure()) return allow_prototype;
4172#ifdef DEBUG
4173 if (HasPrototypeTransitions()) {
4174 ASSERT(GetPrototypeTransitions() != proto_transitions);
4175 ZapPrototypeTransitions();
4176 }
4177#endif
4178 transitions()->SetPrototypeTransitions(proto_transitions);
4179 return this;
4180}
4181
4182
4183bool Map::HasPrototypeTransitions() {
4184 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
4185}
4186
4187
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004188TransitionArray* Map::transitions() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004189 ASSERT(HasTransitionArray());
4190 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4191 return TransitionArray::cast(object);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004192}
4193
4194
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004195void Map::set_transitions(TransitionArray* transition_array,
4196 WriteBarrierMode mode) {
jkummerow@chromium.org91efda92013-03-25 16:32:26 +00004197 // Transition arrays are not shared. When one is replaced, it should not
4198 // keep referenced objects alive, so we zap it.
4199 // When there is another reference to the array somewhere (e.g. a handle),
4200 // not zapping turns from a waste of memory into a source of crashes.
4201 if (HasTransitionArray()) {
4202 ASSERT(transitions() != transition_array);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004203 ZapTransitions();
4204 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004205
4206 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array);
4207 CONDITIONAL_WRITE_BARRIER(
4208 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004209}
4210
4211
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004212void Map::init_back_pointer(Object* undefined) {
4213 ASSERT(undefined->IsUndefined());
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004214 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, undefined);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004215}
4216
4217
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004218void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004219 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
4220 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
4221 (value->IsMap() && GetBackPointer()->IsUndefined()));
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004222 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4223 if (object->IsTransitionArray()) {
4224 TransitionArray::cast(object)->set_back_pointer_storage(value);
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004225 } else {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004226 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, value);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004227 CONDITIONAL_WRITE_BARRIER(
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004228 GetHeap(), this, kTransitionsOrBackPointerOffset, value, mode);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004229 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004230}
4231
4232
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004233// Can either be Smi (no transitions), normal transition array, or a transition
4234// array with the header overwritten as a Smi (thus iterating).
4235TransitionArray* Map::unchecked_transition_array() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004236 Object* object = *HeapObject::RawField(this,
4237 Map::kTransitionsOrBackPointerOffset);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004238 TransitionArray* transition_array = static_cast<TransitionArray*>(object);
4239 return transition_array;
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004240}
4241
4242
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004243HeapObject* Map::UncheckedPrototypeTransitions() {
4244 ASSERT(HasTransitionArray());
4245 ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
4246 return unchecked_transition_array()->UncheckedPrototypeTransitions();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004247}
4248
4249
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004250ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004251ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004252ACCESSORS(Map, constructor, Object, kConstructorOffset)
4253
4254ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004255ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004256ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004257
4258ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004259ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset)
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00004260ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004261ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004262
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004263ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004264
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004265ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004266ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004267ACCESSORS(AccessorInfo, expected_receiver_type, Object,
4268 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004269
ulan@chromium.org750145a2013-03-07 15:14:13 +00004270ACCESSORS(DeclaredAccessorDescriptor, serialized_data, ByteArray,
4271 kSerializedDataOffset)
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004272
4273ACCESSORS(DeclaredAccessorInfo, descriptor, DeclaredAccessorDescriptor,
4274 kDescriptorOffset)
4275
4276ACCESSORS(ExecutableAccessorInfo, getter, Object, kGetterOffset)
4277ACCESSORS(ExecutableAccessorInfo, setter, Object, kSetterOffset)
4278ACCESSORS(ExecutableAccessorInfo, data, Object, kDataOffset)
4279
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004280ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
4281ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
4282
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004283ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
4284ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
4285ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
4286
4287ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
4288ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
4289ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
4290ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
4291ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
4292ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
4293
4294ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
4295ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
4296
4297ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
4298ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
4299
4300ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
4301ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004302ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
4303 kPropertyAccessorsOffset)
4304ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
4305 kPrototypeTemplateOffset)
4306ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
4307ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
4308 kNamedPropertyHandlerOffset)
4309ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
4310 kIndexedPropertyHandlerOffset)
4311ACCESSORS(FunctionTemplateInfo, instance_template, Object,
4312 kInstanceTemplateOffset)
4313ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
4314ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004315ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
4316 kInstanceCallHandlerOffset)
4317ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
4318 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004319ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004320
4321ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00004322ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
4323 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004324
4325ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
4326ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
4327
4328ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
4329
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00004330ACCESSORS(AllocationSiteInfo, payload, Object, kPayloadOffset)
4331
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004332ACCESSORS(Script, source, Object, kSourceOffset)
4333ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004334ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004335ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
4336ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004337ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00004338ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004339ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004340ACCESSORS_TO_SMI(Script, type, kTypeOffset)
4341ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
4342ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00004343ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00004344ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004345ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
4346 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004347
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004348#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004349ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
4350ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
4351ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
4352ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
4353
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004354ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
4355ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
4356ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004357ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004358#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004359
4360ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004361ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
4362 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004363ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
4364ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004365ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
4366 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004367ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004368ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
4369ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00004370ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004371ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
4372 kThisPropertyAssignmentsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004373SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004374
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00004375
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00004376SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004377BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
4378 kHiddenPrototypeBit)
4379BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
4380BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
4381 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00004382BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
4383 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004384BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
4385 kIsExpressionBit)
4386BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
4387 kIsTopLevelBit)
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00004388
whesse@chromium.org7b260152011-06-20 15:33:18 +00004389BOOL_GETTER(SharedFunctionInfo,
4390 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004391 has_only_simple_this_property_assignments,
4392 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004393BOOL_ACCESSORS(SharedFunctionInfo,
4394 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00004395 allows_lazy_compilation,
4396 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004397BOOL_ACCESSORS(SharedFunctionInfo,
4398 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004399 allows_lazy_compilation_without_context,
4400 kAllowLazyCompilationWithoutContext)
4401BOOL_ACCESSORS(SharedFunctionInfo,
4402 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00004403 uses_arguments,
4404 kUsesArguments)
4405BOOL_ACCESSORS(SharedFunctionInfo,
4406 compiler_hints,
4407 has_duplicate_parameters,
4408 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004409
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004410
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004411#if V8_HOST_ARCH_32_BIT
4412SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
4413SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004414 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004415SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004416 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004417SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
4418SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004419 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004420SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
4421SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004422 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004423SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004424 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004425SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004426 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004427SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004428SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
4429SMI_ACCESSORS(SharedFunctionInfo,
4430 stress_deopt_counter,
4431 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004432#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004433
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004434#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004435 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004436 int holder::name() { \
4437 int value = READ_INT_FIELD(this, offset); \
4438 ASSERT(kHeapObjectTag == 1); \
4439 ASSERT((value & kHeapObjectTag) == 0); \
4440 return value >> 1; \
4441 } \
4442 void holder::set_##name(int value) { \
4443 ASSERT(kHeapObjectTag == 1); \
4444 ASSERT((value & 0xC0000000) == 0xC0000000 || \
4445 (value & 0xC0000000) == 0x000000000); \
4446 WRITE_INT_FIELD(this, \
4447 offset, \
4448 (value << 1) & ~kHeapObjectTag); \
4449 }
4450
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004451#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
4452 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004453 INT_ACCESSORS(holder, name, offset)
4454
4455
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004456PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004457PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4458 formal_parameter_count,
4459 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004460
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004461PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4462 expected_nof_properties,
4463 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004464PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
4465
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004466PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
4467PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4468 start_position_and_type,
4469 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004470
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004471PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4472 function_token_position,
4473 kFunctionTokenPositionOffset)
4474PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4475 compiler_hints,
4476 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004477
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004478PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4479 this_property_assignments_count,
4480 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004481PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004482
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004483PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
4484PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4485 stress_deopt_counter,
4486 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004487#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004488
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004489
4490int SharedFunctionInfo::construction_count() {
4491 return READ_BYTE_FIELD(this, kConstructionCountOffset);
4492}
4493
4494
4495void SharedFunctionInfo::set_construction_count(int value) {
4496 ASSERT(0 <= value && value < 256);
4497 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
4498}
4499
4500
whesse@chromium.org7b260152011-06-20 15:33:18 +00004501BOOL_ACCESSORS(SharedFunctionInfo,
4502 compiler_hints,
4503 live_objects_may_exist,
4504 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004505
4506
4507bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004508 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004509}
4510
4511
whesse@chromium.org7b260152011-06-20 15:33:18 +00004512BOOL_GETTER(SharedFunctionInfo,
4513 compiler_hints,
4514 optimization_disabled,
4515 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004516
4517
4518void SharedFunctionInfo::set_optimization_disabled(bool disable) {
4519 set_compiler_hints(BooleanBit::set(compiler_hints(),
4520 kOptimizationDisabled,
4521 disable));
4522 // If disabling optimizations we reflect that in the code object so
4523 // it will not be counted as optimizable code.
4524 if ((code()->kind() == Code::FUNCTION) && disable) {
4525 code()->set_optimizable(false);
4526 }
4527}
4528
4529
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004530int SharedFunctionInfo::profiler_ticks() {
4531 if (code()->kind() != Code::FUNCTION) return 0;
4532 return code()->profiler_ticks();
4533}
4534
4535
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004536LanguageMode SharedFunctionInfo::language_mode() {
4537 int hints = compiler_hints();
4538 if (BooleanBit::get(hints, kExtendedModeFunction)) {
4539 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
4540 return EXTENDED_MODE;
4541 }
4542 return BooleanBit::get(hints, kStrictModeFunction)
4543 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004544}
4545
4546
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004547void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
4548 // We only allow language mode transitions that go set the same language mode
4549 // again or go up in the chain:
4550 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
4551 ASSERT(this->language_mode() == CLASSIC_MODE ||
4552 this->language_mode() == language_mode ||
4553 language_mode == EXTENDED_MODE);
4554 int hints = compiler_hints();
4555 hints = BooleanBit::set(
4556 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
4557 hints = BooleanBit::set(
4558 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
4559 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004560}
4561
4562
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004563bool SharedFunctionInfo::is_classic_mode() {
4564 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
4565}
4566
4567BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
4568 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004569BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
4570BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
4571 name_should_print_as_anonymous,
4572 kNameShouldPrintAsAnonymous)
4573BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
4574BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00004575BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
4576BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
4577 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004578BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004579BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00004580BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004581
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004582void SharedFunctionInfo::BeforeVisitingPointers() {
4583 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
mstarzinger@chromium.org0ae265a2012-12-11 17:41:11 +00004584}
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004585
mstarzinger@chromium.org0ae265a2012-12-11 17:41:11 +00004586
4587void SharedFunctionInfo::ClearOptimizedCodeMap() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004588 set_optimized_code_map(Smi::FromInt(0));
4589}
4590
4591
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004592ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
4593ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
4594
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00004595ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
4596
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004597bool Script::HasValidSource() {
4598 Object* src = this->source();
4599 if (!src->IsString()) return true;
4600 String* src_str = String::cast(src);
4601 if (!StringShape(src_str).IsExternal()) return true;
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00004602 if (src_str->IsOneByteRepresentation()) {
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004603 return ExternalAsciiString::cast(src)->resource() != NULL;
4604 } else if (src_str->IsTwoByteRepresentation()) {
4605 return ExternalTwoByteString::cast(src)->resource() != NULL;
4606 }
4607 return true;
4608}
4609
4610
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00004611void SharedFunctionInfo::DontAdaptArguments() {
4612 ASSERT(code()->kind() == Code::BUILTIN);
4613 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
4614}
4615
4616
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004617int SharedFunctionInfo::start_position() {
4618 return start_position_and_type() >> kStartPositionShift;
4619}
4620
4621
4622void SharedFunctionInfo::set_start_position(int start_position) {
4623 set_start_position_and_type((start_position << kStartPositionShift)
4624 | (start_position_and_type() & ~kStartPositionMask));
4625}
4626
4627
4628Code* SharedFunctionInfo::code() {
4629 return Code::cast(READ_FIELD(this, kCodeOffset));
4630}
4631
4632
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004633Code* SharedFunctionInfo::unchecked_code() {
4634 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
4635}
4636
4637
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004638void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004639 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004640 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004641}
4642
4643
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00004644void SharedFunctionInfo::ReplaceCode(Code* value) {
4645 // If the GC metadata field is already used then the function was
4646 // enqueued as a code flushing candidate and we remove it now.
4647 if (code()->gc_metadata() != NULL) {
4648 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
4649 flusher->EvictCandidate(this);
4650 }
4651
4652 ASSERT(code()->gc_metadata() == NULL && value->gc_metadata() == NULL);
4653 set_code(value);
4654}
4655
4656
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004657ScopeInfo* SharedFunctionInfo::scope_info() {
4658 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00004659}
4660
4661
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004662void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00004663 WriteBarrierMode mode) {
4664 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004665 CONDITIONAL_WRITE_BARRIER(GetHeap(),
4666 this,
4667 kScopeInfoOffset,
4668 reinterpret_cast<Object*>(value),
4669 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00004670}
4671
4672
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004673bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004674 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004675 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004676}
4677
4678
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004679bool SharedFunctionInfo::IsApiFunction() {
4680 return function_data()->IsFunctionTemplateInfo();
4681}
4682
4683
4684FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
4685 ASSERT(IsApiFunction());
4686 return FunctionTemplateInfo::cast(function_data());
4687}
4688
4689
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004690bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004691 return function_data()->IsSmi();
4692}
4693
4694
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004695BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4696 ASSERT(HasBuiltinFunctionId());
4697 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004698}
4699
4700
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004701int SharedFunctionInfo::code_age() {
4702 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
4703}
4704
4705
4706void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00004707 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
4708 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004709}
4710
4711
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004712int SharedFunctionInfo::ic_age() {
4713 return ICAgeBits::decode(counters());
4714}
4715
4716
4717void SharedFunctionInfo::set_ic_age(int ic_age) {
4718 set_counters(ICAgeBits::update(counters(), ic_age));
4719}
4720
4721
4722int SharedFunctionInfo::deopt_count() {
4723 return DeoptCountBits::decode(counters());
4724}
4725
4726
4727void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4728 set_counters(DeoptCountBits::update(counters(), deopt_count));
4729}
4730
4731
4732void SharedFunctionInfo::increment_deopt_count() {
4733 int value = counters();
4734 int deopt_count = DeoptCountBits::decode(value);
4735 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4736 set_counters(DeoptCountBits::update(value, deopt_count));
4737}
4738
4739
4740int SharedFunctionInfo::opt_reenable_tries() {
4741 return OptReenableTriesBits::decode(counters());
4742}
4743
4744
4745void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4746 set_counters(OptReenableTriesBits::update(counters(), tries));
4747}
4748
4749
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004750bool SharedFunctionInfo::has_deoptimization_support() {
4751 Code* code = this->code();
4752 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4753}
4754
4755
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004756void SharedFunctionInfo::TryReenableOptimization() {
4757 int tries = opt_reenable_tries();
4758 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4759 // We reenable optimization whenever the number of tries is a large
4760 // enough power of 2.
4761 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4762 set_optimization_disabled(false);
4763 set_opt_count(0);
4764 set_deopt_count(0);
4765 code()->set_optimizable(true);
4766 }
4767}
4768
4769
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004770bool JSFunction::IsBuiltin() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004771 return context()->global_object()->IsJSBuiltinsObject();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004772}
4773
4774
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004775bool JSFunction::NeedsArgumentsAdaption() {
4776 return shared()->formal_parameter_count() !=
4777 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4778}
4779
4780
4781bool JSFunction::IsOptimized() {
4782 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4783}
4784
4785
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004786bool JSFunction::IsOptimizable() {
4787 return code()->kind() == Code::FUNCTION && code()->optimizable();
4788}
4789
4790
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004791bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004792 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004793}
4794
4795
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00004796bool JSFunction::IsMarkedForInstallingRecompiledCode() {
4797 return code() == GetIsolate()->builtins()->builtin(
4798 Builtins::kInstallRecompiledCode);
4799}
4800
4801
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004802bool JSFunction::IsMarkedForParallelRecompilation() {
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00004803 return code() == GetIsolate()->builtins()->builtin(
4804 Builtins::kParallelRecompile);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004805}
4806
4807
4808bool JSFunction::IsInRecompileQueue() {
4809 return code() == GetIsolate()->builtins()->builtin(
4810 Builtins::kInRecompileQueue);
4811}
4812
4813
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004814Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004815 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004816}
4817
4818
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004819Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004820 return reinterpret_cast<Code*>(
4821 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004822}
4823
4824
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004825void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004826 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004827 Address entry = value->entry();
4828 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004829 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4830 this,
4831 HeapObject::RawField(this, kCodeEntryOffset),
4832 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004833}
4834
4835
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00004836void JSFunction::set_code_no_write_barrier(Code* value) {
4837 ASSERT(!HEAP->InNewSpace(value));
4838 Address entry = value->entry();
4839 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
4840}
4841
4842
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004843void JSFunction::ReplaceCode(Code* code) {
4844 bool was_optimized = IsOptimized();
4845 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4846
4847 set_code(code);
4848
4849 // Add/remove the function from the list of optimized functions for this
4850 // context based on the state change.
4851 if (!was_optimized && is_optimized) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004852 context()->native_context()->AddOptimizedFunction(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004853 }
4854 if (was_optimized && !is_optimized) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004855 context()->native_context()->RemoveOptimizedFunction(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004856 }
4857}
4858
4859
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004860Context* JSFunction::context() {
4861 return Context::cast(READ_FIELD(this, kContextOffset));
4862}
4863
4864
4865Object* JSFunction::unchecked_context() {
4866 return READ_FIELD(this, kContextOffset);
4867}
4868
4869
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004870SharedFunctionInfo* JSFunction::unchecked_shared() {
4871 return reinterpret_cast<SharedFunctionInfo*>(
4872 READ_FIELD(this, kSharedFunctionInfoOffset));
4873}
4874
4875
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004876void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004877 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004878 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004879 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004880}
4881
4882ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4883 kPrototypeOrInitialMapOffset)
4884
4885
4886Map* JSFunction::initial_map() {
4887 return Map::cast(prototype_or_initial_map());
4888}
4889
4890
4891void JSFunction::set_initial_map(Map* value) {
4892 set_prototype_or_initial_map(value);
4893}
4894
4895
4896bool JSFunction::has_initial_map() {
4897 return prototype_or_initial_map()->IsMap();
4898}
4899
4900
4901bool JSFunction::has_instance_prototype() {
4902 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4903}
4904
4905
4906bool JSFunction::has_prototype() {
4907 return map()->has_non_instance_prototype() || has_instance_prototype();
4908}
4909
4910
4911Object* JSFunction::instance_prototype() {
4912 ASSERT(has_instance_prototype());
4913 if (has_initial_map()) return initial_map()->prototype();
4914 // When there is no initial map and the prototype is a JSObject, the
4915 // initial map field is used for the prototype field.
4916 return prototype_or_initial_map();
4917}
4918
4919
4920Object* JSFunction::prototype() {
4921 ASSERT(has_prototype());
4922 // If the function's prototype property has been set to a non-JSObject
4923 // value, that value is stored in the constructor field of the map.
4924 if (map()->has_non_instance_prototype()) return map()->constructor();
4925 return instance_prototype();
4926}
4927
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004928
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004929bool JSFunction::should_have_prototype() {
4930 return map()->function_with_prototype();
4931}
4932
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004933
4934bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004935 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004936}
4937
4938
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004939FixedArray* JSFunction::literals() {
4940 ASSERT(!shared()->bound());
4941 return literals_or_bindings();
4942}
4943
4944
4945void JSFunction::set_literals(FixedArray* literals) {
4946 ASSERT(!shared()->bound());
4947 set_literals_or_bindings(literals);
4948}
4949
4950
4951FixedArray* JSFunction::function_bindings() {
4952 ASSERT(shared()->bound());
4953 return literals_or_bindings();
4954}
4955
4956
4957void JSFunction::set_function_bindings(FixedArray* bindings) {
4958 ASSERT(shared()->bound());
4959 // Bound function literal may be initialized to the empty fixed array
4960 // before the bindings are set.
4961 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4962 bindings->map() == GetHeap()->fixed_cow_array_map());
4963 set_literals_or_bindings(bindings);
4964}
4965
4966
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004967int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004968 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004969 return literals()->length();
4970}
4971
4972
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004973Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004974 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004975 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004976}
4977
4978
4979void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4980 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004981 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004982 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004983 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004984}
4985
4986
4987Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004988 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004989 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4990}
4991
4992
4993void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4994 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004995 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004996 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004997 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004998}
4999
5000
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00005001ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005002ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00005003ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
5004ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
5005
5006
5007void JSProxy::InitializeBody(int object_size, Object* value) {
5008 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
5009 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
5010 WRITE_FIELD(this, offset, value);
5011 }
5012}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00005013
5014
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005015ACCESSORS(JSSet, table, Object, kTableOffset)
5016ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005017ACCESSORS(JSWeakMap, table, Object, kTableOffset)
5018ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00005019
5020
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005021Address Foreign::foreign_address() {
5022 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005023}
5024
5025
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005026void Foreign::set_foreign_address(Address value) {
5027 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005028}
5029
5030
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005031ACCESSORS(JSGeneratorObject, function, JSFunction, kFunctionOffset)
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00005032ACCESSORS(JSGeneratorObject, context, Context, kContextOffset)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005033SMI_ACCESSORS(JSGeneratorObject, continuation, kContinuationOffset)
5034ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset)
5035
5036
5037JSGeneratorObject* JSGeneratorObject::cast(Object* obj) {
5038 ASSERT(obj->IsJSGeneratorObject());
5039 ASSERT(HeapObject::cast(obj)->Size() == JSGeneratorObject::kSize);
5040 return reinterpret_cast<JSGeneratorObject*>(obj);
5041}
5042
5043
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00005044ACCESSORS(JSModule, context, Object, kContextOffset)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00005045ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00005046
5047
5048JSModule* JSModule::cast(Object* obj) {
5049 ASSERT(obj->IsJSModule());
5050 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
5051 return reinterpret_cast<JSModule*>(obj);
5052}
5053
5054
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005055ACCESSORS(JSValue, value, Object, kValueOffset)
5056
5057
5058JSValue* JSValue::cast(Object* obj) {
5059 ASSERT(obj->IsJSValue());
5060 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
5061 return reinterpret_cast<JSValue*>(obj);
5062}
5063
5064
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005065ACCESSORS(JSDate, value, Object, kValueOffset)
5066ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
5067ACCESSORS(JSDate, year, Object, kYearOffset)
5068ACCESSORS(JSDate, month, Object, kMonthOffset)
5069ACCESSORS(JSDate, day, Object, kDayOffset)
5070ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
5071ACCESSORS(JSDate, hour, Object, kHourOffset)
5072ACCESSORS(JSDate, min, Object, kMinOffset)
5073ACCESSORS(JSDate, sec, Object, kSecOffset)
5074
5075
5076JSDate* JSDate::cast(Object* obj) {
5077 ASSERT(obj->IsJSDate());
5078 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
5079 return reinterpret_cast<JSDate*>(obj);
5080}
5081
5082
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00005083ACCESSORS(JSMessageObject, type, String, kTypeOffset)
5084ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
5085ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
5086ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
5087ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
5088SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
5089SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
5090
5091
5092JSMessageObject* JSMessageObject::cast(Object* obj) {
5093 ASSERT(obj->IsJSMessageObject());
5094 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
5095 return reinterpret_cast<JSMessageObject*>(obj);
5096}
5097
5098
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005099INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +00005100INT_ACCESSORS(Code, prologue_offset, kPrologueOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005101ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00005102ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005103ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005104
5105
5106// Type feedback slot: type_feedback_info for FUNCTIONs, stub_info for STUBs.
5107void Code::InitializeTypeFeedbackInfoNoWriteBarrier(Object* value) {
5108 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
5109}
5110
5111
5112Object* Code::type_feedback_info() {
5113 ASSERT(kind() == FUNCTION);
5114 return Object::cast(READ_FIELD(this, kTypeFeedbackInfoOffset));
5115}
5116
5117
5118void Code::set_type_feedback_info(Object* value, WriteBarrierMode mode) {
5119 ASSERT(kind() == FUNCTION);
5120 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
5121 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kTypeFeedbackInfoOffset,
5122 value, mode);
5123}
5124
5125
5126int Code::stub_info() {
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00005127 ASSERT(kind() == COMPARE_IC || kind() == BINARY_OP_IC || kind() == LOAD_IC);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005128 Object* value = READ_FIELD(this, kTypeFeedbackInfoOffset);
5129 return Smi::cast(value)->value();
5130}
5131
5132
5133void Code::set_stub_info(int value) {
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00005134 ASSERT(kind() == COMPARE_IC ||
5135 kind() == BINARY_OP_IC ||
ulan@chromium.org750145a2013-03-07 15:14:13 +00005136 kind() == STUB ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00005137 kind() == LOAD_IC ||
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00005138 kind() == KEYED_LOAD_IC ||
5139 kind() == STORE_IC ||
5140 kind() == KEYED_STORE_IC);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005141 WRITE_FIELD(this, kTypeFeedbackInfoOffset, Smi::FromInt(value));
5142}
5143
5144
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005145void Code::set_deoptimizing_functions(Object* value) {
5146 ASSERT(kind() == OPTIMIZED_FUNCTION);
5147 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
5148}
5149
5150
5151Object* Code::deoptimizing_functions() {
5152 ASSERT(kind() == OPTIMIZED_FUNCTION);
5153 return Object::cast(READ_FIELD(this, kTypeFeedbackInfoOffset));
5154}
5155
5156
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00005157ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00005158INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005159
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005160
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005161byte* Code::instruction_start() {
5162 return FIELD_ADDR(this, kHeaderSize);
5163}
5164
5165
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005166byte* Code::instruction_end() {
5167 return instruction_start() + instruction_size();
5168}
5169
5170
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005171int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005172 return RoundUp(instruction_size(), kObjectAlignment);
5173}
5174
5175
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005176FixedArray* Code::unchecked_deoptimization_data() {
5177 return reinterpret_cast<FixedArray*>(
5178 READ_FIELD(this, kDeoptimizationDataOffset));
5179}
5180
5181
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005182ByteArray* Code::unchecked_relocation_info() {
5183 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005184}
5185
5186
5187byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005188 return unchecked_relocation_info()->GetDataStartAddress();
5189}
5190
5191
5192int Code::relocation_size() {
5193 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005194}
5195
5196
5197byte* Code::entry() {
5198 return instruction_start();
5199}
5200
5201
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005202bool Code::contains(byte* inner_pointer) {
5203 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005204}
5205
5206
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005207ACCESSORS(JSArray, length, Object, kLengthOffset)
5208
5209
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00005210void* JSArrayBuffer::backing_store() {
5211 intptr_t ptr = READ_INTPTR_FIELD(this, kBackingStoreOffset);
5212 return reinterpret_cast<void*>(ptr);
5213}
5214
5215
5216void JSArrayBuffer::set_backing_store(void* value, WriteBarrierMode mode) {
5217 intptr_t ptr = reinterpret_cast<intptr_t>(value);
5218 WRITE_INTPTR_FIELD(this, kBackingStoreOffset, ptr);
5219}
5220
5221
5222ACCESSORS(JSArrayBuffer, byte_length, Object, kByteLengthOffset)
5223
5224
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005225ACCESSORS(JSTypedArray, buffer, Object, kBufferOffset)
5226ACCESSORS(JSTypedArray, byte_offset, Object, kByteOffsetOffset)
5227ACCESSORS(JSTypedArray, byte_length, Object, kByteLengthOffset)
5228ACCESSORS(JSTypedArray, length, Object, kLengthOffset)
5229
5230
ager@chromium.org236ad962008-09-25 09:45:57 +00005231ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00005232
5233
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00005234JSRegExp::Type JSRegExp::TypeTag() {
5235 Object* data = this->data();
5236 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
5237 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
5238 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00005239}
5240
5241
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005242JSRegExp::Type JSRegExp::TypeTagUnchecked() {
5243 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
5244 return static_cast<JSRegExp::Type>(smi->value());
5245}
5246
5247
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00005248int JSRegExp::CaptureCount() {
5249 switch (TypeTag()) {
5250 case ATOM:
5251 return 0;
5252 case IRREGEXP:
5253 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
5254 default:
5255 UNREACHABLE();
5256 return -1;
5257 }
5258}
5259
5260
ager@chromium.orga74f0da2008-12-03 16:05:52 +00005261JSRegExp::Flags JSRegExp::GetFlags() {
5262 ASSERT(this->data()->IsFixedArray());
5263 Object* data = this->data();
5264 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
5265 return Flags(smi->value());
5266}
5267
5268
5269String* JSRegExp::Pattern() {
5270 ASSERT(this->data()->IsFixedArray());
5271 Object* data = this->data();
5272 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
5273 return pattern;
5274}
5275
5276
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00005277Object* JSRegExp::DataAt(int index) {
5278 ASSERT(TypeTag() != NOT_COMPILED);
5279 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00005280}
5281
5282
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005283Object* JSRegExp::DataAtUnchecked(int index) {
5284 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
5285 int offset = FixedArray::kHeaderSize + index * kPointerSize;
5286 return READ_FIELD(fa, offset);
5287}
5288
5289
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00005290void JSRegExp::SetDataAt(int index, Object* value) {
5291 ASSERT(TypeTag() != NOT_COMPILED);
5292 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
5293 FixedArray::cast(data())->set(index, value);
5294}
5295
5296
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005297void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
5298 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
5299 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
5300 if (value->IsSmi()) {
5301 fa->set_unchecked(index, Smi::cast(value));
5302 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005303 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005304 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
5305 }
5306}
5307
5308
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005309ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005310 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005311#if DEBUG
5312 FixedArrayBase* fixed_array =
5313 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
5314 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005315 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
5316 (map == GetHeap()->fixed_array_map() ||
5317 map == GetHeap()->fixed_cow_array_map())) ||
5318 (IsFastDoubleElementsKind(kind) &&
5319 (fixed_array->IsFixedDoubleArray() ||
5320 fixed_array == GetHeap()->empty_fixed_array())) ||
5321 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005322 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005323 fixed_array->IsDictionary()) ||
5324 (kind > DICTIONARY_ELEMENTS));
5325 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
5326 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005327#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005328 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005329}
5330
5331
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00005332ElementsAccessor* JSObject::GetElementsAccessor() {
5333 return ElementsAccessor::ForKind(GetElementsKind());
5334}
5335
5336
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005337bool JSObject::HasFastObjectElements() {
5338 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005339}
5340
5341
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005342bool JSObject::HasFastSmiElements() {
5343 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005344}
5345
5346
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005347bool JSObject::HasFastSmiOrObjectElements() {
5348 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005349}
5350
5351
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00005352bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005353 return IsFastDoubleElementsKind(GetElementsKind());
5354}
5355
5356
5357bool JSObject::HasFastHoleyElements() {
5358 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00005359}
5360
5361
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005362bool JSObject::HasFastElements() {
5363 return IsFastElementsKind(GetElementsKind());
5364}
5365
5366
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005367bool JSObject::HasDictionaryElements() {
5368 return GetElementsKind() == DICTIONARY_ELEMENTS;
5369}
5370
5371
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005372bool JSObject::HasNonStrictArgumentsElements() {
5373 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
5374}
5375
5376
ager@chromium.org3811b432009-10-28 14:53:37 +00005377bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005378 HeapObject* array = elements();
5379 ASSERT(array != NULL);
5380 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00005381}
5382
5383
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005384#define EXTERNAL_ELEMENTS_CHECK(name, type) \
5385bool JSObject::HasExternal##name##Elements() { \
5386 HeapObject* array = elements(); \
5387 ASSERT(array != NULL); \
5388 if (!array->IsHeapObject()) \
5389 return false; \
5390 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00005391}
5392
5393
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005394EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
5395EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
5396EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
5397EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
5398 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
5399EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
5400EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
5401 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
5402EXTERNAL_ELEMENTS_CHECK(Float,
5403 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00005404EXTERNAL_ELEMENTS_CHECK(Double,
5405 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005406EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00005407
5408
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005409bool JSObject::HasNamedInterceptor() {
5410 return map()->has_named_interceptor();
5411}
5412
5413
5414bool JSObject::HasIndexedInterceptor() {
5415 return map()->has_indexed_interceptor();
5416}
5417
5418
lrn@chromium.org303ada72010-10-27 09:33:13 +00005419MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005420 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005421 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005422 Isolate* isolate = GetIsolate();
5423 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00005424 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005425 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
5426 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00005427 if (!maybe_writable_elems->ToObject(&writable_elems)) {
5428 return maybe_writable_elems;
5429 }
5430 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005431 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005432 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005433 return writable_elems;
5434}
5435
5436
ulan@chromium.org750145a2013-03-07 15:14:13 +00005437NameDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005438 ASSERT(!HasFastProperties());
ulan@chromium.org750145a2013-03-07 15:14:13 +00005439 return NameDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005440}
5441
5442
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005443SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005444 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005445 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005446}
5447
5448
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005449bool Name::IsHashFieldComputed(uint32_t field) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005450 return (field & kHashNotComputedMask) == 0;
5451}
5452
5453
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005454bool Name::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005455 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005456}
5457
5458
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005459uint32_t Name::Hash() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005460 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005461 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005462 if (IsHashFieldComputed(field)) return field >> kHashShift;
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005463 // Slow case: compute hash code and set it. Has to be a string.
5464 return String::cast(this)->ComputeAndSetHash();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005465}
5466
5467
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005468StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00005469 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005470 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00005471 array_index_(0),
5472 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005473 is_first_char_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005474 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005475}
ager@chromium.org7c537e22008-10-16 08:43:32 +00005476
5477
5478bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005479 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005480}
5481
5482
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005483uint32_t StringHasher::AddCharacterCore(uint32_t running_hash, uint16_t c) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005484 running_hash += c;
5485 running_hash += (running_hash << 10);
5486 running_hash ^= (running_hash >> 6);
5487 return running_hash;
5488}
5489
5490
5491uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
5492 running_hash += (running_hash << 3);
5493 running_hash ^= (running_hash >> 11);
5494 running_hash += (running_hash << 15);
5495 if ((running_hash & String::kHashBitMask) == 0) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005496 return kZeroHash;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005497 }
5498 return running_hash;
5499}
5500
5501
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005502void StringHasher::AddCharacter(uint16_t c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005503 // Use the Jenkins one-at-a-time hash function to update the hash
5504 // for the given character.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005505 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005506}
5507
5508
5509bool StringHasher::UpdateIndex(uint16_t c) {
5510 ASSERT(is_array_index_);
5511 if (c < '0' || c > '9') {
5512 is_array_index_ = false;
5513 return false;
5514 }
5515 int d = c - '0';
5516 if (is_first_char_) {
5517 is_first_char_ = false;
5518 if (c == '0' && length_ > 1) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00005519 is_array_index_ = false;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005520 return false;
5521 }
5522 }
5523 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
5524 is_array_index_ = false;
5525 return false;
5526 }
5527 array_index_ = array_index_ * 10 + d;
5528 return true;
5529}
5530
5531
5532template<typename Char>
5533inline void StringHasher::AddCharacters(const Char* chars, int length) {
5534 ASSERT(sizeof(Char) == 1 || sizeof(Char) == 2);
5535 int i = 0;
5536 if (is_array_index_) {
5537 for (; i < length; i++) {
5538 AddCharacter(chars[i]);
5539 if (!UpdateIndex(chars[i])) {
5540 i++;
5541 break;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005542 }
5543 }
5544 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005545 for (; i < length; i++) {
5546 ASSERT(!is_array_index_);
5547 AddCharacter(chars[i]);
yangguo@chromium.org154ff992012-03-13 08:09:54 +00005548 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00005549}
5550
5551
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005552template <typename schar>
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005553uint32_t StringHasher::HashSequentialString(const schar* chars,
5554 int length,
5555 uint32_t seed) {
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005556 StringHasher hasher(length, seed);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005557 if (!hasher.has_trivial_hash()) hasher.AddCharacters(chars, length);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005558 return hasher.GetHashField();
5559}
5560
5561
ulan@chromium.org750145a2013-03-07 15:14:13 +00005562bool Name::AsArrayIndex(uint32_t* index) {
5563 return IsString() && String::cast(this)->AsArrayIndex(index);
5564}
5565
5566
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005567bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005568 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00005569 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
5570 return false;
5571 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005572 return SlowAsArrayIndex(index);
5573}
5574
5575
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00005576Object* JSReceiver::GetPrototype() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00005577 return map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005578}
5579
5580
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00005581Object* JSReceiver::GetConstructor() {
5582 return map()->constructor();
5583}
5584
5585
ulan@chromium.org750145a2013-03-07 15:14:13 +00005586bool JSReceiver::HasProperty(Name* name) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00005587 if (IsJSProxy()) {
5588 return JSProxy::cast(this)->HasPropertyWithHandler(name);
5589 }
5590 return GetPropertyAttribute(name) != ABSENT;
5591}
5592
5593
ulan@chromium.org750145a2013-03-07 15:14:13 +00005594bool JSReceiver::HasLocalProperty(Name* name) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00005595 if (IsJSProxy()) {
5596 return JSProxy::cast(this)->HasPropertyWithHandler(name);
5597 }
5598 return GetLocalPropertyAttribute(name) != ABSENT;
5599}
5600
5601
ulan@chromium.org750145a2013-03-07 15:14:13 +00005602PropertyAttributes JSReceiver::GetPropertyAttribute(Name* key) {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00005603 uint32_t index;
5604 if (IsJSObject() && key->AsArrayIndex(&index)) {
5605 return GetElementAttribute(index);
5606 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005607 return GetPropertyAttributeWithReceiver(this, key);
5608}
5609
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00005610
5611PropertyAttributes JSReceiver::GetElementAttribute(uint32_t index) {
5612 if (IsJSProxy()) {
5613 return JSProxy::cast(this)->GetElementAttributeWithHandler(this, index);
5614 }
5615 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5616 this, index, true);
5617}
5618
5619
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005620// TODO(504): this may be useful in other places too where JSGlobalProxy
5621// is used.
5622Object* JSObject::BypassGlobalProxy() {
5623 if (IsJSGlobalProxy()) {
5624 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005625 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005626 ASSERT(proto->IsJSGlobalObject());
5627 return proto;
5628 }
5629 return this;
5630}
5631
5632
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005633MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
5634 return IsJSProxy()
5635 ? JSProxy::cast(this)->GetIdentityHash(flag)
5636 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005637}
5638
5639
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005640bool JSReceiver::HasElement(uint32_t index) {
5641 if (IsJSProxy()) {
5642 return JSProxy::cast(this)->HasElementWithHandler(index);
5643 }
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00005644 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5645 this, index, true) != ABSENT;
5646}
5647
5648
5649bool JSReceiver::HasLocalElement(uint32_t index) {
5650 if (IsJSProxy()) {
5651 return JSProxy::cast(this)->HasElementWithHandler(index);
5652 }
5653 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5654 this, index, false) != ABSENT;
5655}
5656
5657
5658PropertyAttributes JSReceiver::GetLocalElementAttribute(uint32_t index) {
5659 if (IsJSProxy()) {
5660 return JSProxy::cast(this)->GetElementAttributeWithHandler(this, index);
5661 }
5662 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5663 this, index, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005664}
5665
5666
5667bool AccessorInfo::all_can_read() {
5668 return BooleanBit::get(flag(), kAllCanReadBit);
5669}
5670
5671
5672void AccessorInfo::set_all_can_read(bool value) {
5673 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
5674}
5675
5676
5677bool AccessorInfo::all_can_write() {
5678 return BooleanBit::get(flag(), kAllCanWriteBit);
5679}
5680
5681
5682void AccessorInfo::set_all_can_write(bool value) {
5683 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
5684}
5685
5686
ager@chromium.org870a0b62008-11-04 11:43:05 +00005687bool AccessorInfo::prohibits_overwriting() {
5688 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
5689}
5690
5691
5692void AccessorInfo::set_prohibits_overwriting(bool value) {
5693 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
5694}
5695
5696
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005697PropertyAttributes AccessorInfo::property_attributes() {
5698 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
5699}
5700
5701
5702void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005703 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005704}
5705
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005706
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005707bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
5708 Object* function_template = expected_receiver_type();
5709 if (!function_template->IsFunctionTemplateInfo()) return true;
5710 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
5711}
5712
5713
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005714template<typename Shape, typename Key>
5715void Dictionary<Shape, Key>::SetEntry(int entry,
5716 Object* key,
5717 Object* value) {
5718 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
5719}
5720
5721
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005722template<typename Shape, typename Key>
5723void Dictionary<Shape, Key>::SetEntry(int entry,
5724 Object* key,
5725 Object* value,
5726 PropertyDetails details) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00005727 ASSERT(!key->IsName() ||
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005728 details.IsDeleted() ||
5729 details.dictionary_index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005730 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005731 AssertNoAllocation no_gc;
5732 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005733 FixedArray::set(index, key, mode);
5734 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005735 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005736}
5737
5738
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005739bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
5740 ASSERT(other->IsNumber());
5741 return key == static_cast<uint32_t>(other->Number());
5742}
5743
5744
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005745uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
5746 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005747}
5748
5749
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005750uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
5751 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005752 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005753 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005754}
5755
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005756uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
5757 return ComputeIntegerHash(key, seed);
5758}
5759
5760uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
5761 uint32_t seed,
5762 Object* other) {
5763 ASSERT(other->IsNumber());
5764 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
5765}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005766
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00005767MaybeObject* NumberDictionaryShape::AsObject(Heap* heap, uint32_t key) {
5768 return heap->NumberFromUint32(key);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005769}
5770
5771
ulan@chromium.org750145a2013-03-07 15:14:13 +00005772bool NameDictionaryShape::IsMatch(Name* key, Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005773 // We know that all entries in a hash table had their hash keys created.
5774 // Use that knowledge to have fast failure.
ulan@chromium.org750145a2013-03-07 15:14:13 +00005775 if (key->Hash() != Name::cast(other)->Hash()) return false;
5776 return key->Equals(Name::cast(other));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005777}
5778
5779
ulan@chromium.org750145a2013-03-07 15:14:13 +00005780uint32_t NameDictionaryShape::Hash(Name* key) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005781 return key->Hash();
5782}
5783
5784
ulan@chromium.org750145a2013-03-07 15:14:13 +00005785uint32_t NameDictionaryShape::HashForObject(Name* key, Object* other) {
5786 return Name::cast(other)->Hash();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005787}
5788
5789
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00005790MaybeObject* NameDictionaryShape::AsObject(Heap* heap, Name* key) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005791 return key;
5792}
5793
5794
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005795template <int entrysize>
5796bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
5797 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005798}
5799
5800
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005801template <int entrysize>
5802uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005803 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
5804 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005805}
5806
5807
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005808template <int entrysize>
5809uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
5810 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005811 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
5812 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005813}
5814
5815
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005816template <int entrysize>
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00005817MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Heap* heap,
5818 Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005819 return key;
5820}
5821
5822
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005823void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005824 // No write barrier is needed since empty_fixed_array is not in new space.
5825 // Please note this function is used during marking:
5826 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005827 // - IncrementalMarking::Step
danno@chromium.org72204d52012-10-31 10:02:10 +00005828 ASSERT(!heap->InNewSpace(heap->empty_fixed_array()));
5829 WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005830}
5831
5832
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005833void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005834 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005835 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005836 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5837 if (elts->length() < required_size) {
5838 // Doubling in size would be overkill, but leave some slack to avoid
5839 // constantly growing.
5840 Expand(required_size + (required_size >> 3));
5841 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005842 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005843 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5844 // Expand will allocate a new backing store in new space even if the size
5845 // we asked for isn't larger than what we had before.
5846 Expand(required_size);
5847 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005848}
5849
5850
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005851void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005852 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005853 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5854}
5855
5856
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005857bool JSArray::AllowsSetElementsLength() {
5858 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5859 ASSERT(result == !HasExternalArrayElements());
5860 return result;
5861}
5862
5863
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005864MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5865 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005866 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005867 if (maybe_result->IsFailure()) return maybe_result;
5868 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005869 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005870 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005871 (IsFastObjectElementsKind(GetElementsKind()) ||
5872 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005873 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005874 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005875 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005876 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005877}
5878
5879
lrn@chromium.org303ada72010-10-27 09:33:13 +00005880MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005881 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005882 return GetHeap()->CopyFixedArray(this);
5883}
5884
5885
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005886MaybeObject* FixedDoubleArray::Copy() {
5887 if (length() == 0) return this;
5888 return GetHeap()->CopyFixedDoubleArray(this);
5889}
5890
5891
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005892void TypeFeedbackCells::SetAstId(int index, TypeFeedbackId id) {
5893 set(1 + index * 2, Smi::FromInt(id.ToInt()));
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005894}
5895
5896
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005897TypeFeedbackId TypeFeedbackCells::AstId(int index) {
5898 return TypeFeedbackId(Smi::cast(get(1 + index * 2))->value());
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005899}
5900
5901
5902void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
5903 set(index * 2, cell);
5904}
5905
5906
5907JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
5908 return JSGlobalPropertyCell::cast(get(index * 2));
5909}
5910
5911
5912Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5913 return isolate->factory()->the_hole_value();
5914}
5915
5916
5917Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5918 return isolate->factory()->undefined_value();
5919}
5920
5921
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005922Handle<Object> TypeFeedbackCells::MonomorphicArraySentinel(Isolate* isolate,
5923 ElementsKind elements_kind) {
5924 return Handle<Object>(Smi::FromInt(static_cast<int>(elements_kind)), isolate);
5925}
5926
5927
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005928Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
danno@chromium.org72204d52012-10-31 10:02:10 +00005929 return heap->the_hole_value();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005930}
5931
5932
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005933int TypeFeedbackInfo::ic_total_count() {
5934 int current = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5935 return ICTotalCountField::decode(current);
5936}
5937
5938
5939void TypeFeedbackInfo::set_ic_total_count(int count) {
5940 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5941 value = ICTotalCountField::update(value,
5942 ICTotalCountField::decode(count));
5943 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
5944}
5945
5946
5947int TypeFeedbackInfo::ic_with_type_info_count() {
5948 int current = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5949 return ICsWithTypeInfoCountField::decode(current);
5950}
5951
5952
5953void TypeFeedbackInfo::change_ic_with_type_info_count(int delta) {
5954 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5955 int new_count = ICsWithTypeInfoCountField::decode(value) + delta;
5956 // We can get negative count here when the type-feedback info is
5957 // shared between two code objects. The can only happen when
5958 // the debugger made a shallow copy of code object (see Heap::CopyCode).
5959 // Since we do not optimize when the debugger is active, we can skip
5960 // this counter update.
5961 if (new_count >= 0) {
5962 new_count &= ICsWithTypeInfoCountField::kMask;
5963 value = ICsWithTypeInfoCountField::update(value, new_count);
5964 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
5965 }
5966}
5967
5968
5969void TypeFeedbackInfo::initialize_storage() {
5970 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(0));
5971 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(0));
5972}
5973
5974
5975void TypeFeedbackInfo::change_own_type_change_checksum() {
5976 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5977 int checksum = OwnTypeChangeChecksum::decode(value);
5978 checksum = (checksum + 1) % (1 << kTypeChangeChecksumBits);
5979 value = OwnTypeChangeChecksum::update(value, checksum);
5980 // Ensure packed bit field is in Smi range.
5981 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
5982 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
5983 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
5984}
5985
5986
5987void TypeFeedbackInfo::set_inlined_type_change_checksum(int checksum) {
5988 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5989 int mask = (1 << kTypeChangeChecksumBits) - 1;
5990 value = InlinedTypeChangeChecksum::update(value, checksum & mask);
5991 // Ensure packed bit field is in Smi range.
5992 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
5993 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
5994 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
5995}
5996
5997
5998int TypeFeedbackInfo::own_type_change_checksum() {
5999 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
6000 return OwnTypeChangeChecksum::decode(value);
6001}
6002
6003
6004bool TypeFeedbackInfo::matches_inlined_type_change_checksum(int checksum) {
6005 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
6006 int mask = (1 << kTypeChangeChecksumBits) - 1;
6007 return InlinedTypeChangeChecksum::decode(value) == (checksum & mask);
6008}
6009
6010
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00006011ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
6012 kTypeFeedbackCellsOffset)
6013
6014
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00006015SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
6016
6017
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006018Relocatable::Relocatable(Isolate* isolate) {
6019 ASSERT(isolate == Isolate::Current());
6020 isolate_ = isolate;
6021 prev_ = isolate->relocatable_top();
6022 isolate->set_relocatable_top(this);
6023}
6024
6025
6026Relocatable::~Relocatable() {
6027 ASSERT(isolate_ == Isolate::Current());
6028 ASSERT_EQ(isolate_->relocatable_top(), this);
6029 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00006030}
6031
6032
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006033int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
6034 return map->instance_size();
6035}
6036
6037
ager@chromium.orgea91cc52011-05-23 06:06:11 +00006038void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006039 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00006040 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006041}
6042
6043
6044template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00006045void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006046 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00006047 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006048}
6049
6050
6051void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
6052 typedef v8::String::ExternalAsciiStringResource Resource;
6053 v->VisitExternalAsciiString(
6054 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
6055}
6056
6057
6058template<typename StaticVisitor>
6059void ExternalAsciiString::ExternalAsciiStringIterateBody() {
6060 typedef v8::String::ExternalAsciiStringResource Resource;
6061 StaticVisitor::VisitExternalAsciiString(
6062 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
6063}
6064
6065
6066void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
6067 typedef v8::String::ExternalStringResource Resource;
6068 v->VisitExternalTwoByteString(
6069 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
6070}
6071
6072
6073template<typename StaticVisitor>
6074void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
6075 typedef v8::String::ExternalStringResource Resource;
6076 StaticVisitor::VisitExternalTwoByteString(
6077 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
6078}
6079
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006080
6081template<int start_offset, int end_offset, int size>
6082void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
6083 HeapObject* obj,
6084 ObjectVisitor* v) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00006085 v->VisitPointers(HeapObject::RawField(obj, start_offset),
6086 HeapObject::RawField(obj, end_offset));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006087}
6088
6089
6090template<int start_offset>
6091void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
6092 int object_size,
6093 ObjectVisitor* v) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00006094 v->VisitPointers(HeapObject::RawField(obj, start_offset),
6095 HeapObject::RawField(obj, object_size));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006096}
6097
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006098
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00006099#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006100#undef CAST_ACCESSOR
6101#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006102#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00006103#undef ACCESSORS_TO_SMI
6104#undef SMI_ACCESSORS
6105#undef BOOL_GETTER
6106#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006107#undef FIELD_ADDR
6108#undef READ_FIELD
6109#undef WRITE_FIELD
6110#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00006111#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006112#undef READ_DOUBLE_FIELD
6113#undef WRITE_DOUBLE_FIELD
6114#undef READ_INT_FIELD
6115#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00006116#undef READ_INTPTR_FIELD
6117#undef WRITE_INTPTR_FIELD
6118#undef READ_UINT32_FIELD
6119#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006120#undef READ_SHORT_FIELD
6121#undef WRITE_SHORT_FIELD
6122#undef READ_BYTE_FIELD
6123#undef WRITE_BYTE_FIELD
6124
6125
6126} } // namespace v8::internal
6127
6128#endif // V8_OBJECTS_INL_H_