blob: 374bcbd70c8ac2a9461349bc88527b44d0886d2d [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.org46a2a512013-01-18 16:29:40 +0000360#ifndef ENABLE_LATIN_1
361 return (type & kStringEncodingMask) == kOneByteStringTag ||
362 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
363#else
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000364 return (type & kAsciiDataHintMask) == kAsciiDataHintTag;
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000365#endif
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000366}
367
368
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000369bool String::IsOneByteConvertible() {
370 return HasOnlyAsciiChars() || IsOneByteRepresentation();
371}
372
373
ager@chromium.org870a0b62008-11-04 11:43:05 +0000374bool StringShape::IsCons() {
375 return (type_ & kStringRepresentationMask) == kConsStringTag;
376}
377
378
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000379bool StringShape::IsSliced() {
380 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
381}
382
383
384bool StringShape::IsIndirect() {
385 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
386}
387
388
ager@chromium.org870a0b62008-11-04 11:43:05 +0000389bool StringShape::IsExternal() {
390 return (type_ & kStringRepresentationMask) == kExternalStringTag;
391}
392
393
394bool StringShape::IsSequential() {
395 return (type_ & kStringRepresentationMask) == kSeqStringTag;
396}
397
398
399StringRepresentationTag StringShape::representation_tag() {
400 uint32_t tag = (type_ & kStringRepresentationMask);
401 return static_cast<StringRepresentationTag>(tag);
402}
403
404
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000405uint32_t StringShape::encoding_tag() {
406 return type_ & kStringEncodingMask;
407}
408
409
ager@chromium.org870a0b62008-11-04 11:43:05 +0000410uint32_t StringShape::full_representation_tag() {
411 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
412}
413
414
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000415STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
416 Internals::kFullStringRepresentationMask);
417
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000418STATIC_CHECK(static_cast<uint32_t>(kStringEncodingMask) ==
419 Internals::kStringEncodingMask);
420
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000421
ager@chromium.org870a0b62008-11-04 11:43:05 +0000422bool StringShape::IsSequentialAscii() {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000423 return full_representation_tag() == (kSeqStringTag | kOneByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000424}
425
426
427bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000428 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000429}
430
431
432bool StringShape::IsExternalAscii() {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000433 return full_representation_tag() == (kExternalStringTag | kOneByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000434}
435
436
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000437STATIC_CHECK((kExternalStringTag | kOneByteStringTag) ==
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000438 Internals::kExternalAsciiRepresentationTag);
439
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000440STATIC_CHECK(v8::String::ASCII_ENCODING == kOneByteStringTag);
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000441
442
ager@chromium.org870a0b62008-11-04 11:43:05 +0000443bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000444 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000445}
446
447
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000448STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
449 Internals::kExternalTwoByteRepresentationTag);
450
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000451STATIC_CHECK(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000452
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000453uc32 FlatStringReader::Get(int index) {
454 ASSERT(0 <= index && index <= length_);
455 if (is_ascii_) {
456 return static_cast<const byte*>(start_)[index];
457 } else {
458 return static_cast<const uc16*>(start_)[index];
459 }
460}
461
462
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000463bool Object::IsNumber() {
464 return IsSmi() || IsHeapNumber();
465}
466
467
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000468TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
469TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000470
471
472bool Object::IsFiller() {
473 if (!Object::IsHeapObject()) return false;
474 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
475 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
476}
477
478
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000479TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000480
481
ager@chromium.org3811b432009-10-28 14:53:37 +0000482bool Object::IsExternalArray() {
483 if (!Object::IsHeapObject())
484 return false;
485 InstanceType instance_type =
486 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000487 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
488 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000489}
490
491
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000492TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
493TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
494TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
495TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
496TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
497TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
498TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
499TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000500
501
lrn@chromium.org303ada72010-10-27 09:33:13 +0000502bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000503 return HAS_FAILURE_TAG(this);
504}
505
506
lrn@chromium.org303ada72010-10-27 09:33:13 +0000507bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000508 return HAS_FAILURE_TAG(this)
509 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
510}
511
512
lrn@chromium.org303ada72010-10-27 09:33:13 +0000513bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000514 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000515 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000516}
517
518
lrn@chromium.org303ada72010-10-27 09:33:13 +0000519bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000520 return this == Failure::Exception();
521}
522
523
lrn@chromium.org303ada72010-10-27 09:33:13 +0000524bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000525 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000526}
527
528
529Failure* Failure::cast(MaybeObject* obj) {
530 ASSERT(HAS_FAILURE_TAG(obj));
531 return reinterpret_cast<Failure*>(obj);
532}
533
534
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000535bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000536 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000537 return IsHeapObject() &&
538 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
539}
540
541
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000542bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000543 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
544 return IsHeapObject() &&
545 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000546}
547
548
549bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000550 if (!Object::IsHeapObject()) return false;
551 InstanceType type = HeapObject::cast(this)->map()->instance_type();
552 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000553}
554
555
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000556TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
557TYPE_CHECKER(JSSet, JS_SET_TYPE)
558TYPE_CHECKER(JSMap, JS_MAP_TYPE)
559TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
560TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
561TYPE_CHECKER(Map, MAP_TYPE)
562TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
563TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000564
565
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000566bool Object::IsDescriptorArray() {
567 return IsFixedArray();
568}
569
570
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000571bool Object::IsTransitionArray() {
572 return IsFixedArray();
573}
574
575
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000576bool Object::IsDeoptimizationInputData() {
577 // Must be a fixed array.
578 if (!IsFixedArray()) return false;
579
580 // There's no sure way to detect the difference between a fixed array and
581 // a deoptimization data array. Since this is used for asserts we can
582 // check that the length is zero or else the fixed size plus a multiple of
583 // the entry size.
584 int length = FixedArray::cast(this)->length();
585 if (length == 0) return true;
586
587 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
588 return length >= 0 &&
589 length % DeoptimizationInputData::kDeoptEntrySize == 0;
590}
591
592
593bool Object::IsDeoptimizationOutputData() {
594 if (!IsFixedArray()) return false;
595 // There's actually no way to see the difference between a fixed array and
596 // a deoptimization data array. Since this is used for asserts we can check
597 // that the length is plausible though.
598 if (FixedArray::cast(this)->length() % 2 != 0) return false;
599 return true;
600}
601
602
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000603bool Object::IsDependentCode() {
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000604 if (!IsFixedArray()) return false;
605 // There's actually no way to see the difference between a fixed array and
606 // a dependent codes array.
607 return true;
608}
609
610
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000611bool Object::IsTypeFeedbackCells() {
612 if (!IsFixedArray()) return false;
613 // There's actually no way to see the difference between a fixed array and
614 // a cache cells array. Since this is used for asserts we can check that
615 // the length is plausible though.
616 if (FixedArray::cast(this)->length() % 2 != 0) return false;
617 return true;
618}
619
620
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000621bool Object::IsContext() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000622 if (!Object::IsHeapObject()) return false;
623 Map* map = HeapObject::cast(this)->map();
624 Heap* heap = map->GetHeap();
625 return (map == heap->function_context_map() ||
626 map == heap->catch_context_map() ||
627 map == heap->with_context_map() ||
628 map == heap->native_context_map() ||
629 map == heap->block_context_map() ||
630 map == heap->module_context_map() ||
631 map == heap->global_context_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000632}
633
634
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000635bool Object::IsNativeContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000636 return Object::IsHeapObject() &&
637 HeapObject::cast(this)->map() ==
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000638 HeapObject::cast(this)->GetHeap()->native_context_map();
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000639}
640
641
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000642bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000643 return Object::IsHeapObject() &&
644 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000645 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000646}
647
648
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000649TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000650
651
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000652template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000653 return obj->IsJSFunction();
654}
655
656
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000657TYPE_CHECKER(Code, CODE_TYPE)
658TYPE_CHECKER(Oddball, ODDBALL_TYPE)
659TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
660TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000661TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000662TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000663TYPE_CHECKER(JSDate, JS_DATE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000664TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000665
666
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000667bool Object::IsStringWrapper() {
668 return IsJSValue() && JSValue::cast(this)->value()->IsString();
669}
670
671
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000672TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000673
674
675bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000676 return IsOddball() &&
677 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000678}
679
680
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000681TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
682TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000683
684
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000685template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000686 return obj->IsJSArray();
687}
688
689
690bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000691 return Object::IsHeapObject() &&
692 HeapObject::cast(this)->map() ==
693 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000694}
695
696
697bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000698 return IsHashTable() &&
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000699 this != HeapObject::cast(this)->GetHeap()->string_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000700}
701
702
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000703bool Object::IsStringTable() {
danno@chromium.org72204d52012-10-31 10:02:10 +0000704 return IsHashTable() &&
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000705 this == HeapObject::cast(this)->GetHeap()->raw_unchecked_string_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000706}
707
708
ager@chromium.orgac091b72010-05-05 07:34:42 +0000709bool Object::IsJSFunctionResultCache() {
710 if (!IsFixedArray()) return false;
711 FixedArray* self = FixedArray::cast(this);
712 int length = self->length();
713 if (length < JSFunctionResultCache::kEntriesIndex) return false;
714 if ((length - JSFunctionResultCache::kEntriesIndex)
715 % JSFunctionResultCache::kEntrySize != 0) {
716 return false;
717 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +0000718#ifdef VERIFY_HEAP
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000719 if (FLAG_verify_heap) {
720 reinterpret_cast<JSFunctionResultCache*>(this)->
721 JSFunctionResultCacheVerify();
722 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000723#endif
724 return true;
725}
726
727
ricow@chromium.org65fae842010-08-25 15:26:24 +0000728bool Object::IsNormalizedMapCache() {
729 if (!IsFixedArray()) return false;
730 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
731 return false;
732 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +0000733#ifdef VERIFY_HEAP
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000734 if (FLAG_verify_heap) {
735 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
736 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000737#endif
738 return true;
739}
740
741
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000742bool Object::IsCompilationCacheTable() {
743 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000744}
745
746
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000747bool Object::IsCodeCacheHashTable() {
748 return IsHashTable();
749}
750
751
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000752bool Object::IsPolymorphicCodeCacheHashTable() {
753 return IsHashTable();
754}
755
756
ager@chromium.org236ad962008-09-25 09:45:57 +0000757bool Object::IsMapCache() {
758 return IsHashTable();
759}
760
761
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000762bool Object::IsObjectHashTable() {
763 return IsHashTable();
764}
765
766
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000767bool Object::IsPrimitive() {
768 return IsOddball() || IsNumber() || IsString();
769}
770
771
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000772bool Object::IsJSGlobalProxy() {
773 bool result = IsHeapObject() &&
774 (HeapObject::cast(this)->map()->instance_type() ==
775 JS_GLOBAL_PROXY_TYPE);
776 ASSERT(!result || IsAccessCheckNeeded());
777 return result;
778}
779
780
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000781bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000782 if (!IsHeapObject()) return false;
783
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000784 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000785 return type == JS_GLOBAL_OBJECT_TYPE ||
786 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787}
788
789
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000790TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
791TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000792
793
794bool Object::IsUndetectableObject() {
795 return IsHeapObject()
796 && HeapObject::cast(this)->map()->is_undetectable();
797}
798
799
800bool Object::IsAccessCheckNeeded() {
801 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000802 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000803}
804
805
806bool Object::IsStruct() {
807 if (!IsHeapObject()) return false;
808 switch (HeapObject::cast(this)->map()->instance_type()) {
809#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
810 STRUCT_LIST(MAKE_STRUCT_CASE)
811#undef MAKE_STRUCT_CASE
812 default: return false;
813 }
814}
815
816
817#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
818 bool Object::Is##Name() { \
819 return Object::IsHeapObject() \
820 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
821 }
822 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
823#undef MAKE_STRUCT_PREDICATE
824
825
826bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000827 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000828}
829
830
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000831bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000832 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
833}
834
835
836bool Object::IsTheHole() {
837 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000838}
839
840
841bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000842 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000843}
844
845
846bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000847 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000848}
849
850
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000851bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000852 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000853}
854
855
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000856double Object::Number() {
857 ASSERT(IsNumber());
858 return IsSmi()
859 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
860 : reinterpret_cast<HeapNumber*>(this)->value();
861}
862
863
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000864bool Object::IsNaN() {
865 return this->IsHeapNumber() && isnan(HeapNumber::cast(this)->value());
866}
867
868
lrn@chromium.org303ada72010-10-27 09:33:13 +0000869MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000870 if (IsSmi()) return this;
871 if (IsHeapNumber()) {
872 double value = HeapNumber::cast(this)->value();
873 int int_value = FastD2I(value);
874 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
875 return Smi::FromInt(int_value);
876 }
877 }
878 return Failure::Exception();
879}
880
881
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000882bool Object::HasSpecificClassOf(String* name) {
883 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
884}
885
886
lrn@chromium.org303ada72010-10-27 09:33:13 +0000887MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000888 // GetElement can trigger a getter which can cause allocation.
889 // This was not always the case. This ASSERT is here to catch
890 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000891 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000892 return GetElementWithReceiver(this, index);
893}
894
895
lrn@chromium.org303ada72010-10-27 09:33:13 +0000896Object* Object::GetElementNoExceptionThrown(uint32_t index) {
897 MaybeObject* maybe = GetElementWithReceiver(this, index);
898 ASSERT(!maybe->IsFailure());
899 Object* result = NULL; // Initialization to please compiler.
900 maybe->ToObject(&result);
901 return result;
902}
903
904
905MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000906 PropertyAttributes attributes;
907 return GetPropertyWithReceiver(this, key, &attributes);
908}
909
910
lrn@chromium.org303ada72010-10-27 09:33:13 +0000911MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000912 return GetPropertyWithReceiver(this, key, attributes);
913}
914
915
916#define FIELD_ADDR(p, offset) \
917 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
918
919#define READ_FIELD(p, offset) \
920 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
921
922#define WRITE_FIELD(p, offset, value) \
923 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
924
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000925#define WRITE_BARRIER(heap, object, offset, value) \
926 heap->incremental_marking()->RecordWrite( \
927 object, HeapObject::RawField(object, offset), value); \
928 if (heap->InNewSpace(value)) { \
929 heap->RecordWrite(object->address(), offset); \
930 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000931
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000932#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
933 if (mode == UPDATE_WRITE_BARRIER) { \
934 heap->incremental_marking()->RecordWrite( \
935 object, HeapObject::RawField(object, offset), value); \
936 if (heap->InNewSpace(value)) { \
937 heap->RecordWrite(object->address(), offset); \
938 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000939 }
940
lrn@chromium.org7516f052011-03-30 08:52:27 +0000941#ifndef V8_TARGET_ARCH_MIPS
942 #define READ_DOUBLE_FIELD(p, offset) \
943 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
944#else // V8_TARGET_ARCH_MIPS
945 // Prevent gcc from using load-double (mips ldc1) on (possibly)
946 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000947 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000948 union conversion {
949 double d;
950 uint32_t u[2];
951 } c;
952 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
953 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
954 return c.d;
955 }
956 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
957#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958
lrn@chromium.org7516f052011-03-30 08:52:27 +0000959#ifndef V8_TARGET_ARCH_MIPS
960 #define WRITE_DOUBLE_FIELD(p, offset, value) \
961 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
962#else // V8_TARGET_ARCH_MIPS
963 // Prevent gcc from using store-double (mips sdc1) on (possibly)
964 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000965 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000966 double value) {
967 union conversion {
968 double d;
969 uint32_t u[2];
970 } c;
971 c.d = value;
972 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
973 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
974 }
975 #define WRITE_DOUBLE_FIELD(p, offset, value) \
976 write_double_field(p, offset, value)
977#endif // V8_TARGET_ARCH_MIPS
978
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000979
980#define READ_INT_FIELD(p, offset) \
981 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
982
983#define WRITE_INT_FIELD(p, offset, value) \
984 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
985
ager@chromium.org3e875802009-06-29 08:26:34 +0000986#define READ_INTPTR_FIELD(p, offset) \
987 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
988
989#define WRITE_INTPTR_FIELD(p, offset, value) \
990 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
991
ager@chromium.org7c537e22008-10-16 08:43:32 +0000992#define READ_UINT32_FIELD(p, offset) \
993 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
994
995#define WRITE_UINT32_FIELD(p, offset, value) \
996 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
997
danno@chromium.org88aa0582012-03-23 15:11:57 +0000998#define READ_INT64_FIELD(p, offset) \
999 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
1000
1001#define WRITE_INT64_FIELD(p, offset, value) \
1002 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
1003
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001004#define READ_SHORT_FIELD(p, offset) \
1005 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
1006
1007#define WRITE_SHORT_FIELD(p, offset, value) \
1008 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
1009
1010#define READ_BYTE_FIELD(p, offset) \
1011 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
1012
1013#define WRITE_BYTE_FIELD(p, offset, value) \
1014 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
1015
1016
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00001017Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
1018 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001019}
1020
1021
1022int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00001023 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001024}
1025
1026
1027Smi* Smi::FromInt(int value) {
1028 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001029 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +00001030 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001031 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +00001032 return reinterpret_cast<Smi*>(tagged_value);
1033}
1034
1035
1036Smi* Smi::FromIntptr(intptr_t value) {
1037 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001038 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1039 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001040}
1041
1042
1043Failure::Type Failure::type() const {
1044 return static_cast<Type>(value() & kFailureTypeTagMask);
1045}
1046
1047
1048bool Failure::IsInternalError() const {
1049 return type() == INTERNAL_ERROR;
1050}
1051
1052
1053bool Failure::IsOutOfMemoryException() const {
1054 return type() == OUT_OF_MEMORY_EXCEPTION;
1055}
1056
1057
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001058AllocationSpace Failure::allocation_space() const {
1059 ASSERT_EQ(RETRY_AFTER_GC, type());
1060 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1061 & kSpaceTagMask);
1062}
1063
1064
1065Failure* Failure::InternalError() {
1066 return Construct(INTERNAL_ERROR);
1067}
1068
1069
1070Failure* Failure::Exception() {
1071 return Construct(EXCEPTION);
1072}
1073
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001074
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00001075Failure* Failure::OutOfMemoryException(intptr_t value) {
1076 return Construct(OUT_OF_MEMORY_EXCEPTION, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001077}
1078
1079
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001080intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001081 return static_cast<intptr_t>(
1082 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001083}
1084
1085
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001086Failure* Failure::RetryAfterGC() {
1087 return RetryAfterGC(NEW_SPACE);
1088}
1089
1090
1091Failure* Failure::RetryAfterGC(AllocationSpace space) {
1092 ASSERT((space & ~kSpaceTagMask) == 0);
1093 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001094}
1095
1096
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001097Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001098 uintptr_t info =
1099 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001100 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +00001101 // Fill the unused bits with a pattern that's easy to recognize in crash
1102 // dumps.
1103 static const int kFailureMagicPattern = 0x0BAD0000;
1104 return reinterpret_cast<Failure*>(
1105 (info << kFailureTagSize) | kFailureTag | kFailureMagicPattern);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001106}
1107
1108
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001109bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001110#ifdef DEBUG
1111 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1112#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001113
1114#ifdef V8_TARGET_ARCH_X64
1115 // To be representable as a long smi, the value must be a 32-bit integer.
1116 bool result = (value == static_cast<int32_t>(value));
1117#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001118 // To be representable as an tagged small integer, the two
1119 // most-significant bits of 'value' must be either 00 or 11 due to
1120 // sign-extension. To check this we add 01 to the two
1121 // most-significant bits, and check if the most-significant bit is 0
1122 //
1123 // CAUTION: The original code below:
1124 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1125 // may lead to incorrect results according to the C language spec, and
1126 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1127 // compiler may produce undefined results in case of signed integer
1128 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001129 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001130#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001131 ASSERT(result == in_range);
1132 return result;
1133}
1134
1135
kasper.lund7276f142008-07-30 08:49:36 +00001136MapWord MapWord::FromMap(Map* map) {
1137 return MapWord(reinterpret_cast<uintptr_t>(map));
1138}
1139
1140
1141Map* MapWord::ToMap() {
1142 return reinterpret_cast<Map*>(value_);
1143}
1144
1145
1146bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001147 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001148}
1149
1150
1151MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001152 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1153 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001154}
1155
1156
1157HeapObject* MapWord::ToForwardingAddress() {
1158 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001159 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001160}
1161
1162
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001163#ifdef VERIFY_HEAP
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001164void HeapObject::VerifyObjectField(int offset) {
1165 VerifyPointer(READ_FIELD(this, offset));
1166}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001167
1168void HeapObject::VerifySmiField(int offset) {
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001169 CHECK(READ_FIELD(this, offset)->IsSmi());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001170}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001171#endif
1172
1173
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001174Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001175 Heap* heap =
1176 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1177 ASSERT(heap != NULL);
1178 ASSERT(heap->isolate() == Isolate::Current());
1179 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001180}
1181
1182
1183Isolate* HeapObject::GetIsolate() {
1184 return GetHeap()->isolate();
1185}
1186
1187
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001188Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001189 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001190}
1191
1192
1193void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001194 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001195 if (value != NULL) {
1196 // TODO(1600) We are passing NULL as a slot because maps can never be on
1197 // evacuation candidate.
1198 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1199 }
1200}
1201
1202
1203// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001204void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001205 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001206}
1207
1208
kasper.lund7276f142008-07-30 08:49:36 +00001209MapWord HeapObject::map_word() {
1210 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1211}
1212
1213
1214void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001215 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001216 // here.
1217 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1218}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001219
1220
1221HeapObject* HeapObject::FromAddress(Address address) {
1222 ASSERT_TAG_ALIGNED(address);
1223 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1224}
1225
1226
1227Address HeapObject::address() {
1228 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1229}
1230
1231
1232int HeapObject::Size() {
1233 return SizeFromMap(map());
1234}
1235
1236
1237void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1238 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1239 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1240}
1241
1242
1243void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1244 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1245}
1246
1247
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001248double HeapNumber::value() {
1249 return READ_DOUBLE_FIELD(this, kValueOffset);
1250}
1251
1252
1253void HeapNumber::set_value(double value) {
1254 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1255}
1256
1257
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001258int HeapNumber::get_exponent() {
1259 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1260 kExponentShift) - kExponentBias;
1261}
1262
1263
1264int HeapNumber::get_sign() {
1265 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1266}
1267
1268
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001269ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001270
1271
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001272Object** FixedArray::GetFirstElementAddress() {
1273 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1274}
1275
1276
1277bool FixedArray::ContainsOnlySmisOrHoles() {
1278 Object* the_hole = GetHeap()->the_hole_value();
1279 Object** current = GetFirstElementAddress();
1280 for (int i = 0; i < length(); ++i) {
1281 Object* candidate = *current++;
1282 if (!candidate->IsSmi() && candidate != the_hole) return false;
1283 }
1284 return true;
1285}
1286
1287
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001288FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001289 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001290 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001291}
1292
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001293
1294void JSObject::ValidateElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001295#if DEBUG
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001296 if (FLAG_enable_slow_asserts) {
1297 ElementsAccessor* accessor = GetElementsAccessor();
1298 accessor->Validate(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001299 }
1300#endif
1301}
1302
1303
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001304MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001305 ValidateElements();
1306 ElementsKind elements_kind = map()->elements_kind();
1307 if (!IsFastObjectElementsKind(elements_kind)) {
1308 if (IsFastHoleyElementsKind(elements_kind)) {
1309 return TransitionElementsKind(FAST_HOLEY_ELEMENTS);
1310 } else {
1311 return TransitionElementsKind(FAST_ELEMENTS);
1312 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001313 }
1314 return this;
1315}
1316
1317
1318MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001319 uint32_t count,
1320 EnsureElementsMode mode) {
1321 ElementsKind current_kind = map()->elements_kind();
1322 ElementsKind target_kind = current_kind;
1323 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001324 bool is_holey = IsFastHoleyElementsKind(current_kind);
1325 if (current_kind == FAST_HOLEY_ELEMENTS) return this;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001326 Heap* heap = GetHeap();
1327 Object* the_hole = heap->the_hole_value();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001328 for (uint32_t i = 0; i < count; ++i) {
1329 Object* current = *objects++;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001330 if (current == the_hole) {
1331 is_holey = true;
1332 target_kind = GetHoleyElementsKind(target_kind);
1333 } else if (!current->IsSmi()) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001334 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && current->IsNumber()) {
1335 if (IsFastSmiElementsKind(target_kind)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001336 if (is_holey) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001337 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001338 } else {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001339 target_kind = FAST_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001340 }
1341 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001342 } else if (is_holey) {
1343 target_kind = FAST_HOLEY_ELEMENTS;
1344 break;
1345 } else {
1346 target_kind = FAST_ELEMENTS;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001347 }
1348 }
1349 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001350
1351 if (target_kind != current_kind) {
1352 return TransitionElementsKind(target_kind);
1353 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001354 return this;
1355}
1356
1357
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001358MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001359 uint32_t length,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001360 EnsureElementsMode mode) {
1361 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1362 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1363 elements->map() == GetHeap()->fixed_cow_array_map());
1364 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1365 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1366 }
1367 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001368 return EnsureCanContainElements(objects, length, mode);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001369 }
1370
1371 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001372 if (GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) {
1373 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1374 } else if (GetElementsKind() == FAST_SMI_ELEMENTS) {
1375 FixedDoubleArray* double_array = FixedDoubleArray::cast(elements);
1376 for (uint32_t i = 0; i < length; ++i) {
1377 if (double_array->is_the_hole(i)) {
1378 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1379 }
1380 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001381 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1382 }
1383
1384 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001385}
1386
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001387
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001388MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1389 ElementsKind to_kind) {
1390 Map* current_map = map();
1391 ElementsKind from_kind = current_map->elements_kind();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001392 if (from_kind == to_kind) return current_map;
1393
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001394 Context* native_context = isolate->context()->native_context();
1395 Object* maybe_array_maps = native_context->js_array_maps();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001396 if (maybe_array_maps->IsFixedArray()) {
1397 FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
1398 if (array_maps->get(from_kind) == current_map) {
1399 Object* maybe_transitioned_map = array_maps->get(to_kind);
1400 if (maybe_transitioned_map->IsMap()) {
1401 return Map::cast(maybe_transitioned_map);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001402 }
1403 }
1404 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001405
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001406 return GetElementsTransitionMapSlow(to_kind);
1407}
1408
1409
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001410void JSObject::set_map_and_elements(Map* new_map,
1411 FixedArrayBase* value,
1412 WriteBarrierMode mode) {
1413 ASSERT(value->HasValidElements());
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001414 if (new_map != NULL) {
1415 if (mode == UPDATE_WRITE_BARRIER) {
1416 set_map(new_map);
1417 } else {
1418 ASSERT(mode == SKIP_WRITE_BARRIER);
1419 set_map_no_write_barrier(new_map);
1420 }
1421 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001422 ASSERT((map()->has_fast_smi_or_object_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001423 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001424 (value->map() == GetHeap()->fixed_array_map() ||
1425 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001426 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1427 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001428 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001429 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001430}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001431
1432
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001433void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1434 set_map_and_elements(NULL, value, mode);
1435}
1436
1437
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001438void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001439 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1440 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001441}
1442
1443
1444void JSObject::initialize_elements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001445 ASSERT(map()->has_fast_smi_or_object_elements() ||
danno@chromium.org2c26cb12012-05-03 09:06:43 +00001446 map()->has_fast_double_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001447 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1448 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001449}
1450
1451
lrn@chromium.org303ada72010-10-27 09:33:13 +00001452MaybeObject* JSObject::ResetElements() {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001453 if (map()->is_observed()) {
1454 // Maintain invariant that observed elements are always in dictionary mode.
1455 SeededNumberDictionary* dictionary;
1456 MaybeObject* maybe = SeededNumberDictionary::Allocate(0);
1457 if (!maybe->To(&dictionary)) return maybe;
1458 if (map() == GetHeap()->non_strict_arguments_elements_map()) {
1459 FixedArray::cast(elements())->set(1, dictionary);
1460 } else {
1461 set_elements(dictionary);
1462 }
1463 return this;
1464 }
1465
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001466 ElementsKind elements_kind = GetInitialFastElementsKind();
1467 if (!FLAG_smi_only_arrays) {
1468 elements_kind = FastSmiToObjectElementsKind(elements_kind);
1469 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001470 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind);
1471 Map* map;
1472 if (!maybe->To(&map)) return maybe;
1473 set_map(map);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001474 initialize_elements();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001475
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001476 return this;
1477}
1478
1479
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00001480MaybeObject* JSObject::AddFastPropertyUsingMap(Map* map) {
1481 ASSERT(this->map()->NumberOfOwnDescriptors() + 1 ==
1482 map->NumberOfOwnDescriptors());
1483 if (this->map()->unused_property_fields() == 0) {
1484 int new_size = properties()->length() + map->unused_property_fields() + 1;
1485 FixedArray* new_properties;
1486 MaybeObject* maybe_properties = properties()->CopySize(new_size);
1487 if (!maybe_properties->To(&new_properties)) return maybe_properties;
1488 set_properties(new_properties);
1489 }
1490 set_map(map);
1491 return this;
1492}
1493
1494
1495bool JSObject::TryTransitionToField(Handle<JSObject> object,
1496 Handle<String> key) {
1497 if (!object->map()->HasTransitionArray()) return false;
1498 Handle<TransitionArray> transitions(object->map()->transitions());
1499 int transition = transitions->Search(*key);
1500 if (transition == TransitionArray::kNotFound) return false;
1501 PropertyDetails target_details = transitions->GetTargetDetails(transition);
1502 if (target_details.type() != FIELD) return false;
1503 if (target_details.attributes() != NONE) return false;
1504 Handle<Map> target(transitions->GetTarget(transition));
1505 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;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001566 case JS_WEAK_MAP_TYPE:
1567 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001568 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001569 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001570 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001571 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001572 case JS_MESSAGE_OBJECT_TYPE:
1573 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001574 default:
1575 UNREACHABLE();
1576 return 0;
1577 }
1578}
1579
1580
1581int JSObject::GetInternalFieldCount() {
1582 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001583 // Make sure to adjust for the number of in-object properties. These
1584 // properties do contribute to the size, but are not internal fields.
1585 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1586 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001587}
1588
1589
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001590int JSObject::GetInternalFieldOffset(int index) {
1591 ASSERT(index < GetInternalFieldCount() && index >= 0);
1592 return GetHeaderSize() + (kPointerSize * index);
1593}
1594
1595
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596Object* JSObject::GetInternalField(int index) {
1597 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001598 // Internal objects do follow immediately after the header, whereas in-object
1599 // properties are at the end of the object. Therefore there is no need
1600 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001601 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1602}
1603
1604
1605void JSObject::SetInternalField(int index, Object* value) {
1606 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001607 // Internal objects do follow immediately after the header, whereas in-object
1608 // properties are at the end of the object. Therefore there is no need
1609 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001610 int offset = GetHeaderSize() + (kPointerSize * index);
1611 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001612 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001613}
1614
1615
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001616void JSObject::SetInternalField(int index, Smi* value) {
1617 ASSERT(index < GetInternalFieldCount() && index >= 0);
1618 // Internal objects do follow immediately after the header, whereas in-object
1619 // properties are at the end of the object. Therefore there is no need
1620 // to adjust the index here.
1621 int offset = GetHeaderSize() + (kPointerSize * index);
1622 WRITE_FIELD(this, offset, value);
1623}
1624
1625
ager@chromium.org7c537e22008-10-16 08:43:32 +00001626// Access fast-case object properties at index. The use of these routines
1627// is needed to correctly distinguish between properties stored in-object and
1628// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001629Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001630 // Adjust for the number of properties stored in the object.
1631 index -= map()->inobject_properties();
1632 if (index < 0) {
1633 int offset = map()->instance_size() + (index * kPointerSize);
1634 return READ_FIELD(this, offset);
1635 } else {
1636 ASSERT(index < properties()->length());
1637 return properties()->get(index);
1638 }
1639}
1640
1641
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001642Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001643 // Adjust for the number of properties stored in the object.
1644 index -= map()->inobject_properties();
1645 if (index < 0) {
1646 int offset = map()->instance_size() + (index * kPointerSize);
1647 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001648 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001649 } else {
1650 ASSERT(index < properties()->length());
1651 properties()->set(index, value);
1652 }
1653 return value;
1654}
1655
1656
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001657int JSObject::GetInObjectPropertyOffset(int index) {
1658 // Adjust for the number of properties stored in the object.
1659 index -= map()->inobject_properties();
1660 ASSERT(index < 0);
1661 return map()->instance_size() + (index * kPointerSize);
1662}
1663
1664
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001665Object* JSObject::InObjectPropertyAt(int index) {
1666 // Adjust for the number of properties stored in the object.
1667 index -= map()->inobject_properties();
1668 ASSERT(index < 0);
1669 int offset = map()->instance_size() + (index * kPointerSize);
1670 return READ_FIELD(this, offset);
1671}
1672
1673
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001674Object* JSObject::InObjectPropertyAtPut(int index,
1675 Object* value,
1676 WriteBarrierMode mode) {
1677 // Adjust for the number of properties stored in the object.
1678 index -= map()->inobject_properties();
1679 ASSERT(index < 0);
1680 int offset = map()->instance_size() + (index * kPointerSize);
1681 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001682 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001683 return value;
1684}
1685
1686
1687
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001688void JSObject::InitializeBody(Map* map,
1689 Object* pre_allocated_value,
1690 Object* filler_value) {
1691 ASSERT(!filler_value->IsHeapObject() ||
1692 !GetHeap()->InNewSpace(filler_value));
1693 ASSERT(!pre_allocated_value->IsHeapObject() ||
1694 !GetHeap()->InNewSpace(pre_allocated_value));
1695 int size = map->instance_size();
1696 int offset = kHeaderSize;
1697 if (filler_value != pre_allocated_value) {
1698 int pre_allocated = map->pre_allocated_property_fields();
1699 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1700 for (int i = 0; i < pre_allocated; i++) {
1701 WRITE_FIELD(this, offset, pre_allocated_value);
1702 offset += kPointerSize;
1703 }
1704 }
1705 while (offset < size) {
1706 WRITE_FIELD(this, offset, filler_value);
1707 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001708 }
1709}
1710
1711
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001712bool JSObject::HasFastProperties() {
erik.corry@gmail.com88767242012-08-08 14:43:45 +00001713 ASSERT(properties()->IsDictionary() == map()->is_dictionary_map());
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001714 return !properties()->IsDictionary();
1715}
1716
1717
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001718bool JSObject::TooManyFastProperties(int properties,
1719 JSObject::StoreFromKeyed store_mode) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001720 // Allow extra fast properties if the object has more than
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001721 // kFastPropertiesSoftLimit in-object properties. When this is the case,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001722 // it is very unlikely that the object is being used as a dictionary
1723 // and there is a good chance that allowing more map transitions
1724 // will be worth it.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001725 int inobject = map()->inobject_properties();
1726
1727 int limit;
ulan@chromium.orgf6a0c412012-06-15 12:31:06 +00001728 if (store_mode == CERTAINLY_NOT_STORE_FROM_KEYED) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001729 limit = Max(inobject, kMaxFastProperties);
1730 } else {
1731 limit = Max(inobject, kFastPropertiesSoftLimit);
1732 }
1733 return properties > limit;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001734}
1735
1736
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001737void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001738 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001739 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001740 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001741 }
1742}
1743
1744
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001745bool Object::ToArrayIndex(uint32_t* index) {
1746 if (IsSmi()) {
1747 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001748 if (value < 0) return false;
1749 *index = value;
1750 return true;
1751 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001752 if (IsHeapNumber()) {
1753 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754 uint32_t uint_value = static_cast<uint32_t>(value);
1755 if (value == static_cast<double>(uint_value)) {
1756 *index = uint_value;
1757 return true;
1758 }
1759 }
1760 return false;
1761}
1762
1763
1764bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1765 if (!this->IsJSValue()) return false;
1766
1767 JSValue* js_value = JSValue::cast(this);
1768 if (!js_value->value()->IsString()) return false;
1769
1770 String* str = String::cast(js_value->value());
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00001771 if (index >= static_cast<uint32_t>(str->length())) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001772
1773 return true;
1774}
1775
1776
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00001777
1778void Object::VerifyApiCallResultType() {
1779#if ENABLE_EXTRA_CHECKS
1780 if (!(IsSmi() ||
1781 IsString() ||
1782 IsSpecObject() ||
1783 IsHeapNumber() ||
1784 IsUndefined() ||
1785 IsTrue() ||
1786 IsFalse() ||
1787 IsNull())) {
1788 FATAL("API call returned invalid object");
1789 }
1790#endif // ENABLE_EXTRA_CHECKS
1791}
1792
1793
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001794FixedArrayBase* FixedArrayBase::cast(Object* object) {
1795 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1796 return reinterpret_cast<FixedArrayBase*>(object);
1797}
1798
1799
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001800Object* FixedArray::get(int index) {
1801 ASSERT(index >= 0 && index < this->length());
1802 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1803}
1804
1805
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001806bool FixedArray::is_the_hole(int index) {
1807 return get(index) == GetHeap()->the_hole_value();
1808}
1809
1810
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001811void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001812 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001813 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001814 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1815 int offset = kHeaderSize + index * kPointerSize;
1816 WRITE_FIELD(this, offset, value);
1817}
1818
1819
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001821 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001822 ASSERT(index >= 0 && index < this->length());
1823 int offset = kHeaderSize + index * kPointerSize;
1824 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001825 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001826}
1827
1828
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001829inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1830 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1831}
1832
1833
1834inline double FixedDoubleArray::hole_nan_as_double() {
1835 return BitCast<double, uint64_t>(kHoleNanInt64);
1836}
1837
1838
1839inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1840 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1841 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1842 return OS::nan_value();
1843}
1844
1845
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001846double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001847 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1848 map() != HEAP->fixed_array_map());
1849 ASSERT(index >= 0 && index < this->length());
1850 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1851 ASSERT(!is_the_hole_nan(result));
1852 return result;
1853}
1854
danno@chromium.org88aa0582012-03-23 15:11:57 +00001855int64_t FixedDoubleArray::get_representation(int index) {
1856 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1857 map() != HEAP->fixed_array_map());
1858 ASSERT(index >= 0 && index < this->length());
1859 return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1860}
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001861
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001862MaybeObject* FixedDoubleArray::get(int index) {
1863 if (is_the_hole(index)) {
1864 return GetHeap()->the_hole_value();
1865 } else {
1866 return GetHeap()->NumberFromDouble(get_scalar(index));
1867 }
1868}
1869
1870
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001871void FixedDoubleArray::set(int index, double value) {
1872 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1873 map() != HEAP->fixed_array_map());
1874 int offset = kHeaderSize + index * kDoubleSize;
1875 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1876 WRITE_DOUBLE_FIELD(this, offset, value);
1877}
1878
1879
1880void FixedDoubleArray::set_the_hole(int index) {
1881 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1882 map() != HEAP->fixed_array_map());
1883 int offset = kHeaderSize + index * kDoubleSize;
1884 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1885}
1886
1887
1888bool FixedDoubleArray::is_the_hole(int index) {
1889 int offset = kHeaderSize + index * kDoubleSize;
1890 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1891}
1892
1893
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001894WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001895 Heap* heap = GetHeap();
1896 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1897 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001898 return UPDATE_WRITE_BARRIER;
1899}
1900
1901
1902void FixedArray::set(int index,
1903 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001904 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001905 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001906 ASSERT(index >= 0 && index < this->length());
1907 int offset = kHeaderSize + index * kPointerSize;
1908 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001909 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001910}
1911
1912
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001913void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1914 int index,
1915 Object* value) {
danno@chromium.org72204d52012-10-31 10:02:10 +00001916 ASSERT(array->map() != HEAP->fixed_cow_array_map());
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001917 ASSERT(index >= 0 && index < array->length());
1918 int offset = kHeaderSize + index * kPointerSize;
1919 WRITE_FIELD(array, offset, value);
1920 Heap* heap = array->GetHeap();
1921 if (heap->InNewSpace(value)) {
1922 heap->RecordWrite(array->address(), offset);
1923 }
1924}
1925
1926
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001927void FixedArray::NoWriteBarrierSet(FixedArray* array,
1928 int index,
1929 Object* value) {
danno@chromium.org72204d52012-10-31 10:02:10 +00001930 ASSERT(array->map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001931 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001932 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001933 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1934}
1935
1936
1937void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001938 ASSERT(map() != HEAP->fixed_cow_array_map());
1939 set_undefined(GetHeap(), index);
1940}
1941
1942
1943void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001944 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001945 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001946 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001947 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001948}
1949
1950
ager@chromium.org236ad962008-09-25 09:45:57 +00001951void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001952 set_null(GetHeap(), index);
1953}
1954
1955
1956void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001957 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001958 ASSERT(!heap->InNewSpace(heap->null_value()));
1959 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001960}
1961
1962
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001963void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001964 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001965 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001966 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1967 WRITE_FIELD(this,
1968 kHeaderSize + index * kPointerSize,
1969 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001970}
1971
1972
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001973void FixedArray::set_unchecked(int index, Smi* value) {
1974 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1975 int offset = kHeaderSize + index * kPointerSize;
1976 WRITE_FIELD(this, offset, value);
1977}
1978
1979
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001980void FixedArray::set_unchecked(Heap* heap,
1981 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001982 Object* value,
1983 WriteBarrierMode mode) {
1984 int offset = kHeaderSize + index * kPointerSize;
1985 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001986 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001987}
1988
1989
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001990void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001991 ASSERT(index >= 0 && index < this->length());
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00001992 ASSERT(!heap->InNewSpace(heap->null_value()));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001993 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001994}
1995
1996
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001997double* FixedDoubleArray::data_start() {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00001998 return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001999}
2000
2001
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002002Object** FixedArray::data_start() {
2003 return HeapObject::RawField(this, kHeaderSize);
2004}
2005
2006
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00002007bool DescriptorArray::IsEmpty() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002008 ASSERT(length() >= kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002009 this == HEAP->empty_descriptor_array());
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002010 return length() < kFirstIndex;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002011}
2012
2013
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002014void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
2015 WRITE_FIELD(
2016 this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors));
2017}
2018
2019
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002020// Perform a binary search in a fixed array. Low and high are entry indices. If
2021// there are three entries in this array it should be called with low=0 and
2022// high=2.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002023template<SearchMode search_mode, typename T>
2024int BinarySearch(T* array, String* name, int low, int high, int valid_entries) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002025 uint32_t hash = name->Hash();
2026 int limit = high;
2027
2028 ASSERT(low <= high);
2029
2030 while (low != high) {
2031 int mid = (low + high) / 2;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002032 String* mid_name = array->GetSortedKey(mid);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002033 uint32_t mid_hash = mid_name->Hash();
2034
2035 if (mid_hash >= hash) {
2036 high = mid;
2037 } else {
2038 low = mid + 1;
2039 }
2040 }
2041
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002042 for (; low <= limit; ++low) {
2043 int sort_index = array->GetSortedKeyIndex(low);
2044 String* entry = array->GetKey(sort_index);
2045 if (entry->Hash() != hash) break;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002046 if (entry->Equals(name)) {
2047 if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
2048 return sort_index;
2049 }
2050 return T::kNotFound;
2051 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002052 }
2053
2054 return T::kNotFound;
2055}
2056
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002057
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002058// Perform a linear search in this fixed array. len is the number of entry
2059// indices that are valid.
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002060template<SearchMode search_mode, typename T>
2061int LinearSearch(T* array, String* name, int len, int valid_entries) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002062 uint32_t hash = name->Hash();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002063 if (search_mode == ALL_ENTRIES) {
2064 for (int number = 0; number < len; number++) {
2065 int sorted_index = array->GetSortedKeyIndex(number);
2066 String* entry = array->GetKey(sorted_index);
2067 uint32_t current_hash = entry->Hash();
2068 if (current_hash > hash) break;
2069 if (current_hash == hash && entry->Equals(name)) return sorted_index;
2070 }
2071 } else {
2072 ASSERT(len >= valid_entries);
2073 for (int number = 0; number < valid_entries; number++) {
2074 String* entry = array->GetKey(number);
2075 uint32_t current_hash = entry->Hash();
2076 if (current_hash == hash && entry->Equals(name)) return number;
2077 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002078 }
2079 return T::kNotFound;
2080}
2081
2082
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002083template<SearchMode search_mode, typename T>
2084int Search(T* array, String* name, int valid_entries) {
2085 if (search_mode == VALID_ENTRIES) {
2086 SLOW_ASSERT(array->IsSortedNoDuplicates(valid_entries));
2087 } else {
2088 SLOW_ASSERT(array->IsSortedNoDuplicates());
2089 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002090
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002091 int nof = array->number_of_entries();
2092 if (nof == 0) return T::kNotFound;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002093
2094 // Fast case: do linear search for small arrays.
2095 const int kMaxElementsForLinearSearch = 8;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002096 if ((search_mode == ALL_ENTRIES &&
2097 nof <= kMaxElementsForLinearSearch) ||
2098 (search_mode == VALID_ENTRIES &&
2099 valid_entries <= (kMaxElementsForLinearSearch * 3))) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002100 return LinearSearch<search_mode>(array, name, nof, valid_entries);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002101 }
2102
2103 // Slow case: perform binary search.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002104 return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002105}
2106
2107
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002108int DescriptorArray::Search(String* name, int valid_descriptors) {
2109 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002110}
2111
2112
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002113int DescriptorArray::SearchWithCache(String* name, Map* map) {
2114 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
2115 if (number_of_own_descriptors == 0) return kNotFound;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002116
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002117 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002118 int number = cache->Lookup(map, name);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002119
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002120 if (number == DescriptorLookupCache::kAbsent) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002121 number = Search(name, number_of_own_descriptors);
2122 cache->Update(map, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002123 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002124
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002125 return number;
2126}
2127
2128
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002129void Map::LookupDescriptor(JSObject* holder,
2130 String* name,
2131 LookupResult* result) {
2132 DescriptorArray* descriptors = this->instance_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002133 int number = descriptors->SearchWithCache(name, this);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002134 if (number == DescriptorArray::kNotFound) return result->NotFound();
2135 result->DescriptorResult(holder, descriptors->GetDetails(number), number);
2136}
2137
2138
2139void Map::LookupTransition(JSObject* holder,
2140 String* name,
2141 LookupResult* result) {
2142 if (HasTransitionArray()) {
2143 TransitionArray* transition_array = transitions();
2144 int number = transition_array->Search(name);
2145 if (number != TransitionArray::kNotFound) {
2146 return result->TransitionResult(holder, number);
2147 }
2148 }
2149 result->NotFound();
2150}
2151
2152
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002153Object** DescriptorArray::GetKeySlot(int descriptor_number) {
2154 ASSERT(descriptor_number < number_of_descriptors());
2155 return HeapObject::RawField(
2156 reinterpret_cast<HeapObject*>(this),
2157 OffsetOfElementAt(ToKeyIndex(descriptor_number)));
2158}
2159
2160
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00002161Object** DescriptorArray::GetDescriptorStartSlot(int descriptor_number) {
2162 return GetKeySlot(descriptor_number);
2163}
2164
2165
2166Object** DescriptorArray::GetDescriptorEndSlot(int descriptor_number) {
2167 return GetValueSlot(descriptor_number - 1) + 1;
2168}
2169
2170
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002171String* DescriptorArray::GetKey(int descriptor_number) {
2172 ASSERT(descriptor_number < number_of_descriptors());
2173 return String::cast(get(ToKeyIndex(descriptor_number)));
2174}
2175
2176
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002177int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
2178 return GetDetails(descriptor_number).pointer();
2179}
2180
2181
2182String* DescriptorArray::GetSortedKey(int descriptor_number) {
2183 return GetKey(GetSortedKeyIndex(descriptor_number));
2184}
2185
2186
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002187void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
2188 PropertyDetails details = GetDetails(descriptor_index);
2189 set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi());
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002190}
2191
2192
verwaest@chromium.org37141392012-05-31 13:27:02 +00002193Object** DescriptorArray::GetValueSlot(int descriptor_number) {
2194 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002195 return HeapObject::RawField(
2196 reinterpret_cast<HeapObject*>(this),
2197 OffsetOfElementAt(ToValueIndex(descriptor_number)));
verwaest@chromium.org37141392012-05-31 13:27:02 +00002198}
2199
2200
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002201Object* DescriptorArray::GetValue(int descriptor_number) {
2202 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002203 return get(ToValueIndex(descriptor_number));
2204}
2205
2206
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002207PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002208 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002209 Object* details = get(ToDetailsIndex(descriptor_number));
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002210 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002211}
2212
2213
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002214PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002215 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002216}
2217
2218
2219int DescriptorArray::GetFieldIndex(int descriptor_number) {
2220 return Descriptor::IndexFromValue(GetValue(descriptor_number));
2221}
2222
2223
2224JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
2225 return JSFunction::cast(GetValue(descriptor_number));
2226}
2227
2228
2229Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
2230 ASSERT(GetType(descriptor_number) == CALLBACKS);
2231 return GetValue(descriptor_number);
2232}
2233
2234
2235AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
2236 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002237 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002238 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002239}
2240
2241
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002242void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2243 desc->Init(GetKey(descriptor_number),
2244 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002245 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002246}
2247
2248
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002249void DescriptorArray::Set(int descriptor_number,
2250 Descriptor* desc,
2251 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002252 // Range check.
2253 ASSERT(descriptor_number < number_of_descriptors());
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002254 ASSERT(desc->GetDetails().descriptor_index() <=
2255 number_of_descriptors());
2256 ASSERT(desc->GetDetails().descriptor_index() > 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002257
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002258 NoIncrementalWriteBarrierSet(this,
2259 ToKeyIndex(descriptor_number),
2260 desc->GetKey());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002261 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002262 ToValueIndex(descriptor_number),
2263 desc->GetValue());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002264 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002265 ToDetailsIndex(descriptor_number),
2266 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002267}
2268
2269
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002270void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
2271 // Range check.
2272 ASSERT(descriptor_number < number_of_descriptors());
2273 ASSERT(desc->GetDetails().descriptor_index() <=
2274 number_of_descriptors());
2275 ASSERT(desc->GetDetails().descriptor_index() > 0);
2276
2277 set(ToKeyIndex(descriptor_number), desc->GetKey());
2278 set(ToValueIndex(descriptor_number), desc->GetValue());
2279 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
2280}
2281
2282
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002283void DescriptorArray::Append(Descriptor* desc,
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002284 const WhitenessWitness& witness) {
2285 int descriptor_number = number_of_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002286 int enumeration_index = descriptor_number + 1;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002287 SetNumberOfDescriptors(descriptor_number + 1);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002288 desc->SetEnumerationIndex(enumeration_index);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002289 Set(descriptor_number, desc, witness);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002290
2291 uint32_t hash = desc->GetKey()->Hash();
2292
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002293 int insertion;
2294
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002295 for (insertion = descriptor_number; insertion > 0; --insertion) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002296 String* key = GetSortedKey(insertion - 1);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002297 if (key->Hash() <= hash) break;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002298 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002299 }
2300
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002301 SetSortedKey(insertion, descriptor_number);
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002302}
2303
2304
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002305void DescriptorArray::Append(Descriptor* desc) {
2306 int descriptor_number = number_of_descriptors();
2307 int enumeration_index = descriptor_number + 1;
2308 SetNumberOfDescriptors(descriptor_number + 1);
2309 desc->SetEnumerationIndex(enumeration_index);
2310 Set(descriptor_number, desc);
2311
2312 uint32_t hash = desc->GetKey()->Hash();
2313
2314 int insertion;
2315
2316 for (insertion = descriptor_number; insertion > 0; --insertion) {
2317 String* key = GetSortedKey(insertion - 1);
2318 if (key->Hash() <= hash) break;
2319 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
2320 }
2321
2322 SetSortedKey(insertion, descriptor_number);
2323}
2324
2325
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002326void DescriptorArray::SwapSortedKeys(int first, int second) {
2327 int first_key = GetSortedKeyIndex(first);
2328 SetSortedKey(first, GetSortedKeyIndex(second));
2329 SetSortedKey(second, first_key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002330}
2331
2332
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002333DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002334 : marking_(array->GetHeap()->incremental_marking()) {
2335 marking_->EnterNoMarkingScope();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002336 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002337}
2338
2339
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002340DescriptorArray::WhitenessWitness::~WhitenessWitness() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002341 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002342}
2343
2344
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002345template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002346int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2347 const int kMinCapacity = 32;
2348 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2349 if (capacity < kMinCapacity) {
2350 capacity = kMinCapacity; // Guarantee min capacity.
2351 }
2352 return capacity;
2353}
2354
2355
2356template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002357int HashTable<Shape, Key>::FindEntry(Key key) {
2358 return FindEntry(GetIsolate(), key);
2359}
2360
2361
2362// Find entry for key otherwise return kNotFound.
2363template<typename Shape, typename Key>
2364int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2365 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002366 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002367 uint32_t count = 1;
2368 // EnsureCapacity will guarantee the hash table is never full.
2369 while (true) {
2370 Object* element = KeyAt(entry);
danno@chromium.org72204d52012-10-31 10:02:10 +00002371 // Empty entry. Uses raw unchecked accessors because it is called by the
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002372 // string table during bootstrapping.
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002373 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2374 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002375 Shape::IsMatch(key, element)) return entry;
2376 entry = NextProbe(entry, count++, capacity);
2377 }
2378 return kNotFound;
2379}
2380
2381
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002382bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002383 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002384 if (!max_index_object->IsSmi()) return false;
2385 return 0 !=
2386 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2387}
2388
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002389uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002390 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002391 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002392 if (!max_index_object->IsSmi()) return 0;
2393 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2394 return value >> kRequiresSlowElementsTagSize;
2395}
2396
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002397void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002398 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002399}
2400
2401
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002402// ------------------------------------
2403// Cast operations
2404
2405
2406CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002407CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002408CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002409CAST_ACCESSOR(DeoptimizationInputData)
2410CAST_ACCESSOR(DeoptimizationOutputData)
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002411CAST_ACCESSOR(DependentCode)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002412CAST_ACCESSOR(TypeFeedbackCells)
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002413CAST_ACCESSOR(StringTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002414CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002415CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002416CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002417CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002418CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002419CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002420CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002421CAST_ACCESSOR(String)
2422CAST_ACCESSOR(SeqString)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002423CAST_ACCESSOR(SeqOneByteString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002424CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002425CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002426CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002427CAST_ACCESSOR(ExternalString)
2428CAST_ACCESSOR(ExternalAsciiString)
2429CAST_ACCESSOR(ExternalTwoByteString)
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002430CAST_ACCESSOR(Symbol)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002431CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002432CAST_ACCESSOR(JSObject)
2433CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002434CAST_ACCESSOR(HeapObject)
2435CAST_ACCESSOR(HeapNumber)
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002436CAST_ACCESSOR(Name)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002437CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002438CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002439CAST_ACCESSOR(SharedFunctionInfo)
2440CAST_ACCESSOR(Map)
2441CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002442CAST_ACCESSOR(GlobalObject)
2443CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002444CAST_ACCESSOR(JSGlobalObject)
2445CAST_ACCESSOR(JSBuiltinsObject)
2446CAST_ACCESSOR(Code)
2447CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002448CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002449CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002450CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002451CAST_ACCESSOR(JSSet)
2452CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002453CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002454CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002455CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002456CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002457CAST_ACCESSOR(ExternalArray)
2458CAST_ACCESSOR(ExternalByteArray)
2459CAST_ACCESSOR(ExternalUnsignedByteArray)
2460CAST_ACCESSOR(ExternalShortArray)
2461CAST_ACCESSOR(ExternalUnsignedShortArray)
2462CAST_ACCESSOR(ExternalIntArray)
2463CAST_ACCESSOR(ExternalUnsignedIntArray)
2464CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002465CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002466CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002467CAST_ACCESSOR(Struct)
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002468CAST_ACCESSOR(AccessorInfo)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002469
2470
2471#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2472 STRUCT_LIST(MAKE_STRUCT_CAST)
2473#undef MAKE_STRUCT_CAST
2474
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002475
2476template <typename Shape, typename Key>
2477HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002478 ASSERT(obj->IsHashTable());
2479 return reinterpret_cast<HashTable*>(obj);
2480}
2481
2482
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002483SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002484SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002485
ager@chromium.orgac091b72010-05-05 07:34:42 +00002486SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002487
2488
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002489uint32_t Name::hash_field() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002490 return READ_UINT32_FIELD(this, kHashFieldOffset);
2491}
2492
2493
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002494void Name::set_hash_field(uint32_t value) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002495 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002496#if V8_HOST_ARCH_64_BIT
2497 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2498#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002499}
2500
2501
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002502bool String::Equals(String* other) {
2503 if (other == this) return true;
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002504 if (StringShape(this).IsInternalized() &&
2505 StringShape(other).IsInternalized()) {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002506 return false;
2507 }
2508 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002509}
2510
2511
lrn@chromium.org303ada72010-10-27 09:33:13 +00002512MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002513 if (!StringShape(this).IsCons()) return this;
2514 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002515 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002516 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002517}
2518
2519
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002520String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002521 MaybeObject* flat = TryFlatten(pretenure);
2522 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002523 if (!flat->ToObject(&successfully_flattened)) return this;
2524 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002525}
2526
2527
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002528uint16_t String::Get(int index) {
2529 ASSERT(index >= 0 && index < length());
2530 switch (StringShape(this).full_representation_tag()) {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002531 case kSeqStringTag | kOneByteStringTag:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002532 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002533 case kSeqStringTag | kTwoByteStringTag:
2534 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002535 case kConsStringTag | kOneByteStringTag:
ager@chromium.org870a0b62008-11-04 11:43:05 +00002536 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002537 return ConsString::cast(this)->ConsStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002538 case kExternalStringTag | kOneByteStringTag:
ager@chromium.org870a0b62008-11-04 11:43:05 +00002539 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2540 case kExternalStringTag | kTwoByteStringTag:
2541 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002542 case kSlicedStringTag | kOneByteStringTag:
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002543 case kSlicedStringTag | kTwoByteStringTag:
2544 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002545 default:
2546 break;
2547 }
2548
2549 UNREACHABLE();
2550 return 0;
2551}
2552
2553
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002554void String::Set(int index, uint16_t value) {
2555 ASSERT(index >= 0 && index < length());
2556 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002557
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00002558 return this->IsOneByteRepresentation()
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002559 ? SeqOneByteString::cast(this)->SeqOneByteStringSet(index, value)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002560 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002561}
2562
2563
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002564bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002565 if (!StringShape(this).IsCons()) return true;
2566 return ConsString::cast(this)->second()->length() == 0;
2567}
2568
2569
2570String* String::GetUnderlying() {
2571 // Giving direct access to underlying string only makes sense if the
2572 // wrapping string is already flattened.
2573 ASSERT(this->IsFlat());
2574 ASSERT(StringShape(this).IsIndirect());
2575 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2576 const int kUnderlyingOffset = SlicedString::kParentOffset;
2577 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002578}
2579
2580
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002581template<class Visitor, class ConsOp>
2582void String::Visit(
2583 String* string,
2584 unsigned offset,
2585 Visitor& visitor,
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002586 ConsOp& cons_op,
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002587 int32_t type,
2588 unsigned length) {
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002589 ASSERT(length == static_cast<unsigned>(string->length()));
2590 ASSERT(offset <= length);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002591 unsigned slice_offset = offset;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002592 while (true) {
2593 ASSERT(type == string->map()->instance_type());
2594
2595 switch (type & (kStringRepresentationMask | kStringEncodingMask)) {
2596 case kSeqStringTag | kOneByteStringTag:
2597 visitor.VisitOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002598 SeqOneByteString::cast(string)->GetChars() + slice_offset,
2599 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002600 return;
2601
2602 case kSeqStringTag | kTwoByteStringTag:
2603 visitor.VisitTwoByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002604 SeqTwoByteString::cast(string)->GetChars() + slice_offset,
2605 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002606 return;
2607
2608 case kExternalStringTag | kOneByteStringTag:
2609 visitor.VisitOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002610 ExternalAsciiString::cast(string)->GetChars() + slice_offset,
2611 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002612 return;
2613
2614 case kExternalStringTag | kTwoByteStringTag:
2615 visitor.VisitTwoByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002616 ExternalTwoByteString::cast(string)->GetChars() + slice_offset,
2617 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002618 return;
2619
2620 case kSlicedStringTag | kOneByteStringTag:
2621 case kSlicedStringTag | kTwoByteStringTag: {
2622 SlicedString* slicedString = SlicedString::cast(string);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002623 slice_offset += slicedString->offset();
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002624 string = slicedString->parent();
2625 type = string->map()->instance_type();
2626 continue;
2627 }
2628
2629 case kConsStringTag | kOneByteStringTag:
2630 case kConsStringTag | kTwoByteStringTag:
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002631 string = cons_op.Operate(string, &offset, &type, &length);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002632 if (string == NULL) return;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002633 slice_offset = offset;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002634 ASSERT(length == static_cast<unsigned>(string->length()));
2635 continue;
2636
2637 default:
2638 UNREACHABLE();
2639 return;
2640 }
2641 }
2642}
2643
2644
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002645uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002646 ASSERT(index >= 0 && index < length());
2647 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2648}
2649
2650
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002651void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002652 ASSERT(index >= 0 && index < length() && value <= kMaxOneByteCharCode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002653 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2654 static_cast<byte>(value));
2655}
2656
2657
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002658Address SeqOneByteString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002659 return FIELD_ADDR(this, kHeaderSize);
2660}
2661
2662
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002663uint8_t* SeqOneByteString::GetChars() {
2664 return reinterpret_cast<uint8_t*>(GetCharsAddress());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002665}
2666
2667
ager@chromium.org7c537e22008-10-16 08:43:32 +00002668Address SeqTwoByteString::GetCharsAddress() {
2669 return FIELD_ADDR(this, kHeaderSize);
2670}
2671
2672
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002673uc16* SeqTwoByteString::GetChars() {
2674 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2675}
2676
2677
ager@chromium.org7c537e22008-10-16 08:43:32 +00002678uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002679 ASSERT(index >= 0 && index < length());
2680 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2681}
2682
2683
ager@chromium.org7c537e22008-10-16 08:43:32 +00002684void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002685 ASSERT(index >= 0 && index < length());
2686 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2687}
2688
2689
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002690int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002691 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002692}
2693
2694
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002695int SeqOneByteString::SeqOneByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002696 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002697}
2698
2699
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002700String* SlicedString::parent() {
2701 return String::cast(READ_FIELD(this, kParentOffset));
2702}
2703
2704
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002705void SlicedString::set_parent(String* parent, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002706 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002707 WRITE_FIELD(this, kParentOffset, parent);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002708 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kParentOffset, parent, mode);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002709}
2710
2711
2712SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2713
2714
ager@chromium.org870a0b62008-11-04 11:43:05 +00002715String* ConsString::first() {
2716 return String::cast(READ_FIELD(this, kFirstOffset));
2717}
2718
2719
2720Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002721 return READ_FIELD(this, kFirstOffset);
2722}
2723
2724
ager@chromium.org870a0b62008-11-04 11:43:05 +00002725void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002726 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002727 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002728}
2729
2730
ager@chromium.org870a0b62008-11-04 11:43:05 +00002731String* ConsString::second() {
2732 return String::cast(READ_FIELD(this, kSecondOffset));
2733}
2734
2735
2736Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002737 return READ_FIELD(this, kSecondOffset);
2738}
2739
2740
ager@chromium.org870a0b62008-11-04 11:43:05 +00002741void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002742 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002743 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002744}
2745
2746
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002747bool ExternalString::is_short() {
2748 InstanceType type = map()->instance_type();
2749 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002750}
2751
2752
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002753const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002754 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2755}
2756
2757
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002758void ExternalAsciiString::update_data_cache() {
2759 if (is_short()) return;
2760 const char** data_field =
2761 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2762 *data_field = resource()->data();
2763}
2764
2765
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002766void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002767 const ExternalAsciiString::Resource* resource) {
2768 *reinterpret_cast<const Resource**>(
2769 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002770 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002771}
2772
2773
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002774const uint8_t* ExternalAsciiString::GetChars() {
2775 return reinterpret_cast<const uint8_t*>(resource()->data());
erikcorry0ad885c2011-11-21 13:51:57 +00002776}
2777
2778
2779uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2780 ASSERT(index >= 0 && index < length());
2781 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002782}
2783
2784
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002785const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002786 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2787}
2788
2789
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002790void ExternalTwoByteString::update_data_cache() {
2791 if (is_short()) return;
2792 const uint16_t** data_field =
2793 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2794 *data_field = resource()->data();
2795}
2796
2797
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002798void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002799 const ExternalTwoByteString::Resource* resource) {
2800 *reinterpret_cast<const Resource**>(
2801 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002802 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002803}
2804
2805
2806const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002807 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002808}
2809
2810
2811uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2812 ASSERT(index >= 0 && index < length());
2813 return GetChars()[index];
2814}
2815
2816
2817const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2818 unsigned start) {
2819 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002820}
2821
2822
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002823String* ConsStringNullOp::Operate(String*, unsigned*, int32_t*, unsigned*) {
2824 return NULL;
2825}
2826
2827
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002828unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) {
2829 return depth & kDepthMask;
2830}
2831
2832
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002833void ConsStringIteratorOp::PushLeft(ConsString* string) {
2834 frames_[depth_++ & kDepthMask] = string;
2835}
2836
2837
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002838void ConsStringIteratorOp::PushRight(ConsString* string) {
2839 // Inplace update.
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002840 frames_[(depth_-1) & kDepthMask] = string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002841}
2842
2843
2844void ConsStringIteratorOp::AdjustMaximumDepth() {
2845 if (depth_ > maximum_depth_) maximum_depth_ = depth_;
2846}
2847
2848
2849void ConsStringIteratorOp::Pop() {
2850 ASSERT(depth_ > 0);
2851 ASSERT(depth_ <= maximum_depth_);
2852 depth_--;
2853}
2854
2855
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002856bool ConsStringIteratorOp::HasMore() {
2857 return depth_ != 0;
2858}
2859
2860
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002861void ConsStringIteratorOp::Reset() {
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002862 depth_ = 0;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002863}
2864
2865
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002866String* ConsStringIteratorOp::ContinueOperation(int32_t* type_out,
2867 unsigned* length_out) {
2868 bool blew_stack = false;
2869 String* string = NextLeaf(&blew_stack, type_out, length_out);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002870 // String found.
2871 if (string != NULL) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002872 // Verify output.
2873 ASSERT(*length_out == static_cast<unsigned>(string->length()));
2874 ASSERT(*type_out == string->map()->instance_type());
2875 return string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002876 }
2877 // Traversal complete.
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002878 if (!blew_stack) return NULL;
2879 // Restart search from root.
2880 unsigned offset_out;
2881 string = Search(&offset_out, type_out, length_out);
2882 // Verify output.
2883 ASSERT(string == NULL || offset_out == 0);
2884 ASSERT(string == NULL ||
2885 *length_out == static_cast<unsigned>(string->length()));
2886 ASSERT(string == NULL || *type_out == string->map()->instance_type());
2887 return string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002888}
2889
2890
2891uint16_t StringCharacterStream::GetNext() {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002892 ASSERT(buffer8_ != NULL && end_ != NULL);
2893 // Advance cursor if needed.
2894 // TODO(dcarney): Ensure uses of the api call HasMore first and avoid this.
2895 if (buffer8_ == end_) HasMore();
2896 ASSERT(buffer8_ < end_);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002897 return is_one_byte_ ? *buffer8_++ : *buffer16_++;
2898}
2899
2900
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002901StringCharacterStream::StringCharacterStream(String* string,
2902 ConsStringIteratorOp* op,
2903 unsigned offset)
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002904 : is_one_byte_(false),
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002905 op_(op) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002906 Reset(string, offset);
2907}
2908
2909
2910void StringCharacterStream::Reset(String* string, unsigned offset) {
2911 op_->Reset();
2912 buffer8_ = NULL;
2913 end_ = NULL;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002914 int32_t type = string->map()->instance_type();
2915 unsigned length = string->length();
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002916 String::Visit(string, offset, *this, *op_, type, length);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002917}
2918
2919
2920bool StringCharacterStream::HasMore() {
2921 if (buffer8_ != end_) return true;
2922 if (!op_->HasMore()) return false;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002923 unsigned length;
2924 int32_t type;
2925 String* string = op_->ContinueOperation(&type, &length);
2926 if (string == NULL) return false;
2927 ASSERT(!string->IsConsString());
2928 ASSERT(string->length() != 0);
2929 ConsStringNullOp null_op;
2930 String::Visit(string, 0, *this, null_op, type, length);
2931 ASSERT(buffer8_ != end_);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002932 return true;
2933}
2934
2935
2936void StringCharacterStream::VisitOneByteString(
2937 const uint8_t* chars, unsigned length) {
2938 is_one_byte_ = true;
2939 buffer8_ = chars;
2940 end_ = chars + length;
2941}
2942
2943
2944void StringCharacterStream::VisitTwoByteString(
2945 const uint16_t* chars, unsigned length) {
2946 is_one_byte_ = false;
2947 buffer16_ = chars;
2948 end_ = reinterpret_cast<const uint8_t*>(chars + length);
2949}
2950
2951
ager@chromium.orgac091b72010-05-05 07:34:42 +00002952void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002953 set_finger_index(kEntriesIndex);
2954 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002955}
2956
2957
2958void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002959 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002960 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002961 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002962 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002963 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002964 MakeZeroSize();
2965}
2966
2967
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002968int JSFunctionResultCache::size() {
2969 return Smi::cast(get(kCacheSizeIndex))->value();
2970}
2971
2972
2973void JSFunctionResultCache::set_size(int size) {
2974 set(kCacheSizeIndex, Smi::FromInt(size));
2975}
2976
2977
2978int JSFunctionResultCache::finger_index() {
2979 return Smi::cast(get(kFingerIndex))->value();
2980}
2981
2982
2983void JSFunctionResultCache::set_finger_index(int finger_index) {
2984 set(kFingerIndex, Smi::FromInt(finger_index));
2985}
2986
2987
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002988byte ByteArray::get(int index) {
2989 ASSERT(index >= 0 && index < this->length());
2990 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2991}
2992
2993
2994void ByteArray::set(int index, byte value) {
2995 ASSERT(index >= 0 && index < this->length());
2996 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2997}
2998
2999
3000int ByteArray::get_int(int index) {
3001 ASSERT(index >= 0 && (index * kIntSize) < this->length());
3002 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
3003}
3004
3005
3006ByteArray* ByteArray::FromDataStartAddress(Address address) {
3007 ASSERT_TAG_ALIGNED(address);
3008 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
3009}
3010
3011
3012Address ByteArray::GetDataStartAddress() {
3013 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
3014}
3015
3016
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003017uint8_t* ExternalPixelArray::external_pixel_pointer() {
3018 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003019}
3020
3021
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003022uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003023 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003024 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003025 return ptr[index];
3026}
3027
3028
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003029MaybeObject* ExternalPixelArray::get(int index) {
3030 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3031}
3032
3033
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003034void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003035 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003036 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003037 ptr[index] = value;
3038}
3039
3040
ager@chromium.org3811b432009-10-28 14:53:37 +00003041void* ExternalArray::external_pointer() {
3042 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
3043 return reinterpret_cast<void*>(ptr);
3044}
3045
3046
3047void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
3048 intptr_t ptr = reinterpret_cast<intptr_t>(value);
3049 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
3050}
3051
3052
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003053int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003054 ASSERT((index >= 0) && (index < this->length()));
3055 int8_t* ptr = static_cast<int8_t*>(external_pointer());
3056 return ptr[index];
3057}
3058
3059
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003060MaybeObject* ExternalByteArray::get(int index) {
3061 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3062}
3063
3064
ager@chromium.org3811b432009-10-28 14:53:37 +00003065void ExternalByteArray::set(int index, int8_t value) {
3066 ASSERT((index >= 0) && (index < this->length()));
3067 int8_t* ptr = static_cast<int8_t*>(external_pointer());
3068 ptr[index] = value;
3069}
3070
3071
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003072uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003073 ASSERT((index >= 0) && (index < this->length()));
3074 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
3075 return ptr[index];
3076}
3077
3078
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003079MaybeObject* ExternalUnsignedByteArray::get(int index) {
3080 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3081}
3082
3083
ager@chromium.org3811b432009-10-28 14:53:37 +00003084void ExternalUnsignedByteArray::set(int index, uint8_t value) {
3085 ASSERT((index >= 0) && (index < this->length()));
3086 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
3087 ptr[index] = value;
3088}
3089
3090
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003091int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003092 ASSERT((index >= 0) && (index < this->length()));
3093 int16_t* ptr = static_cast<int16_t*>(external_pointer());
3094 return ptr[index];
3095}
3096
3097
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003098MaybeObject* ExternalShortArray::get(int index) {
3099 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3100}
3101
3102
ager@chromium.org3811b432009-10-28 14:53:37 +00003103void ExternalShortArray::set(int index, int16_t value) {
3104 ASSERT((index >= 0) && (index < this->length()));
3105 int16_t* ptr = static_cast<int16_t*>(external_pointer());
3106 ptr[index] = value;
3107}
3108
3109
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003110uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003111 ASSERT((index >= 0) && (index < this->length()));
3112 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
3113 return ptr[index];
3114}
3115
3116
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003117MaybeObject* ExternalUnsignedShortArray::get(int index) {
3118 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3119}
3120
3121
ager@chromium.org3811b432009-10-28 14:53:37 +00003122void ExternalUnsignedShortArray::set(int index, uint16_t value) {
3123 ASSERT((index >= 0) && (index < this->length()));
3124 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
3125 ptr[index] = value;
3126}
3127
3128
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003129int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003130 ASSERT((index >= 0) && (index < this->length()));
3131 int32_t* ptr = static_cast<int32_t*>(external_pointer());
3132 return ptr[index];
3133}
3134
3135
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003136MaybeObject* ExternalIntArray::get(int index) {
3137 return GetHeap()->NumberFromInt32(get_scalar(index));
3138}
3139
3140
ager@chromium.org3811b432009-10-28 14:53:37 +00003141void ExternalIntArray::set(int index, int32_t value) {
3142 ASSERT((index >= 0) && (index < this->length()));
3143 int32_t* ptr = static_cast<int32_t*>(external_pointer());
3144 ptr[index] = value;
3145}
3146
3147
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003148uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003149 ASSERT((index >= 0) && (index < this->length()));
3150 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
3151 return ptr[index];
3152}
3153
3154
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003155MaybeObject* ExternalUnsignedIntArray::get(int index) {
3156 return GetHeap()->NumberFromUint32(get_scalar(index));
3157}
3158
3159
ager@chromium.org3811b432009-10-28 14:53:37 +00003160void ExternalUnsignedIntArray::set(int index, uint32_t value) {
3161 ASSERT((index >= 0) && (index < this->length()));
3162 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
3163 ptr[index] = value;
3164}
3165
3166
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003167float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003168 ASSERT((index >= 0) && (index < this->length()));
3169 float* ptr = static_cast<float*>(external_pointer());
3170 return ptr[index];
3171}
3172
3173
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003174MaybeObject* ExternalFloatArray::get(int index) {
3175 return GetHeap()->NumberFromDouble(get_scalar(index));
3176}
3177
3178
ager@chromium.org3811b432009-10-28 14:53:37 +00003179void ExternalFloatArray::set(int index, float value) {
3180 ASSERT((index >= 0) && (index < this->length()));
3181 float* ptr = static_cast<float*>(external_pointer());
3182 ptr[index] = value;
3183}
3184
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00003185
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003186double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003187 ASSERT((index >= 0) && (index < this->length()));
3188 double* ptr = static_cast<double*>(external_pointer());
3189 return ptr[index];
3190}
3191
3192
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003193MaybeObject* ExternalDoubleArray::get(int index) {
3194 return GetHeap()->NumberFromDouble(get_scalar(index));
3195}
3196
3197
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003198void ExternalDoubleArray::set(int index, double value) {
3199 ASSERT((index >= 0) && (index < this->length()));
3200 double* ptr = static_cast<double*>(external_pointer());
3201 ptr[index] = value;
3202}
3203
3204
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00003205int Map::visitor_id() {
3206 return READ_BYTE_FIELD(this, kVisitorIdOffset);
3207}
3208
3209
3210void Map::set_visitor_id(int id) {
3211 ASSERT(0 <= id && id < 256);
3212 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
3213}
3214
ager@chromium.org3811b432009-10-28 14:53:37 +00003215
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003216int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00003217 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
3218}
3219
3220
3221int Map::inobject_properties() {
3222 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003223}
3224
3225
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003226int Map::pre_allocated_property_fields() {
3227 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
3228}
3229
3230
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003231int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003232 int instance_size = map->instance_size();
3233 if (instance_size != kVariableSizeSentinel) return instance_size;
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00003234 // We can ignore the "internalized" bit becase it is only set for strings
3235 // and thus implies a string type.
3236 int instance_type =
3237 static_cast<int>(map->instance_type()) & ~kIsInternalizedMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003238 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003239 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003240 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003241 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003242 if (instance_type == ASCII_STRING_TYPE) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003243 return SeqOneByteString::SizeFor(
3244 reinterpret_cast<SeqOneByteString*>(this)->length());
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003245 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003246 if (instance_type == BYTE_ARRAY_TYPE) {
3247 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
3248 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003249 if (instance_type == FREE_SPACE_TYPE) {
3250 return reinterpret_cast<FreeSpace*>(this)->size();
3251 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003252 if (instance_type == STRING_TYPE) {
3253 return SeqTwoByteString::SizeFor(
3254 reinterpret_cast<SeqTwoByteString*>(this)->length());
3255 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003256 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
3257 return FixedDoubleArray::SizeFor(
3258 reinterpret_cast<FixedDoubleArray*>(this)->length());
3259 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003260 ASSERT(instance_type == CODE_TYPE);
3261 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003262}
3263
3264
3265void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003266 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003267 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003268 ASSERT(0 <= value && value < 256);
3269 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
3270}
3271
3272
ager@chromium.org7c537e22008-10-16 08:43:32 +00003273void Map::set_inobject_properties(int value) {
3274 ASSERT(0 <= value && value < 256);
3275 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
3276}
3277
3278
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003279void Map::set_pre_allocated_property_fields(int value) {
3280 ASSERT(0 <= value && value < 256);
3281 WRITE_BYTE_FIELD(this,
3282 kPreAllocatedPropertyFieldsOffset,
3283 static_cast<byte>(value));
3284}
3285
3286
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003287InstanceType Map::instance_type() {
3288 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
3289}
3290
3291
3292void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003293 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
3294}
3295
3296
3297int Map::unused_property_fields() {
3298 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
3299}
3300
3301
3302void Map::set_unused_property_fields(int value) {
3303 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
3304}
3305
3306
3307byte Map::bit_field() {
3308 return READ_BYTE_FIELD(this, kBitFieldOffset);
3309}
3310
3311
3312void Map::set_bit_field(byte value) {
3313 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
3314}
3315
3316
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00003317byte Map::bit_field2() {
3318 return READ_BYTE_FIELD(this, kBitField2Offset);
3319}
3320
3321
3322void Map::set_bit_field2(byte value) {
3323 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
3324}
3325
3326
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003327void Map::set_non_instance_prototype(bool value) {
3328 if (value) {
3329 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
3330 } else {
3331 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
3332 }
3333}
3334
3335
3336bool Map::has_non_instance_prototype() {
3337 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
3338}
3339
3340
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003341void Map::set_function_with_prototype(bool value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003342 set_bit_field3(FunctionWithPrototype::update(bit_field3(), value));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003343}
3344
3345
3346bool Map::function_with_prototype() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003347 return FunctionWithPrototype::decode(bit_field3());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003348}
3349
3350
ager@chromium.org870a0b62008-11-04 11:43:05 +00003351void Map::set_is_access_check_needed(bool access_check_needed) {
3352 if (access_check_needed) {
3353 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
3354 } else {
3355 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
3356 }
3357}
3358
3359
3360bool Map::is_access_check_needed() {
3361 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
3362}
3363
3364
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003365void Map::set_is_extensible(bool value) {
3366 if (value) {
3367 set_bit_field2(bit_field2() | (1 << kIsExtensible));
3368 } else {
3369 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
3370 }
3371}
3372
3373bool Map::is_extensible() {
3374 return ((1 << kIsExtensible) & bit_field2()) != 0;
3375}
3376
3377
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003378void Map::set_attached_to_shared_function_info(bool value) {
3379 if (value) {
3380 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
3381 } else {
3382 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
3383 }
3384}
3385
3386bool Map::attached_to_shared_function_info() {
3387 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
3388}
3389
3390
3391void Map::set_is_shared(bool value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003392 set_bit_field3(IsShared::update(bit_field3(), value));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003393}
3394
erik.corry@gmail.com88767242012-08-08 14:43:45 +00003395
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003396bool Map::is_shared() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003397 return IsShared::decode(bit_field3());
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003398}
3399
3400
erik.corry@gmail.com88767242012-08-08 14:43:45 +00003401void Map::set_dictionary_map(bool value) {
3402 set_bit_field3(DictionaryMap::update(bit_field3(), value));
3403}
3404
3405
3406bool Map::is_dictionary_map() {
3407 return DictionaryMap::decode(bit_field3());
3408}
3409
3410
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003411JSFunction* Map::unchecked_constructor() {
3412 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
3413}
3414
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003415
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003416Code::Flags Code::flags() {
3417 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
3418}
3419
3420
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00003421inline bool Map::CanTrackAllocationSite() {
3422 return instance_type() == JS_ARRAY_TYPE;
3423}
3424
3425
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00003426void Map::set_owns_descriptors(bool is_shared) {
3427 set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
3428}
3429
3430
3431bool Map::owns_descriptors() {
3432 return OwnsDescriptors::decode(bit_field3());
3433}
3434
3435
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00003436void Map::set_is_observed(bool is_observed) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003437 ASSERT(instance_type() < FIRST_JS_OBJECT_TYPE ||
3438 instance_type() > LAST_JS_OBJECT_TYPE ||
3439 has_slow_elements_kind() || has_external_array_elements());
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00003440 set_bit_field3(IsObserved::update(bit_field3(), is_observed));
3441}
3442
3443
3444bool Map::is_observed() {
3445 return IsObserved::decode(bit_field3());
3446}
3447
3448
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003449void Map::NotifyLeafMapLayoutChange() {
3450 dependent_code()->DeoptimizeDependentCodeGroup(
3451 DependentCode::kPrototypeCheckGroup);
3452}
3453
3454
3455bool Map::CanOmitPrototypeChecks() {
3456 return !HasTransitionArray() && !is_dictionary_map() &&
3457 FLAG_omit_prototype_checks_for_leaf_maps;
3458}
3459
3460
3461void Map::AddDependentCode(DependentCode::DependencyGroup group,
3462 Handle<Code> code) {
3463 Handle<DependentCode> codes =
3464 DependentCode::Insert(Handle<DependentCode>(dependent_code()),
3465 group, code);
3466 if (*codes != dependent_code()) {
3467 set_dependent_code(*codes);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003468 }
3469}
3470
3471
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003472int DependentCode::number_of_entries(DependencyGroup group) {
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003473 if (length() == 0) return 0;
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003474 return Smi::cast(get(group))->value();
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003475}
3476
3477
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003478void DependentCode::set_number_of_entries(DependencyGroup group, int value) {
3479 set(group, Smi::FromInt(value));
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003480}
3481
3482
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003483Code* DependentCode::code_at(int i) {
3484 return Code::cast(get(kCodesStartIndex + i));
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003485}
3486
3487
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003488void DependentCode::set_code_at(int i, Code* value) {
3489 set(kCodesStartIndex + i, value);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003490}
3491
3492
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003493Object** DependentCode::code_slot_at(int i) {
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003494 return HeapObject::RawField(
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003495 this, FixedArray::OffsetOfElementAt(kCodesStartIndex + i));
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003496}
3497
3498
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003499void DependentCode::clear_code_at(int i) {
3500 set_undefined(kCodesStartIndex + i);
3501}
3502
3503
3504void DependentCode::ExtendGroup(DependencyGroup group) {
3505 GroupStartIndexes starts(this);
3506 for (int g = kGroupCount - 1; g > group; g--) {
3507 if (starts.at(g) < starts.at(g + 1)) {
3508 set_code_at(starts.at(g + 1), code_at(starts.at(g)));
3509 }
3510 }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003511}
3512
3513
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003514void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003515 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003516 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003517 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
3518 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003519 ExtractArgumentsCountFromFlags(flags) >= 0);
3520 WRITE_INT_FIELD(this, kFlagsOffset, flags);
3521}
3522
3523
3524Code::Kind Code::kind() {
3525 return ExtractKindFromFlags(flags());
3526}
3527
3528
kasper.lund7276f142008-07-30 08:49:36 +00003529InlineCacheState Code::ic_state() {
3530 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003531 // Only allow uninitialized or debugger states for non-IC code
3532 // objects. This is used in the debugger to determine whether or not
3533 // a call to code object has been replaced with a debug break call.
3534 ASSERT(is_inline_cache_stub() ||
3535 result == UNINITIALIZED ||
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003536 result == DEBUG_STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003537 return result;
3538}
3539
3540
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003541Code::ExtraICState Code::extra_ic_state() {
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003542 ASSERT(is_inline_cache_stub() || ic_state() == DEBUG_STUB);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003543 return ExtractExtraICStateFromFlags(flags());
3544}
3545
3546
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003547Code::StubType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003548 return ExtractTypeFromFlags(flags());
3549}
3550
3551
3552int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003553 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003554 return ExtractArgumentsCountFromFlags(flags());
3555}
3556
3557
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003558int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003559 ASSERT(kind() == STUB ||
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003560 kind() == COMPILED_STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003561 kind() == UNARY_OP_IC ||
3562 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003563 kind() == COMPARE_IC ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00003564 kind() == LOAD_IC ||
3565 kind() == KEYED_LOAD_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003566 kind() == TO_BOOLEAN_IC);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003567 return StubMajorKeyField::decode(
3568 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasper.lund7276f142008-07-30 08:49:36 +00003569}
3570
3571
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003572void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003573 ASSERT(kind() == STUB ||
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003574 kind() == COMPILED_STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003575 kind() == UNARY_OP_IC ||
3576 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003577 kind() == COMPARE_IC ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00003578 kind() == LOAD_IC ||
3579 kind() == KEYED_LOAD_IC ||
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00003580 kind() == STORE_IC ||
3581 kind() == KEYED_STORE_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003582 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003583 ASSERT(0 <= major && major < 256);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003584 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3585 int updated = StubMajorKeyField::update(previous, major);
3586 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003587}
3588
3589
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003590bool Code::is_pregenerated() {
3591 return kind() == STUB && IsPregeneratedField::decode(flags());
3592}
3593
3594
3595void Code::set_is_pregenerated(bool value) {
3596 ASSERT(kind() == STUB);
3597 Flags f = flags();
3598 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3599 set_flags(f);
3600}
3601
3602
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003603bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003604 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003605 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3606}
3607
3608
3609void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003610 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003611 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3612}
3613
3614
3615bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003616 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003617 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3618 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003619}
3620
3621
3622void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003623 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003624 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3625 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3626 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3627}
3628
3629
3630bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003631 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003632 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3633 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3634}
3635
3636
3637void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003638 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003639 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3640 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3641 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003642}
3643
3644
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003645bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003646 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003647 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3648 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3649}
3650
3651
3652void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003653 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003654 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3655 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3656 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3657}
3658
3659
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003660int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003661 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003662 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3663}
3664
3665
3666void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003667 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003668 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3669 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3670}
3671
3672
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003673int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003674 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003675 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3676}
3677
3678
3679void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003680 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003681 ASSERT(ticks < 256);
3682 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3683}
3684
3685
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003686unsigned Code::stack_slots() {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003687 ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003688 return StackSlotsField::decode(
3689 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003690}
3691
3692
3693void Code::set_stack_slots(unsigned slots) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003694 CHECK(slots <= (1 << kStackSlotsBitCount));
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003695 ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003696 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3697 int updated = StackSlotsField::update(previous, slots);
3698 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003699}
3700
3701
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003702unsigned Code::safepoint_table_offset() {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003703 ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003704 return SafepointTableOffsetField::decode(
3705 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003706}
3707
3708
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003709void Code::set_safepoint_table_offset(unsigned offset) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003710 CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003711 ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003712 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003713 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3714 int updated = SafepointTableOffsetField::update(previous, offset);
3715 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003716}
3717
3718
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003719unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003720 ASSERT_EQ(FUNCTION, kind());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003721 return StackCheckTableOffsetField::decode(
3722 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003723}
3724
3725
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003726void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003727 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003728 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003729 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3730 int updated = StackCheckTableOffsetField::update(previous, offset);
3731 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003732}
3733
3734
3735CheckType Code::check_type() {
3736 ASSERT(is_call_stub() || is_keyed_call_stub());
3737 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3738 return static_cast<CheckType>(type);
3739}
3740
3741
3742void Code::set_check_type(CheckType value) {
3743 ASSERT(is_call_stub() || is_keyed_call_stub());
3744 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3745}
3746
3747
danno@chromium.org40cb8782011-05-25 07:58:50 +00003748byte Code::unary_op_type() {
3749 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003750 return UnaryOpTypeField::decode(
3751 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003752}
3753
3754
danno@chromium.org40cb8782011-05-25 07:58:50 +00003755void Code::set_unary_op_type(byte value) {
3756 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003757 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3758 int updated = UnaryOpTypeField::update(previous, value);
3759 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003760}
3761
3762
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003763byte Code::to_boolean_state() {
3764 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003765 return ToBooleanStateField::decode(
3766 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003767}
3768
3769
3770void Code::set_to_boolean_state(byte value) {
3771 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003772 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3773 int updated = ToBooleanStateField::update(previous, value);
3774 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003775}
3776
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003777
3778bool Code::has_function_cache() {
3779 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003780 return HasFunctionCacheField::decode(
3781 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003782}
3783
3784
3785void Code::set_has_function_cache(bool flag) {
3786 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003787 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3788 int updated = HasFunctionCacheField::update(previous, flag);
3789 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003790}
3791
3792
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003793bool Code::marked_for_deoptimization() {
3794 ASSERT(kind() == OPTIMIZED_FUNCTION);
3795 return MarkedForDeoptimizationField::decode(
3796 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
3797}
3798
3799
3800void Code::set_marked_for_deoptimization(bool flag) {
3801 ASSERT(kind() == OPTIMIZED_FUNCTION);
3802 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3803 int updated = MarkedForDeoptimizationField::update(previous, flag);
3804 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
3805}
3806
3807
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003808bool Code::is_inline_cache_stub() {
3809 Kind kind = this->kind();
3810 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3811}
3812
3813
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003814bool Code::is_debug_break() {
3815 return ic_state() == DEBUG_STUB && extra_ic_state() == DEBUG_BREAK;
3816}
3817
3818
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003819Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003820 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003821 ExtraICState extra_ic_state,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003822 StubType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003823 int argc,
3824 InlineCacheHolderFlag holder) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003825 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003826 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003827 | ICStateField::encode(ic_state)
3828 | TypeField::encode(type)
3829 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003830 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003831 | CacheHolderField::encode(holder);
3832 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003833}
3834
3835
3836Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003837 ExtraICState extra_ic_state,
hpayer@chromium.org8432c912013-02-28 15:55:26 +00003838 StubType type,
3839 int argc,
3840 InlineCacheHolderFlag holder) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003841 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003842}
3843
3844
3845Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003846 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003847}
3848
3849
kasper.lund7276f142008-07-30 08:49:36 +00003850InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003851 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003852}
3853
3854
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003855Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003856 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003857}
3858
3859
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003860Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003861 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003862}
3863
3864
3865int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003866 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003867}
3868
3869
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003870InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003871 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003872}
3873
3874
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003875Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003876 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003877 return static_cast<Flags>(bits);
3878}
3879
3880
ager@chromium.org8bb60582008-12-11 12:02:20 +00003881Code* Code::GetCodeFromTargetAddress(Address address) {
3882 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3883 // GetCodeFromTargetAddress might be called when marking objects during mark
3884 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3885 // Code::cast. Code::cast does not work when the object's map is
3886 // marked.
3887 Code* result = reinterpret_cast<Code*>(code);
3888 return result;
3889}
3890
3891
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003892Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3893 return HeapObject::
3894 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3895}
3896
3897
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003898Object* Map::prototype() {
3899 return READ_FIELD(this, kPrototypeOffset);
3900}
3901
3902
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003903void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003904 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003905 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003906 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003907}
3908
3909
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003910// If the descriptor is using the empty transition array, install a new empty
3911// transition array that will have place for an element transition.
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003912static MaybeObject* EnsureHasTransitionArray(Map* map) {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003913 TransitionArray* transitions;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003914 MaybeObject* maybe_transitions;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003915 if (!map->HasTransitionArray()) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003916 maybe_transitions = TransitionArray::Allocate(0);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003917 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3918 transitions->set_back_pointer_storage(map->GetBackPointer());
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003919 } else if (!map->transitions()->IsFullTransitionArray()) {
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003920 maybe_transitions = map->transitions()->ExtendToFullTransitionArray();
3921 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3922 } else {
3923 return map;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003924 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003925 map->set_transitions(transitions);
3926 return transitions;
3927}
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003928
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003929
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003930void Map::InitializeDescriptors(DescriptorArray* descriptors) {
verwaest@chromium.org652f4fa2012-10-08 08:48:51 +00003931 int len = descriptors->number_of_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00003932#ifdef DEBUG
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003933 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003934
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003935 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors];
3936 for (int i = 0; i < len; ++i) used_indices[i] = false;
3937
3938 // Ensure that all enumeration indexes between 1 and length occur uniquely in
3939 // the descriptor array.
3940 for (int i = 0; i < len; ++i) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00003941 int enum_index = descriptors->GetDetails(i).descriptor_index() -
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003942 PropertyDetails::kInitialIndex;
3943 ASSERT(0 <= enum_index && enum_index < len);
3944 ASSERT(!used_indices[enum_index]);
3945 used_indices[enum_index] = true;
3946 }
3947#endif
3948
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003949 set_instance_descriptors(descriptors);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00003950 SetNumberOfOwnDescriptors(len);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003951}
3952
3953
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003954ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003955SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)
danno@chromium.org40cb8782011-05-25 07:58:50 +00003956
3957
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003958void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003959 Object* back_pointer = GetBackPointer();
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00003960
3961 if (Heap::ShouldZapGarbage() && HasTransitionArray()) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003962 ZapTransitions();
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003963 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00003964
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003965 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003966 CONDITIONAL_WRITE_BARRIER(
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003967 heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode);
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003968}
3969
3970
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003971void Map::AppendDescriptor(Descriptor* desc,
3972 const DescriptorArray::WhitenessWitness& witness) {
3973 DescriptorArray* descriptors = instance_descriptors();
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00003974 int number_of_own_descriptors = NumberOfOwnDescriptors();
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003975 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
3976 descriptors->Append(desc, witness);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00003977 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003978}
3979
danno@chromium.org40cb8782011-05-25 07:58:50 +00003980
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003981Object* Map::GetBackPointer() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003982 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003983 if (object->IsDescriptorArray()) {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003984 return TransitionArray::cast(object)->back_pointer_storage();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003985 } else {
3986 ASSERT(object->IsMap() || object->IsUndefined());
3987 return object;
3988 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003989}
3990
3991
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003992bool Map::HasElementsTransition() {
3993 return HasTransitionArray() && transitions()->HasElementsTransition();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003994}
3995
3996
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003997bool Map::HasTransitionArray() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003998 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
3999 return object->IsTransitionArray();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004000}
4001
4002
4003Map* Map::elements_transition_map() {
4004 return transitions()->elements_transition();
4005}
4006
4007
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +00004008bool Map::CanHaveMoreTransitions() {
4009 if (!HasTransitionArray()) return true;
4010 return FixedArray::SizeFor(transitions()->length() +
4011 TransitionArray::kTransitionSize)
4012 <= Page::kMaxNonCodeHeapObjectSize;
4013}
4014
4015
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004016MaybeObject* Map::AddTransition(String* key,
4017 Map* target,
4018 SimpleTransitionFlag flag) {
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004019 if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004020 return TransitionArray::NewWith(flag, key, target, GetBackPointer());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004021}
4022
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004023
4024void Map::SetTransition(int transition_index, Map* target) {
4025 transitions()->SetTarget(transition_index, target);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00004026}
4027
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004028
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00004029Map* Map::GetTransition(int transition_index) {
4030 return transitions()->GetTarget(transition_index);
4031}
4032
4033
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004034MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004035 MaybeObject* allow_elements = EnsureHasTransitionArray(this);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004036 if (allow_elements->IsFailure()) return allow_elements;
4037 transitions()->set_elements_transition(transitioned_map);
4038 return this;
4039}
4040
4041
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004042FixedArray* Map::GetPrototypeTransitions() {
4043 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
4044 if (!transitions()->HasPrototypeTransitions()) {
4045 return GetHeap()->empty_fixed_array();
4046 }
4047 return transitions()->GetPrototypeTransitions();
4048}
4049
4050
4051MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004052 MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004053 if (allow_prototype->IsFailure()) return allow_prototype;
4054#ifdef DEBUG
4055 if (HasPrototypeTransitions()) {
4056 ASSERT(GetPrototypeTransitions() != proto_transitions);
4057 ZapPrototypeTransitions();
4058 }
4059#endif
4060 transitions()->SetPrototypeTransitions(proto_transitions);
4061 return this;
4062}
4063
4064
4065bool Map::HasPrototypeTransitions() {
4066 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
4067}
4068
4069
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004070TransitionArray* Map::transitions() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004071 ASSERT(HasTransitionArray());
4072 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4073 return TransitionArray::cast(object);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004074}
4075
4076
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004077void Map::set_transitions(TransitionArray* transition_array,
4078 WriteBarrierMode mode) {
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00004079 // In release mode, only run this code if verify_heap is on.
4080 if (Heap::ShouldZapGarbage() && HasTransitionArray()) {
4081 CHECK(transitions() != transition_array);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004082 ZapTransitions();
4083 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004084
4085 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array);
4086 CONDITIONAL_WRITE_BARRIER(
4087 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004088}
4089
4090
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004091void Map::init_back_pointer(Object* undefined) {
4092 ASSERT(undefined->IsUndefined());
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004093 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, undefined);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004094}
4095
4096
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004097void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004098 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
4099 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
4100 (value->IsMap() && GetBackPointer()->IsUndefined()));
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004101 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4102 if (object->IsTransitionArray()) {
4103 TransitionArray::cast(object)->set_back_pointer_storage(value);
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004104 } else {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004105 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, value);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004106 CONDITIONAL_WRITE_BARRIER(
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004107 GetHeap(), this, kTransitionsOrBackPointerOffset, value, mode);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004108 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004109}
4110
4111
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004112// Can either be Smi (no transitions), normal transition array, or a transition
4113// array with the header overwritten as a Smi (thus iterating).
4114TransitionArray* Map::unchecked_transition_array() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004115 Object* object = *HeapObject::RawField(this,
4116 Map::kTransitionsOrBackPointerOffset);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004117 TransitionArray* transition_array = static_cast<TransitionArray*>(object);
4118 return transition_array;
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004119}
4120
4121
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004122HeapObject* Map::UncheckedPrototypeTransitions() {
4123 ASSERT(HasTransitionArray());
4124 ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
4125 return unchecked_transition_array()->UncheckedPrototypeTransitions();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004126}
4127
4128
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004129ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004130ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004131ACCESSORS(Map, constructor, Object, kConstructorOffset)
4132
4133ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004134ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004135ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004136
4137ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004138ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset)
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00004139ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004140ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004141
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004142ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004143
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004144ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004145ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004146ACCESSORS(AccessorInfo, expected_receiver_type, Object,
4147 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004148
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004149ACCESSORS(DeclaredAccessorDescriptor, internal_field, Smi, kInternalFieldOffset)
4150
4151ACCESSORS(DeclaredAccessorInfo, descriptor, DeclaredAccessorDescriptor,
4152 kDescriptorOffset)
4153
4154ACCESSORS(ExecutableAccessorInfo, getter, Object, kGetterOffset)
4155ACCESSORS(ExecutableAccessorInfo, setter, Object, kSetterOffset)
4156ACCESSORS(ExecutableAccessorInfo, data, Object, kDataOffset)
4157
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004158ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
4159ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
4160
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004161ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
4162ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
4163ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
4164
4165ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
4166ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
4167ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
4168ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
4169ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
4170ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
4171
4172ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
4173ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
4174
4175ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
4176ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
4177
4178ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
4179ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004180ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
4181 kPropertyAccessorsOffset)
4182ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
4183 kPrototypeTemplateOffset)
4184ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
4185ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
4186 kNamedPropertyHandlerOffset)
4187ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
4188 kIndexedPropertyHandlerOffset)
4189ACCESSORS(FunctionTemplateInfo, instance_template, Object,
4190 kInstanceTemplateOffset)
4191ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
4192ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004193ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
4194 kInstanceCallHandlerOffset)
4195ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
4196 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004197ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004198
4199ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00004200ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
4201 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004202
4203ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
4204ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
4205
4206ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
4207
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00004208ACCESSORS(AllocationSiteInfo, payload, Object, kPayloadOffset)
4209
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004210ACCESSORS(Script, source, Object, kSourceOffset)
4211ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004212ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004213ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
4214ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004215ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00004216ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004217ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004218ACCESSORS_TO_SMI(Script, type, kTypeOffset)
4219ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
4220ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00004221ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00004222ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004223ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
4224 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004225
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004226#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004227ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
4228ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
4229ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
4230ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
4231
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004232ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
4233ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
4234ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004235ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004236#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004237
4238ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004239ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
4240 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004241ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
4242ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004243ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
4244 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004245ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004246ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
4247ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00004248ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004249ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
4250 kThisPropertyAssignmentsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004251SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004252
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00004253
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00004254SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004255BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
4256 kHiddenPrototypeBit)
4257BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
4258BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
4259 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00004260BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
4261 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004262BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
4263 kIsExpressionBit)
4264BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
4265 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004266BOOL_GETTER(SharedFunctionInfo,
4267 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004268 has_only_simple_this_property_assignments,
4269 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004270BOOL_ACCESSORS(SharedFunctionInfo,
4271 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00004272 allows_lazy_compilation,
4273 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004274BOOL_ACCESSORS(SharedFunctionInfo,
4275 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004276 allows_lazy_compilation_without_context,
4277 kAllowLazyCompilationWithoutContext)
4278BOOL_ACCESSORS(SharedFunctionInfo,
4279 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00004280 uses_arguments,
4281 kUsesArguments)
4282BOOL_ACCESSORS(SharedFunctionInfo,
4283 compiler_hints,
4284 has_duplicate_parameters,
4285 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004286
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004287
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004288#if V8_HOST_ARCH_32_BIT
4289SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
4290SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004291 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004292SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004293 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004294SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
4295SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004296 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004297SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
4298SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004299 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004300SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004301 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004302SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004303 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004304SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004305SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
4306SMI_ACCESSORS(SharedFunctionInfo,
4307 stress_deopt_counter,
4308 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004309#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004310
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004311#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004312 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004313 int holder::name() { \
4314 int value = READ_INT_FIELD(this, offset); \
4315 ASSERT(kHeapObjectTag == 1); \
4316 ASSERT((value & kHeapObjectTag) == 0); \
4317 return value >> 1; \
4318 } \
4319 void holder::set_##name(int value) { \
4320 ASSERT(kHeapObjectTag == 1); \
4321 ASSERT((value & 0xC0000000) == 0xC0000000 || \
4322 (value & 0xC0000000) == 0x000000000); \
4323 WRITE_INT_FIELD(this, \
4324 offset, \
4325 (value << 1) & ~kHeapObjectTag); \
4326 }
4327
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004328#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
4329 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004330 INT_ACCESSORS(holder, name, offset)
4331
4332
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004333PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004334PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4335 formal_parameter_count,
4336 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004337
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004338PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4339 expected_nof_properties,
4340 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004341PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
4342
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004343PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
4344PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4345 start_position_and_type,
4346 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004347
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004348PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4349 function_token_position,
4350 kFunctionTokenPositionOffset)
4351PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4352 compiler_hints,
4353 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004354
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004355PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4356 this_property_assignments_count,
4357 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004358PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004359
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004360PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
4361PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4362 stress_deopt_counter,
4363 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004364#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004365
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004366
4367int SharedFunctionInfo::construction_count() {
4368 return READ_BYTE_FIELD(this, kConstructionCountOffset);
4369}
4370
4371
4372void SharedFunctionInfo::set_construction_count(int value) {
4373 ASSERT(0 <= value && value < 256);
4374 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
4375}
4376
4377
whesse@chromium.org7b260152011-06-20 15:33:18 +00004378BOOL_ACCESSORS(SharedFunctionInfo,
4379 compiler_hints,
4380 live_objects_may_exist,
4381 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004382
4383
4384bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004385 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004386}
4387
4388
whesse@chromium.org7b260152011-06-20 15:33:18 +00004389BOOL_GETTER(SharedFunctionInfo,
4390 compiler_hints,
4391 optimization_disabled,
4392 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004393
4394
4395void SharedFunctionInfo::set_optimization_disabled(bool disable) {
4396 set_compiler_hints(BooleanBit::set(compiler_hints(),
4397 kOptimizationDisabled,
4398 disable));
4399 // If disabling optimizations we reflect that in the code object so
4400 // it will not be counted as optimizable code.
4401 if ((code()->kind() == Code::FUNCTION) && disable) {
4402 code()->set_optimizable(false);
4403 }
4404}
4405
4406
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004407int SharedFunctionInfo::profiler_ticks() {
4408 if (code()->kind() != Code::FUNCTION) return 0;
4409 return code()->profiler_ticks();
4410}
4411
4412
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004413LanguageMode SharedFunctionInfo::language_mode() {
4414 int hints = compiler_hints();
4415 if (BooleanBit::get(hints, kExtendedModeFunction)) {
4416 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
4417 return EXTENDED_MODE;
4418 }
4419 return BooleanBit::get(hints, kStrictModeFunction)
4420 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004421}
4422
4423
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004424void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
4425 // We only allow language mode transitions that go set the same language mode
4426 // again or go up in the chain:
4427 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
4428 ASSERT(this->language_mode() == CLASSIC_MODE ||
4429 this->language_mode() == language_mode ||
4430 language_mode == EXTENDED_MODE);
4431 int hints = compiler_hints();
4432 hints = BooleanBit::set(
4433 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
4434 hints = BooleanBit::set(
4435 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
4436 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004437}
4438
4439
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004440bool SharedFunctionInfo::is_classic_mode() {
4441 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
4442}
4443
4444BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
4445 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004446BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
4447BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
4448 name_should_print_as_anonymous,
4449 kNameShouldPrintAsAnonymous)
4450BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
4451BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00004452BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
4453BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
4454 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004455BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004456BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004457
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004458void SharedFunctionInfo::BeforeVisitingPointers() {
4459 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
mstarzinger@chromium.org0ae265a2012-12-11 17:41:11 +00004460}
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004461
mstarzinger@chromium.org0ae265a2012-12-11 17:41:11 +00004462
4463void SharedFunctionInfo::ClearOptimizedCodeMap() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004464 set_optimized_code_map(Smi::FromInt(0));
4465}
4466
4467
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004468ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
4469ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
4470
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00004471ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
4472
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004473bool Script::HasValidSource() {
4474 Object* src = this->source();
4475 if (!src->IsString()) return true;
4476 String* src_str = String::cast(src);
4477 if (!StringShape(src_str).IsExternal()) return true;
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00004478 if (src_str->IsOneByteRepresentation()) {
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004479 return ExternalAsciiString::cast(src)->resource() != NULL;
4480 } else if (src_str->IsTwoByteRepresentation()) {
4481 return ExternalTwoByteString::cast(src)->resource() != NULL;
4482 }
4483 return true;
4484}
4485
4486
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00004487void SharedFunctionInfo::DontAdaptArguments() {
4488 ASSERT(code()->kind() == Code::BUILTIN);
4489 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
4490}
4491
4492
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004493int SharedFunctionInfo::start_position() {
4494 return start_position_and_type() >> kStartPositionShift;
4495}
4496
4497
4498void SharedFunctionInfo::set_start_position(int start_position) {
4499 set_start_position_and_type((start_position << kStartPositionShift)
4500 | (start_position_and_type() & ~kStartPositionMask));
4501}
4502
4503
4504Code* SharedFunctionInfo::code() {
4505 return Code::cast(READ_FIELD(this, kCodeOffset));
4506}
4507
4508
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004509Code* SharedFunctionInfo::unchecked_code() {
4510 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
4511}
4512
4513
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004514void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004515 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004516 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004517}
4518
4519
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00004520void SharedFunctionInfo::ReplaceCode(Code* value) {
4521 // If the GC metadata field is already used then the function was
4522 // enqueued as a code flushing candidate and we remove it now.
4523 if (code()->gc_metadata() != NULL) {
4524 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
4525 flusher->EvictCandidate(this);
4526 }
4527
4528 ASSERT(code()->gc_metadata() == NULL && value->gc_metadata() == NULL);
4529 set_code(value);
4530}
4531
4532
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004533ScopeInfo* SharedFunctionInfo::scope_info() {
4534 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00004535}
4536
4537
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004538void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00004539 WriteBarrierMode mode) {
4540 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004541 CONDITIONAL_WRITE_BARRIER(GetHeap(),
4542 this,
4543 kScopeInfoOffset,
4544 reinterpret_cast<Object*>(value),
4545 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00004546}
4547
4548
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004549bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004550 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004551 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004552}
4553
4554
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004555bool SharedFunctionInfo::IsApiFunction() {
4556 return function_data()->IsFunctionTemplateInfo();
4557}
4558
4559
4560FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
4561 ASSERT(IsApiFunction());
4562 return FunctionTemplateInfo::cast(function_data());
4563}
4564
4565
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004566bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004567 return function_data()->IsSmi();
4568}
4569
4570
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004571BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4572 ASSERT(HasBuiltinFunctionId());
4573 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004574}
4575
4576
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004577int SharedFunctionInfo::code_age() {
4578 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
4579}
4580
4581
4582void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00004583 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
4584 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004585}
4586
4587
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004588int SharedFunctionInfo::ic_age() {
4589 return ICAgeBits::decode(counters());
4590}
4591
4592
4593void SharedFunctionInfo::set_ic_age(int ic_age) {
4594 set_counters(ICAgeBits::update(counters(), ic_age));
4595}
4596
4597
4598int SharedFunctionInfo::deopt_count() {
4599 return DeoptCountBits::decode(counters());
4600}
4601
4602
4603void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4604 set_counters(DeoptCountBits::update(counters(), deopt_count));
4605}
4606
4607
4608void SharedFunctionInfo::increment_deopt_count() {
4609 int value = counters();
4610 int deopt_count = DeoptCountBits::decode(value);
4611 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4612 set_counters(DeoptCountBits::update(value, deopt_count));
4613}
4614
4615
4616int SharedFunctionInfo::opt_reenable_tries() {
4617 return OptReenableTriesBits::decode(counters());
4618}
4619
4620
4621void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4622 set_counters(OptReenableTriesBits::update(counters(), tries));
4623}
4624
4625
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004626bool SharedFunctionInfo::has_deoptimization_support() {
4627 Code* code = this->code();
4628 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4629}
4630
4631
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004632void SharedFunctionInfo::TryReenableOptimization() {
4633 int tries = opt_reenable_tries();
4634 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4635 // We reenable optimization whenever the number of tries is a large
4636 // enough power of 2.
4637 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4638 set_optimization_disabled(false);
4639 set_opt_count(0);
4640 set_deopt_count(0);
4641 code()->set_optimizable(true);
4642 }
4643}
4644
4645
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004646bool JSFunction::IsBuiltin() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004647 return context()->global_object()->IsJSBuiltinsObject();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004648}
4649
4650
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004651bool JSFunction::NeedsArgumentsAdaption() {
4652 return shared()->formal_parameter_count() !=
4653 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4654}
4655
4656
4657bool JSFunction::IsOptimized() {
4658 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4659}
4660
4661
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004662bool JSFunction::IsOptimizable() {
4663 return code()->kind() == Code::FUNCTION && code()->optimizable();
4664}
4665
4666
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004667bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004668 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004669}
4670
4671
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004672bool JSFunction::IsMarkedForParallelRecompilation() {
4673 return code() ==
4674 GetIsolate()->builtins()->builtin(Builtins::kParallelRecompile);
4675}
4676
4677
4678bool JSFunction::IsInRecompileQueue() {
4679 return code() == GetIsolate()->builtins()->builtin(
4680 Builtins::kInRecompileQueue);
4681}
4682
4683
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004684Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004685 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004686}
4687
4688
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004689Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004690 return reinterpret_cast<Code*>(
4691 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004692}
4693
4694
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004695void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004696 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004697 Address entry = value->entry();
4698 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004699 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4700 this,
4701 HeapObject::RawField(this, kCodeEntryOffset),
4702 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004703}
4704
4705
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004706void JSFunction::ReplaceCode(Code* code) {
4707 bool was_optimized = IsOptimized();
4708 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4709
4710 set_code(code);
4711
4712 // Add/remove the function from the list of optimized functions for this
4713 // context based on the state change.
4714 if (!was_optimized && is_optimized) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004715 context()->native_context()->AddOptimizedFunction(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004716 }
4717 if (was_optimized && !is_optimized) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004718 context()->native_context()->RemoveOptimizedFunction(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004719 }
4720}
4721
4722
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004723Context* JSFunction::context() {
4724 return Context::cast(READ_FIELD(this, kContextOffset));
4725}
4726
4727
4728Object* JSFunction::unchecked_context() {
4729 return READ_FIELD(this, kContextOffset);
4730}
4731
4732
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004733SharedFunctionInfo* JSFunction::unchecked_shared() {
4734 return reinterpret_cast<SharedFunctionInfo*>(
4735 READ_FIELD(this, kSharedFunctionInfoOffset));
4736}
4737
4738
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004739void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004740 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004741 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004742 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004743}
4744
4745ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4746 kPrototypeOrInitialMapOffset)
4747
4748
4749Map* JSFunction::initial_map() {
4750 return Map::cast(prototype_or_initial_map());
4751}
4752
4753
4754void JSFunction::set_initial_map(Map* value) {
4755 set_prototype_or_initial_map(value);
4756}
4757
4758
4759bool JSFunction::has_initial_map() {
4760 return prototype_or_initial_map()->IsMap();
4761}
4762
4763
4764bool JSFunction::has_instance_prototype() {
4765 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4766}
4767
4768
4769bool JSFunction::has_prototype() {
4770 return map()->has_non_instance_prototype() || has_instance_prototype();
4771}
4772
4773
4774Object* JSFunction::instance_prototype() {
4775 ASSERT(has_instance_prototype());
4776 if (has_initial_map()) return initial_map()->prototype();
4777 // When there is no initial map and the prototype is a JSObject, the
4778 // initial map field is used for the prototype field.
4779 return prototype_or_initial_map();
4780}
4781
4782
4783Object* JSFunction::prototype() {
4784 ASSERT(has_prototype());
4785 // If the function's prototype property has been set to a non-JSObject
4786 // value, that value is stored in the constructor field of the map.
4787 if (map()->has_non_instance_prototype()) return map()->constructor();
4788 return instance_prototype();
4789}
4790
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004791
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004792bool JSFunction::should_have_prototype() {
4793 return map()->function_with_prototype();
4794}
4795
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004796
4797bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004798 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004799}
4800
4801
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004802FixedArray* JSFunction::literals() {
4803 ASSERT(!shared()->bound());
4804 return literals_or_bindings();
4805}
4806
4807
4808void JSFunction::set_literals(FixedArray* literals) {
4809 ASSERT(!shared()->bound());
4810 set_literals_or_bindings(literals);
4811}
4812
4813
4814FixedArray* JSFunction::function_bindings() {
4815 ASSERT(shared()->bound());
4816 return literals_or_bindings();
4817}
4818
4819
4820void JSFunction::set_function_bindings(FixedArray* bindings) {
4821 ASSERT(shared()->bound());
4822 // Bound function literal may be initialized to the empty fixed array
4823 // before the bindings are set.
4824 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4825 bindings->map() == GetHeap()->fixed_cow_array_map());
4826 set_literals_or_bindings(bindings);
4827}
4828
4829
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004830int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004831 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004832 return literals()->length();
4833}
4834
4835
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004836Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004837 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004838 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004839}
4840
4841
4842void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4843 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004844 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004845 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004846 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004847}
4848
4849
4850Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004851 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004852 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4853}
4854
4855
4856void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4857 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004858 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004859 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004860 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004861}
4862
4863
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004864ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004865ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004866ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4867ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4868
4869
4870void JSProxy::InitializeBody(int object_size, Object* value) {
4871 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4872 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4873 WRITE_FIELD(this, offset, value);
4874 }
4875}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004876
4877
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004878ACCESSORS(JSSet, table, Object, kTableOffset)
4879ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004880ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4881ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004882
4883
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004884Address Foreign::foreign_address() {
4885 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004886}
4887
4888
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004889void Foreign::set_foreign_address(Address value) {
4890 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004891}
4892
4893
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004894ACCESSORS(JSModule, context, Object, kContextOffset)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004895ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004896
4897
4898JSModule* JSModule::cast(Object* obj) {
4899 ASSERT(obj->IsJSModule());
4900 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4901 return reinterpret_cast<JSModule*>(obj);
4902}
4903
4904
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004905ACCESSORS(JSValue, value, Object, kValueOffset)
4906
4907
4908JSValue* JSValue::cast(Object* obj) {
4909 ASSERT(obj->IsJSValue());
4910 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4911 return reinterpret_cast<JSValue*>(obj);
4912}
4913
4914
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004915ACCESSORS(JSDate, value, Object, kValueOffset)
4916ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4917ACCESSORS(JSDate, year, Object, kYearOffset)
4918ACCESSORS(JSDate, month, Object, kMonthOffset)
4919ACCESSORS(JSDate, day, Object, kDayOffset)
4920ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4921ACCESSORS(JSDate, hour, Object, kHourOffset)
4922ACCESSORS(JSDate, min, Object, kMinOffset)
4923ACCESSORS(JSDate, sec, Object, kSecOffset)
4924
4925
4926JSDate* JSDate::cast(Object* obj) {
4927 ASSERT(obj->IsJSDate());
4928 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4929 return reinterpret_cast<JSDate*>(obj);
4930}
4931
4932
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004933ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4934ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4935ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4936ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4937ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4938SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4939SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4940
4941
4942JSMessageObject* JSMessageObject::cast(Object* obj) {
4943 ASSERT(obj->IsJSMessageObject());
4944 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4945 return reinterpret_cast<JSMessageObject*>(obj);
4946}
4947
4948
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004949INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +00004950INT_ACCESSORS(Code, prologue_offset, kPrologueOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004951ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004952ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004953ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004954
4955
4956// Type feedback slot: type_feedback_info for FUNCTIONs, stub_info for STUBs.
4957void Code::InitializeTypeFeedbackInfoNoWriteBarrier(Object* value) {
4958 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
4959}
4960
4961
4962Object* Code::type_feedback_info() {
4963 ASSERT(kind() == FUNCTION);
4964 return Object::cast(READ_FIELD(this, kTypeFeedbackInfoOffset));
4965}
4966
4967
4968void Code::set_type_feedback_info(Object* value, WriteBarrierMode mode) {
4969 ASSERT(kind() == FUNCTION);
4970 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
4971 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kTypeFeedbackInfoOffset,
4972 value, mode);
4973}
4974
4975
4976int Code::stub_info() {
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00004977 ASSERT(kind() == COMPARE_IC || kind() == BINARY_OP_IC || kind() == LOAD_IC);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004978 Object* value = READ_FIELD(this, kTypeFeedbackInfoOffset);
4979 return Smi::cast(value)->value();
4980}
4981
4982
4983void Code::set_stub_info(int value) {
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00004984 ASSERT(kind() == COMPARE_IC ||
4985 kind() == BINARY_OP_IC ||
4986 kind() == LOAD_IC ||
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00004987 kind() == KEYED_LOAD_IC ||
4988 kind() == STORE_IC ||
4989 kind() == KEYED_STORE_IC);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004990 WRITE_FIELD(this, kTypeFeedbackInfoOffset, Smi::FromInt(value));
4991}
4992
4993
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00004994void Code::set_deoptimizing_functions(Object* value) {
4995 ASSERT(kind() == OPTIMIZED_FUNCTION);
4996 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
4997}
4998
4999
5000Object* Code::deoptimizing_functions() {
5001 ASSERT(kind() == OPTIMIZED_FUNCTION);
5002 return Object::cast(READ_FIELD(this, kTypeFeedbackInfoOffset));
5003}
5004
5005
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00005006ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00005007INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005008
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005009
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005010byte* Code::instruction_start() {
5011 return FIELD_ADDR(this, kHeaderSize);
5012}
5013
5014
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005015byte* Code::instruction_end() {
5016 return instruction_start() + instruction_size();
5017}
5018
5019
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005020int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005021 return RoundUp(instruction_size(), kObjectAlignment);
5022}
5023
5024
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005025FixedArray* Code::unchecked_deoptimization_data() {
5026 return reinterpret_cast<FixedArray*>(
5027 READ_FIELD(this, kDeoptimizationDataOffset));
5028}
5029
5030
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005031ByteArray* Code::unchecked_relocation_info() {
5032 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005033}
5034
5035
5036byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005037 return unchecked_relocation_info()->GetDataStartAddress();
5038}
5039
5040
5041int Code::relocation_size() {
5042 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005043}
5044
5045
5046byte* Code::entry() {
5047 return instruction_start();
5048}
5049
5050
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005051bool Code::contains(byte* inner_pointer) {
5052 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005053}
5054
5055
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005056ACCESSORS(JSArray, length, Object, kLengthOffset)
5057
5058
ager@chromium.org236ad962008-09-25 09:45:57 +00005059ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00005060
5061
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00005062JSRegExp::Type JSRegExp::TypeTag() {
5063 Object* data = this->data();
5064 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
5065 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
5066 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00005067}
5068
5069
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005070JSRegExp::Type JSRegExp::TypeTagUnchecked() {
5071 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
5072 return static_cast<JSRegExp::Type>(smi->value());
5073}
5074
5075
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00005076int JSRegExp::CaptureCount() {
5077 switch (TypeTag()) {
5078 case ATOM:
5079 return 0;
5080 case IRREGEXP:
5081 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
5082 default:
5083 UNREACHABLE();
5084 return -1;
5085 }
5086}
5087
5088
ager@chromium.orga74f0da2008-12-03 16:05:52 +00005089JSRegExp::Flags JSRegExp::GetFlags() {
5090 ASSERT(this->data()->IsFixedArray());
5091 Object* data = this->data();
5092 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
5093 return Flags(smi->value());
5094}
5095
5096
5097String* JSRegExp::Pattern() {
5098 ASSERT(this->data()->IsFixedArray());
5099 Object* data = this->data();
5100 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
5101 return pattern;
5102}
5103
5104
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00005105Object* JSRegExp::DataAt(int index) {
5106 ASSERT(TypeTag() != NOT_COMPILED);
5107 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00005108}
5109
5110
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005111Object* JSRegExp::DataAtUnchecked(int index) {
5112 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
5113 int offset = FixedArray::kHeaderSize + index * kPointerSize;
5114 return READ_FIELD(fa, offset);
5115}
5116
5117
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00005118void JSRegExp::SetDataAt(int index, Object* value) {
5119 ASSERT(TypeTag() != NOT_COMPILED);
5120 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
5121 FixedArray::cast(data())->set(index, value);
5122}
5123
5124
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005125void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
5126 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
5127 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
5128 if (value->IsSmi()) {
5129 fa->set_unchecked(index, Smi::cast(value));
5130 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005131 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005132 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
5133 }
5134}
5135
5136
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005137ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005138 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005139#if DEBUG
5140 FixedArrayBase* fixed_array =
5141 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
5142 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005143 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
5144 (map == GetHeap()->fixed_array_map() ||
5145 map == GetHeap()->fixed_cow_array_map())) ||
5146 (IsFastDoubleElementsKind(kind) &&
5147 (fixed_array->IsFixedDoubleArray() ||
5148 fixed_array == GetHeap()->empty_fixed_array())) ||
5149 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005150 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005151 fixed_array->IsDictionary()) ||
5152 (kind > DICTIONARY_ELEMENTS));
5153 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
5154 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005155#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005156 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005157}
5158
5159
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00005160ElementsAccessor* JSObject::GetElementsAccessor() {
5161 return ElementsAccessor::ForKind(GetElementsKind());
5162}
5163
5164
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005165bool JSObject::HasFastObjectElements() {
5166 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005167}
5168
5169
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005170bool JSObject::HasFastSmiElements() {
5171 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005172}
5173
5174
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005175bool JSObject::HasFastSmiOrObjectElements() {
5176 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005177}
5178
5179
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00005180bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005181 return IsFastDoubleElementsKind(GetElementsKind());
5182}
5183
5184
5185bool JSObject::HasFastHoleyElements() {
5186 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00005187}
5188
5189
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005190bool JSObject::HasFastElements() {
5191 return IsFastElementsKind(GetElementsKind());
5192}
5193
5194
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005195bool JSObject::HasDictionaryElements() {
5196 return GetElementsKind() == DICTIONARY_ELEMENTS;
5197}
5198
5199
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005200bool JSObject::HasNonStrictArgumentsElements() {
5201 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
5202}
5203
5204
ager@chromium.org3811b432009-10-28 14:53:37 +00005205bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005206 HeapObject* array = elements();
5207 ASSERT(array != NULL);
5208 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00005209}
5210
5211
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005212#define EXTERNAL_ELEMENTS_CHECK(name, type) \
5213bool JSObject::HasExternal##name##Elements() { \
5214 HeapObject* array = elements(); \
5215 ASSERT(array != NULL); \
5216 if (!array->IsHeapObject()) \
5217 return false; \
5218 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00005219}
5220
5221
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005222EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
5223EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
5224EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
5225EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
5226 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
5227EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
5228EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
5229 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
5230EXTERNAL_ELEMENTS_CHECK(Float,
5231 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00005232EXTERNAL_ELEMENTS_CHECK(Double,
5233 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005234EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00005235
5236
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005237bool JSObject::HasNamedInterceptor() {
5238 return map()->has_named_interceptor();
5239}
5240
5241
5242bool JSObject::HasIndexedInterceptor() {
5243 return map()->has_indexed_interceptor();
5244}
5245
5246
lrn@chromium.org303ada72010-10-27 09:33:13 +00005247MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005248 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005249 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005250 Isolate* isolate = GetIsolate();
5251 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00005252 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005253 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
5254 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00005255 if (!maybe_writable_elems->ToObject(&writable_elems)) {
5256 return maybe_writable_elems;
5257 }
5258 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005259 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005260 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005261 return writable_elems;
5262}
5263
5264
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005265StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005266 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005267 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005268}
5269
5270
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005271SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005272 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005273 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005274}
5275
5276
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005277bool Name::IsHashFieldComputed(uint32_t field) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005278 return (field & kHashNotComputedMask) == 0;
5279}
5280
5281
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005282bool Name::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005283 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005284}
5285
5286
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005287uint32_t Name::Hash() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005288 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005289 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005290 if (IsHashFieldComputed(field)) return field >> kHashShift;
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005291 // Slow case: compute hash code and set it. Has to be a string.
5292 return String::cast(this)->ComputeAndSetHash();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005293}
5294
5295
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005296StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00005297 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005298 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00005299 array_index_(0),
5300 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005301 is_first_char_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005302 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005303}
ager@chromium.org7c537e22008-10-16 08:43:32 +00005304
5305
5306bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005307 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005308}
5309
5310
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005311uint32_t StringHasher::AddCharacterCore(uint32_t running_hash, uint16_t c) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005312 running_hash += c;
5313 running_hash += (running_hash << 10);
5314 running_hash ^= (running_hash >> 6);
5315 return running_hash;
5316}
5317
5318
5319uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
5320 running_hash += (running_hash << 3);
5321 running_hash ^= (running_hash >> 11);
5322 running_hash += (running_hash << 15);
5323 if ((running_hash & String::kHashBitMask) == 0) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005324 return kZeroHash;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005325 }
5326 return running_hash;
5327}
5328
5329
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005330void StringHasher::AddCharacter(uint16_t c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005331 // Use the Jenkins one-at-a-time hash function to update the hash
5332 // for the given character.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005333 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005334}
5335
5336
5337bool StringHasher::UpdateIndex(uint16_t c) {
5338 ASSERT(is_array_index_);
5339 if (c < '0' || c > '9') {
5340 is_array_index_ = false;
5341 return false;
5342 }
5343 int d = c - '0';
5344 if (is_first_char_) {
5345 is_first_char_ = false;
5346 if (c == '0' && length_ > 1) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00005347 is_array_index_ = false;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005348 return false;
5349 }
5350 }
5351 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
5352 is_array_index_ = false;
5353 return false;
5354 }
5355 array_index_ = array_index_ * 10 + d;
5356 return true;
5357}
5358
5359
5360template<typename Char>
5361inline void StringHasher::AddCharacters(const Char* chars, int length) {
5362 ASSERT(sizeof(Char) == 1 || sizeof(Char) == 2);
5363 int i = 0;
5364 if (is_array_index_) {
5365 for (; i < length; i++) {
5366 AddCharacter(chars[i]);
5367 if (!UpdateIndex(chars[i])) {
5368 i++;
5369 break;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005370 }
5371 }
5372 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005373 for (; i < length; i++) {
5374 ASSERT(!is_array_index_);
5375 AddCharacter(chars[i]);
yangguo@chromium.org154ff992012-03-13 08:09:54 +00005376 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00005377}
5378
5379
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005380template <typename schar>
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005381uint32_t StringHasher::HashSequentialString(const schar* chars,
5382 int length,
5383 uint32_t seed) {
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005384 StringHasher hasher(length, seed);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005385 if (!hasher.has_trivial_hash()) hasher.AddCharacters(chars, length);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005386 return hasher.GetHashField();
5387}
5388
5389
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005390bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005391 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00005392 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
5393 return false;
5394 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005395 return SlowAsArrayIndex(index);
5396}
5397
5398
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00005399Object* JSReceiver::GetPrototype() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00005400 return map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005401}
5402
5403
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00005404Object* JSReceiver::GetConstructor() {
5405 return map()->constructor();
5406}
5407
5408
rossberg@chromium.org717967f2011-07-20 13:44:42 +00005409bool JSReceiver::HasProperty(String* name) {
5410 if (IsJSProxy()) {
5411 return JSProxy::cast(this)->HasPropertyWithHandler(name);
5412 }
5413 return GetPropertyAttribute(name) != ABSENT;
5414}
5415
5416
5417bool JSReceiver::HasLocalProperty(String* name) {
5418 if (IsJSProxy()) {
5419 return JSProxy::cast(this)->HasPropertyWithHandler(name);
5420 }
5421 return GetLocalPropertyAttribute(name) != ABSENT;
5422}
5423
5424
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00005425PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00005426 uint32_t index;
5427 if (IsJSObject() && key->AsArrayIndex(&index)) {
5428 return GetElementAttribute(index);
5429 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005430 return GetPropertyAttributeWithReceiver(this, key);
5431}
5432
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00005433
5434PropertyAttributes JSReceiver::GetElementAttribute(uint32_t index) {
5435 if (IsJSProxy()) {
5436 return JSProxy::cast(this)->GetElementAttributeWithHandler(this, index);
5437 }
5438 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5439 this, index, true);
5440}
5441
5442
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005443// TODO(504): this may be useful in other places too where JSGlobalProxy
5444// is used.
5445Object* JSObject::BypassGlobalProxy() {
5446 if (IsJSGlobalProxy()) {
5447 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005448 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005449 ASSERT(proto->IsJSGlobalObject());
5450 return proto;
5451 }
5452 return this;
5453}
5454
5455
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005456MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
5457 return IsJSProxy()
5458 ? JSProxy::cast(this)->GetIdentityHash(flag)
5459 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005460}
5461
5462
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005463bool JSReceiver::HasElement(uint32_t index) {
5464 if (IsJSProxy()) {
5465 return JSProxy::cast(this)->HasElementWithHandler(index);
5466 }
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00005467 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5468 this, index, true) != ABSENT;
5469}
5470
5471
5472bool JSReceiver::HasLocalElement(uint32_t index) {
5473 if (IsJSProxy()) {
5474 return JSProxy::cast(this)->HasElementWithHandler(index);
5475 }
5476 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5477 this, index, false) != ABSENT;
5478}
5479
5480
5481PropertyAttributes JSReceiver::GetLocalElementAttribute(uint32_t index) {
5482 if (IsJSProxy()) {
5483 return JSProxy::cast(this)->GetElementAttributeWithHandler(this, index);
5484 }
5485 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5486 this, index, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005487}
5488
5489
5490bool AccessorInfo::all_can_read() {
5491 return BooleanBit::get(flag(), kAllCanReadBit);
5492}
5493
5494
5495void AccessorInfo::set_all_can_read(bool value) {
5496 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
5497}
5498
5499
5500bool AccessorInfo::all_can_write() {
5501 return BooleanBit::get(flag(), kAllCanWriteBit);
5502}
5503
5504
5505void AccessorInfo::set_all_can_write(bool value) {
5506 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
5507}
5508
5509
ager@chromium.org870a0b62008-11-04 11:43:05 +00005510bool AccessorInfo::prohibits_overwriting() {
5511 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
5512}
5513
5514
5515void AccessorInfo::set_prohibits_overwriting(bool value) {
5516 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
5517}
5518
5519
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005520PropertyAttributes AccessorInfo::property_attributes() {
5521 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
5522}
5523
5524
5525void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005526 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005527}
5528
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005529
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005530bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
5531 Object* function_template = expected_receiver_type();
5532 if (!function_template->IsFunctionTemplateInfo()) return true;
5533 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
5534}
5535
5536
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005537template<typename Shape, typename Key>
5538void Dictionary<Shape, Key>::SetEntry(int entry,
5539 Object* key,
5540 Object* value) {
5541 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
5542}
5543
5544
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005545template<typename Shape, typename Key>
5546void Dictionary<Shape, Key>::SetEntry(int entry,
5547 Object* key,
5548 Object* value,
5549 PropertyDetails details) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005550 ASSERT(!key->IsString() ||
5551 details.IsDeleted() ||
5552 details.dictionary_index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005553 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005554 AssertNoAllocation no_gc;
5555 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005556 FixedArray::set(index, key, mode);
5557 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005558 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005559}
5560
5561
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005562bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
5563 ASSERT(other->IsNumber());
5564 return key == static_cast<uint32_t>(other->Number());
5565}
5566
5567
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005568uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
5569 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005570}
5571
5572
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005573uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
5574 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005575 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005576 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005577}
5578
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005579uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
5580 return ComputeIntegerHash(key, seed);
5581}
5582
5583uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
5584 uint32_t seed,
5585 Object* other) {
5586 ASSERT(other->IsNumber());
5587 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
5588}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005589
5590MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
5591 return Isolate::Current()->heap()->NumberFromUint32(key);
5592}
5593
5594
5595bool StringDictionaryShape::IsMatch(String* key, Object* other) {
5596 // We know that all entries in a hash table had their hash keys created.
5597 // Use that knowledge to have fast failure.
5598 if (key->Hash() != String::cast(other)->Hash()) return false;
5599 return key->Equals(String::cast(other));
5600}
5601
5602
5603uint32_t StringDictionaryShape::Hash(String* key) {
5604 return key->Hash();
5605}
5606
5607
5608uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
5609 return String::cast(other)->Hash();
5610}
5611
5612
5613MaybeObject* StringDictionaryShape::AsObject(String* key) {
5614 return key;
5615}
5616
5617
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005618template <int entrysize>
5619bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
5620 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005621}
5622
5623
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005624template <int entrysize>
5625uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005626 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
5627 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005628}
5629
5630
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005631template <int entrysize>
5632uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
5633 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005634 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
5635 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005636}
5637
5638
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005639template <int entrysize>
5640MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005641 return key;
5642}
5643
5644
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005645void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005646 // No write barrier is needed since empty_fixed_array is not in new space.
5647 // Please note this function is used during marking:
5648 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005649 // - IncrementalMarking::Step
danno@chromium.org72204d52012-10-31 10:02:10 +00005650 ASSERT(!heap->InNewSpace(heap->empty_fixed_array()));
5651 WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005652}
5653
5654
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005655void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005656 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005657 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005658 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5659 if (elts->length() < required_size) {
5660 // Doubling in size would be overkill, but leave some slack to avoid
5661 // constantly growing.
5662 Expand(required_size + (required_size >> 3));
5663 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005664 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005665 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5666 // Expand will allocate a new backing store in new space even if the size
5667 // we asked for isn't larger than what we had before.
5668 Expand(required_size);
5669 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005670}
5671
5672
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005673void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005674 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005675 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5676}
5677
5678
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005679bool JSArray::AllowsSetElementsLength() {
5680 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5681 ASSERT(result == !HasExternalArrayElements());
5682 return result;
5683}
5684
5685
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005686MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5687 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005688 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005689 if (maybe_result->IsFailure()) return maybe_result;
5690 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005691 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005692 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005693 (IsFastObjectElementsKind(GetElementsKind()) ||
5694 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005695 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005696 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005697 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005698 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005699}
5700
5701
lrn@chromium.org303ada72010-10-27 09:33:13 +00005702MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005703 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005704 return GetHeap()->CopyFixedArray(this);
5705}
5706
5707
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005708MaybeObject* FixedDoubleArray::Copy() {
5709 if (length() == 0) return this;
5710 return GetHeap()->CopyFixedDoubleArray(this);
5711}
5712
5713
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005714void TypeFeedbackCells::SetAstId(int index, TypeFeedbackId id) {
5715 set(1 + index * 2, Smi::FromInt(id.ToInt()));
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005716}
5717
5718
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005719TypeFeedbackId TypeFeedbackCells::AstId(int index) {
5720 return TypeFeedbackId(Smi::cast(get(1 + index * 2))->value());
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005721}
5722
5723
5724void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
5725 set(index * 2, cell);
5726}
5727
5728
5729JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
5730 return JSGlobalPropertyCell::cast(get(index * 2));
5731}
5732
5733
5734Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5735 return isolate->factory()->the_hole_value();
5736}
5737
5738
5739Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5740 return isolate->factory()->undefined_value();
5741}
5742
5743
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005744Handle<Object> TypeFeedbackCells::MonomorphicArraySentinel(Isolate* isolate,
5745 ElementsKind elements_kind) {
5746 return Handle<Object>(Smi::FromInt(static_cast<int>(elements_kind)), isolate);
5747}
5748
5749
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005750Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
danno@chromium.org72204d52012-10-31 10:02:10 +00005751 return heap->the_hole_value();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005752}
5753
5754
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005755int TypeFeedbackInfo::ic_total_count() {
5756 int current = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5757 return ICTotalCountField::decode(current);
5758}
5759
5760
5761void TypeFeedbackInfo::set_ic_total_count(int count) {
5762 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5763 value = ICTotalCountField::update(value,
5764 ICTotalCountField::decode(count));
5765 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
5766}
5767
5768
5769int TypeFeedbackInfo::ic_with_type_info_count() {
5770 int current = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5771 return ICsWithTypeInfoCountField::decode(current);
5772}
5773
5774
5775void TypeFeedbackInfo::change_ic_with_type_info_count(int delta) {
5776 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5777 int new_count = ICsWithTypeInfoCountField::decode(value) + delta;
5778 // We can get negative count here when the type-feedback info is
5779 // shared between two code objects. The can only happen when
5780 // the debugger made a shallow copy of code object (see Heap::CopyCode).
5781 // Since we do not optimize when the debugger is active, we can skip
5782 // this counter update.
5783 if (new_count >= 0) {
5784 new_count &= ICsWithTypeInfoCountField::kMask;
5785 value = ICsWithTypeInfoCountField::update(value, new_count);
5786 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
5787 }
5788}
5789
5790
5791void TypeFeedbackInfo::initialize_storage() {
5792 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(0));
5793 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(0));
5794}
5795
5796
5797void TypeFeedbackInfo::change_own_type_change_checksum() {
5798 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5799 int checksum = OwnTypeChangeChecksum::decode(value);
5800 checksum = (checksum + 1) % (1 << kTypeChangeChecksumBits);
5801 value = OwnTypeChangeChecksum::update(value, checksum);
5802 // Ensure packed bit field is in Smi range.
5803 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
5804 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
5805 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
5806}
5807
5808
5809void TypeFeedbackInfo::set_inlined_type_change_checksum(int checksum) {
5810 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5811 int mask = (1 << kTypeChangeChecksumBits) - 1;
5812 value = InlinedTypeChangeChecksum::update(value, checksum & mask);
5813 // Ensure packed bit field is in Smi range.
5814 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
5815 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
5816 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
5817}
5818
5819
5820int TypeFeedbackInfo::own_type_change_checksum() {
5821 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5822 return OwnTypeChangeChecksum::decode(value);
5823}
5824
5825
5826bool TypeFeedbackInfo::matches_inlined_type_change_checksum(int checksum) {
5827 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5828 int mask = (1 << kTypeChangeChecksumBits) - 1;
5829 return InlinedTypeChangeChecksum::decode(value) == (checksum & mask);
5830}
5831
5832
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005833ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
5834 kTypeFeedbackCellsOffset)
5835
5836
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00005837SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
5838
5839
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005840Relocatable::Relocatable(Isolate* isolate) {
5841 ASSERT(isolate == Isolate::Current());
5842 isolate_ = isolate;
5843 prev_ = isolate->relocatable_top();
5844 isolate->set_relocatable_top(this);
5845}
5846
5847
5848Relocatable::~Relocatable() {
5849 ASSERT(isolate_ == Isolate::Current());
5850 ASSERT_EQ(isolate_->relocatable_top(), this);
5851 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005852}
5853
5854
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005855int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
5856 return map->instance_size();
5857}
5858
5859
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005860void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005861 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005862 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005863}
5864
5865
5866template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005867void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005868 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005869 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005870}
5871
5872
5873void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5874 typedef v8::String::ExternalAsciiStringResource Resource;
5875 v->VisitExternalAsciiString(
5876 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5877}
5878
5879
5880template<typename StaticVisitor>
5881void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5882 typedef v8::String::ExternalAsciiStringResource Resource;
5883 StaticVisitor::VisitExternalAsciiString(
5884 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5885}
5886
5887
5888void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5889 typedef v8::String::ExternalStringResource Resource;
5890 v->VisitExternalTwoByteString(
5891 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5892}
5893
5894
5895template<typename StaticVisitor>
5896void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5897 typedef v8::String::ExternalStringResource Resource;
5898 StaticVisitor::VisitExternalTwoByteString(
5899 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5900}
5901
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005902
5903template<int start_offset, int end_offset, int size>
5904void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5905 HeapObject* obj,
5906 ObjectVisitor* v) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005907 v->VisitPointers(HeapObject::RawField(obj, start_offset),
5908 HeapObject::RawField(obj, end_offset));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005909}
5910
5911
5912template<int start_offset>
5913void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5914 int object_size,
5915 ObjectVisitor* v) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005916 v->VisitPointers(HeapObject::RawField(obj, start_offset),
5917 HeapObject::RawField(obj, object_size));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005918}
5919
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005920
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005921#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005922#undef CAST_ACCESSOR
5923#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005924#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005925#undef ACCESSORS_TO_SMI
5926#undef SMI_ACCESSORS
5927#undef BOOL_GETTER
5928#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005929#undef FIELD_ADDR
5930#undef READ_FIELD
5931#undef WRITE_FIELD
5932#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005933#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005934#undef READ_DOUBLE_FIELD
5935#undef WRITE_DOUBLE_FIELD
5936#undef READ_INT_FIELD
5937#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005938#undef READ_INTPTR_FIELD
5939#undef WRITE_INTPTR_FIELD
5940#undef READ_UINT32_FIELD
5941#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005942#undef READ_SHORT_FIELD
5943#undef WRITE_SHORT_FIELD
5944#undef READ_BYTE_FIELD
5945#undef WRITE_BYTE_FIELD
5946
5947
5948} } // namespace v8::internal
5949
5950#endif // V8_OBJECTS_INL_H_