blob: ec03405fdd8e368b3404dfdfc51035ee7441edbc [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)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000656TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000657TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000658TYPE_CHECKER(JSDate, JS_DATE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000659TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000660
661
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000662bool Object::IsStringWrapper() {
663 return IsJSValue() && JSValue::cast(this)->value()->IsString();
664}
665
666
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000667TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000668
669
670bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000671 return IsOddball() &&
672 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000673}
674
675
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000676TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000677TYPE_CHECKER(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000678TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000679
680
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000681template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000682 return obj->IsJSArray();
683}
684
685
686bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000687 return Object::IsHeapObject() &&
688 HeapObject::cast(this)->map() ==
689 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000690}
691
692
693bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000694 return IsHashTable() &&
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000695 this != HeapObject::cast(this)->GetHeap()->string_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000696}
697
698
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000699bool Object::IsStringTable() {
danno@chromium.org72204d52012-10-31 10:02:10 +0000700 return IsHashTable() &&
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000701 this == HeapObject::cast(this)->GetHeap()->raw_unchecked_string_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000702}
703
704
ager@chromium.orgac091b72010-05-05 07:34:42 +0000705bool Object::IsJSFunctionResultCache() {
706 if (!IsFixedArray()) return false;
707 FixedArray* self = FixedArray::cast(this);
708 int length = self->length();
709 if (length < JSFunctionResultCache::kEntriesIndex) return false;
710 if ((length - JSFunctionResultCache::kEntriesIndex)
711 % JSFunctionResultCache::kEntrySize != 0) {
712 return false;
713 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +0000714#ifdef VERIFY_HEAP
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000715 if (FLAG_verify_heap) {
716 reinterpret_cast<JSFunctionResultCache*>(this)->
717 JSFunctionResultCacheVerify();
718 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000719#endif
720 return true;
721}
722
723
ricow@chromium.org65fae842010-08-25 15:26:24 +0000724bool Object::IsNormalizedMapCache() {
725 if (!IsFixedArray()) return false;
726 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
727 return false;
728 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +0000729#ifdef VERIFY_HEAP
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000730 if (FLAG_verify_heap) {
731 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
732 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000733#endif
734 return true;
735}
736
737
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000738bool Object::IsCompilationCacheTable() {
739 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000740}
741
742
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000743bool Object::IsCodeCacheHashTable() {
744 return IsHashTable();
745}
746
747
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000748bool Object::IsPolymorphicCodeCacheHashTable() {
749 return IsHashTable();
750}
751
752
ager@chromium.org236ad962008-09-25 09:45:57 +0000753bool Object::IsMapCache() {
754 return IsHashTable();
755}
756
757
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000758bool Object::IsObjectHashTable() {
759 return IsHashTable();
760}
761
762
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000763bool Object::IsPrimitive() {
764 return IsOddball() || IsNumber() || IsString();
765}
766
767
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000768bool Object::IsJSGlobalProxy() {
769 bool result = IsHeapObject() &&
770 (HeapObject::cast(this)->map()->instance_type() ==
771 JS_GLOBAL_PROXY_TYPE);
772 ASSERT(!result || IsAccessCheckNeeded());
773 return result;
774}
775
776
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000778 if (!IsHeapObject()) return false;
779
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000780 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000781 return type == JS_GLOBAL_OBJECT_TYPE ||
782 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000783}
784
785
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000786TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
787TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000788
789
790bool Object::IsUndetectableObject() {
791 return IsHeapObject()
792 && HeapObject::cast(this)->map()->is_undetectable();
793}
794
795
796bool Object::IsAccessCheckNeeded() {
797 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000798 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000799}
800
801
802bool Object::IsStruct() {
803 if (!IsHeapObject()) return false;
804 switch (HeapObject::cast(this)->map()->instance_type()) {
805#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
806 STRUCT_LIST(MAKE_STRUCT_CASE)
807#undef MAKE_STRUCT_CASE
808 default: return false;
809 }
810}
811
812
813#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
814 bool Object::Is##Name() { \
815 return Object::IsHeapObject() \
816 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
817 }
818 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
819#undef MAKE_STRUCT_PREDICATE
820
821
822bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000823 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000824}
825
826
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000827bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000828 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
829}
830
831
832bool Object::IsTheHole() {
833 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000834}
835
836
837bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000838 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000839}
840
841
842bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000843 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000844}
845
846
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000847bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000848 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000849}
850
851
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000852double Object::Number() {
853 ASSERT(IsNumber());
854 return IsSmi()
855 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
856 : reinterpret_cast<HeapNumber*>(this)->value();
857}
858
859
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000860bool Object::IsNaN() {
861 return this->IsHeapNumber() && isnan(HeapNumber::cast(this)->value());
862}
863
864
lrn@chromium.org303ada72010-10-27 09:33:13 +0000865MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000866 if (IsSmi()) return this;
867 if (IsHeapNumber()) {
868 double value = HeapNumber::cast(this)->value();
869 int int_value = FastD2I(value);
870 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
871 return Smi::FromInt(int_value);
872 }
873 }
874 return Failure::Exception();
875}
876
877
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000878bool Object::HasSpecificClassOf(String* name) {
879 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
880}
881
882
lrn@chromium.org303ada72010-10-27 09:33:13 +0000883MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000884 // GetElement can trigger a getter which can cause allocation.
885 // This was not always the case. This ASSERT is here to catch
886 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000887 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000888 return GetElementWithReceiver(this, index);
889}
890
891
lrn@chromium.org303ada72010-10-27 09:33:13 +0000892Object* Object::GetElementNoExceptionThrown(uint32_t index) {
893 MaybeObject* maybe = GetElementWithReceiver(this, index);
894 ASSERT(!maybe->IsFailure());
895 Object* result = NULL; // Initialization to please compiler.
896 maybe->ToObject(&result);
897 return result;
898}
899
900
ulan@chromium.org750145a2013-03-07 15:14:13 +0000901MaybeObject* Object::GetProperty(Name* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000902 PropertyAttributes attributes;
903 return GetPropertyWithReceiver(this, key, &attributes);
904}
905
906
ulan@chromium.org750145a2013-03-07 15:14:13 +0000907MaybeObject* Object::GetProperty(Name* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000908 return GetPropertyWithReceiver(this, key, attributes);
909}
910
911
912#define FIELD_ADDR(p, offset) \
913 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
914
915#define READ_FIELD(p, offset) \
916 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
917
918#define WRITE_FIELD(p, offset, value) \
919 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
920
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000921#define WRITE_BARRIER(heap, object, offset, value) \
922 heap->incremental_marking()->RecordWrite( \
923 object, HeapObject::RawField(object, offset), value); \
924 if (heap->InNewSpace(value)) { \
925 heap->RecordWrite(object->address(), offset); \
926 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000927
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000928#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
929 if (mode == UPDATE_WRITE_BARRIER) { \
930 heap->incremental_marking()->RecordWrite( \
931 object, HeapObject::RawField(object, offset), value); \
932 if (heap->InNewSpace(value)) { \
933 heap->RecordWrite(object->address(), offset); \
934 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000935 }
936
lrn@chromium.org7516f052011-03-30 08:52:27 +0000937#ifndef V8_TARGET_ARCH_MIPS
938 #define READ_DOUBLE_FIELD(p, offset) \
939 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
940#else // V8_TARGET_ARCH_MIPS
941 // Prevent gcc from using load-double (mips ldc1) on (possibly)
942 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000943 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000944 union conversion {
945 double d;
946 uint32_t u[2];
947 } c;
948 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
949 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
950 return c.d;
951 }
952 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
953#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000954
lrn@chromium.org7516f052011-03-30 08:52:27 +0000955#ifndef V8_TARGET_ARCH_MIPS
956 #define WRITE_DOUBLE_FIELD(p, offset, value) \
957 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
958#else // V8_TARGET_ARCH_MIPS
959 // Prevent gcc from using store-double (mips sdc1) on (possibly)
960 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000961 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000962 double value) {
963 union conversion {
964 double d;
965 uint32_t u[2];
966 } c;
967 c.d = value;
968 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
969 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
970 }
971 #define WRITE_DOUBLE_FIELD(p, offset, value) \
972 write_double_field(p, offset, value)
973#endif // V8_TARGET_ARCH_MIPS
974
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000975
976#define READ_INT_FIELD(p, offset) \
977 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
978
979#define WRITE_INT_FIELD(p, offset, value) \
980 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
981
ager@chromium.org3e875802009-06-29 08:26:34 +0000982#define READ_INTPTR_FIELD(p, offset) \
983 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
984
985#define WRITE_INTPTR_FIELD(p, offset, value) \
986 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
987
ager@chromium.org7c537e22008-10-16 08:43:32 +0000988#define READ_UINT32_FIELD(p, offset) \
989 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
990
991#define WRITE_UINT32_FIELD(p, offset, value) \
992 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
993
danno@chromium.org88aa0582012-03-23 15:11:57 +0000994#define READ_INT64_FIELD(p, offset) \
995 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
996
997#define WRITE_INT64_FIELD(p, offset, value) \
998 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
999
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001000#define READ_SHORT_FIELD(p, offset) \
1001 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
1002
1003#define WRITE_SHORT_FIELD(p, offset, value) \
1004 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
1005
1006#define READ_BYTE_FIELD(p, offset) \
1007 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
1008
1009#define WRITE_BYTE_FIELD(p, offset, value) \
1010 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
1011
1012
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00001013Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
1014 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001015}
1016
1017
1018int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00001019 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020}
1021
1022
1023Smi* Smi::FromInt(int value) {
1024 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001025 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +00001026 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001027 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +00001028 return reinterpret_cast<Smi*>(tagged_value);
1029}
1030
1031
1032Smi* Smi::FromIntptr(intptr_t value) {
1033 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001034 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1035 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001036}
1037
1038
1039Failure::Type Failure::type() const {
1040 return static_cast<Type>(value() & kFailureTypeTagMask);
1041}
1042
1043
1044bool Failure::IsInternalError() const {
1045 return type() == INTERNAL_ERROR;
1046}
1047
1048
1049bool Failure::IsOutOfMemoryException() const {
1050 return type() == OUT_OF_MEMORY_EXCEPTION;
1051}
1052
1053
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001054AllocationSpace Failure::allocation_space() const {
1055 ASSERT_EQ(RETRY_AFTER_GC, type());
1056 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1057 & kSpaceTagMask);
1058}
1059
1060
1061Failure* Failure::InternalError() {
1062 return Construct(INTERNAL_ERROR);
1063}
1064
1065
1066Failure* Failure::Exception() {
1067 return Construct(EXCEPTION);
1068}
1069
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001070
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00001071Failure* Failure::OutOfMemoryException(intptr_t value) {
1072 return Construct(OUT_OF_MEMORY_EXCEPTION, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001073}
1074
1075
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001076intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001077 return static_cast<intptr_t>(
1078 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001079}
1080
1081
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001082Failure* Failure::RetryAfterGC() {
1083 return RetryAfterGC(NEW_SPACE);
1084}
1085
1086
1087Failure* Failure::RetryAfterGC(AllocationSpace space) {
1088 ASSERT((space & ~kSpaceTagMask) == 0);
1089 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001090}
1091
1092
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001093Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001094 uintptr_t info =
1095 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001096 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +00001097 // Fill the unused bits with a pattern that's easy to recognize in crash
1098 // dumps.
1099 static const int kFailureMagicPattern = 0x0BAD0000;
1100 return reinterpret_cast<Failure*>(
1101 (info << kFailureTagSize) | kFailureTag | kFailureMagicPattern);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001102}
1103
1104
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001105bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001106#ifdef DEBUG
1107 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1108#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001109
1110#ifdef V8_TARGET_ARCH_X64
1111 // To be representable as a long smi, the value must be a 32-bit integer.
1112 bool result = (value == static_cast<int32_t>(value));
1113#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001114 // To be representable as an tagged small integer, the two
1115 // most-significant bits of 'value' must be either 00 or 11 due to
1116 // sign-extension. To check this we add 01 to the two
1117 // most-significant bits, and check if the most-significant bit is 0
1118 //
1119 // CAUTION: The original code below:
1120 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1121 // may lead to incorrect results according to the C language spec, and
1122 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1123 // compiler may produce undefined results in case of signed integer
1124 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001125 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001126#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001127 ASSERT(result == in_range);
1128 return result;
1129}
1130
1131
kasper.lund7276f142008-07-30 08:49:36 +00001132MapWord MapWord::FromMap(Map* map) {
1133 return MapWord(reinterpret_cast<uintptr_t>(map));
1134}
1135
1136
1137Map* MapWord::ToMap() {
1138 return reinterpret_cast<Map*>(value_);
1139}
1140
1141
1142bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001143 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001144}
1145
1146
1147MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001148 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1149 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001150}
1151
1152
1153HeapObject* MapWord::ToForwardingAddress() {
1154 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001155 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001156}
1157
1158
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001159#ifdef VERIFY_HEAP
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001160void HeapObject::VerifyObjectField(int offset) {
1161 VerifyPointer(READ_FIELD(this, offset));
1162}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001163
1164void HeapObject::VerifySmiField(int offset) {
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001165 CHECK(READ_FIELD(this, offset)->IsSmi());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001166}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001167#endif
1168
1169
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001170Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001171 Heap* heap =
1172 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1173 ASSERT(heap != NULL);
1174 ASSERT(heap->isolate() == Isolate::Current());
1175 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001176}
1177
1178
1179Isolate* HeapObject::GetIsolate() {
1180 return GetHeap()->isolate();
1181}
1182
1183
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001184Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001185 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001186}
1187
1188
1189void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001190 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001191 if (value != NULL) {
1192 // TODO(1600) We are passing NULL as a slot because maps can never be on
1193 // evacuation candidate.
1194 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1195 }
1196}
1197
1198
1199// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001200void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001201 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001202}
1203
1204
kasper.lund7276f142008-07-30 08:49:36 +00001205MapWord HeapObject::map_word() {
1206 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1207}
1208
1209
1210void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001211 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001212 // here.
1213 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1214}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001215
1216
1217HeapObject* HeapObject::FromAddress(Address address) {
1218 ASSERT_TAG_ALIGNED(address);
1219 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1220}
1221
1222
1223Address HeapObject::address() {
1224 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1225}
1226
1227
1228int HeapObject::Size() {
1229 return SizeFromMap(map());
1230}
1231
1232
1233void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1234 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1235 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1236}
1237
1238
1239void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1240 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1241}
1242
1243
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001244double HeapNumber::value() {
1245 return READ_DOUBLE_FIELD(this, kValueOffset);
1246}
1247
1248
1249void HeapNumber::set_value(double value) {
1250 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1251}
1252
1253
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001254int HeapNumber::get_exponent() {
1255 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1256 kExponentShift) - kExponentBias;
1257}
1258
1259
1260int HeapNumber::get_sign() {
1261 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1262}
1263
1264
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001265ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001266
1267
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001268Object** FixedArray::GetFirstElementAddress() {
1269 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1270}
1271
1272
1273bool FixedArray::ContainsOnlySmisOrHoles() {
1274 Object* the_hole = GetHeap()->the_hole_value();
1275 Object** current = GetFirstElementAddress();
1276 for (int i = 0; i < length(); ++i) {
1277 Object* candidate = *current++;
1278 if (!candidate->IsSmi() && candidate != the_hole) return false;
1279 }
1280 return true;
1281}
1282
1283
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001284FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001285 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001286 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001287}
1288
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001289
1290void JSObject::ValidateElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001291#if DEBUG
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001292 if (FLAG_enable_slow_asserts) {
1293 ElementsAccessor* accessor = GetElementsAccessor();
1294 accessor->Validate(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001295 }
1296#endif
1297}
1298
1299
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001300MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001301 ValidateElements();
1302 ElementsKind elements_kind = map()->elements_kind();
1303 if (!IsFastObjectElementsKind(elements_kind)) {
1304 if (IsFastHoleyElementsKind(elements_kind)) {
1305 return TransitionElementsKind(FAST_HOLEY_ELEMENTS);
1306 } else {
1307 return TransitionElementsKind(FAST_ELEMENTS);
1308 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001309 }
1310 return this;
1311}
1312
1313
1314MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001315 uint32_t count,
1316 EnsureElementsMode mode) {
1317 ElementsKind current_kind = map()->elements_kind();
1318 ElementsKind target_kind = current_kind;
1319 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001320 bool is_holey = IsFastHoleyElementsKind(current_kind);
1321 if (current_kind == FAST_HOLEY_ELEMENTS) return this;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001322 Heap* heap = GetHeap();
1323 Object* the_hole = heap->the_hole_value();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001324 for (uint32_t i = 0; i < count; ++i) {
1325 Object* current = *objects++;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001326 if (current == the_hole) {
1327 is_holey = true;
1328 target_kind = GetHoleyElementsKind(target_kind);
1329 } else if (!current->IsSmi()) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001330 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && current->IsNumber()) {
1331 if (IsFastSmiElementsKind(target_kind)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001332 if (is_holey) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001333 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001334 } else {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001335 target_kind = FAST_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001336 }
1337 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001338 } else if (is_holey) {
1339 target_kind = FAST_HOLEY_ELEMENTS;
1340 break;
1341 } else {
1342 target_kind = FAST_ELEMENTS;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001343 }
1344 }
1345 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001346
1347 if (target_kind != current_kind) {
1348 return TransitionElementsKind(target_kind);
1349 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001350 return this;
1351}
1352
1353
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001354MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001355 uint32_t length,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001356 EnsureElementsMode mode) {
1357 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1358 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1359 elements->map() == GetHeap()->fixed_cow_array_map());
1360 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1361 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1362 }
1363 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001364 return EnsureCanContainElements(objects, length, mode);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001365 }
1366
1367 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001368 if (GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) {
1369 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1370 } else if (GetElementsKind() == FAST_SMI_ELEMENTS) {
1371 FixedDoubleArray* double_array = FixedDoubleArray::cast(elements);
1372 for (uint32_t i = 0; i < length; ++i) {
1373 if (double_array->is_the_hole(i)) {
1374 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1375 }
1376 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001377 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1378 }
1379
1380 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001381}
1382
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001383
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001384MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1385 ElementsKind to_kind) {
1386 Map* current_map = map();
1387 ElementsKind from_kind = current_map->elements_kind();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001388 if (from_kind == to_kind) return current_map;
1389
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001390 Context* native_context = isolate->context()->native_context();
1391 Object* maybe_array_maps = native_context->js_array_maps();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001392 if (maybe_array_maps->IsFixedArray()) {
1393 FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
1394 if (array_maps->get(from_kind) == current_map) {
1395 Object* maybe_transitioned_map = array_maps->get(to_kind);
1396 if (maybe_transitioned_map->IsMap()) {
1397 return Map::cast(maybe_transitioned_map);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001398 }
1399 }
1400 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001401
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001402 return GetElementsTransitionMapSlow(to_kind);
1403}
1404
1405
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001406void JSObject::set_map_and_elements(Map* new_map,
1407 FixedArrayBase* value,
1408 WriteBarrierMode mode) {
1409 ASSERT(value->HasValidElements());
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001410 if (new_map != NULL) {
1411 if (mode == UPDATE_WRITE_BARRIER) {
1412 set_map(new_map);
1413 } else {
1414 ASSERT(mode == SKIP_WRITE_BARRIER);
1415 set_map_no_write_barrier(new_map);
1416 }
1417 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001418 ASSERT((map()->has_fast_smi_or_object_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001419 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001420 (value->map() == GetHeap()->fixed_array_map() ||
1421 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001422 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1423 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001424 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001425 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001426}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001427
1428
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001429void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1430 set_map_and_elements(NULL, value, mode);
1431}
1432
1433
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001434void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001435 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1436 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001437}
1438
1439
1440void JSObject::initialize_elements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001441 ASSERT(map()->has_fast_smi_or_object_elements() ||
danno@chromium.org2c26cb12012-05-03 09:06:43 +00001442 map()->has_fast_double_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001443 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1444 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001445}
1446
1447
lrn@chromium.org303ada72010-10-27 09:33:13 +00001448MaybeObject* JSObject::ResetElements() {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001449 if (map()->is_observed()) {
1450 // Maintain invariant that observed elements are always in dictionary mode.
1451 SeededNumberDictionary* dictionary;
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001452 MaybeObject* maybe = SeededNumberDictionary::Allocate(GetHeap(), 0);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001453 if (!maybe->To(&dictionary)) return maybe;
1454 if (map() == GetHeap()->non_strict_arguments_elements_map()) {
1455 FixedArray::cast(elements())->set(1, dictionary);
1456 } else {
1457 set_elements(dictionary);
1458 }
1459 return this;
1460 }
1461
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001462 ElementsKind elements_kind = GetInitialFastElementsKind();
1463 if (!FLAG_smi_only_arrays) {
1464 elements_kind = FastSmiToObjectElementsKind(elements_kind);
1465 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001466 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind);
1467 Map* map;
1468 if (!maybe->To(&map)) return maybe;
1469 set_map(map);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001470 initialize_elements();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001471
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001472 return this;
1473}
1474
1475
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00001476MaybeObject* JSObject::AddFastPropertyUsingMap(Map* map) {
1477 ASSERT(this->map()->NumberOfOwnDescriptors() + 1 ==
1478 map->NumberOfOwnDescriptors());
1479 if (this->map()->unused_property_fields() == 0) {
1480 int new_size = properties()->length() + map->unused_property_fields() + 1;
1481 FixedArray* new_properties;
1482 MaybeObject* maybe_properties = properties()->CopySize(new_size);
1483 if (!maybe_properties->To(&new_properties)) return maybe_properties;
1484 set_properties(new_properties);
1485 }
1486 set_map(map);
1487 return this;
1488}
1489
1490
1491bool JSObject::TryTransitionToField(Handle<JSObject> object,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001492 Handle<Name> key) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00001493 if (!object->map()->HasTransitionArray()) return false;
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001494 Handle<Map> target;
1495 {
1496 AssertNoAllocation no_allocation;
1497 TransitionArray* transitions = object->map()->transitions();
1498 int transition = transitions->Search(*key);
1499 if (transition == TransitionArray::kNotFound) return false;
1500 PropertyDetails target_details = transitions->GetTargetDetails(transition);
1501 if (target_details.type() != FIELD) return false;
1502 if (target_details.attributes() != NONE) return false;
1503 target = Handle<Map>(transitions->GetTarget(transition));
1504 }
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00001505 JSObject::AddFastPropertyUsingMap(object, target);
1506 return true;
1507}
1508
1509
1510int JSObject::LastAddedFieldIndex() {
1511 Map* map = this->map();
1512 int last_added = map->LastAdded();
1513 return map->instance_descriptors()->GetFieldIndex(last_added);
1514}
1515
1516
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001517ACCESSORS(Oddball, to_string, String, kToStringOffset)
1518ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1519
1520
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001521byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001522 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001523}
1524
1525
1526void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001527 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001528}
1529
1530
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001531Object* JSGlobalPropertyCell::value() {
1532 return READ_FIELD(this, kValueOffset);
1533}
1534
1535
1536void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1537 // The write barrier is not used for global property cells.
1538 ASSERT(!val->IsJSGlobalPropertyCell());
1539 WRITE_FIELD(this, kValueOffset, val);
1540}
1541
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001542
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001543int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001544 InstanceType type = map()->instance_type();
1545 // Check for the most common kind of JavaScript object before
1546 // falling into the generic switch. This speeds up the internal
1547 // field operations considerably on average.
1548 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1549 switch (type) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001550 case JS_MODULE_TYPE:
1551 return JSModule::kSize;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001552 case JS_GLOBAL_PROXY_TYPE:
1553 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001554 case JS_GLOBAL_OBJECT_TYPE:
1555 return JSGlobalObject::kSize;
1556 case JS_BUILTINS_OBJECT_TYPE:
1557 return JSBuiltinsObject::kSize;
1558 case JS_FUNCTION_TYPE:
1559 return JSFunction::kSize;
1560 case JS_VALUE_TYPE:
1561 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001562 case JS_DATE_TYPE:
1563 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001564 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001565 return JSArray::kSize;
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001566 case JS_ARRAY_BUFFER_TYPE:
1567 return JSArrayBuffer::kSize;
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001568 case JS_SET_TYPE:
1569 return JSSet::kSize;
1570 case JS_MAP_TYPE:
1571 return JSMap::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001572 case JS_WEAK_MAP_TYPE:
1573 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001574 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001575 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001576 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001577 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001578 case JS_MESSAGE_OBJECT_TYPE:
1579 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001580 default:
1581 UNREACHABLE();
1582 return 0;
1583 }
1584}
1585
1586
1587int JSObject::GetInternalFieldCount() {
1588 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001589 // Make sure to adjust for the number of in-object properties. These
1590 // properties do contribute to the size, but are not internal fields.
1591 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1592 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001593}
1594
1595
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001596int JSObject::GetInternalFieldOffset(int index) {
1597 ASSERT(index < GetInternalFieldCount() && index >= 0);
1598 return GetHeaderSize() + (kPointerSize * index);
1599}
1600
1601
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001602Object* JSObject::GetInternalField(int index) {
1603 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001604 // Internal objects do follow immediately after the header, whereas in-object
1605 // properties are at the end of the object. Therefore there is no need
1606 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001607 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1608}
1609
1610
1611void JSObject::SetInternalField(int index, Object* value) {
1612 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001613 // Internal objects do follow immediately after the header, whereas in-object
1614 // properties are at the end of the object. Therefore there is no need
1615 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001616 int offset = GetHeaderSize() + (kPointerSize * index);
1617 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001618 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001619}
1620
1621
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001622void JSObject::SetInternalField(int index, Smi* value) {
1623 ASSERT(index < GetInternalFieldCount() && index >= 0);
1624 // Internal objects do follow immediately after the header, whereas in-object
1625 // properties are at the end of the object. Therefore there is no need
1626 // to adjust the index here.
1627 int offset = GetHeaderSize() + (kPointerSize * index);
1628 WRITE_FIELD(this, offset, value);
1629}
1630
1631
ager@chromium.org7c537e22008-10-16 08:43:32 +00001632// Access fast-case object properties at index. The use of these routines
1633// is needed to correctly distinguish between properties stored in-object and
1634// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001635Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001636 // Adjust for the number of properties stored in the object.
1637 index -= map()->inobject_properties();
1638 if (index < 0) {
1639 int offset = map()->instance_size() + (index * kPointerSize);
1640 return READ_FIELD(this, offset);
1641 } else {
1642 ASSERT(index < properties()->length());
1643 return properties()->get(index);
1644 }
1645}
1646
1647
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001648Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001649 // Adjust for the number of properties stored in the object.
1650 index -= map()->inobject_properties();
1651 if (index < 0) {
1652 int offset = map()->instance_size() + (index * kPointerSize);
1653 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001654 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001655 } else {
1656 ASSERT(index < properties()->length());
1657 properties()->set(index, value);
1658 }
1659 return value;
1660}
1661
1662
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001663int JSObject::GetInObjectPropertyOffset(int index) {
1664 // Adjust for the number of properties stored in the object.
1665 index -= map()->inobject_properties();
1666 ASSERT(index < 0);
1667 return map()->instance_size() + (index * kPointerSize);
1668}
1669
1670
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001671Object* JSObject::InObjectPropertyAt(int index) {
1672 // Adjust for the number of properties stored in the object.
1673 index -= map()->inobject_properties();
1674 ASSERT(index < 0);
1675 int offset = map()->instance_size() + (index * kPointerSize);
1676 return READ_FIELD(this, offset);
1677}
1678
1679
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001680Object* JSObject::InObjectPropertyAtPut(int index,
1681 Object* value,
1682 WriteBarrierMode mode) {
1683 // Adjust for the number of properties stored in the object.
1684 index -= map()->inobject_properties();
1685 ASSERT(index < 0);
1686 int offset = map()->instance_size() + (index * kPointerSize);
1687 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001688 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001689 return value;
1690}
1691
1692
1693
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001694void JSObject::InitializeBody(Map* map,
1695 Object* pre_allocated_value,
1696 Object* filler_value) {
1697 ASSERT(!filler_value->IsHeapObject() ||
1698 !GetHeap()->InNewSpace(filler_value));
1699 ASSERT(!pre_allocated_value->IsHeapObject() ||
1700 !GetHeap()->InNewSpace(pre_allocated_value));
1701 int size = map->instance_size();
1702 int offset = kHeaderSize;
1703 if (filler_value != pre_allocated_value) {
1704 int pre_allocated = map->pre_allocated_property_fields();
1705 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1706 for (int i = 0; i < pre_allocated; i++) {
1707 WRITE_FIELD(this, offset, pre_allocated_value);
1708 offset += kPointerSize;
1709 }
1710 }
1711 while (offset < size) {
1712 WRITE_FIELD(this, offset, filler_value);
1713 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001714 }
1715}
1716
1717
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001718bool JSObject::HasFastProperties() {
erik.corry@gmail.com88767242012-08-08 14:43:45 +00001719 ASSERT(properties()->IsDictionary() == map()->is_dictionary_map());
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001720 return !properties()->IsDictionary();
1721}
1722
1723
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001724bool JSObject::TooManyFastProperties(int properties,
1725 JSObject::StoreFromKeyed store_mode) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001726 // Allow extra fast properties if the object has more than
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001727 // kFastPropertiesSoftLimit in-object properties. When this is the case,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001728 // it is very unlikely that the object is being used as a dictionary
1729 // and there is a good chance that allowing more map transitions
1730 // will be worth it.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001731 int inobject = map()->inobject_properties();
1732
1733 int limit;
ulan@chromium.orgf6a0c412012-06-15 12:31:06 +00001734 if (store_mode == CERTAINLY_NOT_STORE_FROM_KEYED) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001735 limit = Max(inobject, kMaxFastProperties);
1736 } else {
1737 limit = Max(inobject, kFastPropertiesSoftLimit);
1738 }
1739 return properties > limit;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001740}
1741
1742
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001743void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001744 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001745 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001746 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001747 }
1748}
1749
1750
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001751bool Object::ToArrayIndex(uint32_t* index) {
1752 if (IsSmi()) {
1753 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754 if (value < 0) return false;
1755 *index = value;
1756 return true;
1757 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001758 if (IsHeapNumber()) {
1759 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001760 uint32_t uint_value = static_cast<uint32_t>(value);
1761 if (value == static_cast<double>(uint_value)) {
1762 *index = uint_value;
1763 return true;
1764 }
1765 }
1766 return false;
1767}
1768
1769
1770bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1771 if (!this->IsJSValue()) return false;
1772
1773 JSValue* js_value = JSValue::cast(this);
1774 if (!js_value->value()->IsString()) return false;
1775
1776 String* str = String::cast(js_value->value());
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00001777 if (index >= static_cast<uint32_t>(str->length())) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001778
1779 return true;
1780}
1781
1782
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00001783
1784void Object::VerifyApiCallResultType() {
1785#if ENABLE_EXTRA_CHECKS
1786 if (!(IsSmi() ||
1787 IsString() ||
1788 IsSpecObject() ||
1789 IsHeapNumber() ||
1790 IsUndefined() ||
1791 IsTrue() ||
1792 IsFalse() ||
1793 IsNull())) {
1794 FATAL("API call returned invalid object");
1795 }
1796#endif // ENABLE_EXTRA_CHECKS
1797}
1798
1799
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001800FixedArrayBase* FixedArrayBase::cast(Object* object) {
1801 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1802 return reinterpret_cast<FixedArrayBase*>(object);
1803}
1804
1805
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001806Object* FixedArray::get(int index) {
1807 ASSERT(index >= 0 && index < this->length());
1808 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1809}
1810
1811
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001812bool FixedArray::is_the_hole(int index) {
1813 return get(index) == GetHeap()->the_hole_value();
1814}
1815
1816
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001817void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001818 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001819 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001820 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1821 int offset = kHeaderSize + index * kPointerSize;
1822 WRITE_FIELD(this, offset, value);
1823}
1824
1825
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001826void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001827 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001828 ASSERT(index >= 0 && index < this->length());
1829 int offset = kHeaderSize + index * kPointerSize;
1830 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001831 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001832}
1833
1834
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001835inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1836 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1837}
1838
1839
1840inline double FixedDoubleArray::hole_nan_as_double() {
1841 return BitCast<double, uint64_t>(kHoleNanInt64);
1842}
1843
1844
1845inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1846 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1847 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1848 return OS::nan_value();
1849}
1850
1851
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001852double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001853 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1854 map() != HEAP->fixed_array_map());
1855 ASSERT(index >= 0 && index < this->length());
1856 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1857 ASSERT(!is_the_hole_nan(result));
1858 return result;
1859}
1860
danno@chromium.org88aa0582012-03-23 15:11:57 +00001861int64_t FixedDoubleArray::get_representation(int index) {
1862 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1863 map() != HEAP->fixed_array_map());
1864 ASSERT(index >= 0 && index < this->length());
1865 return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1866}
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001867
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001868MaybeObject* FixedDoubleArray::get(int index) {
1869 if (is_the_hole(index)) {
1870 return GetHeap()->the_hole_value();
1871 } else {
1872 return GetHeap()->NumberFromDouble(get_scalar(index));
1873 }
1874}
1875
1876
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001877void FixedDoubleArray::set(int index, double value) {
1878 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1879 map() != HEAP->fixed_array_map());
1880 int offset = kHeaderSize + index * kDoubleSize;
1881 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1882 WRITE_DOUBLE_FIELD(this, offset, value);
1883}
1884
1885
1886void FixedDoubleArray::set_the_hole(int index) {
1887 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1888 map() != HEAP->fixed_array_map());
1889 int offset = kHeaderSize + index * kDoubleSize;
1890 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1891}
1892
1893
1894bool FixedDoubleArray::is_the_hole(int index) {
1895 int offset = kHeaderSize + index * kDoubleSize;
1896 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1897}
1898
1899
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001900WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001901 Heap* heap = GetHeap();
1902 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1903 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001904 return UPDATE_WRITE_BARRIER;
1905}
1906
1907
1908void FixedArray::set(int index,
1909 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001910 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001911 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001912 ASSERT(index >= 0 && index < this->length());
1913 int offset = kHeaderSize + index * kPointerSize;
1914 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001915 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001916}
1917
1918
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001919void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1920 int index,
1921 Object* value) {
danno@chromium.org72204d52012-10-31 10:02:10 +00001922 ASSERT(array->map() != HEAP->fixed_cow_array_map());
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001923 ASSERT(index >= 0 && index < array->length());
1924 int offset = kHeaderSize + index * kPointerSize;
1925 WRITE_FIELD(array, offset, value);
1926 Heap* heap = array->GetHeap();
1927 if (heap->InNewSpace(value)) {
1928 heap->RecordWrite(array->address(), offset);
1929 }
1930}
1931
1932
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001933void FixedArray::NoWriteBarrierSet(FixedArray* array,
1934 int index,
1935 Object* value) {
danno@chromium.org72204d52012-10-31 10:02:10 +00001936 ASSERT(array->map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001937 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001938 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001939 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1940}
1941
1942
1943void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001944 ASSERT(map() != HEAP->fixed_cow_array_map());
1945 set_undefined(GetHeap(), index);
1946}
1947
1948
1949void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001950 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001951 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001952 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001953 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001954}
1955
1956
ager@chromium.org236ad962008-09-25 09:45:57 +00001957void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001958 set_null(GetHeap(), index);
1959}
1960
1961
1962void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001963 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001964 ASSERT(!heap->InNewSpace(heap->null_value()));
1965 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001966}
1967
1968
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001969void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001970 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001971 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001972 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1973 WRITE_FIELD(this,
1974 kHeaderSize + index * kPointerSize,
1975 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001976}
1977
1978
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001979void FixedArray::set_unchecked(int index, Smi* value) {
1980 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1981 int offset = kHeaderSize + index * kPointerSize;
1982 WRITE_FIELD(this, offset, value);
1983}
1984
1985
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001986void FixedArray::set_unchecked(Heap* heap,
1987 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001988 Object* value,
1989 WriteBarrierMode mode) {
1990 int offset = kHeaderSize + index * kPointerSize;
1991 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001992 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001993}
1994
1995
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001996void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001997 ASSERT(index >= 0 && index < this->length());
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00001998 ASSERT(!heap->InNewSpace(heap->null_value()));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001999 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00002000}
2001
2002
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002003double* FixedDoubleArray::data_start() {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00002004 return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002005}
2006
2007
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002008Object** FixedArray::data_start() {
2009 return HeapObject::RawField(this, kHeaderSize);
2010}
2011
2012
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00002013bool DescriptorArray::IsEmpty() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002014 ASSERT(length() >= kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002015 this == HEAP->empty_descriptor_array());
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002016 return length() < kFirstIndex;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002017}
2018
2019
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002020void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
2021 WRITE_FIELD(
2022 this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors));
2023}
2024
2025
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002026// Perform a binary search in a fixed array. Low and high are entry indices. If
2027// there are three entries in this array it should be called with low=0 and
2028// high=2.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002029template<SearchMode search_mode, typename T>
ulan@chromium.org750145a2013-03-07 15:14:13 +00002030int BinarySearch(T* array, Name* name, int low, int high, int valid_entries) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002031 uint32_t hash = name->Hash();
2032 int limit = high;
2033
2034 ASSERT(low <= high);
2035
2036 while (low != high) {
2037 int mid = (low + high) / 2;
ulan@chromium.org750145a2013-03-07 15:14:13 +00002038 Name* mid_name = array->GetSortedKey(mid);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002039 uint32_t mid_hash = mid_name->Hash();
2040
2041 if (mid_hash >= hash) {
2042 high = mid;
2043 } else {
2044 low = mid + 1;
2045 }
2046 }
2047
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002048 for (; low <= limit; ++low) {
2049 int sort_index = array->GetSortedKeyIndex(low);
ulan@chromium.org750145a2013-03-07 15:14:13 +00002050 Name* entry = array->GetKey(sort_index);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002051 if (entry->Hash() != hash) break;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002052 if (entry->Equals(name)) {
2053 if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
2054 return sort_index;
2055 }
2056 return T::kNotFound;
2057 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002058 }
2059
2060 return T::kNotFound;
2061}
2062
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002063
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002064// Perform a linear search in this fixed array. len is the number of entry
2065// indices that are valid.
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002066template<SearchMode search_mode, typename T>
ulan@chromium.org750145a2013-03-07 15:14:13 +00002067int LinearSearch(T* array, Name* name, int len, int valid_entries) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002068 uint32_t hash = name->Hash();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002069 if (search_mode == ALL_ENTRIES) {
2070 for (int number = 0; number < len; number++) {
2071 int sorted_index = array->GetSortedKeyIndex(number);
ulan@chromium.org750145a2013-03-07 15:14:13 +00002072 Name* entry = array->GetKey(sorted_index);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002073 uint32_t current_hash = entry->Hash();
2074 if (current_hash > hash) break;
2075 if (current_hash == hash && entry->Equals(name)) return sorted_index;
2076 }
2077 } else {
2078 ASSERT(len >= valid_entries);
2079 for (int number = 0; number < valid_entries; number++) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002080 Name* entry = array->GetKey(number);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002081 uint32_t current_hash = entry->Hash();
2082 if (current_hash == hash && entry->Equals(name)) return number;
2083 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002084 }
2085 return T::kNotFound;
2086}
2087
2088
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002089template<SearchMode search_mode, typename T>
ulan@chromium.org750145a2013-03-07 15:14:13 +00002090int Search(T* array, Name* name, int valid_entries) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002091 if (search_mode == VALID_ENTRIES) {
2092 SLOW_ASSERT(array->IsSortedNoDuplicates(valid_entries));
2093 } else {
2094 SLOW_ASSERT(array->IsSortedNoDuplicates());
2095 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002096
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002097 int nof = array->number_of_entries();
2098 if (nof == 0) return T::kNotFound;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002099
2100 // Fast case: do linear search for small arrays.
2101 const int kMaxElementsForLinearSearch = 8;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002102 if ((search_mode == ALL_ENTRIES &&
2103 nof <= kMaxElementsForLinearSearch) ||
2104 (search_mode == VALID_ENTRIES &&
2105 valid_entries <= (kMaxElementsForLinearSearch * 3))) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002106 return LinearSearch<search_mode>(array, name, nof, valid_entries);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002107 }
2108
2109 // Slow case: perform binary search.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002110 return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002111}
2112
2113
ulan@chromium.org750145a2013-03-07 15:14:13 +00002114int DescriptorArray::Search(Name* name, int valid_descriptors) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002115 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002116}
2117
2118
ulan@chromium.org750145a2013-03-07 15:14:13 +00002119int DescriptorArray::SearchWithCache(Name* name, Map* map) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002120 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
2121 if (number_of_own_descriptors == 0) return kNotFound;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002122
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002123 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002124 int number = cache->Lookup(map, name);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002125
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002126 if (number == DescriptorLookupCache::kAbsent) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002127 number = Search(name, number_of_own_descriptors);
2128 cache->Update(map, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002129 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002130
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002131 return number;
2132}
2133
2134
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002135void Map::LookupDescriptor(JSObject* holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +00002136 Name* name,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002137 LookupResult* result) {
2138 DescriptorArray* descriptors = this->instance_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002139 int number = descriptors->SearchWithCache(name, this);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002140 if (number == DescriptorArray::kNotFound) return result->NotFound();
2141 result->DescriptorResult(holder, descriptors->GetDetails(number), number);
2142}
2143
2144
2145void Map::LookupTransition(JSObject* holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +00002146 Name* name,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002147 LookupResult* result) {
2148 if (HasTransitionArray()) {
2149 TransitionArray* transition_array = transitions();
2150 int number = transition_array->Search(name);
2151 if (number != TransitionArray::kNotFound) {
2152 return result->TransitionResult(holder, number);
2153 }
2154 }
2155 result->NotFound();
2156}
2157
2158
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002159Object** DescriptorArray::GetKeySlot(int descriptor_number) {
2160 ASSERT(descriptor_number < number_of_descriptors());
2161 return HeapObject::RawField(
2162 reinterpret_cast<HeapObject*>(this),
2163 OffsetOfElementAt(ToKeyIndex(descriptor_number)));
2164}
2165
2166
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00002167Object** DescriptorArray::GetDescriptorStartSlot(int descriptor_number) {
2168 return GetKeySlot(descriptor_number);
2169}
2170
2171
2172Object** DescriptorArray::GetDescriptorEndSlot(int descriptor_number) {
2173 return GetValueSlot(descriptor_number - 1) + 1;
2174}
2175
2176
ulan@chromium.org750145a2013-03-07 15:14:13 +00002177Name* DescriptorArray::GetKey(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002178 ASSERT(descriptor_number < number_of_descriptors());
ulan@chromium.org750145a2013-03-07 15:14:13 +00002179 return Name::cast(get(ToKeyIndex(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002180}
2181
2182
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002183int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
2184 return GetDetails(descriptor_number).pointer();
2185}
2186
2187
ulan@chromium.org750145a2013-03-07 15:14:13 +00002188Name* DescriptorArray::GetSortedKey(int descriptor_number) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002189 return GetKey(GetSortedKeyIndex(descriptor_number));
2190}
2191
2192
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002193void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
2194 PropertyDetails details = GetDetails(descriptor_index);
2195 set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi());
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002196}
2197
2198
verwaest@chromium.org37141392012-05-31 13:27:02 +00002199Object** DescriptorArray::GetValueSlot(int descriptor_number) {
2200 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002201 return HeapObject::RawField(
2202 reinterpret_cast<HeapObject*>(this),
2203 OffsetOfElementAt(ToValueIndex(descriptor_number)));
verwaest@chromium.org37141392012-05-31 13:27:02 +00002204}
2205
2206
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002207Object* DescriptorArray::GetValue(int descriptor_number) {
2208 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002209 return get(ToValueIndex(descriptor_number));
2210}
2211
2212
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002213PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002214 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002215 Object* details = get(ToDetailsIndex(descriptor_number));
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002216 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002217}
2218
2219
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002220PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002221 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002222}
2223
2224
2225int DescriptorArray::GetFieldIndex(int descriptor_number) {
2226 return Descriptor::IndexFromValue(GetValue(descriptor_number));
2227}
2228
2229
2230JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
2231 return JSFunction::cast(GetValue(descriptor_number));
2232}
2233
2234
2235Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
2236 ASSERT(GetType(descriptor_number) == CALLBACKS);
2237 return GetValue(descriptor_number);
2238}
2239
2240
2241AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
2242 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002243 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002244 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002245}
2246
2247
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002248void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2249 desc->Init(GetKey(descriptor_number),
2250 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002251 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002252}
2253
2254
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002255void DescriptorArray::Set(int descriptor_number,
2256 Descriptor* desc,
2257 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002258 // Range check.
2259 ASSERT(descriptor_number < number_of_descriptors());
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002260 ASSERT(desc->GetDetails().descriptor_index() <=
2261 number_of_descriptors());
2262 ASSERT(desc->GetDetails().descriptor_index() > 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002263
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002264 NoIncrementalWriteBarrierSet(this,
2265 ToKeyIndex(descriptor_number),
2266 desc->GetKey());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002267 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002268 ToValueIndex(descriptor_number),
2269 desc->GetValue());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002270 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002271 ToDetailsIndex(descriptor_number),
2272 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002273}
2274
2275
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002276void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
2277 // Range check.
2278 ASSERT(descriptor_number < number_of_descriptors());
2279 ASSERT(desc->GetDetails().descriptor_index() <=
2280 number_of_descriptors());
2281 ASSERT(desc->GetDetails().descriptor_index() > 0);
2282
2283 set(ToKeyIndex(descriptor_number), desc->GetKey());
2284 set(ToValueIndex(descriptor_number), desc->GetValue());
2285 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
2286}
2287
2288
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002289void DescriptorArray::Append(Descriptor* desc,
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002290 const WhitenessWitness& witness) {
2291 int descriptor_number = number_of_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002292 int enumeration_index = descriptor_number + 1;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002293 SetNumberOfDescriptors(descriptor_number + 1);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002294 desc->SetEnumerationIndex(enumeration_index);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002295 Set(descriptor_number, desc, witness);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002296
2297 uint32_t hash = desc->GetKey()->Hash();
2298
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002299 int insertion;
2300
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002301 for (insertion = descriptor_number; insertion > 0; --insertion) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002302 Name* key = GetSortedKey(insertion - 1);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002303 if (key->Hash() <= hash) break;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002304 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002305 }
2306
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002307 SetSortedKey(insertion, descriptor_number);
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002308}
2309
2310
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002311void DescriptorArray::Append(Descriptor* desc) {
2312 int descriptor_number = number_of_descriptors();
2313 int enumeration_index = descriptor_number + 1;
2314 SetNumberOfDescriptors(descriptor_number + 1);
2315 desc->SetEnumerationIndex(enumeration_index);
2316 Set(descriptor_number, desc);
2317
2318 uint32_t hash = desc->GetKey()->Hash();
2319
2320 int insertion;
2321
2322 for (insertion = descriptor_number; insertion > 0; --insertion) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002323 Name* key = GetSortedKey(insertion - 1);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002324 if (key->Hash() <= hash) break;
2325 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
2326 }
2327
2328 SetSortedKey(insertion, descriptor_number);
2329}
2330
2331
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002332void DescriptorArray::SwapSortedKeys(int first, int second) {
2333 int first_key = GetSortedKeyIndex(first);
2334 SetSortedKey(first, GetSortedKeyIndex(second));
2335 SetSortedKey(second, first_key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002336}
2337
2338
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002339DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002340 : marking_(array->GetHeap()->incremental_marking()) {
2341 marking_->EnterNoMarkingScope();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002342 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002343}
2344
2345
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002346DescriptorArray::WhitenessWitness::~WhitenessWitness() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002347 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002348}
2349
2350
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002351template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002352int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2353 const int kMinCapacity = 32;
2354 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2355 if (capacity < kMinCapacity) {
2356 capacity = kMinCapacity; // Guarantee min capacity.
2357 }
2358 return capacity;
2359}
2360
2361
2362template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002363int HashTable<Shape, Key>::FindEntry(Key key) {
2364 return FindEntry(GetIsolate(), key);
2365}
2366
2367
2368// Find entry for key otherwise return kNotFound.
2369template<typename Shape, typename Key>
2370int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2371 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002372 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002373 uint32_t count = 1;
2374 // EnsureCapacity will guarantee the hash table is never full.
2375 while (true) {
2376 Object* element = KeyAt(entry);
danno@chromium.org72204d52012-10-31 10:02:10 +00002377 // Empty entry. Uses raw unchecked accessors because it is called by the
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002378 // string table during bootstrapping.
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002379 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2380 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002381 Shape::IsMatch(key, element)) return entry;
2382 entry = NextProbe(entry, count++, capacity);
2383 }
2384 return kNotFound;
2385}
2386
2387
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002388bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002389 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002390 if (!max_index_object->IsSmi()) return false;
2391 return 0 !=
2392 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2393}
2394
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002395uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002396 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002397 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002398 if (!max_index_object->IsSmi()) return 0;
2399 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2400 return value >> kRequiresSlowElementsTagSize;
2401}
2402
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002403void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002404 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002405}
2406
2407
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002408// ------------------------------------
2409// Cast operations
2410
2411
2412CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002413CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002414CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002415CAST_ACCESSOR(DeoptimizationInputData)
2416CAST_ACCESSOR(DeoptimizationOutputData)
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002417CAST_ACCESSOR(DependentCode)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002418CAST_ACCESSOR(TypeFeedbackCells)
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002419CAST_ACCESSOR(StringTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002420CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002421CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002422CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002423CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002424CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002425CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002426CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002427CAST_ACCESSOR(String)
2428CAST_ACCESSOR(SeqString)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002429CAST_ACCESSOR(SeqOneByteString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002430CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002431CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002432CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002433CAST_ACCESSOR(ExternalString)
2434CAST_ACCESSOR(ExternalAsciiString)
2435CAST_ACCESSOR(ExternalTwoByteString)
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002436CAST_ACCESSOR(Symbol)
ulan@chromium.org750145a2013-03-07 15:14:13 +00002437CAST_ACCESSOR(Name)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002438CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002439CAST_ACCESSOR(JSObject)
2440CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002441CAST_ACCESSOR(HeapObject)
2442CAST_ACCESSOR(HeapNumber)
2443CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002444CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002445CAST_ACCESSOR(SharedFunctionInfo)
2446CAST_ACCESSOR(Map)
2447CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002448CAST_ACCESSOR(GlobalObject)
2449CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002450CAST_ACCESSOR(JSGlobalObject)
2451CAST_ACCESSOR(JSBuiltinsObject)
2452CAST_ACCESSOR(Code)
2453CAST_ACCESSOR(JSArray)
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00002454CAST_ACCESSOR(JSArrayBuffer)
ager@chromium.org236ad962008-09-25 09:45:57 +00002455CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002456CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002457CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002458CAST_ACCESSOR(JSSet)
2459CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002460CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002461CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002462CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002463CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002464CAST_ACCESSOR(ExternalArray)
2465CAST_ACCESSOR(ExternalByteArray)
2466CAST_ACCESSOR(ExternalUnsignedByteArray)
2467CAST_ACCESSOR(ExternalShortArray)
2468CAST_ACCESSOR(ExternalUnsignedShortArray)
2469CAST_ACCESSOR(ExternalIntArray)
2470CAST_ACCESSOR(ExternalUnsignedIntArray)
2471CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002472CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002473CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002474CAST_ACCESSOR(Struct)
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002475CAST_ACCESSOR(AccessorInfo)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002476
2477
2478#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2479 STRUCT_LIST(MAKE_STRUCT_CAST)
2480#undef MAKE_STRUCT_CAST
2481
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002482
2483template <typename Shape, typename Key>
2484HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002485 ASSERT(obj->IsHashTable());
2486 return reinterpret_cast<HashTable*>(obj);
2487}
2488
2489
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002490SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002491SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002492
ager@chromium.orgac091b72010-05-05 07:34:42 +00002493SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002494
2495
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002496uint32_t Name::hash_field() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002497 return READ_UINT32_FIELD(this, kHashFieldOffset);
2498}
2499
2500
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002501void Name::set_hash_field(uint32_t value) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002502 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002503#if V8_HOST_ARCH_64_BIT
2504 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2505#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002506}
2507
2508
ulan@chromium.org750145a2013-03-07 15:14:13 +00002509bool Name::Equals(Name* other) {
2510 if (other == this) return true;
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00002511 if (this->IsSymbol() || other->IsSymbol() ||
2512 (this->IsInternalizedString() && other->IsInternalizedString())) {
2513 return false;
2514 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00002515 return String::cast(this)->SlowEquals(String::cast(other));
2516}
2517
2518
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00002519ACCESSORS(Symbol, name, Object, kNameOffset)
2520
2521
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002522bool String::Equals(String* other) {
2523 if (other == this) return true;
ulan@chromium.org750145a2013-03-07 15:14:13 +00002524 if (this->IsInternalizedString() && other->IsInternalizedString()) {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002525 return false;
2526 }
2527 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002528}
2529
2530
lrn@chromium.org303ada72010-10-27 09:33:13 +00002531MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002532 if (!StringShape(this).IsCons()) return this;
2533 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002534 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002535 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002536}
2537
2538
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002539String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002540 MaybeObject* flat = TryFlatten(pretenure);
2541 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002542 if (!flat->ToObject(&successfully_flattened)) return this;
2543 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002544}
2545
2546
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002547uint16_t String::Get(int index) {
2548 ASSERT(index >= 0 && index < length());
2549 switch (StringShape(this).full_representation_tag()) {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002550 case kSeqStringTag | kOneByteStringTag:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002551 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002552 case kSeqStringTag | kTwoByteStringTag:
2553 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002554 case kConsStringTag | kOneByteStringTag:
ager@chromium.org870a0b62008-11-04 11:43:05 +00002555 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002556 return ConsString::cast(this)->ConsStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002557 case kExternalStringTag | kOneByteStringTag:
ager@chromium.org870a0b62008-11-04 11:43:05 +00002558 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2559 case kExternalStringTag | kTwoByteStringTag:
2560 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002561 case kSlicedStringTag | kOneByteStringTag:
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002562 case kSlicedStringTag | kTwoByteStringTag:
2563 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002564 default:
2565 break;
2566 }
2567
2568 UNREACHABLE();
2569 return 0;
2570}
2571
2572
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002573void String::Set(int index, uint16_t value) {
2574 ASSERT(index >= 0 && index < length());
2575 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002576
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00002577 return this->IsOneByteRepresentation()
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002578 ? SeqOneByteString::cast(this)->SeqOneByteStringSet(index, value)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002579 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002580}
2581
2582
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002583bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002584 if (!StringShape(this).IsCons()) return true;
2585 return ConsString::cast(this)->second()->length() == 0;
2586}
2587
2588
2589String* String::GetUnderlying() {
2590 // Giving direct access to underlying string only makes sense if the
2591 // wrapping string is already flattened.
2592 ASSERT(this->IsFlat());
2593 ASSERT(StringShape(this).IsIndirect());
2594 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2595 const int kUnderlyingOffset = SlicedString::kParentOffset;
2596 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002597}
2598
2599
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002600template<class Visitor, class ConsOp>
2601void String::Visit(
2602 String* string,
2603 unsigned offset,
2604 Visitor& visitor,
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002605 ConsOp& cons_op,
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002606 int32_t type,
2607 unsigned length) {
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002608 ASSERT(length == static_cast<unsigned>(string->length()));
2609 ASSERT(offset <= length);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002610 unsigned slice_offset = offset;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002611 while (true) {
2612 ASSERT(type == string->map()->instance_type());
2613
2614 switch (type & (kStringRepresentationMask | kStringEncodingMask)) {
2615 case kSeqStringTag | kOneByteStringTag:
2616 visitor.VisitOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002617 SeqOneByteString::cast(string)->GetChars() + slice_offset,
2618 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002619 return;
2620
2621 case kSeqStringTag | kTwoByteStringTag:
2622 visitor.VisitTwoByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002623 SeqTwoByteString::cast(string)->GetChars() + slice_offset,
2624 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002625 return;
2626
2627 case kExternalStringTag | kOneByteStringTag:
2628 visitor.VisitOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002629 ExternalAsciiString::cast(string)->GetChars() + slice_offset,
2630 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002631 return;
2632
2633 case kExternalStringTag | kTwoByteStringTag:
2634 visitor.VisitTwoByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002635 ExternalTwoByteString::cast(string)->GetChars() + slice_offset,
2636 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002637 return;
2638
2639 case kSlicedStringTag | kOneByteStringTag:
2640 case kSlicedStringTag | kTwoByteStringTag: {
2641 SlicedString* slicedString = SlicedString::cast(string);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002642 slice_offset += slicedString->offset();
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002643 string = slicedString->parent();
2644 type = string->map()->instance_type();
2645 continue;
2646 }
2647
2648 case kConsStringTag | kOneByteStringTag:
2649 case kConsStringTag | kTwoByteStringTag:
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002650 string = cons_op.Operate(string, &offset, &type, &length);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002651 if (string == NULL) return;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002652 slice_offset = offset;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002653 ASSERT(length == static_cast<unsigned>(string->length()));
2654 continue;
2655
2656 default:
2657 UNREACHABLE();
2658 return;
2659 }
2660 }
2661}
2662
2663
ulan@chromium.org750145a2013-03-07 15:14:13 +00002664// TODO(dcarney): Remove this class after conversion to VisitFlat.
2665class ConsStringCaptureOp {
2666 public:
2667 inline ConsStringCaptureOp() : cons_string_(NULL) {}
2668 inline String* Operate(String* string, unsigned*, int32_t*, unsigned*) {
2669 cons_string_ = ConsString::cast(string);
2670 return NULL;
2671 }
2672 ConsString* cons_string_;
2673};
2674
2675
2676template<class Visitor>
2677ConsString* String::VisitFlat(Visitor* visitor,
2678 String* string,
2679 int offset,
2680 int length,
2681 int32_t type) {
2682 ASSERT(length >= 0 && length == string->length());
2683 ASSERT(offset >= 0 && offset <= length);
2684 ConsStringCaptureOp op;
2685 Visit(string, offset, *visitor, op, type, static_cast<unsigned>(length));
2686 return op.cons_string_;
2687}
2688
2689
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002690uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002691 ASSERT(index >= 0 && index < length());
2692 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2693}
2694
2695
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002696void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002697 ASSERT(index >= 0 && index < length() && value <= kMaxOneByteCharCode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002698 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2699 static_cast<byte>(value));
2700}
2701
2702
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002703Address SeqOneByteString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002704 return FIELD_ADDR(this, kHeaderSize);
2705}
2706
2707
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002708uint8_t* SeqOneByteString::GetChars() {
2709 return reinterpret_cast<uint8_t*>(GetCharsAddress());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002710}
2711
2712
ager@chromium.org7c537e22008-10-16 08:43:32 +00002713Address SeqTwoByteString::GetCharsAddress() {
2714 return FIELD_ADDR(this, kHeaderSize);
2715}
2716
2717
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002718uc16* SeqTwoByteString::GetChars() {
2719 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2720}
2721
2722
ager@chromium.org7c537e22008-10-16 08:43:32 +00002723uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002724 ASSERT(index >= 0 && index < length());
2725 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2726}
2727
2728
ager@chromium.org7c537e22008-10-16 08:43:32 +00002729void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002730 ASSERT(index >= 0 && index < length());
2731 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2732}
2733
2734
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002735int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002736 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002737}
2738
2739
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002740int SeqOneByteString::SeqOneByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002741 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002742}
2743
2744
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002745String* SlicedString::parent() {
2746 return String::cast(READ_FIELD(this, kParentOffset));
2747}
2748
2749
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002750void SlicedString::set_parent(String* parent, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002751 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002752 WRITE_FIELD(this, kParentOffset, parent);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002753 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kParentOffset, parent, mode);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002754}
2755
2756
2757SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2758
2759
ager@chromium.org870a0b62008-11-04 11:43:05 +00002760String* ConsString::first() {
2761 return String::cast(READ_FIELD(this, kFirstOffset));
2762}
2763
2764
2765Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002766 return READ_FIELD(this, kFirstOffset);
2767}
2768
2769
ager@chromium.org870a0b62008-11-04 11:43:05 +00002770void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002771 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002772 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002773}
2774
2775
ager@chromium.org870a0b62008-11-04 11:43:05 +00002776String* ConsString::second() {
2777 return String::cast(READ_FIELD(this, kSecondOffset));
2778}
2779
2780
2781Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002782 return READ_FIELD(this, kSecondOffset);
2783}
2784
2785
ager@chromium.org870a0b62008-11-04 11:43:05 +00002786void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002787 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002788 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002789}
2790
2791
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002792bool ExternalString::is_short() {
2793 InstanceType type = map()->instance_type();
2794 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002795}
2796
2797
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002798const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002799 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2800}
2801
2802
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002803void ExternalAsciiString::update_data_cache() {
2804 if (is_short()) return;
2805 const char** data_field =
2806 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2807 *data_field = resource()->data();
2808}
2809
2810
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002811void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002812 const ExternalAsciiString::Resource* resource) {
2813 *reinterpret_cast<const Resource**>(
2814 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002815 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002816}
2817
2818
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002819const uint8_t* ExternalAsciiString::GetChars() {
2820 return reinterpret_cast<const uint8_t*>(resource()->data());
erikcorry0ad885c2011-11-21 13:51:57 +00002821}
2822
2823
2824uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2825 ASSERT(index >= 0 && index < length());
2826 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002827}
2828
2829
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002830const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002831 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2832}
2833
2834
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002835void ExternalTwoByteString::update_data_cache() {
2836 if (is_short()) return;
2837 const uint16_t** data_field =
2838 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2839 *data_field = resource()->data();
2840}
2841
2842
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002843void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002844 const ExternalTwoByteString::Resource* resource) {
2845 *reinterpret_cast<const Resource**>(
2846 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002847 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002848}
2849
2850
2851const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002852 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002853}
2854
2855
2856uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2857 ASSERT(index >= 0 && index < length());
2858 return GetChars()[index];
2859}
2860
2861
2862const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2863 unsigned start) {
2864 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002865}
2866
2867
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002868String* ConsStringNullOp::Operate(String*, unsigned*, int32_t*, unsigned*) {
2869 return NULL;
2870}
2871
2872
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002873unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) {
2874 return depth & kDepthMask;
2875}
2876
2877
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002878void ConsStringIteratorOp::PushLeft(ConsString* string) {
2879 frames_[depth_++ & kDepthMask] = string;
2880}
2881
2882
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002883void ConsStringIteratorOp::PushRight(ConsString* string) {
2884 // Inplace update.
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002885 frames_[(depth_-1) & kDepthMask] = string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002886}
2887
2888
2889void ConsStringIteratorOp::AdjustMaximumDepth() {
2890 if (depth_ > maximum_depth_) maximum_depth_ = depth_;
2891}
2892
2893
2894void ConsStringIteratorOp::Pop() {
2895 ASSERT(depth_ > 0);
2896 ASSERT(depth_ <= maximum_depth_);
2897 depth_--;
2898}
2899
2900
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002901bool ConsStringIteratorOp::HasMore() {
2902 return depth_ != 0;
2903}
2904
2905
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002906void ConsStringIteratorOp::Reset() {
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002907 depth_ = 0;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002908}
2909
2910
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002911String* ConsStringIteratorOp::ContinueOperation(int32_t* type_out,
2912 unsigned* length_out) {
2913 bool blew_stack = false;
2914 String* string = NextLeaf(&blew_stack, type_out, length_out);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002915 // String found.
2916 if (string != NULL) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002917 // Verify output.
2918 ASSERT(*length_out == static_cast<unsigned>(string->length()));
2919 ASSERT(*type_out == string->map()->instance_type());
2920 return string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002921 }
2922 // Traversal complete.
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002923 if (!blew_stack) return NULL;
2924 // Restart search from root.
2925 unsigned offset_out;
2926 string = Search(&offset_out, type_out, length_out);
2927 // Verify output.
2928 ASSERT(string == NULL || offset_out == 0);
2929 ASSERT(string == NULL ||
2930 *length_out == static_cast<unsigned>(string->length()));
2931 ASSERT(string == NULL || *type_out == string->map()->instance_type());
2932 return string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002933}
2934
2935
2936uint16_t StringCharacterStream::GetNext() {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002937 ASSERT(buffer8_ != NULL && end_ != NULL);
2938 // Advance cursor if needed.
2939 // TODO(dcarney): Ensure uses of the api call HasMore first and avoid this.
2940 if (buffer8_ == end_) HasMore();
2941 ASSERT(buffer8_ < end_);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002942 return is_one_byte_ ? *buffer8_++ : *buffer16_++;
2943}
2944
2945
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002946StringCharacterStream::StringCharacterStream(String* string,
2947 ConsStringIteratorOp* op,
2948 unsigned offset)
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002949 : is_one_byte_(false),
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002950 op_(op) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002951 Reset(string, offset);
2952}
2953
2954
2955void StringCharacterStream::Reset(String* string, unsigned offset) {
2956 op_->Reset();
2957 buffer8_ = NULL;
2958 end_ = NULL;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002959 int32_t type = string->map()->instance_type();
2960 unsigned length = string->length();
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002961 String::Visit(string, offset, *this, *op_, type, length);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002962}
2963
2964
2965bool StringCharacterStream::HasMore() {
2966 if (buffer8_ != end_) return true;
2967 if (!op_->HasMore()) return false;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002968 unsigned length;
2969 int32_t type;
2970 String* string = op_->ContinueOperation(&type, &length);
2971 if (string == NULL) return false;
2972 ASSERT(!string->IsConsString());
2973 ASSERT(string->length() != 0);
2974 ConsStringNullOp null_op;
2975 String::Visit(string, 0, *this, null_op, type, length);
2976 ASSERT(buffer8_ != end_);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002977 return true;
2978}
2979
2980
2981void StringCharacterStream::VisitOneByteString(
2982 const uint8_t* chars, unsigned length) {
2983 is_one_byte_ = true;
2984 buffer8_ = chars;
2985 end_ = chars + length;
2986}
2987
2988
2989void StringCharacterStream::VisitTwoByteString(
2990 const uint16_t* chars, unsigned length) {
2991 is_one_byte_ = false;
2992 buffer16_ = chars;
2993 end_ = reinterpret_cast<const uint8_t*>(chars + length);
2994}
2995
2996
ager@chromium.orgac091b72010-05-05 07:34:42 +00002997void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002998 set_finger_index(kEntriesIndex);
2999 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00003000}
3001
3002
3003void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003004 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00003005 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00003006 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003007 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00003008 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00003009 MakeZeroSize();
3010}
3011
3012
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003013int JSFunctionResultCache::size() {
3014 return Smi::cast(get(kCacheSizeIndex))->value();
3015}
3016
3017
3018void JSFunctionResultCache::set_size(int size) {
3019 set(kCacheSizeIndex, Smi::FromInt(size));
3020}
3021
3022
3023int JSFunctionResultCache::finger_index() {
3024 return Smi::cast(get(kFingerIndex))->value();
3025}
3026
3027
3028void JSFunctionResultCache::set_finger_index(int finger_index) {
3029 set(kFingerIndex, Smi::FromInt(finger_index));
3030}
3031
3032
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003033byte ByteArray::get(int index) {
3034 ASSERT(index >= 0 && index < this->length());
3035 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
3036}
3037
3038
3039void ByteArray::set(int index, byte value) {
3040 ASSERT(index >= 0 && index < this->length());
3041 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
3042}
3043
3044
3045int ByteArray::get_int(int index) {
3046 ASSERT(index >= 0 && (index * kIntSize) < this->length());
3047 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
3048}
3049
3050
3051ByteArray* ByteArray::FromDataStartAddress(Address address) {
3052 ASSERT_TAG_ALIGNED(address);
3053 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
3054}
3055
3056
3057Address ByteArray::GetDataStartAddress() {
3058 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
3059}
3060
3061
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003062uint8_t* ExternalPixelArray::external_pixel_pointer() {
3063 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003064}
3065
3066
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003067uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003068 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003069 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003070 return ptr[index];
3071}
3072
3073
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003074MaybeObject* ExternalPixelArray::get(int index) {
3075 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3076}
3077
3078
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003079void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003080 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003081 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003082 ptr[index] = value;
3083}
3084
3085
ager@chromium.org3811b432009-10-28 14:53:37 +00003086void* ExternalArray::external_pointer() {
3087 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
3088 return reinterpret_cast<void*>(ptr);
3089}
3090
3091
3092void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
3093 intptr_t ptr = reinterpret_cast<intptr_t>(value);
3094 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
3095}
3096
3097
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003098int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003099 ASSERT((index >= 0) && (index < this->length()));
3100 int8_t* ptr = static_cast<int8_t*>(external_pointer());
3101 return ptr[index];
3102}
3103
3104
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003105MaybeObject* ExternalByteArray::get(int index) {
3106 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3107}
3108
3109
ager@chromium.org3811b432009-10-28 14:53:37 +00003110void ExternalByteArray::set(int index, int8_t value) {
3111 ASSERT((index >= 0) && (index < this->length()));
3112 int8_t* ptr = static_cast<int8_t*>(external_pointer());
3113 ptr[index] = value;
3114}
3115
3116
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003117uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003118 ASSERT((index >= 0) && (index < this->length()));
3119 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
3120 return ptr[index];
3121}
3122
3123
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003124MaybeObject* ExternalUnsignedByteArray::get(int index) {
3125 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3126}
3127
3128
ager@chromium.org3811b432009-10-28 14:53:37 +00003129void ExternalUnsignedByteArray::set(int index, uint8_t value) {
3130 ASSERT((index >= 0) && (index < this->length()));
3131 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
3132 ptr[index] = value;
3133}
3134
3135
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003136int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003137 ASSERT((index >= 0) && (index < this->length()));
3138 int16_t* ptr = static_cast<int16_t*>(external_pointer());
3139 return ptr[index];
3140}
3141
3142
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003143MaybeObject* ExternalShortArray::get(int index) {
3144 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3145}
3146
3147
ager@chromium.org3811b432009-10-28 14:53:37 +00003148void ExternalShortArray::set(int index, int16_t value) {
3149 ASSERT((index >= 0) && (index < this->length()));
3150 int16_t* ptr = static_cast<int16_t*>(external_pointer());
3151 ptr[index] = value;
3152}
3153
3154
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003155uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003156 ASSERT((index >= 0) && (index < this->length()));
3157 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
3158 return ptr[index];
3159}
3160
3161
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003162MaybeObject* ExternalUnsignedShortArray::get(int index) {
3163 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3164}
3165
3166
ager@chromium.org3811b432009-10-28 14:53:37 +00003167void ExternalUnsignedShortArray::set(int index, uint16_t value) {
3168 ASSERT((index >= 0) && (index < this->length()));
3169 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
3170 ptr[index] = value;
3171}
3172
3173
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003174int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003175 ASSERT((index >= 0) && (index < this->length()));
3176 int32_t* ptr = static_cast<int32_t*>(external_pointer());
3177 return ptr[index];
3178}
3179
3180
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003181MaybeObject* ExternalIntArray::get(int index) {
3182 return GetHeap()->NumberFromInt32(get_scalar(index));
3183}
3184
3185
ager@chromium.org3811b432009-10-28 14:53:37 +00003186void ExternalIntArray::set(int index, int32_t value) {
3187 ASSERT((index >= 0) && (index < this->length()));
3188 int32_t* ptr = static_cast<int32_t*>(external_pointer());
3189 ptr[index] = value;
3190}
3191
3192
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003193uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003194 ASSERT((index >= 0) && (index < this->length()));
3195 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
3196 return ptr[index];
3197}
3198
3199
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003200MaybeObject* ExternalUnsignedIntArray::get(int index) {
3201 return GetHeap()->NumberFromUint32(get_scalar(index));
3202}
3203
3204
ager@chromium.org3811b432009-10-28 14:53:37 +00003205void ExternalUnsignedIntArray::set(int index, uint32_t value) {
3206 ASSERT((index >= 0) && (index < this->length()));
3207 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
3208 ptr[index] = value;
3209}
3210
3211
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003212float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003213 ASSERT((index >= 0) && (index < this->length()));
3214 float* ptr = static_cast<float*>(external_pointer());
3215 return ptr[index];
3216}
3217
3218
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003219MaybeObject* ExternalFloatArray::get(int index) {
3220 return GetHeap()->NumberFromDouble(get_scalar(index));
3221}
3222
3223
ager@chromium.org3811b432009-10-28 14:53:37 +00003224void ExternalFloatArray::set(int index, float value) {
3225 ASSERT((index >= 0) && (index < this->length()));
3226 float* ptr = static_cast<float*>(external_pointer());
3227 ptr[index] = value;
3228}
3229
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00003230
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003231double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003232 ASSERT((index >= 0) && (index < this->length()));
3233 double* ptr = static_cast<double*>(external_pointer());
3234 return ptr[index];
3235}
3236
3237
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003238MaybeObject* ExternalDoubleArray::get(int index) {
3239 return GetHeap()->NumberFromDouble(get_scalar(index));
3240}
3241
3242
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003243void ExternalDoubleArray::set(int index, double value) {
3244 ASSERT((index >= 0) && (index < this->length()));
3245 double* ptr = static_cast<double*>(external_pointer());
3246 ptr[index] = value;
3247}
3248
3249
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00003250int Map::visitor_id() {
3251 return READ_BYTE_FIELD(this, kVisitorIdOffset);
3252}
3253
3254
3255void Map::set_visitor_id(int id) {
3256 ASSERT(0 <= id && id < 256);
3257 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
3258}
3259
ager@chromium.org3811b432009-10-28 14:53:37 +00003260
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003261int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00003262 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
3263}
3264
3265
3266int Map::inobject_properties() {
3267 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003268}
3269
3270
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003271int Map::pre_allocated_property_fields() {
3272 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
3273}
3274
3275
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003276int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003277 int instance_size = map->instance_size();
3278 if (instance_size != kVariableSizeSentinel) return instance_size;
ulan@chromium.org750145a2013-03-07 15:14:13 +00003279 // We can ignore the "internalized" bit because it is only set for strings
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00003280 // and thus implies a string type.
3281 int instance_type =
3282 static_cast<int>(map->instance_type()) & ~kIsInternalizedMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003283 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003284 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003285 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003286 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003287 if (instance_type == ASCII_STRING_TYPE) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003288 return SeqOneByteString::SizeFor(
3289 reinterpret_cast<SeqOneByteString*>(this)->length());
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003290 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003291 if (instance_type == BYTE_ARRAY_TYPE) {
3292 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
3293 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003294 if (instance_type == FREE_SPACE_TYPE) {
3295 return reinterpret_cast<FreeSpace*>(this)->size();
3296 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003297 if (instance_type == STRING_TYPE) {
3298 return SeqTwoByteString::SizeFor(
3299 reinterpret_cast<SeqTwoByteString*>(this)->length());
3300 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003301 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
3302 return FixedDoubleArray::SizeFor(
3303 reinterpret_cast<FixedDoubleArray*>(this)->length());
3304 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003305 ASSERT(instance_type == CODE_TYPE);
3306 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003307}
3308
3309
3310void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003311 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003312 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003313 ASSERT(0 <= value && value < 256);
3314 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
3315}
3316
3317
ager@chromium.org7c537e22008-10-16 08:43:32 +00003318void Map::set_inobject_properties(int value) {
3319 ASSERT(0 <= value && value < 256);
3320 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
3321}
3322
3323
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003324void Map::set_pre_allocated_property_fields(int value) {
3325 ASSERT(0 <= value && value < 256);
3326 WRITE_BYTE_FIELD(this,
3327 kPreAllocatedPropertyFieldsOffset,
3328 static_cast<byte>(value));
3329}
3330
3331
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003332InstanceType Map::instance_type() {
3333 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
3334}
3335
3336
3337void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003338 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
3339}
3340
3341
3342int Map::unused_property_fields() {
3343 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
3344}
3345
3346
3347void Map::set_unused_property_fields(int value) {
3348 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
3349}
3350
3351
3352byte Map::bit_field() {
3353 return READ_BYTE_FIELD(this, kBitFieldOffset);
3354}
3355
3356
3357void Map::set_bit_field(byte value) {
3358 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
3359}
3360
3361
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00003362byte Map::bit_field2() {
3363 return READ_BYTE_FIELD(this, kBitField2Offset);
3364}
3365
3366
3367void Map::set_bit_field2(byte value) {
3368 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
3369}
3370
3371
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003372void Map::set_non_instance_prototype(bool value) {
3373 if (value) {
3374 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
3375 } else {
3376 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
3377 }
3378}
3379
3380
3381bool Map::has_non_instance_prototype() {
3382 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
3383}
3384
3385
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003386void Map::set_function_with_prototype(bool value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003387 set_bit_field3(FunctionWithPrototype::update(bit_field3(), value));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003388}
3389
3390
3391bool Map::function_with_prototype() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003392 return FunctionWithPrototype::decode(bit_field3());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003393}
3394
3395
ager@chromium.org870a0b62008-11-04 11:43:05 +00003396void Map::set_is_access_check_needed(bool access_check_needed) {
3397 if (access_check_needed) {
3398 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
3399 } else {
3400 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
3401 }
3402}
3403
3404
3405bool Map::is_access_check_needed() {
3406 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
3407}
3408
3409
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003410void Map::set_is_extensible(bool value) {
3411 if (value) {
3412 set_bit_field2(bit_field2() | (1 << kIsExtensible));
3413 } else {
3414 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
3415 }
3416}
3417
3418bool Map::is_extensible() {
3419 return ((1 << kIsExtensible) & bit_field2()) != 0;
3420}
3421
3422
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003423void Map::set_attached_to_shared_function_info(bool value) {
3424 if (value) {
3425 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
3426 } else {
3427 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
3428 }
3429}
3430
3431bool Map::attached_to_shared_function_info() {
3432 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
3433}
3434
3435
3436void Map::set_is_shared(bool value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003437 set_bit_field3(IsShared::update(bit_field3(), value));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003438}
3439
erik.corry@gmail.com88767242012-08-08 14:43:45 +00003440
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003441bool Map::is_shared() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003442 return IsShared::decode(bit_field3());
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003443}
3444
3445
erik.corry@gmail.com88767242012-08-08 14:43:45 +00003446void Map::set_dictionary_map(bool value) {
3447 set_bit_field3(DictionaryMap::update(bit_field3(), value));
3448}
3449
3450
3451bool Map::is_dictionary_map() {
3452 return DictionaryMap::decode(bit_field3());
3453}
3454
3455
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003456JSFunction* Map::unchecked_constructor() {
3457 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
3458}
3459
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003460
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003461Code::Flags Code::flags() {
3462 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
3463}
3464
3465
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00003466inline bool Map::CanTrackAllocationSite() {
3467 return instance_type() == JS_ARRAY_TYPE;
3468}
3469
3470
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00003471void Map::set_owns_descriptors(bool is_shared) {
3472 set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
3473}
3474
3475
3476bool Map::owns_descriptors() {
3477 return OwnsDescriptors::decode(bit_field3());
3478}
3479
3480
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00003481void Map::set_is_observed(bool is_observed) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003482 ASSERT(instance_type() < FIRST_JS_OBJECT_TYPE ||
3483 instance_type() > LAST_JS_OBJECT_TYPE ||
3484 has_slow_elements_kind() || has_external_array_elements());
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00003485 set_bit_field3(IsObserved::update(bit_field3(), is_observed));
3486}
3487
3488
3489bool Map::is_observed() {
3490 return IsObserved::decode(bit_field3());
3491}
3492
3493
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003494void Map::NotifyLeafMapLayoutChange() {
3495 dependent_code()->DeoptimizeDependentCodeGroup(
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003496 GetIsolate(),
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003497 DependentCode::kPrototypeCheckGroup);
3498}
3499
3500
3501bool Map::CanOmitPrototypeChecks() {
3502 return !HasTransitionArray() && !is_dictionary_map() &&
3503 FLAG_omit_prototype_checks_for_leaf_maps;
3504}
3505
3506
3507void Map::AddDependentCode(DependentCode::DependencyGroup group,
3508 Handle<Code> code) {
3509 Handle<DependentCode> codes =
3510 DependentCode::Insert(Handle<DependentCode>(dependent_code()),
3511 group, code);
3512 if (*codes != dependent_code()) {
3513 set_dependent_code(*codes);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003514 }
3515}
3516
3517
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003518int DependentCode::number_of_entries(DependencyGroup group) {
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003519 if (length() == 0) return 0;
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003520 return Smi::cast(get(group))->value();
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003521}
3522
3523
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003524void DependentCode::set_number_of_entries(DependencyGroup group, int value) {
3525 set(group, Smi::FromInt(value));
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003526}
3527
3528
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003529Code* DependentCode::code_at(int i) {
3530 return Code::cast(get(kCodesStartIndex + i));
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003531}
3532
3533
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003534void DependentCode::set_code_at(int i, Code* value) {
3535 set(kCodesStartIndex + i, value);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003536}
3537
3538
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003539Object** DependentCode::code_slot_at(int i) {
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003540 return HeapObject::RawField(
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003541 this, FixedArray::OffsetOfElementAt(kCodesStartIndex + i));
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003542}
3543
3544
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003545void DependentCode::clear_code_at(int i) {
3546 set_undefined(kCodesStartIndex + i);
3547}
3548
3549
3550void DependentCode::ExtendGroup(DependencyGroup group) {
3551 GroupStartIndexes starts(this);
3552 for (int g = kGroupCount - 1; g > group; g--) {
3553 if (starts.at(g) < starts.at(g + 1)) {
3554 set_code_at(starts.at(g + 1), code_at(starts.at(g)));
3555 }
3556 }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003557}
3558
3559
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003560void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003561 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003562 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003563 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
3564 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003565 ExtractArgumentsCountFromFlags(flags) >= 0);
3566 WRITE_INT_FIELD(this, kFlagsOffset, flags);
3567}
3568
3569
3570Code::Kind Code::kind() {
3571 return ExtractKindFromFlags(flags());
3572}
3573
3574
kasper.lund7276f142008-07-30 08:49:36 +00003575InlineCacheState Code::ic_state() {
3576 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003577 // Only allow uninitialized or debugger states for non-IC code
3578 // objects. This is used in the debugger to determine whether or not
3579 // a call to code object has been replaced with a debug break call.
3580 ASSERT(is_inline_cache_stub() ||
3581 result == UNINITIALIZED ||
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003582 result == DEBUG_STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003583 return result;
3584}
3585
3586
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003587Code::ExtraICState Code::extra_ic_state() {
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003588 ASSERT(is_inline_cache_stub() || ic_state() == DEBUG_STUB);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003589 return ExtractExtraICStateFromFlags(flags());
3590}
3591
3592
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003593Code::StubType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003594 return ExtractTypeFromFlags(flags());
3595}
3596
3597
3598int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003599 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003600 return ExtractArgumentsCountFromFlags(flags());
3601}
3602
3603
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003604int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003605 ASSERT(kind() == STUB ||
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003606 kind() == COMPILED_STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003607 kind() == UNARY_OP_IC ||
3608 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003609 kind() == COMPARE_IC ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00003610 kind() == LOAD_IC ||
3611 kind() == KEYED_LOAD_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003612 kind() == TO_BOOLEAN_IC);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003613 return StubMajorKeyField::decode(
3614 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasper.lund7276f142008-07-30 08:49:36 +00003615}
3616
3617
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003618void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003619 ASSERT(kind() == STUB ||
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003620 kind() == COMPILED_STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003621 kind() == UNARY_OP_IC ||
3622 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003623 kind() == COMPARE_IC ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00003624 kind() == LOAD_IC ||
3625 kind() == KEYED_LOAD_IC ||
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00003626 kind() == STORE_IC ||
3627 kind() == KEYED_STORE_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003628 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003629 ASSERT(0 <= major && major < 256);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003630 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3631 int updated = StubMajorKeyField::update(previous, major);
3632 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003633}
3634
3635
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003636bool Code::is_pregenerated() {
3637 return kind() == STUB && IsPregeneratedField::decode(flags());
3638}
3639
3640
3641void Code::set_is_pregenerated(bool value) {
3642 ASSERT(kind() == STUB);
3643 Flags f = flags();
3644 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3645 set_flags(f);
3646}
3647
3648
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003649bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003650 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003651 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3652}
3653
3654
3655void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003656 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003657 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3658}
3659
3660
3661bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003662 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003663 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3664 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003665}
3666
3667
3668void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003669 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003670 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3671 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3672 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3673}
3674
3675
3676bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003677 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003678 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3679 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3680}
3681
3682
3683void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003684 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003685 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3686 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3687 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003688}
3689
3690
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003691bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003692 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003693 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3694 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3695}
3696
3697
3698void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003699 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003700 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3701 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3702 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3703}
3704
3705
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003706int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003707 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003708 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3709}
3710
3711
3712void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003713 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003714 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3715 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3716}
3717
3718
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003719int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003720 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003721 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3722}
3723
3724
3725void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003726 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003727 ASSERT(ticks < 256);
3728 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3729}
3730
3731
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003732unsigned Code::stack_slots() {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003733 ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003734 return StackSlotsField::decode(
3735 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003736}
3737
3738
3739void Code::set_stack_slots(unsigned slots) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003740 CHECK(slots <= (1 << kStackSlotsBitCount));
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003741 ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003742 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3743 int updated = StackSlotsField::update(previous, slots);
3744 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003745}
3746
3747
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003748unsigned Code::safepoint_table_offset() {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003749 ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003750 return SafepointTableOffsetField::decode(
3751 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003752}
3753
3754
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003755void Code::set_safepoint_table_offset(unsigned offset) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003756 CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003757 ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003758 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003759 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3760 int updated = SafepointTableOffsetField::update(previous, offset);
3761 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003762}
3763
3764
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003765unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003766 ASSERT_EQ(FUNCTION, kind());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003767 return StackCheckTableOffsetField::decode(
3768 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003769}
3770
3771
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003772void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003773 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003774 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003775 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3776 int updated = StackCheckTableOffsetField::update(previous, offset);
3777 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003778}
3779
3780
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00003781bool Code::stack_check_patched_for_osr() {
3782 ASSERT_EQ(FUNCTION, kind());
3783 return StackCheckPatchedForOSRField::decode(
3784 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
3785}
3786
3787
3788void Code::set_stack_check_patched_for_osr(bool value) {
3789 ASSERT_EQ(FUNCTION, kind());
3790 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3791 int updated = StackCheckPatchedForOSRField::update(previous, value);
3792 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
3793}
3794
3795
3796
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003797CheckType Code::check_type() {
3798 ASSERT(is_call_stub() || is_keyed_call_stub());
3799 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3800 return static_cast<CheckType>(type);
3801}
3802
3803
3804void Code::set_check_type(CheckType value) {
3805 ASSERT(is_call_stub() || is_keyed_call_stub());
3806 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3807}
3808
3809
danno@chromium.org40cb8782011-05-25 07:58:50 +00003810byte Code::unary_op_type() {
3811 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003812 return UnaryOpTypeField::decode(
3813 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003814}
3815
3816
danno@chromium.org40cb8782011-05-25 07:58:50 +00003817void Code::set_unary_op_type(byte value) {
3818 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003819 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3820 int updated = UnaryOpTypeField::update(previous, value);
3821 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003822}
3823
3824
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003825byte Code::to_boolean_state() {
3826 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003827 return ToBooleanStateField::decode(
3828 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003829}
3830
3831
3832void Code::set_to_boolean_state(byte value) {
3833 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003834 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3835 int updated = ToBooleanStateField::update(previous, value);
3836 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003837}
3838
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003839
3840bool Code::has_function_cache() {
3841 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003842 return HasFunctionCacheField::decode(
3843 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003844}
3845
3846
3847void Code::set_has_function_cache(bool flag) {
3848 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003849 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3850 int updated = HasFunctionCacheField::update(previous, flag);
3851 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003852}
3853
3854
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003855bool Code::marked_for_deoptimization() {
3856 ASSERT(kind() == OPTIMIZED_FUNCTION);
3857 return MarkedForDeoptimizationField::decode(
3858 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
3859}
3860
3861
3862void Code::set_marked_for_deoptimization(bool flag) {
3863 ASSERT(kind() == OPTIMIZED_FUNCTION);
3864 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3865 int updated = MarkedForDeoptimizationField::update(previous, flag);
3866 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
3867}
3868
3869
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003870bool Code::is_inline_cache_stub() {
3871 Kind kind = this->kind();
3872 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3873}
3874
3875
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003876bool Code::is_debug_break() {
3877 return ic_state() == DEBUG_STUB && extra_ic_state() == DEBUG_BREAK;
3878}
3879
3880
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003881Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003882 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003883 ExtraICState extra_ic_state,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003884 StubType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003885 int argc,
3886 InlineCacheHolderFlag holder) {
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003887 ASSERT(argc <= Code::kMaxArguments);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003888 // Compute the bit mask.
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003889 unsigned int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003890 | ICStateField::encode(ic_state)
3891 | TypeField::encode(type)
3892 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003893 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003894 | CacheHolderField::encode(holder);
3895 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003896}
3897
3898
3899Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003900 ExtraICState extra_ic_state,
hpayer@chromium.org8432c912013-02-28 15:55:26 +00003901 StubType type,
3902 int argc,
3903 InlineCacheHolderFlag holder) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003904 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003905}
3906
3907
3908Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003909 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003910}
3911
3912
kasper.lund7276f142008-07-30 08:49:36 +00003913InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003914 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003915}
3916
3917
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003918Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003919 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003920}
3921
3922
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003923Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003924 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003925}
3926
3927
3928int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003929 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003930}
3931
3932
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003933InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003934 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003935}
3936
3937
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003938Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003939 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003940 return static_cast<Flags>(bits);
3941}
3942
3943
ager@chromium.org8bb60582008-12-11 12:02:20 +00003944Code* Code::GetCodeFromTargetAddress(Address address) {
3945 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3946 // GetCodeFromTargetAddress might be called when marking objects during mark
3947 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3948 // Code::cast. Code::cast does not work when the object's map is
3949 // marked.
3950 Code* result = reinterpret_cast<Code*>(code);
3951 return result;
3952}
3953
3954
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003955Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3956 return HeapObject::
3957 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3958}
3959
3960
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003961Object* Map::prototype() {
3962 return READ_FIELD(this, kPrototypeOffset);
3963}
3964
3965
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003966void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003967 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003968 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003969 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003970}
3971
3972
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003973// If the descriptor is using the empty transition array, install a new empty
3974// transition array that will have place for an element transition.
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003975static MaybeObject* EnsureHasTransitionArray(Map* map) {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003976 TransitionArray* transitions;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003977 MaybeObject* maybe_transitions;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003978 if (!map->HasTransitionArray()) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003979 maybe_transitions = TransitionArray::Allocate(0);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003980 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3981 transitions->set_back_pointer_storage(map->GetBackPointer());
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003982 } else if (!map->transitions()->IsFullTransitionArray()) {
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003983 maybe_transitions = map->transitions()->ExtendToFullTransitionArray();
3984 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3985 } else {
3986 return map;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003987 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003988 map->set_transitions(transitions);
3989 return transitions;
3990}
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003991
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003992
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003993void Map::InitializeDescriptors(DescriptorArray* descriptors) {
verwaest@chromium.org652f4fa2012-10-08 08:48:51 +00003994 int len = descriptors->number_of_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00003995#ifdef DEBUG
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003996 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003997
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003998 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors];
3999 for (int i = 0; i < len; ++i) used_indices[i] = false;
4000
4001 // Ensure that all enumeration indexes between 1 and length occur uniquely in
4002 // the descriptor array.
4003 for (int i = 0; i < len; ++i) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004004 int enum_index = descriptors->GetDetails(i).descriptor_index() -
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004005 PropertyDetails::kInitialIndex;
4006 ASSERT(0 <= enum_index && enum_index < len);
4007 ASSERT(!used_indices[enum_index]);
4008 used_indices[enum_index] = true;
4009 }
4010#endif
4011
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004012 set_instance_descriptors(descriptors);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00004013 SetNumberOfOwnDescriptors(len);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004014}
4015
4016
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004017ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004018SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)
danno@chromium.org40cb8782011-05-25 07:58:50 +00004019
4020
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004021void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004022 Object* back_pointer = GetBackPointer();
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00004023
4024 if (Heap::ShouldZapGarbage() && HasTransitionArray()) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004025 ZapTransitions();
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00004026 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00004027
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004028 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004029 CONDITIONAL_WRITE_BARRIER(
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004030 heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode);
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00004031}
4032
4033
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004034void Map::AppendDescriptor(Descriptor* desc,
4035 const DescriptorArray::WhitenessWitness& witness) {
4036 DescriptorArray* descriptors = instance_descriptors();
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004037 int number_of_own_descriptors = NumberOfOwnDescriptors();
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004038 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
4039 descriptors->Append(desc, witness);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004040 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004041}
4042
danno@chromium.org40cb8782011-05-25 07:58:50 +00004043
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004044Object* Map::GetBackPointer() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004045 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004046 if (object->IsDescriptorArray()) {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004047 return TransitionArray::cast(object)->back_pointer_storage();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004048 } else {
4049 ASSERT(object->IsMap() || object->IsUndefined());
4050 return object;
4051 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004052}
4053
4054
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004055bool Map::HasElementsTransition() {
4056 return HasTransitionArray() && transitions()->HasElementsTransition();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004057}
4058
4059
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004060bool Map::HasTransitionArray() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004061 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4062 return object->IsTransitionArray();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004063}
4064
4065
4066Map* Map::elements_transition_map() {
4067 return transitions()->elements_transition();
4068}
4069
4070
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +00004071bool Map::CanHaveMoreTransitions() {
4072 if (!HasTransitionArray()) return true;
4073 return FixedArray::SizeFor(transitions()->length() +
4074 TransitionArray::kTransitionSize)
4075 <= Page::kMaxNonCodeHeapObjectSize;
4076}
4077
4078
ulan@chromium.org750145a2013-03-07 15:14:13 +00004079MaybeObject* Map::AddTransition(Name* key,
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004080 Map* target,
4081 SimpleTransitionFlag flag) {
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004082 if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004083 return TransitionArray::NewWith(flag, key, target, GetBackPointer());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004084}
4085
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004086
4087void Map::SetTransition(int transition_index, Map* target) {
4088 transitions()->SetTarget(transition_index, target);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00004089}
4090
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004091
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00004092Map* Map::GetTransition(int transition_index) {
4093 return transitions()->GetTarget(transition_index);
4094}
4095
4096
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004097MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004098 MaybeObject* allow_elements = EnsureHasTransitionArray(this);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004099 if (allow_elements->IsFailure()) return allow_elements;
4100 transitions()->set_elements_transition(transitioned_map);
4101 return this;
4102}
4103
4104
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004105FixedArray* Map::GetPrototypeTransitions() {
4106 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
4107 if (!transitions()->HasPrototypeTransitions()) {
4108 return GetHeap()->empty_fixed_array();
4109 }
4110 return transitions()->GetPrototypeTransitions();
4111}
4112
4113
4114MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004115 MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004116 if (allow_prototype->IsFailure()) return allow_prototype;
4117#ifdef DEBUG
4118 if (HasPrototypeTransitions()) {
4119 ASSERT(GetPrototypeTransitions() != proto_transitions);
4120 ZapPrototypeTransitions();
4121 }
4122#endif
4123 transitions()->SetPrototypeTransitions(proto_transitions);
4124 return this;
4125}
4126
4127
4128bool Map::HasPrototypeTransitions() {
4129 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
4130}
4131
4132
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004133TransitionArray* Map::transitions() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004134 ASSERT(HasTransitionArray());
4135 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4136 return TransitionArray::cast(object);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004137}
4138
4139
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004140void Map::set_transitions(TransitionArray* transition_array,
4141 WriteBarrierMode mode) {
jkummerow@chromium.org91efda92013-03-25 16:32:26 +00004142 // Transition arrays are not shared. When one is replaced, it should not
4143 // keep referenced objects alive, so we zap it.
4144 // When there is another reference to the array somewhere (e.g. a handle),
4145 // not zapping turns from a waste of memory into a source of crashes.
4146 if (HasTransitionArray()) {
4147 ASSERT(transitions() != transition_array);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004148 ZapTransitions();
4149 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004150
4151 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array);
4152 CONDITIONAL_WRITE_BARRIER(
4153 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004154}
4155
4156
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004157void Map::init_back_pointer(Object* undefined) {
4158 ASSERT(undefined->IsUndefined());
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004159 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, undefined);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004160}
4161
4162
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004163void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004164 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
4165 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
4166 (value->IsMap() && GetBackPointer()->IsUndefined()));
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004167 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4168 if (object->IsTransitionArray()) {
4169 TransitionArray::cast(object)->set_back_pointer_storage(value);
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004170 } else {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004171 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, value);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004172 CONDITIONAL_WRITE_BARRIER(
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004173 GetHeap(), this, kTransitionsOrBackPointerOffset, value, mode);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004174 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004175}
4176
4177
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004178// Can either be Smi (no transitions), normal transition array, or a transition
4179// array with the header overwritten as a Smi (thus iterating).
4180TransitionArray* Map::unchecked_transition_array() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004181 Object* object = *HeapObject::RawField(this,
4182 Map::kTransitionsOrBackPointerOffset);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004183 TransitionArray* transition_array = static_cast<TransitionArray*>(object);
4184 return transition_array;
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004185}
4186
4187
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004188HeapObject* Map::UncheckedPrototypeTransitions() {
4189 ASSERT(HasTransitionArray());
4190 ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
4191 return unchecked_transition_array()->UncheckedPrototypeTransitions();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004192}
4193
4194
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004195ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004196ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004197ACCESSORS(Map, constructor, Object, kConstructorOffset)
4198
4199ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004200ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004201ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004202
4203ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004204ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset)
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00004205ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004206ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004207
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004208ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004209
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004210ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004211ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004212ACCESSORS(AccessorInfo, expected_receiver_type, Object,
4213 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004214
ulan@chromium.org750145a2013-03-07 15:14:13 +00004215ACCESSORS(DeclaredAccessorDescriptor, serialized_data, ByteArray,
4216 kSerializedDataOffset)
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004217
4218ACCESSORS(DeclaredAccessorInfo, descriptor, DeclaredAccessorDescriptor,
4219 kDescriptorOffset)
4220
4221ACCESSORS(ExecutableAccessorInfo, getter, Object, kGetterOffset)
4222ACCESSORS(ExecutableAccessorInfo, setter, Object, kSetterOffset)
4223ACCESSORS(ExecutableAccessorInfo, data, Object, kDataOffset)
4224
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004225ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
4226ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
4227
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004228ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
4229ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
4230ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
4231
4232ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
4233ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
4234ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
4235ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
4236ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
4237ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
4238
4239ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
4240ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
4241
4242ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
4243ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
4244
4245ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
4246ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004247ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
4248 kPropertyAccessorsOffset)
4249ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
4250 kPrototypeTemplateOffset)
4251ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
4252ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
4253 kNamedPropertyHandlerOffset)
4254ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
4255 kIndexedPropertyHandlerOffset)
4256ACCESSORS(FunctionTemplateInfo, instance_template, Object,
4257 kInstanceTemplateOffset)
4258ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
4259ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004260ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
4261 kInstanceCallHandlerOffset)
4262ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
4263 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004264ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004265
4266ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00004267ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
4268 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004269
4270ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
4271ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
4272
4273ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
4274
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00004275ACCESSORS(AllocationSiteInfo, payload, Object, kPayloadOffset)
4276
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004277ACCESSORS(Script, source, Object, kSourceOffset)
4278ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004279ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004280ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
4281ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004282ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00004283ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004284ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004285ACCESSORS_TO_SMI(Script, type, kTypeOffset)
4286ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
4287ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00004288ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00004289ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004290ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
4291 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004292
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004293#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004294ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
4295ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
4296ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
4297ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
4298
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004299ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
4300ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
4301ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004302ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004303#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004304
4305ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004306ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
4307 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004308ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
4309ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004310ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
4311 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004312ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004313ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
4314ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00004315ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004316ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
4317 kThisPropertyAssignmentsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004318SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004319
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00004320
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00004321SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004322BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
4323 kHiddenPrototypeBit)
4324BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
4325BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
4326 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00004327BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
4328 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004329BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
4330 kIsExpressionBit)
4331BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
4332 kIsTopLevelBit)
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00004333
whesse@chromium.org7b260152011-06-20 15:33:18 +00004334BOOL_GETTER(SharedFunctionInfo,
4335 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004336 has_only_simple_this_property_assignments,
4337 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004338BOOL_ACCESSORS(SharedFunctionInfo,
4339 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00004340 allows_lazy_compilation,
4341 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004342BOOL_ACCESSORS(SharedFunctionInfo,
4343 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004344 allows_lazy_compilation_without_context,
4345 kAllowLazyCompilationWithoutContext)
4346BOOL_ACCESSORS(SharedFunctionInfo,
4347 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00004348 uses_arguments,
4349 kUsesArguments)
4350BOOL_ACCESSORS(SharedFunctionInfo,
4351 compiler_hints,
4352 has_duplicate_parameters,
4353 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004354
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004355
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004356#if V8_HOST_ARCH_32_BIT
4357SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
4358SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004359 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004360SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004361 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004362SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
4363SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004364 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004365SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
4366SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004367 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004368SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004369 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004370SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004371 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004372SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004373SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
4374SMI_ACCESSORS(SharedFunctionInfo,
4375 stress_deopt_counter,
4376 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004377#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004378
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004379#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004380 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004381 int holder::name() { \
4382 int value = READ_INT_FIELD(this, offset); \
4383 ASSERT(kHeapObjectTag == 1); \
4384 ASSERT((value & kHeapObjectTag) == 0); \
4385 return value >> 1; \
4386 } \
4387 void holder::set_##name(int value) { \
4388 ASSERT(kHeapObjectTag == 1); \
4389 ASSERT((value & 0xC0000000) == 0xC0000000 || \
4390 (value & 0xC0000000) == 0x000000000); \
4391 WRITE_INT_FIELD(this, \
4392 offset, \
4393 (value << 1) & ~kHeapObjectTag); \
4394 }
4395
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004396#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
4397 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004398 INT_ACCESSORS(holder, name, offset)
4399
4400
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004401PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004402PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4403 formal_parameter_count,
4404 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004405
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004406PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4407 expected_nof_properties,
4408 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004409PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
4410
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004411PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
4412PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4413 start_position_and_type,
4414 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004415
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004416PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4417 function_token_position,
4418 kFunctionTokenPositionOffset)
4419PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4420 compiler_hints,
4421 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004422
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004423PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4424 this_property_assignments_count,
4425 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004426PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004427
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004428PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
4429PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4430 stress_deopt_counter,
4431 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004432#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004433
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004434
4435int SharedFunctionInfo::construction_count() {
4436 return READ_BYTE_FIELD(this, kConstructionCountOffset);
4437}
4438
4439
4440void SharedFunctionInfo::set_construction_count(int value) {
4441 ASSERT(0 <= value && value < 256);
4442 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
4443}
4444
4445
whesse@chromium.org7b260152011-06-20 15:33:18 +00004446BOOL_ACCESSORS(SharedFunctionInfo,
4447 compiler_hints,
4448 live_objects_may_exist,
4449 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004450
4451
4452bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004453 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004454}
4455
4456
whesse@chromium.org7b260152011-06-20 15:33:18 +00004457BOOL_GETTER(SharedFunctionInfo,
4458 compiler_hints,
4459 optimization_disabled,
4460 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004461
4462
4463void SharedFunctionInfo::set_optimization_disabled(bool disable) {
4464 set_compiler_hints(BooleanBit::set(compiler_hints(),
4465 kOptimizationDisabled,
4466 disable));
4467 // If disabling optimizations we reflect that in the code object so
4468 // it will not be counted as optimizable code.
4469 if ((code()->kind() == Code::FUNCTION) && disable) {
4470 code()->set_optimizable(false);
4471 }
4472}
4473
4474
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004475int SharedFunctionInfo::profiler_ticks() {
4476 if (code()->kind() != Code::FUNCTION) return 0;
4477 return code()->profiler_ticks();
4478}
4479
4480
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004481LanguageMode SharedFunctionInfo::language_mode() {
4482 int hints = compiler_hints();
4483 if (BooleanBit::get(hints, kExtendedModeFunction)) {
4484 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
4485 return EXTENDED_MODE;
4486 }
4487 return BooleanBit::get(hints, kStrictModeFunction)
4488 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004489}
4490
4491
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004492void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
4493 // We only allow language mode transitions that go set the same language mode
4494 // again or go up in the chain:
4495 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
4496 ASSERT(this->language_mode() == CLASSIC_MODE ||
4497 this->language_mode() == language_mode ||
4498 language_mode == EXTENDED_MODE);
4499 int hints = compiler_hints();
4500 hints = BooleanBit::set(
4501 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
4502 hints = BooleanBit::set(
4503 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
4504 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004505}
4506
4507
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004508bool SharedFunctionInfo::is_classic_mode() {
4509 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
4510}
4511
4512BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
4513 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004514BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
4515BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
4516 name_should_print_as_anonymous,
4517 kNameShouldPrintAsAnonymous)
4518BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
4519BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00004520BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
4521BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
4522 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004523BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004524BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00004525BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004526
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004527void SharedFunctionInfo::BeforeVisitingPointers() {
4528 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
mstarzinger@chromium.org0ae265a2012-12-11 17:41:11 +00004529}
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004530
mstarzinger@chromium.org0ae265a2012-12-11 17:41:11 +00004531
4532void SharedFunctionInfo::ClearOptimizedCodeMap() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004533 set_optimized_code_map(Smi::FromInt(0));
4534}
4535
4536
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004537ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
4538ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
4539
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00004540ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
4541
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004542bool Script::HasValidSource() {
4543 Object* src = this->source();
4544 if (!src->IsString()) return true;
4545 String* src_str = String::cast(src);
4546 if (!StringShape(src_str).IsExternal()) return true;
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00004547 if (src_str->IsOneByteRepresentation()) {
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004548 return ExternalAsciiString::cast(src)->resource() != NULL;
4549 } else if (src_str->IsTwoByteRepresentation()) {
4550 return ExternalTwoByteString::cast(src)->resource() != NULL;
4551 }
4552 return true;
4553}
4554
4555
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00004556void SharedFunctionInfo::DontAdaptArguments() {
4557 ASSERT(code()->kind() == Code::BUILTIN);
4558 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
4559}
4560
4561
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004562int SharedFunctionInfo::start_position() {
4563 return start_position_and_type() >> kStartPositionShift;
4564}
4565
4566
4567void SharedFunctionInfo::set_start_position(int start_position) {
4568 set_start_position_and_type((start_position << kStartPositionShift)
4569 | (start_position_and_type() & ~kStartPositionMask));
4570}
4571
4572
4573Code* SharedFunctionInfo::code() {
4574 return Code::cast(READ_FIELD(this, kCodeOffset));
4575}
4576
4577
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004578Code* SharedFunctionInfo::unchecked_code() {
4579 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
4580}
4581
4582
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004583void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004584 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004585 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004586}
4587
4588
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00004589void SharedFunctionInfo::ReplaceCode(Code* value) {
4590 // If the GC metadata field is already used then the function was
4591 // enqueued as a code flushing candidate and we remove it now.
4592 if (code()->gc_metadata() != NULL) {
4593 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
4594 flusher->EvictCandidate(this);
4595 }
4596
4597 ASSERT(code()->gc_metadata() == NULL && value->gc_metadata() == NULL);
4598 set_code(value);
4599}
4600
4601
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004602ScopeInfo* SharedFunctionInfo::scope_info() {
4603 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00004604}
4605
4606
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004607void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00004608 WriteBarrierMode mode) {
4609 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004610 CONDITIONAL_WRITE_BARRIER(GetHeap(),
4611 this,
4612 kScopeInfoOffset,
4613 reinterpret_cast<Object*>(value),
4614 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00004615}
4616
4617
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004618bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004619 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004620 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004621}
4622
4623
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004624bool SharedFunctionInfo::IsApiFunction() {
4625 return function_data()->IsFunctionTemplateInfo();
4626}
4627
4628
4629FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
4630 ASSERT(IsApiFunction());
4631 return FunctionTemplateInfo::cast(function_data());
4632}
4633
4634
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004635bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004636 return function_data()->IsSmi();
4637}
4638
4639
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004640BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4641 ASSERT(HasBuiltinFunctionId());
4642 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004643}
4644
4645
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004646int SharedFunctionInfo::code_age() {
4647 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
4648}
4649
4650
4651void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00004652 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
4653 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004654}
4655
4656
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004657int SharedFunctionInfo::ic_age() {
4658 return ICAgeBits::decode(counters());
4659}
4660
4661
4662void SharedFunctionInfo::set_ic_age(int ic_age) {
4663 set_counters(ICAgeBits::update(counters(), ic_age));
4664}
4665
4666
4667int SharedFunctionInfo::deopt_count() {
4668 return DeoptCountBits::decode(counters());
4669}
4670
4671
4672void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4673 set_counters(DeoptCountBits::update(counters(), deopt_count));
4674}
4675
4676
4677void SharedFunctionInfo::increment_deopt_count() {
4678 int value = counters();
4679 int deopt_count = DeoptCountBits::decode(value);
4680 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4681 set_counters(DeoptCountBits::update(value, deopt_count));
4682}
4683
4684
4685int SharedFunctionInfo::opt_reenable_tries() {
4686 return OptReenableTriesBits::decode(counters());
4687}
4688
4689
4690void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4691 set_counters(OptReenableTriesBits::update(counters(), tries));
4692}
4693
4694
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004695bool SharedFunctionInfo::has_deoptimization_support() {
4696 Code* code = this->code();
4697 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4698}
4699
4700
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004701void SharedFunctionInfo::TryReenableOptimization() {
4702 int tries = opt_reenable_tries();
4703 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4704 // We reenable optimization whenever the number of tries is a large
4705 // enough power of 2.
4706 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4707 set_optimization_disabled(false);
4708 set_opt_count(0);
4709 set_deopt_count(0);
4710 code()->set_optimizable(true);
4711 }
4712}
4713
4714
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004715bool JSFunction::IsBuiltin() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004716 return context()->global_object()->IsJSBuiltinsObject();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004717}
4718
4719
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004720bool JSFunction::NeedsArgumentsAdaption() {
4721 return shared()->formal_parameter_count() !=
4722 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4723}
4724
4725
4726bool JSFunction::IsOptimized() {
4727 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4728}
4729
4730
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004731bool JSFunction::IsOptimizable() {
4732 return code()->kind() == Code::FUNCTION && code()->optimizable();
4733}
4734
4735
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004736bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004737 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004738}
4739
4740
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00004741bool JSFunction::IsMarkedForInstallingRecompiledCode() {
4742 return code() == GetIsolate()->builtins()->builtin(
4743 Builtins::kInstallRecompiledCode);
4744}
4745
4746
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004747bool JSFunction::IsMarkedForParallelRecompilation() {
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00004748 return code() == GetIsolate()->builtins()->builtin(
4749 Builtins::kParallelRecompile);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004750}
4751
4752
4753bool JSFunction::IsInRecompileQueue() {
4754 return code() == GetIsolate()->builtins()->builtin(
4755 Builtins::kInRecompileQueue);
4756}
4757
4758
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004759Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004760 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004761}
4762
4763
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004764Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004765 return reinterpret_cast<Code*>(
4766 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004767}
4768
4769
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004770void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004771 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004772 Address entry = value->entry();
4773 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004774 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4775 this,
4776 HeapObject::RawField(this, kCodeEntryOffset),
4777 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004778}
4779
4780
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00004781void JSFunction::set_code_no_write_barrier(Code* value) {
4782 ASSERT(!HEAP->InNewSpace(value));
4783 Address entry = value->entry();
4784 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
4785}
4786
4787
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004788void JSFunction::ReplaceCode(Code* code) {
4789 bool was_optimized = IsOptimized();
4790 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4791
4792 set_code(code);
4793
4794 // Add/remove the function from the list of optimized functions for this
4795 // context based on the state change.
4796 if (!was_optimized && is_optimized) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004797 context()->native_context()->AddOptimizedFunction(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004798 }
4799 if (was_optimized && !is_optimized) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004800 context()->native_context()->RemoveOptimizedFunction(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004801 }
4802}
4803
4804
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004805Context* JSFunction::context() {
4806 return Context::cast(READ_FIELD(this, kContextOffset));
4807}
4808
4809
4810Object* JSFunction::unchecked_context() {
4811 return READ_FIELD(this, kContextOffset);
4812}
4813
4814
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004815SharedFunctionInfo* JSFunction::unchecked_shared() {
4816 return reinterpret_cast<SharedFunctionInfo*>(
4817 READ_FIELD(this, kSharedFunctionInfoOffset));
4818}
4819
4820
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004821void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004822 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004823 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004824 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004825}
4826
4827ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4828 kPrototypeOrInitialMapOffset)
4829
4830
4831Map* JSFunction::initial_map() {
4832 return Map::cast(prototype_or_initial_map());
4833}
4834
4835
4836void JSFunction::set_initial_map(Map* value) {
4837 set_prototype_or_initial_map(value);
4838}
4839
4840
4841bool JSFunction::has_initial_map() {
4842 return prototype_or_initial_map()->IsMap();
4843}
4844
4845
4846bool JSFunction::has_instance_prototype() {
4847 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4848}
4849
4850
4851bool JSFunction::has_prototype() {
4852 return map()->has_non_instance_prototype() || has_instance_prototype();
4853}
4854
4855
4856Object* JSFunction::instance_prototype() {
4857 ASSERT(has_instance_prototype());
4858 if (has_initial_map()) return initial_map()->prototype();
4859 // When there is no initial map and the prototype is a JSObject, the
4860 // initial map field is used for the prototype field.
4861 return prototype_or_initial_map();
4862}
4863
4864
4865Object* JSFunction::prototype() {
4866 ASSERT(has_prototype());
4867 // If the function's prototype property has been set to a non-JSObject
4868 // value, that value is stored in the constructor field of the map.
4869 if (map()->has_non_instance_prototype()) return map()->constructor();
4870 return instance_prototype();
4871}
4872
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004873
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004874bool JSFunction::should_have_prototype() {
4875 return map()->function_with_prototype();
4876}
4877
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004878
4879bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004880 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004881}
4882
4883
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004884FixedArray* JSFunction::literals() {
4885 ASSERT(!shared()->bound());
4886 return literals_or_bindings();
4887}
4888
4889
4890void JSFunction::set_literals(FixedArray* literals) {
4891 ASSERT(!shared()->bound());
4892 set_literals_or_bindings(literals);
4893}
4894
4895
4896FixedArray* JSFunction::function_bindings() {
4897 ASSERT(shared()->bound());
4898 return literals_or_bindings();
4899}
4900
4901
4902void JSFunction::set_function_bindings(FixedArray* bindings) {
4903 ASSERT(shared()->bound());
4904 // Bound function literal may be initialized to the empty fixed array
4905 // before the bindings are set.
4906 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4907 bindings->map() == GetHeap()->fixed_cow_array_map());
4908 set_literals_or_bindings(bindings);
4909}
4910
4911
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004912int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004913 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004914 return literals()->length();
4915}
4916
4917
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004918Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004919 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004920 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004921}
4922
4923
4924void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4925 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004926 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004927 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004928 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004929}
4930
4931
4932Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004933 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004934 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4935}
4936
4937
4938void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4939 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004940 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004941 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004942 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004943}
4944
4945
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004946ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004947ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004948ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4949ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4950
4951
4952void JSProxy::InitializeBody(int object_size, Object* value) {
4953 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4954 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4955 WRITE_FIELD(this, offset, value);
4956 }
4957}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004958
4959
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004960ACCESSORS(JSSet, table, Object, kTableOffset)
4961ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004962ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4963ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004964
4965
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004966Address Foreign::foreign_address() {
4967 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004968}
4969
4970
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004971void Foreign::set_foreign_address(Address value) {
4972 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004973}
4974
4975
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004976ACCESSORS(JSModule, context, Object, kContextOffset)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004977ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004978
4979
4980JSModule* JSModule::cast(Object* obj) {
4981 ASSERT(obj->IsJSModule());
4982 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4983 return reinterpret_cast<JSModule*>(obj);
4984}
4985
4986
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004987ACCESSORS(JSValue, value, Object, kValueOffset)
4988
4989
4990JSValue* JSValue::cast(Object* obj) {
4991 ASSERT(obj->IsJSValue());
4992 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4993 return reinterpret_cast<JSValue*>(obj);
4994}
4995
4996
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004997ACCESSORS(JSDate, value, Object, kValueOffset)
4998ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4999ACCESSORS(JSDate, year, Object, kYearOffset)
5000ACCESSORS(JSDate, month, Object, kMonthOffset)
5001ACCESSORS(JSDate, day, Object, kDayOffset)
5002ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
5003ACCESSORS(JSDate, hour, Object, kHourOffset)
5004ACCESSORS(JSDate, min, Object, kMinOffset)
5005ACCESSORS(JSDate, sec, Object, kSecOffset)
5006
5007
5008JSDate* JSDate::cast(Object* obj) {
5009 ASSERT(obj->IsJSDate());
5010 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
5011 return reinterpret_cast<JSDate*>(obj);
5012}
5013
5014
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00005015ACCESSORS(JSMessageObject, type, String, kTypeOffset)
5016ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
5017ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
5018ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
5019ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
5020SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
5021SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
5022
5023
5024JSMessageObject* JSMessageObject::cast(Object* obj) {
5025 ASSERT(obj->IsJSMessageObject());
5026 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
5027 return reinterpret_cast<JSMessageObject*>(obj);
5028}
5029
5030
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005031INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +00005032INT_ACCESSORS(Code, prologue_offset, kPrologueOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005033ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00005034ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005035ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005036
5037
5038// Type feedback slot: type_feedback_info for FUNCTIONs, stub_info for STUBs.
5039void Code::InitializeTypeFeedbackInfoNoWriteBarrier(Object* value) {
5040 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
5041}
5042
5043
5044Object* Code::type_feedback_info() {
5045 ASSERT(kind() == FUNCTION);
5046 return Object::cast(READ_FIELD(this, kTypeFeedbackInfoOffset));
5047}
5048
5049
5050void Code::set_type_feedback_info(Object* value, WriteBarrierMode mode) {
5051 ASSERT(kind() == FUNCTION);
5052 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
5053 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kTypeFeedbackInfoOffset,
5054 value, mode);
5055}
5056
5057
5058int Code::stub_info() {
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00005059 ASSERT(kind() == COMPARE_IC || kind() == BINARY_OP_IC || kind() == LOAD_IC);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005060 Object* value = READ_FIELD(this, kTypeFeedbackInfoOffset);
5061 return Smi::cast(value)->value();
5062}
5063
5064
5065void Code::set_stub_info(int value) {
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00005066 ASSERT(kind() == COMPARE_IC ||
5067 kind() == BINARY_OP_IC ||
ulan@chromium.org750145a2013-03-07 15:14:13 +00005068 kind() == STUB ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00005069 kind() == LOAD_IC ||
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00005070 kind() == KEYED_LOAD_IC ||
5071 kind() == STORE_IC ||
5072 kind() == KEYED_STORE_IC);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005073 WRITE_FIELD(this, kTypeFeedbackInfoOffset, Smi::FromInt(value));
5074}
5075
5076
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005077void Code::set_deoptimizing_functions(Object* value) {
5078 ASSERT(kind() == OPTIMIZED_FUNCTION);
5079 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
5080}
5081
5082
5083Object* Code::deoptimizing_functions() {
5084 ASSERT(kind() == OPTIMIZED_FUNCTION);
5085 return Object::cast(READ_FIELD(this, kTypeFeedbackInfoOffset));
5086}
5087
5088
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00005089ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00005090INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005091
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005092
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005093byte* Code::instruction_start() {
5094 return FIELD_ADDR(this, kHeaderSize);
5095}
5096
5097
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005098byte* Code::instruction_end() {
5099 return instruction_start() + instruction_size();
5100}
5101
5102
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005103int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005104 return RoundUp(instruction_size(), kObjectAlignment);
5105}
5106
5107
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005108FixedArray* Code::unchecked_deoptimization_data() {
5109 return reinterpret_cast<FixedArray*>(
5110 READ_FIELD(this, kDeoptimizationDataOffset));
5111}
5112
5113
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005114ByteArray* Code::unchecked_relocation_info() {
5115 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005116}
5117
5118
5119byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005120 return unchecked_relocation_info()->GetDataStartAddress();
5121}
5122
5123
5124int Code::relocation_size() {
5125 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005126}
5127
5128
5129byte* Code::entry() {
5130 return instruction_start();
5131}
5132
5133
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005134bool Code::contains(byte* inner_pointer) {
5135 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005136}
5137
5138
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005139ACCESSORS(JSArray, length, Object, kLengthOffset)
5140
5141
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00005142void* JSArrayBuffer::backing_store() {
5143 intptr_t ptr = READ_INTPTR_FIELD(this, kBackingStoreOffset);
5144 return reinterpret_cast<void*>(ptr);
5145}
5146
5147
5148void JSArrayBuffer::set_backing_store(void* value, WriteBarrierMode mode) {
5149 intptr_t ptr = reinterpret_cast<intptr_t>(value);
5150 WRITE_INTPTR_FIELD(this, kBackingStoreOffset, ptr);
5151}
5152
5153
5154ACCESSORS(JSArrayBuffer, byte_length, Object, kByteLengthOffset)
5155
5156
ager@chromium.org236ad962008-09-25 09:45:57 +00005157ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00005158
5159
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00005160JSRegExp::Type JSRegExp::TypeTag() {
5161 Object* data = this->data();
5162 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
5163 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
5164 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00005165}
5166
5167
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005168JSRegExp::Type JSRegExp::TypeTagUnchecked() {
5169 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
5170 return static_cast<JSRegExp::Type>(smi->value());
5171}
5172
5173
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00005174int JSRegExp::CaptureCount() {
5175 switch (TypeTag()) {
5176 case ATOM:
5177 return 0;
5178 case IRREGEXP:
5179 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
5180 default:
5181 UNREACHABLE();
5182 return -1;
5183 }
5184}
5185
5186
ager@chromium.orga74f0da2008-12-03 16:05:52 +00005187JSRegExp::Flags JSRegExp::GetFlags() {
5188 ASSERT(this->data()->IsFixedArray());
5189 Object* data = this->data();
5190 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
5191 return Flags(smi->value());
5192}
5193
5194
5195String* JSRegExp::Pattern() {
5196 ASSERT(this->data()->IsFixedArray());
5197 Object* data = this->data();
5198 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
5199 return pattern;
5200}
5201
5202
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00005203Object* JSRegExp::DataAt(int index) {
5204 ASSERT(TypeTag() != NOT_COMPILED);
5205 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00005206}
5207
5208
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005209Object* JSRegExp::DataAtUnchecked(int index) {
5210 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
5211 int offset = FixedArray::kHeaderSize + index * kPointerSize;
5212 return READ_FIELD(fa, offset);
5213}
5214
5215
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00005216void JSRegExp::SetDataAt(int index, Object* value) {
5217 ASSERT(TypeTag() != NOT_COMPILED);
5218 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
5219 FixedArray::cast(data())->set(index, value);
5220}
5221
5222
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005223void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
5224 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
5225 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
5226 if (value->IsSmi()) {
5227 fa->set_unchecked(index, Smi::cast(value));
5228 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005229 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005230 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
5231 }
5232}
5233
5234
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005235ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005236 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005237#if DEBUG
5238 FixedArrayBase* fixed_array =
5239 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
5240 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005241 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
5242 (map == GetHeap()->fixed_array_map() ||
5243 map == GetHeap()->fixed_cow_array_map())) ||
5244 (IsFastDoubleElementsKind(kind) &&
5245 (fixed_array->IsFixedDoubleArray() ||
5246 fixed_array == GetHeap()->empty_fixed_array())) ||
5247 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005248 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005249 fixed_array->IsDictionary()) ||
5250 (kind > DICTIONARY_ELEMENTS));
5251 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
5252 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005253#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005254 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005255}
5256
5257
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00005258ElementsAccessor* JSObject::GetElementsAccessor() {
5259 return ElementsAccessor::ForKind(GetElementsKind());
5260}
5261
5262
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005263bool JSObject::HasFastObjectElements() {
5264 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005265}
5266
5267
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005268bool JSObject::HasFastSmiElements() {
5269 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005270}
5271
5272
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005273bool JSObject::HasFastSmiOrObjectElements() {
5274 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005275}
5276
5277
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00005278bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005279 return IsFastDoubleElementsKind(GetElementsKind());
5280}
5281
5282
5283bool JSObject::HasFastHoleyElements() {
5284 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00005285}
5286
5287
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005288bool JSObject::HasFastElements() {
5289 return IsFastElementsKind(GetElementsKind());
5290}
5291
5292
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005293bool JSObject::HasDictionaryElements() {
5294 return GetElementsKind() == DICTIONARY_ELEMENTS;
5295}
5296
5297
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005298bool JSObject::HasNonStrictArgumentsElements() {
5299 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
5300}
5301
5302
ager@chromium.org3811b432009-10-28 14:53:37 +00005303bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005304 HeapObject* array = elements();
5305 ASSERT(array != NULL);
5306 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00005307}
5308
5309
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005310#define EXTERNAL_ELEMENTS_CHECK(name, type) \
5311bool JSObject::HasExternal##name##Elements() { \
5312 HeapObject* array = elements(); \
5313 ASSERT(array != NULL); \
5314 if (!array->IsHeapObject()) \
5315 return false; \
5316 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00005317}
5318
5319
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005320EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
5321EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
5322EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
5323EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
5324 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
5325EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
5326EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
5327 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
5328EXTERNAL_ELEMENTS_CHECK(Float,
5329 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00005330EXTERNAL_ELEMENTS_CHECK(Double,
5331 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005332EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00005333
5334
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005335bool JSObject::HasNamedInterceptor() {
5336 return map()->has_named_interceptor();
5337}
5338
5339
5340bool JSObject::HasIndexedInterceptor() {
5341 return map()->has_indexed_interceptor();
5342}
5343
5344
lrn@chromium.org303ada72010-10-27 09:33:13 +00005345MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005346 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005347 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005348 Isolate* isolate = GetIsolate();
5349 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00005350 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005351 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
5352 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00005353 if (!maybe_writable_elems->ToObject(&writable_elems)) {
5354 return maybe_writable_elems;
5355 }
5356 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005357 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005358 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005359 return writable_elems;
5360}
5361
5362
ulan@chromium.org750145a2013-03-07 15:14:13 +00005363NameDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005364 ASSERT(!HasFastProperties());
ulan@chromium.org750145a2013-03-07 15:14:13 +00005365 return NameDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005366}
5367
5368
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005369SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005370 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005371 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005372}
5373
5374
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005375bool Name::IsHashFieldComputed(uint32_t field) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005376 return (field & kHashNotComputedMask) == 0;
5377}
5378
5379
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005380bool Name::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005381 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005382}
5383
5384
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005385uint32_t Name::Hash() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005386 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005387 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005388 if (IsHashFieldComputed(field)) return field >> kHashShift;
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005389 // Slow case: compute hash code and set it. Has to be a string.
5390 return String::cast(this)->ComputeAndSetHash();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005391}
5392
5393
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005394StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00005395 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005396 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00005397 array_index_(0),
5398 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005399 is_first_char_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005400 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005401}
ager@chromium.org7c537e22008-10-16 08:43:32 +00005402
5403
5404bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005405 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005406}
5407
5408
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005409uint32_t StringHasher::AddCharacterCore(uint32_t running_hash, uint16_t c) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005410 running_hash += c;
5411 running_hash += (running_hash << 10);
5412 running_hash ^= (running_hash >> 6);
5413 return running_hash;
5414}
5415
5416
5417uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
5418 running_hash += (running_hash << 3);
5419 running_hash ^= (running_hash >> 11);
5420 running_hash += (running_hash << 15);
5421 if ((running_hash & String::kHashBitMask) == 0) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005422 return kZeroHash;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005423 }
5424 return running_hash;
5425}
5426
5427
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005428void StringHasher::AddCharacter(uint16_t c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005429 // Use the Jenkins one-at-a-time hash function to update the hash
5430 // for the given character.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005431 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005432}
5433
5434
5435bool StringHasher::UpdateIndex(uint16_t c) {
5436 ASSERT(is_array_index_);
5437 if (c < '0' || c > '9') {
5438 is_array_index_ = false;
5439 return false;
5440 }
5441 int d = c - '0';
5442 if (is_first_char_) {
5443 is_first_char_ = false;
5444 if (c == '0' && length_ > 1) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00005445 is_array_index_ = false;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005446 return false;
5447 }
5448 }
5449 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
5450 is_array_index_ = false;
5451 return false;
5452 }
5453 array_index_ = array_index_ * 10 + d;
5454 return true;
5455}
5456
5457
5458template<typename Char>
5459inline void StringHasher::AddCharacters(const Char* chars, int length) {
5460 ASSERT(sizeof(Char) == 1 || sizeof(Char) == 2);
5461 int i = 0;
5462 if (is_array_index_) {
5463 for (; i < length; i++) {
5464 AddCharacter(chars[i]);
5465 if (!UpdateIndex(chars[i])) {
5466 i++;
5467 break;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005468 }
5469 }
5470 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005471 for (; i < length; i++) {
5472 ASSERT(!is_array_index_);
5473 AddCharacter(chars[i]);
yangguo@chromium.org154ff992012-03-13 08:09:54 +00005474 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00005475}
5476
5477
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005478template <typename schar>
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005479uint32_t StringHasher::HashSequentialString(const schar* chars,
5480 int length,
5481 uint32_t seed) {
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005482 StringHasher hasher(length, seed);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005483 if (!hasher.has_trivial_hash()) hasher.AddCharacters(chars, length);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005484 return hasher.GetHashField();
5485}
5486
5487
ulan@chromium.org750145a2013-03-07 15:14:13 +00005488bool Name::AsArrayIndex(uint32_t* index) {
5489 return IsString() && String::cast(this)->AsArrayIndex(index);
5490}
5491
5492
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005493bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005494 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00005495 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
5496 return false;
5497 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005498 return SlowAsArrayIndex(index);
5499}
5500
5501
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00005502Object* JSReceiver::GetPrototype() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00005503 return map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005504}
5505
5506
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00005507Object* JSReceiver::GetConstructor() {
5508 return map()->constructor();
5509}
5510
5511
ulan@chromium.org750145a2013-03-07 15:14:13 +00005512bool JSReceiver::HasProperty(Name* name) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00005513 if (IsJSProxy()) {
5514 return JSProxy::cast(this)->HasPropertyWithHandler(name);
5515 }
5516 return GetPropertyAttribute(name) != ABSENT;
5517}
5518
5519
ulan@chromium.org750145a2013-03-07 15:14:13 +00005520bool JSReceiver::HasLocalProperty(Name* name) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00005521 if (IsJSProxy()) {
5522 return JSProxy::cast(this)->HasPropertyWithHandler(name);
5523 }
5524 return GetLocalPropertyAttribute(name) != ABSENT;
5525}
5526
5527
ulan@chromium.org750145a2013-03-07 15:14:13 +00005528PropertyAttributes JSReceiver::GetPropertyAttribute(Name* key) {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00005529 uint32_t index;
5530 if (IsJSObject() && key->AsArrayIndex(&index)) {
5531 return GetElementAttribute(index);
5532 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005533 return GetPropertyAttributeWithReceiver(this, key);
5534}
5535
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00005536
5537PropertyAttributes JSReceiver::GetElementAttribute(uint32_t index) {
5538 if (IsJSProxy()) {
5539 return JSProxy::cast(this)->GetElementAttributeWithHandler(this, index);
5540 }
5541 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5542 this, index, true);
5543}
5544
5545
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005546// TODO(504): this may be useful in other places too where JSGlobalProxy
5547// is used.
5548Object* JSObject::BypassGlobalProxy() {
5549 if (IsJSGlobalProxy()) {
5550 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005551 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005552 ASSERT(proto->IsJSGlobalObject());
5553 return proto;
5554 }
5555 return this;
5556}
5557
5558
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005559MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
5560 return IsJSProxy()
5561 ? JSProxy::cast(this)->GetIdentityHash(flag)
5562 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005563}
5564
5565
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005566bool JSReceiver::HasElement(uint32_t index) {
5567 if (IsJSProxy()) {
5568 return JSProxy::cast(this)->HasElementWithHandler(index);
5569 }
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00005570 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5571 this, index, true) != ABSENT;
5572}
5573
5574
5575bool JSReceiver::HasLocalElement(uint32_t index) {
5576 if (IsJSProxy()) {
5577 return JSProxy::cast(this)->HasElementWithHandler(index);
5578 }
5579 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5580 this, index, false) != ABSENT;
5581}
5582
5583
5584PropertyAttributes JSReceiver::GetLocalElementAttribute(uint32_t index) {
5585 if (IsJSProxy()) {
5586 return JSProxy::cast(this)->GetElementAttributeWithHandler(this, index);
5587 }
5588 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5589 this, index, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005590}
5591
5592
5593bool AccessorInfo::all_can_read() {
5594 return BooleanBit::get(flag(), kAllCanReadBit);
5595}
5596
5597
5598void AccessorInfo::set_all_can_read(bool value) {
5599 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
5600}
5601
5602
5603bool AccessorInfo::all_can_write() {
5604 return BooleanBit::get(flag(), kAllCanWriteBit);
5605}
5606
5607
5608void AccessorInfo::set_all_can_write(bool value) {
5609 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
5610}
5611
5612
ager@chromium.org870a0b62008-11-04 11:43:05 +00005613bool AccessorInfo::prohibits_overwriting() {
5614 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
5615}
5616
5617
5618void AccessorInfo::set_prohibits_overwriting(bool value) {
5619 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
5620}
5621
5622
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005623PropertyAttributes AccessorInfo::property_attributes() {
5624 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
5625}
5626
5627
5628void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005629 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005630}
5631
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005632
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005633bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
5634 Object* function_template = expected_receiver_type();
5635 if (!function_template->IsFunctionTemplateInfo()) return true;
5636 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
5637}
5638
5639
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005640template<typename Shape, typename Key>
5641void Dictionary<Shape, Key>::SetEntry(int entry,
5642 Object* key,
5643 Object* value) {
5644 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
5645}
5646
5647
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005648template<typename Shape, typename Key>
5649void Dictionary<Shape, Key>::SetEntry(int entry,
5650 Object* key,
5651 Object* value,
5652 PropertyDetails details) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00005653 ASSERT(!key->IsName() ||
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005654 details.IsDeleted() ||
5655 details.dictionary_index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005656 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005657 AssertNoAllocation no_gc;
5658 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005659 FixedArray::set(index, key, mode);
5660 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005661 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005662}
5663
5664
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005665bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
5666 ASSERT(other->IsNumber());
5667 return key == static_cast<uint32_t>(other->Number());
5668}
5669
5670
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005671uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
5672 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005673}
5674
5675
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005676uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
5677 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005678 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005679 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005680}
5681
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005682uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
5683 return ComputeIntegerHash(key, seed);
5684}
5685
5686uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
5687 uint32_t seed,
5688 Object* other) {
5689 ASSERT(other->IsNumber());
5690 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
5691}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005692
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00005693MaybeObject* NumberDictionaryShape::AsObject(Heap* heap, uint32_t key) {
5694 return heap->NumberFromUint32(key);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005695}
5696
5697
ulan@chromium.org750145a2013-03-07 15:14:13 +00005698bool NameDictionaryShape::IsMatch(Name* key, Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005699 // We know that all entries in a hash table had their hash keys created.
5700 // Use that knowledge to have fast failure.
ulan@chromium.org750145a2013-03-07 15:14:13 +00005701 if (key->Hash() != Name::cast(other)->Hash()) return false;
5702 return key->Equals(Name::cast(other));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005703}
5704
5705
ulan@chromium.org750145a2013-03-07 15:14:13 +00005706uint32_t NameDictionaryShape::Hash(Name* key) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005707 return key->Hash();
5708}
5709
5710
ulan@chromium.org750145a2013-03-07 15:14:13 +00005711uint32_t NameDictionaryShape::HashForObject(Name* key, Object* other) {
5712 return Name::cast(other)->Hash();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005713}
5714
5715
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00005716MaybeObject* NameDictionaryShape::AsObject(Heap* heap, Name* key) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005717 return key;
5718}
5719
5720
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005721template <int entrysize>
5722bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
5723 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005724}
5725
5726
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005727template <int entrysize>
5728uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005729 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
5730 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005731}
5732
5733
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005734template <int entrysize>
5735uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
5736 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005737 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
5738 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005739}
5740
5741
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005742template <int entrysize>
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00005743MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Heap* heap,
5744 Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005745 return key;
5746}
5747
5748
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005749void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005750 // No write barrier is needed since empty_fixed_array is not in new space.
5751 // Please note this function is used during marking:
5752 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005753 // - IncrementalMarking::Step
danno@chromium.org72204d52012-10-31 10:02:10 +00005754 ASSERT(!heap->InNewSpace(heap->empty_fixed_array()));
5755 WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005756}
5757
5758
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005759void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005760 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005761 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005762 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5763 if (elts->length() < required_size) {
5764 // Doubling in size would be overkill, but leave some slack to avoid
5765 // constantly growing.
5766 Expand(required_size + (required_size >> 3));
5767 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005768 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005769 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5770 // Expand will allocate a new backing store in new space even if the size
5771 // we asked for isn't larger than what we had before.
5772 Expand(required_size);
5773 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005774}
5775
5776
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005777void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005778 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005779 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5780}
5781
5782
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005783bool JSArray::AllowsSetElementsLength() {
5784 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5785 ASSERT(result == !HasExternalArrayElements());
5786 return result;
5787}
5788
5789
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005790MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5791 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005792 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005793 if (maybe_result->IsFailure()) return maybe_result;
5794 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005795 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005796 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005797 (IsFastObjectElementsKind(GetElementsKind()) ||
5798 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005799 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005800 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005801 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005802 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005803}
5804
5805
lrn@chromium.org303ada72010-10-27 09:33:13 +00005806MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005807 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005808 return GetHeap()->CopyFixedArray(this);
5809}
5810
5811
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005812MaybeObject* FixedDoubleArray::Copy() {
5813 if (length() == 0) return this;
5814 return GetHeap()->CopyFixedDoubleArray(this);
5815}
5816
5817
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005818void TypeFeedbackCells::SetAstId(int index, TypeFeedbackId id) {
5819 set(1 + index * 2, Smi::FromInt(id.ToInt()));
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005820}
5821
5822
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005823TypeFeedbackId TypeFeedbackCells::AstId(int index) {
5824 return TypeFeedbackId(Smi::cast(get(1 + index * 2))->value());
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005825}
5826
5827
5828void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
5829 set(index * 2, cell);
5830}
5831
5832
5833JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
5834 return JSGlobalPropertyCell::cast(get(index * 2));
5835}
5836
5837
5838Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5839 return isolate->factory()->the_hole_value();
5840}
5841
5842
5843Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5844 return isolate->factory()->undefined_value();
5845}
5846
5847
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005848Handle<Object> TypeFeedbackCells::MonomorphicArraySentinel(Isolate* isolate,
5849 ElementsKind elements_kind) {
5850 return Handle<Object>(Smi::FromInt(static_cast<int>(elements_kind)), isolate);
5851}
5852
5853
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005854Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
danno@chromium.org72204d52012-10-31 10:02:10 +00005855 return heap->the_hole_value();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005856}
5857
5858
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005859int TypeFeedbackInfo::ic_total_count() {
5860 int current = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5861 return ICTotalCountField::decode(current);
5862}
5863
5864
5865void TypeFeedbackInfo::set_ic_total_count(int count) {
5866 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5867 value = ICTotalCountField::update(value,
5868 ICTotalCountField::decode(count));
5869 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
5870}
5871
5872
5873int TypeFeedbackInfo::ic_with_type_info_count() {
5874 int current = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5875 return ICsWithTypeInfoCountField::decode(current);
5876}
5877
5878
5879void TypeFeedbackInfo::change_ic_with_type_info_count(int delta) {
5880 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5881 int new_count = ICsWithTypeInfoCountField::decode(value) + delta;
5882 // We can get negative count here when the type-feedback info is
5883 // shared between two code objects. The can only happen when
5884 // the debugger made a shallow copy of code object (see Heap::CopyCode).
5885 // Since we do not optimize when the debugger is active, we can skip
5886 // this counter update.
5887 if (new_count >= 0) {
5888 new_count &= ICsWithTypeInfoCountField::kMask;
5889 value = ICsWithTypeInfoCountField::update(value, new_count);
5890 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
5891 }
5892}
5893
5894
5895void TypeFeedbackInfo::initialize_storage() {
5896 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(0));
5897 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(0));
5898}
5899
5900
5901void TypeFeedbackInfo::change_own_type_change_checksum() {
5902 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5903 int checksum = OwnTypeChangeChecksum::decode(value);
5904 checksum = (checksum + 1) % (1 << kTypeChangeChecksumBits);
5905 value = OwnTypeChangeChecksum::update(value, checksum);
5906 // Ensure packed bit field is in Smi range.
5907 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
5908 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
5909 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
5910}
5911
5912
5913void TypeFeedbackInfo::set_inlined_type_change_checksum(int checksum) {
5914 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5915 int mask = (1 << kTypeChangeChecksumBits) - 1;
5916 value = InlinedTypeChangeChecksum::update(value, checksum & mask);
5917 // Ensure packed bit field is in Smi range.
5918 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
5919 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
5920 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
5921}
5922
5923
5924int TypeFeedbackInfo::own_type_change_checksum() {
5925 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5926 return OwnTypeChangeChecksum::decode(value);
5927}
5928
5929
5930bool TypeFeedbackInfo::matches_inlined_type_change_checksum(int checksum) {
5931 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5932 int mask = (1 << kTypeChangeChecksumBits) - 1;
5933 return InlinedTypeChangeChecksum::decode(value) == (checksum & mask);
5934}
5935
5936
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005937ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
5938 kTypeFeedbackCellsOffset)
5939
5940
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00005941SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
5942
5943
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005944Relocatable::Relocatable(Isolate* isolate) {
5945 ASSERT(isolate == Isolate::Current());
5946 isolate_ = isolate;
5947 prev_ = isolate->relocatable_top();
5948 isolate->set_relocatable_top(this);
5949}
5950
5951
5952Relocatable::~Relocatable() {
5953 ASSERT(isolate_ == Isolate::Current());
5954 ASSERT_EQ(isolate_->relocatable_top(), this);
5955 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005956}
5957
5958
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005959int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
5960 return map->instance_size();
5961}
5962
5963
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005964void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005965 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005966 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005967}
5968
5969
5970template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005971void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005972 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005973 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005974}
5975
5976
5977void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5978 typedef v8::String::ExternalAsciiStringResource Resource;
5979 v->VisitExternalAsciiString(
5980 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5981}
5982
5983
5984template<typename StaticVisitor>
5985void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5986 typedef v8::String::ExternalAsciiStringResource Resource;
5987 StaticVisitor::VisitExternalAsciiString(
5988 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5989}
5990
5991
5992void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5993 typedef v8::String::ExternalStringResource Resource;
5994 v->VisitExternalTwoByteString(
5995 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5996}
5997
5998
5999template<typename StaticVisitor>
6000void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
6001 typedef v8::String::ExternalStringResource Resource;
6002 StaticVisitor::VisitExternalTwoByteString(
6003 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
6004}
6005
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006006
6007template<int start_offset, int end_offset, int size>
6008void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
6009 HeapObject* obj,
6010 ObjectVisitor* v) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00006011 v->VisitPointers(HeapObject::RawField(obj, start_offset),
6012 HeapObject::RawField(obj, end_offset));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006013}
6014
6015
6016template<int start_offset>
6017void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
6018 int object_size,
6019 ObjectVisitor* v) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00006020 v->VisitPointers(HeapObject::RawField(obj, start_offset),
6021 HeapObject::RawField(obj, object_size));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006022}
6023
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006024
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00006025#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006026#undef CAST_ACCESSOR
6027#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006028#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00006029#undef ACCESSORS_TO_SMI
6030#undef SMI_ACCESSORS
6031#undef BOOL_GETTER
6032#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006033#undef FIELD_ADDR
6034#undef READ_FIELD
6035#undef WRITE_FIELD
6036#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00006037#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006038#undef READ_DOUBLE_FIELD
6039#undef WRITE_DOUBLE_FIELD
6040#undef READ_INT_FIELD
6041#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00006042#undef READ_INTPTR_FIELD
6043#undef WRITE_INTPTR_FIELD
6044#undef READ_UINT32_FIELD
6045#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006046#undef READ_SHORT_FIELD
6047#undef WRITE_SHORT_FIELD
6048#undef READ_BYTE_FIELD
6049#undef WRITE_BYTE_FIELD
6050
6051
6052} } // namespace v8::internal
6053
6054#endif // V8_OBJECTS_INL_H_