blob: 18894c1d56123f99fe02df5967ea06ffdac8a857 [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
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000145bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
146 // There is a constraint on the object; check.
147 if (!this->IsJSObject()) return false;
148 // Fetch the constructor function of the object.
149 Object* cons_obj = JSObject::cast(this)->map()->constructor();
150 if (!cons_obj->IsJSFunction()) return false;
151 JSFunction* fun = JSFunction::cast(cons_obj);
152 // Iterate through the chain of inheriting function templates to
153 // see if the required one occurs.
154 for (Object* type = fun->shared()->function_data();
155 type->IsFunctionTemplateInfo();
156 type = FunctionTemplateInfo::cast(type)->parent_template()) {
157 if (type == expected) return true;
158 }
159 // Didn't find the required type in the inheritance chain.
160 return false;
161}
162
163
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000164bool Object::IsSmi() {
165 return HAS_SMI_TAG(this);
166}
167
168
169bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000170 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000171}
172
173
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000174bool Object::NonFailureIsHeapObject() {
175 ASSERT(!this->IsFailure());
176 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
177}
178
179
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000180TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000181
182
183bool Object::IsString() {
184 return Object::IsHeapObject()
185 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
186}
187
188
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000189bool Object::IsSpecObject() {
190 return Object::IsHeapObject()
191 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
192}
193
194
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000195bool Object::IsSpecFunction() {
196 if (!Object::IsHeapObject()) return false;
197 InstanceType type = HeapObject::cast(this)->map()->instance_type();
198 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
199}
200
201
ager@chromium.org870a0b62008-11-04 11:43:05 +0000202bool Object::IsSymbol() {
203 if (!this->IsHeapObject()) return false;
204 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000205 // Because the symbol tag is non-zero and no non-string types have the
206 // symbol bit set we can test for symbols with a very simple test
207 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000208 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000209 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
210 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000211}
212
213
214bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000215 if (!IsString()) return false;
216 return StringShape(String::cast(this)).IsCons();
217}
218
219
220bool Object::IsSlicedString() {
221 if (!IsString()) return false;
222 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000223}
224
225
ager@chromium.org870a0b62008-11-04 11:43:05 +0000226bool Object::IsSeqString() {
227 if (!IsString()) return false;
228 return StringShape(String::cast(this)).IsSequential();
229}
230
231
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000232bool Object::IsSeqOneByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000233 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000234 return StringShape(String::cast(this)).IsSequential() &&
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000235 String::cast(this)->IsOneByteRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000236}
237
238
239bool Object::IsSeqTwoByteString() {
240 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000241 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000242 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243}
244
245
246bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000247 if (!IsString()) return false;
248 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000249}
250
251
252bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000253 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000254 return StringShape(String::cast(this)).IsExternal() &&
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000255 String::cast(this)->IsOneByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000256}
257
258
259bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000260 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000261 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000262 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000263}
264
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000265bool Object::HasValidElements() {
266 // Dictionary is covered under FixedArray.
267 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
268}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000269
ager@chromium.org870a0b62008-11-04 11:43:05 +0000270StringShape::StringShape(String* str)
271 : type_(str->map()->instance_type()) {
272 set_valid();
273 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000274}
275
276
ager@chromium.org870a0b62008-11-04 11:43:05 +0000277StringShape::StringShape(Map* map)
278 : type_(map->instance_type()) {
279 set_valid();
280 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000281}
282
283
ager@chromium.org870a0b62008-11-04 11:43:05 +0000284StringShape::StringShape(InstanceType t)
285 : type_(static_cast<uint32_t>(t)) {
286 set_valid();
287 ASSERT((type_ & kIsNotStringMask) == kStringTag);
288}
289
290
291bool StringShape::IsSymbol() {
292 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000293 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000294 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000295}
296
297
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000298bool String::IsOneByteRepresentation() {
ager@chromium.org5ec48922009-05-05 07:25:34 +0000299 uint32_t type = map()->instance_type();
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000300 return (type & kStringEncodingMask) == kOneByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000301}
302
303
ager@chromium.org5ec48922009-05-05 07:25:34 +0000304bool String::IsTwoByteRepresentation() {
305 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000306 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000307}
308
309
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000310bool String::IsOneByteRepresentationUnderneath() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000311 uint32_t type = map()->instance_type();
312 STATIC_ASSERT(kIsIndirectStringTag != 0);
313 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
314 ASSERT(IsFlat());
315 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000316 case kOneByteStringTag:
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000317 return true;
318 case kTwoByteStringTag:
319 return false;
320 default: // Cons or sliced string. Need to go deeper.
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000321 return GetUnderlying()->IsOneByteRepresentation();
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000322 }
323}
324
325
326bool String::IsTwoByteRepresentationUnderneath() {
327 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 false;
334 case kTwoByteStringTag:
335 return true;
336 default: // Cons or sliced string. Need to go deeper.
337 return GetUnderlying()->IsTwoByteRepresentation();
338 }
339}
340
341
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000342bool String::HasOnlyAsciiChars() {
343 uint32_t type = map()->instance_type();
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000344#ifndef ENABLE_LATIN_1
345 return (type & kStringEncodingMask) == kOneByteStringTag ||
346 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
347#else
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000348 return (type & kAsciiDataHintMask) == kAsciiDataHintTag;
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000349#endif
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000350}
351
352
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000353bool String::IsOneByteConvertible() {
354 return HasOnlyAsciiChars() || IsOneByteRepresentation();
355}
356
357
ager@chromium.org870a0b62008-11-04 11:43:05 +0000358bool StringShape::IsCons() {
359 return (type_ & kStringRepresentationMask) == kConsStringTag;
360}
361
362
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000363bool StringShape::IsSliced() {
364 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
365}
366
367
368bool StringShape::IsIndirect() {
369 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
370}
371
372
ager@chromium.org870a0b62008-11-04 11:43:05 +0000373bool StringShape::IsExternal() {
374 return (type_ & kStringRepresentationMask) == kExternalStringTag;
375}
376
377
378bool StringShape::IsSequential() {
379 return (type_ & kStringRepresentationMask) == kSeqStringTag;
380}
381
382
383StringRepresentationTag StringShape::representation_tag() {
384 uint32_t tag = (type_ & kStringRepresentationMask);
385 return static_cast<StringRepresentationTag>(tag);
386}
387
388
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000389uint32_t StringShape::encoding_tag() {
390 return type_ & kStringEncodingMask;
391}
392
393
ager@chromium.org870a0b62008-11-04 11:43:05 +0000394uint32_t StringShape::full_representation_tag() {
395 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
396}
397
398
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000399STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
400 Internals::kFullStringRepresentationMask);
401
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000402STATIC_CHECK(static_cast<uint32_t>(kStringEncodingMask) ==
403 Internals::kStringEncodingMask);
404
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000405
ager@chromium.org870a0b62008-11-04 11:43:05 +0000406bool StringShape::IsSequentialAscii() {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000407 return full_representation_tag() == (kSeqStringTag | kOneByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000408}
409
410
411bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000412 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000413}
414
415
416bool StringShape::IsExternalAscii() {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000417 return full_representation_tag() == (kExternalStringTag | kOneByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000418}
419
420
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000421STATIC_CHECK((kExternalStringTag | kOneByteStringTag) ==
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000422 Internals::kExternalAsciiRepresentationTag);
423
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000424STATIC_CHECK(v8::String::ASCII_ENCODING == kOneByteStringTag);
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000425
426
ager@chromium.org870a0b62008-11-04 11:43:05 +0000427bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000428 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000429}
430
431
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000432STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
433 Internals::kExternalTwoByteRepresentationTag);
434
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000435STATIC_CHECK(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000436
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000437uc32 FlatStringReader::Get(int index) {
438 ASSERT(0 <= index && index <= length_);
439 if (is_ascii_) {
440 return static_cast<const byte*>(start_)[index];
441 } else {
442 return static_cast<const uc16*>(start_)[index];
443 }
444}
445
446
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000447bool Object::IsNumber() {
448 return IsSmi() || IsHeapNumber();
449}
450
451
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000452TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
453TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000454
455
456bool Object::IsFiller() {
457 if (!Object::IsHeapObject()) return false;
458 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
459 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
460}
461
462
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000463TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000464
465
ager@chromium.org3811b432009-10-28 14:53:37 +0000466bool Object::IsExternalArray() {
467 if (!Object::IsHeapObject())
468 return false;
469 InstanceType instance_type =
470 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000471 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
472 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000473}
474
475
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000476TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
477TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
478TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
479TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
480TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
481TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
482TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
483TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000484
485
lrn@chromium.org303ada72010-10-27 09:33:13 +0000486bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000487 return HAS_FAILURE_TAG(this);
488}
489
490
lrn@chromium.org303ada72010-10-27 09:33:13 +0000491bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000492 return HAS_FAILURE_TAG(this)
493 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
494}
495
496
lrn@chromium.org303ada72010-10-27 09:33:13 +0000497bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000498 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000499 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000500}
501
502
lrn@chromium.org303ada72010-10-27 09:33:13 +0000503bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000504 return this == Failure::Exception();
505}
506
507
lrn@chromium.org303ada72010-10-27 09:33:13 +0000508bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000509 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000510}
511
512
513Failure* Failure::cast(MaybeObject* obj) {
514 ASSERT(HAS_FAILURE_TAG(obj));
515 return reinterpret_cast<Failure*>(obj);
516}
517
518
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000519bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000520 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000521 return IsHeapObject() &&
522 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
523}
524
525
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000526bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000527 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
528 return IsHeapObject() &&
529 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000530}
531
532
533bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000534 if (!Object::IsHeapObject()) return false;
535 InstanceType type = HeapObject::cast(this)->map()->instance_type();
536 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000537}
538
539
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000540TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
541TYPE_CHECKER(JSSet, JS_SET_TYPE)
542TYPE_CHECKER(JSMap, JS_MAP_TYPE)
543TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
544TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
545TYPE_CHECKER(Map, MAP_TYPE)
546TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
547TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000548
549
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000550bool Object::IsDescriptorArray() {
551 return IsFixedArray();
552}
553
554
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000555bool Object::IsTransitionArray() {
556 return IsFixedArray();
557}
558
559
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000560bool Object::IsDeoptimizationInputData() {
561 // Must be a fixed array.
562 if (!IsFixedArray()) return false;
563
564 // There's no sure way to detect the difference between a fixed array and
565 // a deoptimization data array. Since this is used for asserts we can
566 // check that the length is zero or else the fixed size plus a multiple of
567 // the entry size.
568 int length = FixedArray::cast(this)->length();
569 if (length == 0) return true;
570
571 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
572 return length >= 0 &&
573 length % DeoptimizationInputData::kDeoptEntrySize == 0;
574}
575
576
577bool Object::IsDeoptimizationOutputData() {
578 if (!IsFixedArray()) return false;
579 // There's actually no way to see the difference between a fixed array and
580 // a deoptimization data array. Since this is used for asserts we can check
581 // that the length is plausible though.
582 if (FixedArray::cast(this)->length() % 2 != 0) return false;
583 return true;
584}
585
586
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000587bool Object::IsDependentCodes() {
588 if (!IsFixedArray()) return false;
589 // There's actually no way to see the difference between a fixed array and
590 // a dependent codes array.
591 return true;
592}
593
594
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000595bool Object::IsTypeFeedbackCells() {
596 if (!IsFixedArray()) return false;
597 // There's actually no way to see the difference between a fixed array and
598 // a cache cells array. Since this is used for asserts we can check that
599 // the length is plausible though.
600 if (FixedArray::cast(this)->length() % 2 != 0) return false;
601 return true;
602}
603
604
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000605bool Object::IsContext() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000606 if (!Object::IsHeapObject()) return false;
607 Map* map = HeapObject::cast(this)->map();
608 Heap* heap = map->GetHeap();
609 return (map == heap->function_context_map() ||
610 map == heap->catch_context_map() ||
611 map == heap->with_context_map() ||
612 map == heap->native_context_map() ||
613 map == heap->block_context_map() ||
614 map == heap->module_context_map() ||
615 map == heap->global_context_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616}
617
618
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000619bool Object::IsNativeContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000620 return Object::IsHeapObject() &&
621 HeapObject::cast(this)->map() ==
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000622 HeapObject::cast(this)->GetHeap()->native_context_map();
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000623}
624
625
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000626bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000627 return Object::IsHeapObject() &&
628 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000629 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000630}
631
632
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000633TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000634
635
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000636template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000637 return obj->IsJSFunction();
638}
639
640
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000641TYPE_CHECKER(Code, CODE_TYPE)
642TYPE_CHECKER(Oddball, ODDBALL_TYPE)
643TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
644TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000645TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000646TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000647TYPE_CHECKER(JSDate, JS_DATE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000648TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000649
650
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000651bool Object::IsStringWrapper() {
652 return IsJSValue() && JSValue::cast(this)->value()->IsString();
653}
654
655
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000656TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000657
658
659bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000660 return IsOddball() &&
661 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000662}
663
664
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000665TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
666TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000667
668
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000669template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000670 return obj->IsJSArray();
671}
672
673
674bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000675 return Object::IsHeapObject() &&
676 HeapObject::cast(this)->map() ==
677 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000678}
679
680
681bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000682 return IsHashTable() &&
683 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000684}
685
686
687bool Object::IsSymbolTable() {
danno@chromium.org72204d52012-10-31 10:02:10 +0000688 return IsHashTable() &&
689 this == HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000690}
691
692
ager@chromium.orgac091b72010-05-05 07:34:42 +0000693bool Object::IsJSFunctionResultCache() {
694 if (!IsFixedArray()) return false;
695 FixedArray* self = FixedArray::cast(this);
696 int length = self->length();
697 if (length < JSFunctionResultCache::kEntriesIndex) return false;
698 if ((length - JSFunctionResultCache::kEntriesIndex)
699 % JSFunctionResultCache::kEntrySize != 0) {
700 return false;
701 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +0000702#ifdef VERIFY_HEAP
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000703 if (FLAG_verify_heap) {
704 reinterpret_cast<JSFunctionResultCache*>(this)->
705 JSFunctionResultCacheVerify();
706 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000707#endif
708 return true;
709}
710
711
ricow@chromium.org65fae842010-08-25 15:26:24 +0000712bool Object::IsNormalizedMapCache() {
713 if (!IsFixedArray()) return false;
714 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
715 return false;
716 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +0000717#ifdef VERIFY_HEAP
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000718 if (FLAG_verify_heap) {
719 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
720 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000721#endif
722 return true;
723}
724
725
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000726bool Object::IsCompilationCacheTable() {
727 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000728}
729
730
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000731bool Object::IsCodeCacheHashTable() {
732 return IsHashTable();
733}
734
735
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000736bool Object::IsPolymorphicCodeCacheHashTable() {
737 return IsHashTable();
738}
739
740
ager@chromium.org236ad962008-09-25 09:45:57 +0000741bool Object::IsMapCache() {
742 return IsHashTable();
743}
744
745
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000746bool Object::IsObjectHashTable() {
747 return IsHashTable();
748}
749
750
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000751bool Object::IsPrimitive() {
752 return IsOddball() || IsNumber() || IsString();
753}
754
755
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000756bool Object::IsJSGlobalProxy() {
757 bool result = IsHeapObject() &&
758 (HeapObject::cast(this)->map()->instance_type() ==
759 JS_GLOBAL_PROXY_TYPE);
760 ASSERT(!result || IsAccessCheckNeeded());
761 return result;
762}
763
764
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000765bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000766 if (!IsHeapObject()) return false;
767
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000768 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000769 return type == JS_GLOBAL_OBJECT_TYPE ||
770 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000771}
772
773
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000774TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
775TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000776
777
778bool Object::IsUndetectableObject() {
779 return IsHeapObject()
780 && HeapObject::cast(this)->map()->is_undetectable();
781}
782
783
784bool Object::IsAccessCheckNeeded() {
785 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000786 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787}
788
789
790bool Object::IsStruct() {
791 if (!IsHeapObject()) return false;
792 switch (HeapObject::cast(this)->map()->instance_type()) {
793#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
794 STRUCT_LIST(MAKE_STRUCT_CASE)
795#undef MAKE_STRUCT_CASE
796 default: return false;
797 }
798}
799
800
801#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
802 bool Object::Is##Name() { \
803 return Object::IsHeapObject() \
804 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
805 }
806 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
807#undef MAKE_STRUCT_PREDICATE
808
809
810bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000811 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000812}
813
814
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000815bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000816 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
817}
818
819
820bool Object::IsTheHole() {
821 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000822}
823
824
825bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000826 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000827}
828
829
830bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000831 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000832}
833
834
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000835bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000836 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000837}
838
839
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000840double Object::Number() {
841 ASSERT(IsNumber());
842 return IsSmi()
843 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
844 : reinterpret_cast<HeapNumber*>(this)->value();
845}
846
847
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000848bool Object::IsNaN() {
849 return this->IsHeapNumber() && isnan(HeapNumber::cast(this)->value());
850}
851
852
lrn@chromium.org303ada72010-10-27 09:33:13 +0000853MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000854 if (IsSmi()) return this;
855 if (IsHeapNumber()) {
856 double value = HeapNumber::cast(this)->value();
857 int int_value = FastD2I(value);
858 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
859 return Smi::FromInt(int_value);
860 }
861 }
862 return Failure::Exception();
863}
864
865
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000866bool Object::HasSpecificClassOf(String* name) {
867 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
868}
869
870
lrn@chromium.org303ada72010-10-27 09:33:13 +0000871MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000872 // GetElement can trigger a getter which can cause allocation.
873 // This was not always the case. This ASSERT is here to catch
874 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000875 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000876 return GetElementWithReceiver(this, index);
877}
878
879
lrn@chromium.org303ada72010-10-27 09:33:13 +0000880Object* Object::GetElementNoExceptionThrown(uint32_t index) {
881 MaybeObject* maybe = GetElementWithReceiver(this, index);
882 ASSERT(!maybe->IsFailure());
883 Object* result = NULL; // Initialization to please compiler.
884 maybe->ToObject(&result);
885 return result;
886}
887
888
889MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000890 PropertyAttributes attributes;
891 return GetPropertyWithReceiver(this, key, &attributes);
892}
893
894
lrn@chromium.org303ada72010-10-27 09:33:13 +0000895MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000896 return GetPropertyWithReceiver(this, key, attributes);
897}
898
899
900#define FIELD_ADDR(p, offset) \
901 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
902
903#define READ_FIELD(p, offset) \
904 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
905
906#define WRITE_FIELD(p, offset, value) \
907 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
908
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000909#define WRITE_BARRIER(heap, object, offset, value) \
910 heap->incremental_marking()->RecordWrite( \
911 object, HeapObject::RawField(object, offset), value); \
912 if (heap->InNewSpace(value)) { \
913 heap->RecordWrite(object->address(), offset); \
914 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000915
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000916#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
917 if (mode == UPDATE_WRITE_BARRIER) { \
918 heap->incremental_marking()->RecordWrite( \
919 object, HeapObject::RawField(object, offset), value); \
920 if (heap->InNewSpace(value)) { \
921 heap->RecordWrite(object->address(), offset); \
922 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000923 }
924
lrn@chromium.org7516f052011-03-30 08:52:27 +0000925#ifndef V8_TARGET_ARCH_MIPS
926 #define READ_DOUBLE_FIELD(p, offset) \
927 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
928#else // V8_TARGET_ARCH_MIPS
929 // Prevent gcc from using load-double (mips ldc1) on (possibly)
930 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000931 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000932 union conversion {
933 double d;
934 uint32_t u[2];
935 } c;
936 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
937 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
938 return c.d;
939 }
940 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
941#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000942
lrn@chromium.org7516f052011-03-30 08:52:27 +0000943#ifndef V8_TARGET_ARCH_MIPS
944 #define WRITE_DOUBLE_FIELD(p, offset, value) \
945 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
946#else // V8_TARGET_ARCH_MIPS
947 // Prevent gcc from using store-double (mips sdc1) on (possibly)
948 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000949 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000950 double value) {
951 union conversion {
952 double d;
953 uint32_t u[2];
954 } c;
955 c.d = value;
956 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
957 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
958 }
959 #define WRITE_DOUBLE_FIELD(p, offset, value) \
960 write_double_field(p, offset, value)
961#endif // V8_TARGET_ARCH_MIPS
962
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000963
964#define READ_INT_FIELD(p, offset) \
965 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
966
967#define WRITE_INT_FIELD(p, offset, value) \
968 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
969
ager@chromium.org3e875802009-06-29 08:26:34 +0000970#define READ_INTPTR_FIELD(p, offset) \
971 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
972
973#define WRITE_INTPTR_FIELD(p, offset, value) \
974 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
975
ager@chromium.org7c537e22008-10-16 08:43:32 +0000976#define READ_UINT32_FIELD(p, offset) \
977 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
978
979#define WRITE_UINT32_FIELD(p, offset, value) \
980 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
981
danno@chromium.org88aa0582012-03-23 15:11:57 +0000982#define READ_INT64_FIELD(p, offset) \
983 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
984
985#define WRITE_INT64_FIELD(p, offset, value) \
986 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
987
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000988#define READ_SHORT_FIELD(p, offset) \
989 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
990
991#define WRITE_SHORT_FIELD(p, offset, value) \
992 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
993
994#define READ_BYTE_FIELD(p, offset) \
995 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
996
997#define WRITE_BYTE_FIELD(p, offset, value) \
998 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
999
1000
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00001001Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
1002 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001003}
1004
1005
1006int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00001007 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001008}
1009
1010
1011Smi* Smi::FromInt(int value) {
1012 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001013 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +00001014 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001015 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +00001016 return reinterpret_cast<Smi*>(tagged_value);
1017}
1018
1019
1020Smi* Smi::FromIntptr(intptr_t value) {
1021 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001022 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1023 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001024}
1025
1026
1027Failure::Type Failure::type() const {
1028 return static_cast<Type>(value() & kFailureTypeTagMask);
1029}
1030
1031
1032bool Failure::IsInternalError() const {
1033 return type() == INTERNAL_ERROR;
1034}
1035
1036
1037bool Failure::IsOutOfMemoryException() const {
1038 return type() == OUT_OF_MEMORY_EXCEPTION;
1039}
1040
1041
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001042AllocationSpace Failure::allocation_space() const {
1043 ASSERT_EQ(RETRY_AFTER_GC, type());
1044 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1045 & kSpaceTagMask);
1046}
1047
1048
1049Failure* Failure::InternalError() {
1050 return Construct(INTERNAL_ERROR);
1051}
1052
1053
1054Failure* Failure::Exception() {
1055 return Construct(EXCEPTION);
1056}
1057
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001058
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00001059Failure* Failure::OutOfMemoryException(intptr_t value) {
1060 return Construct(OUT_OF_MEMORY_EXCEPTION, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001061}
1062
1063
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001064intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001065 return static_cast<intptr_t>(
1066 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001067}
1068
1069
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001070Failure* Failure::RetryAfterGC() {
1071 return RetryAfterGC(NEW_SPACE);
1072}
1073
1074
1075Failure* Failure::RetryAfterGC(AllocationSpace space) {
1076 ASSERT((space & ~kSpaceTagMask) == 0);
1077 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001078}
1079
1080
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001081Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001082 uintptr_t info =
1083 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001084 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +00001085 // Fill the unused bits with a pattern that's easy to recognize in crash
1086 // dumps.
1087 static const int kFailureMagicPattern = 0x0BAD0000;
1088 return reinterpret_cast<Failure*>(
1089 (info << kFailureTagSize) | kFailureTag | kFailureMagicPattern);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001090}
1091
1092
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001093bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001094#ifdef DEBUG
1095 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1096#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001097
1098#ifdef V8_TARGET_ARCH_X64
1099 // To be representable as a long smi, the value must be a 32-bit integer.
1100 bool result = (value == static_cast<int32_t>(value));
1101#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001102 // To be representable as an tagged small integer, the two
1103 // most-significant bits of 'value' must be either 00 or 11 due to
1104 // sign-extension. To check this we add 01 to the two
1105 // most-significant bits, and check if the most-significant bit is 0
1106 //
1107 // CAUTION: The original code below:
1108 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1109 // may lead to incorrect results according to the C language spec, and
1110 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1111 // compiler may produce undefined results in case of signed integer
1112 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001113 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001114#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001115 ASSERT(result == in_range);
1116 return result;
1117}
1118
1119
kasper.lund7276f142008-07-30 08:49:36 +00001120MapWord MapWord::FromMap(Map* map) {
1121 return MapWord(reinterpret_cast<uintptr_t>(map));
1122}
1123
1124
1125Map* MapWord::ToMap() {
1126 return reinterpret_cast<Map*>(value_);
1127}
1128
1129
1130bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001131 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001132}
1133
1134
1135MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001136 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1137 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001138}
1139
1140
1141HeapObject* MapWord::ToForwardingAddress() {
1142 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001143 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001144}
1145
1146
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001147#ifdef VERIFY_HEAP
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001148void HeapObject::VerifyObjectField(int offset) {
1149 VerifyPointer(READ_FIELD(this, offset));
1150}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001151
1152void HeapObject::VerifySmiField(int offset) {
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001153 CHECK(READ_FIELD(this, offset)->IsSmi());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001154}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001155#endif
1156
1157
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001158Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001159 Heap* heap =
1160 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1161 ASSERT(heap != NULL);
1162 ASSERT(heap->isolate() == Isolate::Current());
1163 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001164}
1165
1166
1167Isolate* HeapObject::GetIsolate() {
1168 return GetHeap()->isolate();
1169}
1170
1171
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001172Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001173 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001174}
1175
1176
1177void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001178 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001179 if (value != NULL) {
1180 // TODO(1600) We are passing NULL as a slot because maps can never be on
1181 // evacuation candidate.
1182 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1183 }
1184}
1185
1186
1187// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001188void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001189 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001190}
1191
1192
kasper.lund7276f142008-07-30 08:49:36 +00001193MapWord HeapObject::map_word() {
1194 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1195}
1196
1197
1198void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001199 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001200 // here.
1201 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1202}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001203
1204
1205HeapObject* HeapObject::FromAddress(Address address) {
1206 ASSERT_TAG_ALIGNED(address);
1207 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1208}
1209
1210
1211Address HeapObject::address() {
1212 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1213}
1214
1215
1216int HeapObject::Size() {
1217 return SizeFromMap(map());
1218}
1219
1220
1221void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1222 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1223 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1224}
1225
1226
1227void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1228 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1229}
1230
1231
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001232double HeapNumber::value() {
1233 return READ_DOUBLE_FIELD(this, kValueOffset);
1234}
1235
1236
1237void HeapNumber::set_value(double value) {
1238 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1239}
1240
1241
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001242int HeapNumber::get_exponent() {
1243 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1244 kExponentShift) - kExponentBias;
1245}
1246
1247
1248int HeapNumber::get_sign() {
1249 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1250}
1251
1252
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001253ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001254
1255
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001256Object** FixedArray::GetFirstElementAddress() {
1257 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1258}
1259
1260
1261bool FixedArray::ContainsOnlySmisOrHoles() {
1262 Object* the_hole = GetHeap()->the_hole_value();
1263 Object** current = GetFirstElementAddress();
1264 for (int i = 0; i < length(); ++i) {
1265 Object* candidate = *current++;
1266 if (!candidate->IsSmi() && candidate != the_hole) return false;
1267 }
1268 return true;
1269}
1270
1271
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001272FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001273 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001274 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001275}
1276
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001277
1278void JSObject::ValidateElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001279#if DEBUG
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001280 if (FLAG_enable_slow_asserts) {
1281 ElementsAccessor* accessor = GetElementsAccessor();
1282 accessor->Validate(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001283 }
1284#endif
1285}
1286
1287
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001288MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001289 ValidateElements();
1290 ElementsKind elements_kind = map()->elements_kind();
1291 if (!IsFastObjectElementsKind(elements_kind)) {
1292 if (IsFastHoleyElementsKind(elements_kind)) {
1293 return TransitionElementsKind(FAST_HOLEY_ELEMENTS);
1294 } else {
1295 return TransitionElementsKind(FAST_ELEMENTS);
1296 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001297 }
1298 return this;
1299}
1300
1301
1302MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001303 uint32_t count,
1304 EnsureElementsMode mode) {
1305 ElementsKind current_kind = map()->elements_kind();
1306 ElementsKind target_kind = current_kind;
1307 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001308 bool is_holey = IsFastHoleyElementsKind(current_kind);
1309 if (current_kind == FAST_HOLEY_ELEMENTS) return this;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001310 Heap* heap = GetHeap();
1311 Object* the_hole = heap->the_hole_value();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001312 for (uint32_t i = 0; i < count; ++i) {
1313 Object* current = *objects++;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001314 if (current == the_hole) {
1315 is_holey = true;
1316 target_kind = GetHoleyElementsKind(target_kind);
1317 } else if (!current->IsSmi()) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001318 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && current->IsNumber()) {
1319 if (IsFastSmiElementsKind(target_kind)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001320 if (is_holey) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001321 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001322 } else {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001323 target_kind = FAST_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001324 }
1325 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001326 } else if (is_holey) {
1327 target_kind = FAST_HOLEY_ELEMENTS;
1328 break;
1329 } else {
1330 target_kind = FAST_ELEMENTS;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001331 }
1332 }
1333 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001334
1335 if (target_kind != current_kind) {
1336 return TransitionElementsKind(target_kind);
1337 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001338 return this;
1339}
1340
1341
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001342MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001343 uint32_t length,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001344 EnsureElementsMode mode) {
1345 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1346 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1347 elements->map() == GetHeap()->fixed_cow_array_map());
1348 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1349 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1350 }
1351 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001352 return EnsureCanContainElements(objects, length, mode);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001353 }
1354
1355 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001356 if (GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) {
1357 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1358 } else if (GetElementsKind() == FAST_SMI_ELEMENTS) {
1359 FixedDoubleArray* double_array = FixedDoubleArray::cast(elements);
1360 for (uint32_t i = 0; i < length; ++i) {
1361 if (double_array->is_the_hole(i)) {
1362 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1363 }
1364 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001365 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1366 }
1367
1368 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001369}
1370
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001371
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001372MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1373 ElementsKind to_kind) {
1374 Map* current_map = map();
1375 ElementsKind from_kind = current_map->elements_kind();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001376 if (from_kind == to_kind) return current_map;
1377
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001378 Context* native_context = isolate->context()->native_context();
1379 Object* maybe_array_maps = native_context->js_array_maps();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001380 if (maybe_array_maps->IsFixedArray()) {
1381 FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
1382 if (array_maps->get(from_kind) == current_map) {
1383 Object* maybe_transitioned_map = array_maps->get(to_kind);
1384 if (maybe_transitioned_map->IsMap()) {
1385 return Map::cast(maybe_transitioned_map);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001386 }
1387 }
1388 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001389
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001390 return GetElementsTransitionMapSlow(to_kind);
1391}
1392
1393
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001394void JSObject::set_map_and_elements(Map* new_map,
1395 FixedArrayBase* value,
1396 WriteBarrierMode mode) {
1397 ASSERT(value->HasValidElements());
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001398 if (new_map != NULL) {
1399 if (mode == UPDATE_WRITE_BARRIER) {
1400 set_map(new_map);
1401 } else {
1402 ASSERT(mode == SKIP_WRITE_BARRIER);
1403 set_map_no_write_barrier(new_map);
1404 }
1405 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001406 ASSERT((map()->has_fast_smi_or_object_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001407 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001408 (value->map() == GetHeap()->fixed_array_map() ||
1409 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001410 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1411 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001412 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001413 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001414}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001415
1416
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001417void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1418 set_map_and_elements(NULL, value, mode);
1419}
1420
1421
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001422void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001423 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1424 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001425}
1426
1427
1428void JSObject::initialize_elements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001429 ASSERT(map()->has_fast_smi_or_object_elements() ||
danno@chromium.org2c26cb12012-05-03 09:06:43 +00001430 map()->has_fast_double_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001431 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1432 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001433}
1434
1435
lrn@chromium.org303ada72010-10-27 09:33:13 +00001436MaybeObject* JSObject::ResetElements() {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001437 if (map()->is_observed()) {
1438 // Maintain invariant that observed elements are always in dictionary mode.
1439 SeededNumberDictionary* dictionary;
1440 MaybeObject* maybe = SeededNumberDictionary::Allocate(0);
1441 if (!maybe->To(&dictionary)) return maybe;
1442 if (map() == GetHeap()->non_strict_arguments_elements_map()) {
1443 FixedArray::cast(elements())->set(1, dictionary);
1444 } else {
1445 set_elements(dictionary);
1446 }
1447 return this;
1448 }
1449
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001450 ElementsKind elements_kind = GetInitialFastElementsKind();
1451 if (!FLAG_smi_only_arrays) {
1452 elements_kind = FastSmiToObjectElementsKind(elements_kind);
1453 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001454 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind);
1455 Map* map;
1456 if (!maybe->To(&map)) return maybe;
1457 set_map(map);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001458 initialize_elements();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001459
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001460 return this;
1461}
1462
1463
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00001464MaybeObject* JSObject::AddFastPropertyUsingMap(Map* map) {
1465 ASSERT(this->map()->NumberOfOwnDescriptors() + 1 ==
1466 map->NumberOfOwnDescriptors());
1467 if (this->map()->unused_property_fields() == 0) {
1468 int new_size = properties()->length() + map->unused_property_fields() + 1;
1469 FixedArray* new_properties;
1470 MaybeObject* maybe_properties = properties()->CopySize(new_size);
1471 if (!maybe_properties->To(&new_properties)) return maybe_properties;
1472 set_properties(new_properties);
1473 }
1474 set_map(map);
1475 return this;
1476}
1477
1478
1479bool JSObject::TryTransitionToField(Handle<JSObject> object,
1480 Handle<String> key) {
1481 if (!object->map()->HasTransitionArray()) return false;
1482 Handle<TransitionArray> transitions(object->map()->transitions());
1483 int transition = transitions->Search(*key);
1484 if (transition == TransitionArray::kNotFound) return false;
1485 PropertyDetails target_details = transitions->GetTargetDetails(transition);
1486 if (target_details.type() != FIELD) return false;
1487 if (target_details.attributes() != NONE) return false;
1488 Handle<Map> target(transitions->GetTarget(transition));
1489 JSObject::AddFastPropertyUsingMap(object, target);
1490 return true;
1491}
1492
1493
1494int JSObject::LastAddedFieldIndex() {
1495 Map* map = this->map();
1496 int last_added = map->LastAdded();
1497 return map->instance_descriptors()->GetFieldIndex(last_added);
1498}
1499
1500
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001501ACCESSORS(Oddball, to_string, String, kToStringOffset)
1502ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1503
1504
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001505byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001506 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001507}
1508
1509
1510void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001511 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001512}
1513
1514
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001515Object* JSGlobalPropertyCell::value() {
1516 return READ_FIELD(this, kValueOffset);
1517}
1518
1519
1520void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1521 // The write barrier is not used for global property cells.
1522 ASSERT(!val->IsJSGlobalPropertyCell());
1523 WRITE_FIELD(this, kValueOffset, val);
1524}
1525
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001526
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001527int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001528 InstanceType type = map()->instance_type();
1529 // Check for the most common kind of JavaScript object before
1530 // falling into the generic switch. This speeds up the internal
1531 // field operations considerably on average.
1532 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1533 switch (type) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001534 case JS_MODULE_TYPE:
1535 return JSModule::kSize;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001536 case JS_GLOBAL_PROXY_TYPE:
1537 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001538 case JS_GLOBAL_OBJECT_TYPE:
1539 return JSGlobalObject::kSize;
1540 case JS_BUILTINS_OBJECT_TYPE:
1541 return JSBuiltinsObject::kSize;
1542 case JS_FUNCTION_TYPE:
1543 return JSFunction::kSize;
1544 case JS_VALUE_TYPE:
1545 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001546 case JS_DATE_TYPE:
1547 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001548 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001549 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001550 case JS_WEAK_MAP_TYPE:
1551 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001552 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001553 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001554 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001555 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001556 case JS_MESSAGE_OBJECT_TYPE:
1557 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001558 default:
1559 UNREACHABLE();
1560 return 0;
1561 }
1562}
1563
1564
1565int JSObject::GetInternalFieldCount() {
1566 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001567 // Make sure to adjust for the number of in-object properties. These
1568 // properties do contribute to the size, but are not internal fields.
1569 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1570 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001571}
1572
1573
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001574int JSObject::GetInternalFieldOffset(int index) {
1575 ASSERT(index < GetInternalFieldCount() && index >= 0);
1576 return GetHeaderSize() + (kPointerSize * index);
1577}
1578
1579
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001580Object* JSObject::GetInternalField(int index) {
1581 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001582 // Internal objects do follow immediately after the header, whereas in-object
1583 // properties are at the end of the object. Therefore there is no need
1584 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001585 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1586}
1587
1588
1589void JSObject::SetInternalField(int index, Object* value) {
1590 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001591 // Internal objects do follow immediately after the header, whereas in-object
1592 // properties are at the end of the object. Therefore there is no need
1593 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001594 int offset = GetHeaderSize() + (kPointerSize * index);
1595 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001596 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001597}
1598
1599
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001600void JSObject::SetInternalField(int index, Smi* value) {
1601 ASSERT(index < GetInternalFieldCount() && index >= 0);
1602 // Internal objects do follow immediately after the header, whereas in-object
1603 // properties are at the end of the object. Therefore there is no need
1604 // to adjust the index here.
1605 int offset = GetHeaderSize() + (kPointerSize * index);
1606 WRITE_FIELD(this, offset, value);
1607}
1608
1609
ager@chromium.org7c537e22008-10-16 08:43:32 +00001610// Access fast-case object properties at index. The use of these routines
1611// is needed to correctly distinguish between properties stored in-object and
1612// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001613Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001614 // Adjust for the number of properties stored in the object.
1615 index -= map()->inobject_properties();
1616 if (index < 0) {
1617 int offset = map()->instance_size() + (index * kPointerSize);
1618 return READ_FIELD(this, offset);
1619 } else {
1620 ASSERT(index < properties()->length());
1621 return properties()->get(index);
1622 }
1623}
1624
1625
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001626Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001627 // Adjust for the number of properties stored in the object.
1628 index -= map()->inobject_properties();
1629 if (index < 0) {
1630 int offset = map()->instance_size() + (index * kPointerSize);
1631 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001632 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001633 } else {
1634 ASSERT(index < properties()->length());
1635 properties()->set(index, value);
1636 }
1637 return value;
1638}
1639
1640
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001641int JSObject::GetInObjectPropertyOffset(int index) {
1642 // Adjust for the number of properties stored in the object.
1643 index -= map()->inobject_properties();
1644 ASSERT(index < 0);
1645 return map()->instance_size() + (index * kPointerSize);
1646}
1647
1648
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001649Object* JSObject::InObjectPropertyAt(int index) {
1650 // Adjust for the number of properties stored in the object.
1651 index -= map()->inobject_properties();
1652 ASSERT(index < 0);
1653 int offset = map()->instance_size() + (index * kPointerSize);
1654 return READ_FIELD(this, offset);
1655}
1656
1657
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001658Object* JSObject::InObjectPropertyAtPut(int index,
1659 Object* value,
1660 WriteBarrierMode mode) {
1661 // Adjust for the number of properties stored in the object.
1662 index -= map()->inobject_properties();
1663 ASSERT(index < 0);
1664 int offset = map()->instance_size() + (index * kPointerSize);
1665 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001666 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001667 return value;
1668}
1669
1670
1671
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001672void JSObject::InitializeBody(Map* map,
1673 Object* pre_allocated_value,
1674 Object* filler_value) {
1675 ASSERT(!filler_value->IsHeapObject() ||
1676 !GetHeap()->InNewSpace(filler_value));
1677 ASSERT(!pre_allocated_value->IsHeapObject() ||
1678 !GetHeap()->InNewSpace(pre_allocated_value));
1679 int size = map->instance_size();
1680 int offset = kHeaderSize;
1681 if (filler_value != pre_allocated_value) {
1682 int pre_allocated = map->pre_allocated_property_fields();
1683 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1684 for (int i = 0; i < pre_allocated; i++) {
1685 WRITE_FIELD(this, offset, pre_allocated_value);
1686 offset += kPointerSize;
1687 }
1688 }
1689 while (offset < size) {
1690 WRITE_FIELD(this, offset, filler_value);
1691 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001692 }
1693}
1694
1695
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001696bool JSObject::HasFastProperties() {
erik.corry@gmail.com88767242012-08-08 14:43:45 +00001697 ASSERT(properties()->IsDictionary() == map()->is_dictionary_map());
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001698 return !properties()->IsDictionary();
1699}
1700
1701
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001702bool JSObject::TooManyFastProperties(int properties,
1703 JSObject::StoreFromKeyed store_mode) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001704 // Allow extra fast properties if the object has more than
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001705 // kFastPropertiesSoftLimit in-object properties. When this is the case,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001706 // it is very unlikely that the object is being used as a dictionary
1707 // and there is a good chance that allowing more map transitions
1708 // will be worth it.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001709 int inobject = map()->inobject_properties();
1710
1711 int limit;
ulan@chromium.orgf6a0c412012-06-15 12:31:06 +00001712 if (store_mode == CERTAINLY_NOT_STORE_FROM_KEYED) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001713 limit = Max(inobject, kMaxFastProperties);
1714 } else {
1715 limit = Max(inobject, kFastPropertiesSoftLimit);
1716 }
1717 return properties > limit;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001718}
1719
1720
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001721void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001722 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001723 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001724 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001725 }
1726}
1727
1728
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001729bool Object::ToArrayIndex(uint32_t* index) {
1730 if (IsSmi()) {
1731 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001732 if (value < 0) return false;
1733 *index = value;
1734 return true;
1735 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001736 if (IsHeapNumber()) {
1737 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001738 uint32_t uint_value = static_cast<uint32_t>(value);
1739 if (value == static_cast<double>(uint_value)) {
1740 *index = uint_value;
1741 return true;
1742 }
1743 }
1744 return false;
1745}
1746
1747
1748bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1749 if (!this->IsJSValue()) return false;
1750
1751 JSValue* js_value = JSValue::cast(this);
1752 if (!js_value->value()->IsString()) return false;
1753
1754 String* str = String::cast(js_value->value());
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00001755 if (index >= static_cast<uint32_t>(str->length())) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001756
1757 return true;
1758}
1759
1760
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00001761
1762void Object::VerifyApiCallResultType() {
1763#if ENABLE_EXTRA_CHECKS
1764 if (!(IsSmi() ||
1765 IsString() ||
1766 IsSpecObject() ||
1767 IsHeapNumber() ||
1768 IsUndefined() ||
1769 IsTrue() ||
1770 IsFalse() ||
1771 IsNull())) {
1772 FATAL("API call returned invalid object");
1773 }
1774#endif // ENABLE_EXTRA_CHECKS
1775}
1776
1777
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001778FixedArrayBase* FixedArrayBase::cast(Object* object) {
1779 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1780 return reinterpret_cast<FixedArrayBase*>(object);
1781}
1782
1783
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001784Object* FixedArray::get(int index) {
1785 ASSERT(index >= 0 && index < this->length());
1786 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1787}
1788
1789
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001790bool FixedArray::is_the_hole(int index) {
1791 return get(index) == GetHeap()->the_hole_value();
1792}
1793
1794
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001795void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001796 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001797 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001798 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1799 int offset = kHeaderSize + index * kPointerSize;
1800 WRITE_FIELD(this, offset, value);
1801}
1802
1803
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001804void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001805 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001806 ASSERT(index >= 0 && index < this->length());
1807 int offset = kHeaderSize + index * kPointerSize;
1808 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001809 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001810}
1811
1812
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001813inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1814 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1815}
1816
1817
1818inline double FixedDoubleArray::hole_nan_as_double() {
1819 return BitCast<double, uint64_t>(kHoleNanInt64);
1820}
1821
1822
1823inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1824 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1825 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1826 return OS::nan_value();
1827}
1828
1829
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001830double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001831 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1832 map() != HEAP->fixed_array_map());
1833 ASSERT(index >= 0 && index < this->length());
1834 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1835 ASSERT(!is_the_hole_nan(result));
1836 return result;
1837}
1838
danno@chromium.org88aa0582012-03-23 15:11:57 +00001839int64_t FixedDoubleArray::get_representation(int index) {
1840 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1841 map() != HEAP->fixed_array_map());
1842 ASSERT(index >= 0 && index < this->length());
1843 return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1844}
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001845
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001846MaybeObject* FixedDoubleArray::get(int index) {
1847 if (is_the_hole(index)) {
1848 return GetHeap()->the_hole_value();
1849 } else {
1850 return GetHeap()->NumberFromDouble(get_scalar(index));
1851 }
1852}
1853
1854
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001855void FixedDoubleArray::set(int index, double value) {
1856 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1857 map() != HEAP->fixed_array_map());
1858 int offset = kHeaderSize + index * kDoubleSize;
1859 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1860 WRITE_DOUBLE_FIELD(this, offset, value);
1861}
1862
1863
1864void FixedDoubleArray::set_the_hole(int index) {
1865 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1866 map() != HEAP->fixed_array_map());
1867 int offset = kHeaderSize + index * kDoubleSize;
1868 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1869}
1870
1871
1872bool FixedDoubleArray::is_the_hole(int index) {
1873 int offset = kHeaderSize + index * kDoubleSize;
1874 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1875}
1876
1877
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001878WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001879 Heap* heap = GetHeap();
1880 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1881 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001882 return UPDATE_WRITE_BARRIER;
1883}
1884
1885
1886void FixedArray::set(int index,
1887 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001888 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001889 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001890 ASSERT(index >= 0 && index < this->length());
1891 int offset = kHeaderSize + index * kPointerSize;
1892 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001893 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001894}
1895
1896
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001897void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1898 int index,
1899 Object* value) {
danno@chromium.org72204d52012-10-31 10:02:10 +00001900 ASSERT(array->map() != HEAP->fixed_cow_array_map());
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001901 ASSERT(index >= 0 && index < array->length());
1902 int offset = kHeaderSize + index * kPointerSize;
1903 WRITE_FIELD(array, offset, value);
1904 Heap* heap = array->GetHeap();
1905 if (heap->InNewSpace(value)) {
1906 heap->RecordWrite(array->address(), offset);
1907 }
1908}
1909
1910
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001911void FixedArray::NoWriteBarrierSet(FixedArray* array,
1912 int index,
1913 Object* value) {
danno@chromium.org72204d52012-10-31 10:02:10 +00001914 ASSERT(array->map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001915 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001916 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001917 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1918}
1919
1920
1921void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001922 ASSERT(map() != HEAP->fixed_cow_array_map());
1923 set_undefined(GetHeap(), index);
1924}
1925
1926
1927void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001928 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001929 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001930 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001931 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001932}
1933
1934
ager@chromium.org236ad962008-09-25 09:45:57 +00001935void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001936 set_null(GetHeap(), index);
1937}
1938
1939
1940void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001941 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001942 ASSERT(!heap->InNewSpace(heap->null_value()));
1943 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001944}
1945
1946
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001947void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001948 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001949 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001950 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1951 WRITE_FIELD(this,
1952 kHeaderSize + index * kPointerSize,
1953 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001954}
1955
1956
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001957void FixedArray::set_unchecked(int index, Smi* value) {
1958 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1959 int offset = kHeaderSize + index * kPointerSize;
1960 WRITE_FIELD(this, offset, value);
1961}
1962
1963
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001964void FixedArray::set_unchecked(Heap* heap,
1965 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001966 Object* value,
1967 WriteBarrierMode mode) {
1968 int offset = kHeaderSize + index * kPointerSize;
1969 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001970 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001971}
1972
1973
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001974void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001975 ASSERT(index >= 0 && index < this->length());
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00001976 ASSERT(!heap->InNewSpace(heap->null_value()));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001977 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001978}
1979
1980
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001981double* FixedDoubleArray::data_start() {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00001982 return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001983}
1984
1985
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001986Object** FixedArray::data_start() {
1987 return HeapObject::RawField(this, kHeaderSize);
1988}
1989
1990
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001991bool DescriptorArray::IsEmpty() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001992 ASSERT(length() >= kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001993 this == HEAP->empty_descriptor_array());
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001994 return length() < kFirstIndex;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001995}
1996
1997
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00001998void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
1999 WRITE_FIELD(
2000 this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors));
2001}
2002
2003
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002004// Perform a binary search in a fixed array. Low and high are entry indices. If
2005// there are three entries in this array it should be called with low=0 and
2006// high=2.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002007template<SearchMode search_mode, typename T>
2008int BinarySearch(T* array, String* name, int low, int high, int valid_entries) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002009 uint32_t hash = name->Hash();
2010 int limit = high;
2011
2012 ASSERT(low <= high);
2013
2014 while (low != high) {
2015 int mid = (low + high) / 2;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002016 String* mid_name = array->GetSortedKey(mid);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002017 uint32_t mid_hash = mid_name->Hash();
2018
2019 if (mid_hash >= hash) {
2020 high = mid;
2021 } else {
2022 low = mid + 1;
2023 }
2024 }
2025
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002026 for (; low <= limit; ++low) {
2027 int sort_index = array->GetSortedKeyIndex(low);
2028 String* entry = array->GetKey(sort_index);
2029 if (entry->Hash() != hash) break;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002030 if (entry->Equals(name)) {
2031 if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
2032 return sort_index;
2033 }
2034 return T::kNotFound;
2035 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002036 }
2037
2038 return T::kNotFound;
2039}
2040
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002041
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002042// Perform a linear search in this fixed array. len is the number of entry
2043// indices that are valid.
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002044template<SearchMode search_mode, typename T>
2045int LinearSearch(T* array, String* name, int len, int valid_entries) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002046 uint32_t hash = name->Hash();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002047 if (search_mode == ALL_ENTRIES) {
2048 for (int number = 0; number < len; number++) {
2049 int sorted_index = array->GetSortedKeyIndex(number);
2050 String* entry = array->GetKey(sorted_index);
2051 uint32_t current_hash = entry->Hash();
2052 if (current_hash > hash) break;
2053 if (current_hash == hash && entry->Equals(name)) return sorted_index;
2054 }
2055 } else {
2056 ASSERT(len >= valid_entries);
2057 for (int number = 0; number < valid_entries; number++) {
2058 String* entry = array->GetKey(number);
2059 uint32_t current_hash = entry->Hash();
2060 if (current_hash == hash && entry->Equals(name)) return number;
2061 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002062 }
2063 return T::kNotFound;
2064}
2065
2066
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002067template<SearchMode search_mode, typename T>
2068int Search(T* array, String* name, int valid_entries) {
2069 if (search_mode == VALID_ENTRIES) {
2070 SLOW_ASSERT(array->IsSortedNoDuplicates(valid_entries));
2071 } else {
2072 SLOW_ASSERT(array->IsSortedNoDuplicates());
2073 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002074
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002075 int nof = array->number_of_entries();
2076 if (nof == 0) return T::kNotFound;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002077
2078 // Fast case: do linear search for small arrays.
2079 const int kMaxElementsForLinearSearch = 8;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002080 if ((search_mode == ALL_ENTRIES &&
2081 nof <= kMaxElementsForLinearSearch) ||
2082 (search_mode == VALID_ENTRIES &&
2083 valid_entries <= (kMaxElementsForLinearSearch * 3))) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002084 return LinearSearch<search_mode>(array, name, nof, valid_entries);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002085 }
2086
2087 // Slow case: perform binary search.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002088 return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002089}
2090
2091
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002092int DescriptorArray::Search(String* name, int valid_descriptors) {
2093 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002094}
2095
2096
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002097int DescriptorArray::SearchWithCache(String* name, Map* map) {
2098 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
2099 if (number_of_own_descriptors == 0) return kNotFound;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002100
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002101 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002102 int number = cache->Lookup(map, name);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002103
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002104 if (number == DescriptorLookupCache::kAbsent) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002105 number = Search(name, number_of_own_descriptors);
2106 cache->Update(map, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002107 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002108
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002109 return number;
2110}
2111
2112
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002113void Map::LookupDescriptor(JSObject* holder,
2114 String* name,
2115 LookupResult* result) {
2116 DescriptorArray* descriptors = this->instance_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002117 int number = descriptors->SearchWithCache(name, this);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002118 if (number == DescriptorArray::kNotFound) return result->NotFound();
2119 result->DescriptorResult(holder, descriptors->GetDetails(number), number);
2120}
2121
2122
2123void Map::LookupTransition(JSObject* holder,
2124 String* name,
2125 LookupResult* result) {
2126 if (HasTransitionArray()) {
2127 TransitionArray* transition_array = transitions();
2128 int number = transition_array->Search(name);
2129 if (number != TransitionArray::kNotFound) {
2130 return result->TransitionResult(holder, number);
2131 }
2132 }
2133 result->NotFound();
2134}
2135
2136
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002137Object** DescriptorArray::GetKeySlot(int descriptor_number) {
2138 ASSERT(descriptor_number < number_of_descriptors());
2139 return HeapObject::RawField(
2140 reinterpret_cast<HeapObject*>(this),
2141 OffsetOfElementAt(ToKeyIndex(descriptor_number)));
2142}
2143
2144
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00002145Object** DescriptorArray::GetDescriptorStartSlot(int descriptor_number) {
2146 return GetKeySlot(descriptor_number);
2147}
2148
2149
2150Object** DescriptorArray::GetDescriptorEndSlot(int descriptor_number) {
2151 return GetValueSlot(descriptor_number - 1) + 1;
2152}
2153
2154
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002155String* DescriptorArray::GetKey(int descriptor_number) {
2156 ASSERT(descriptor_number < number_of_descriptors());
2157 return String::cast(get(ToKeyIndex(descriptor_number)));
2158}
2159
2160
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002161int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
2162 return GetDetails(descriptor_number).pointer();
2163}
2164
2165
2166String* DescriptorArray::GetSortedKey(int descriptor_number) {
2167 return GetKey(GetSortedKeyIndex(descriptor_number));
2168}
2169
2170
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002171void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
2172 PropertyDetails details = GetDetails(descriptor_index);
2173 set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi());
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002174}
2175
2176
verwaest@chromium.org37141392012-05-31 13:27:02 +00002177Object** DescriptorArray::GetValueSlot(int descriptor_number) {
2178 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002179 return HeapObject::RawField(
2180 reinterpret_cast<HeapObject*>(this),
2181 OffsetOfElementAt(ToValueIndex(descriptor_number)));
verwaest@chromium.org37141392012-05-31 13:27:02 +00002182}
2183
2184
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002185Object* DescriptorArray::GetValue(int descriptor_number) {
2186 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002187 return get(ToValueIndex(descriptor_number));
2188}
2189
2190
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002191PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002192 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002193 Object* details = get(ToDetailsIndex(descriptor_number));
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002194 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002195}
2196
2197
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002198PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002199 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002200}
2201
2202
2203int DescriptorArray::GetFieldIndex(int descriptor_number) {
2204 return Descriptor::IndexFromValue(GetValue(descriptor_number));
2205}
2206
2207
2208JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
2209 return JSFunction::cast(GetValue(descriptor_number));
2210}
2211
2212
2213Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
2214 ASSERT(GetType(descriptor_number) == CALLBACKS);
2215 return GetValue(descriptor_number);
2216}
2217
2218
2219AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
2220 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002221 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002222 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002223}
2224
2225
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002226void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2227 desc->Init(GetKey(descriptor_number),
2228 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002229 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002230}
2231
2232
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002233void DescriptorArray::Set(int descriptor_number,
2234 Descriptor* desc,
2235 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002236 // Range check.
2237 ASSERT(descriptor_number < number_of_descriptors());
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002238 ASSERT(desc->GetDetails().descriptor_index() <=
2239 number_of_descriptors());
2240 ASSERT(desc->GetDetails().descriptor_index() > 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002241
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002242 NoIncrementalWriteBarrierSet(this,
2243 ToKeyIndex(descriptor_number),
2244 desc->GetKey());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002245 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002246 ToValueIndex(descriptor_number),
2247 desc->GetValue());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002248 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002249 ToDetailsIndex(descriptor_number),
2250 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002251}
2252
2253
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002254void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
2255 // Range check.
2256 ASSERT(descriptor_number < number_of_descriptors());
2257 ASSERT(desc->GetDetails().descriptor_index() <=
2258 number_of_descriptors());
2259 ASSERT(desc->GetDetails().descriptor_index() > 0);
2260
2261 set(ToKeyIndex(descriptor_number), desc->GetKey());
2262 set(ToValueIndex(descriptor_number), desc->GetValue());
2263 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
2264}
2265
2266
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002267void DescriptorArray::Append(Descriptor* desc,
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002268 const WhitenessWitness& witness) {
2269 int descriptor_number = number_of_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002270 int enumeration_index = descriptor_number + 1;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002271 SetNumberOfDescriptors(descriptor_number + 1);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002272 desc->SetEnumerationIndex(enumeration_index);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002273 Set(descriptor_number, desc, witness);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002274
2275 uint32_t hash = desc->GetKey()->Hash();
2276
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002277 int insertion;
2278
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002279 for (insertion = descriptor_number; insertion > 0; --insertion) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002280 String* key = GetSortedKey(insertion - 1);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002281 if (key->Hash() <= hash) break;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002282 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002283 }
2284
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002285 SetSortedKey(insertion, descriptor_number);
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002286}
2287
2288
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002289void DescriptorArray::Append(Descriptor* desc) {
2290 int descriptor_number = number_of_descriptors();
2291 int enumeration_index = descriptor_number + 1;
2292 SetNumberOfDescriptors(descriptor_number + 1);
2293 desc->SetEnumerationIndex(enumeration_index);
2294 Set(descriptor_number, desc);
2295
2296 uint32_t hash = desc->GetKey()->Hash();
2297
2298 int insertion;
2299
2300 for (insertion = descriptor_number; insertion > 0; --insertion) {
2301 String* key = GetSortedKey(insertion - 1);
2302 if (key->Hash() <= hash) break;
2303 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
2304 }
2305
2306 SetSortedKey(insertion, descriptor_number);
2307}
2308
2309
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002310void DescriptorArray::SwapSortedKeys(int first, int second) {
2311 int first_key = GetSortedKeyIndex(first);
2312 SetSortedKey(first, GetSortedKeyIndex(second));
2313 SetSortedKey(second, first_key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002314}
2315
2316
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002317DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002318 : marking_(array->GetHeap()->incremental_marking()) {
2319 marking_->EnterNoMarkingScope();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002320 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002321}
2322
2323
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002324DescriptorArray::WhitenessWitness::~WhitenessWitness() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002325 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002326}
2327
2328
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002329template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002330int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2331 const int kMinCapacity = 32;
2332 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2333 if (capacity < kMinCapacity) {
2334 capacity = kMinCapacity; // Guarantee min capacity.
2335 }
2336 return capacity;
2337}
2338
2339
2340template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002341int HashTable<Shape, Key>::FindEntry(Key key) {
2342 return FindEntry(GetIsolate(), key);
2343}
2344
2345
2346// Find entry for key otherwise return kNotFound.
2347template<typename Shape, typename Key>
2348int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2349 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002350 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002351 uint32_t count = 1;
2352 // EnsureCapacity will guarantee the hash table is never full.
2353 while (true) {
2354 Object* element = KeyAt(entry);
danno@chromium.org72204d52012-10-31 10:02:10 +00002355 // Empty entry. Uses raw unchecked accessors because it is called by the
2356 // symbol table during bootstrapping.
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002357 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2358 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002359 Shape::IsMatch(key, element)) return entry;
2360 entry = NextProbe(entry, count++, capacity);
2361 }
2362 return kNotFound;
2363}
2364
2365
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002366bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002367 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002368 if (!max_index_object->IsSmi()) return false;
2369 return 0 !=
2370 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2371}
2372
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002373uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002374 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002375 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002376 if (!max_index_object->IsSmi()) return 0;
2377 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2378 return value >> kRequiresSlowElementsTagSize;
2379}
2380
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002381void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002382 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002383}
2384
2385
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002386// ------------------------------------
2387// Cast operations
2388
2389
2390CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002391CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002392CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002393CAST_ACCESSOR(DeoptimizationInputData)
2394CAST_ACCESSOR(DeoptimizationOutputData)
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002395CAST_ACCESSOR(DependentCodes)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002396CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002397CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002398CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002399CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002400CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002401CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002402CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002403CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002404CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002405CAST_ACCESSOR(String)
2406CAST_ACCESSOR(SeqString)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002407CAST_ACCESSOR(SeqOneByteString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002408CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002409CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002410CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002411CAST_ACCESSOR(ExternalString)
2412CAST_ACCESSOR(ExternalAsciiString)
2413CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002414CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002415CAST_ACCESSOR(JSObject)
2416CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002417CAST_ACCESSOR(HeapObject)
2418CAST_ACCESSOR(HeapNumber)
2419CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002420CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002421CAST_ACCESSOR(SharedFunctionInfo)
2422CAST_ACCESSOR(Map)
2423CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002424CAST_ACCESSOR(GlobalObject)
2425CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002426CAST_ACCESSOR(JSGlobalObject)
2427CAST_ACCESSOR(JSBuiltinsObject)
2428CAST_ACCESSOR(Code)
2429CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002430CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002431CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002432CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002433CAST_ACCESSOR(JSSet)
2434CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002435CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002436CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002437CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002438CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002439CAST_ACCESSOR(ExternalArray)
2440CAST_ACCESSOR(ExternalByteArray)
2441CAST_ACCESSOR(ExternalUnsignedByteArray)
2442CAST_ACCESSOR(ExternalShortArray)
2443CAST_ACCESSOR(ExternalUnsignedShortArray)
2444CAST_ACCESSOR(ExternalIntArray)
2445CAST_ACCESSOR(ExternalUnsignedIntArray)
2446CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002447CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002448CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002449CAST_ACCESSOR(Struct)
2450
2451
2452#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2453 STRUCT_LIST(MAKE_STRUCT_CAST)
2454#undef MAKE_STRUCT_CAST
2455
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002456
2457template <typename Shape, typename Key>
2458HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002459 ASSERT(obj->IsHashTable());
2460 return reinterpret_cast<HashTable*>(obj);
2461}
2462
2463
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002464SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002465SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002466
ager@chromium.orgac091b72010-05-05 07:34:42 +00002467SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002468
2469
2470uint32_t String::hash_field() {
2471 return READ_UINT32_FIELD(this, kHashFieldOffset);
2472}
2473
2474
2475void String::set_hash_field(uint32_t value) {
2476 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002477#if V8_HOST_ARCH_64_BIT
2478 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2479#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002480}
2481
2482
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002483bool String::Equals(String* other) {
2484 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002485 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2486 return false;
2487 }
2488 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002489}
2490
2491
lrn@chromium.org303ada72010-10-27 09:33:13 +00002492MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002493 if (!StringShape(this).IsCons()) return this;
2494 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002495 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002496 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002497}
2498
2499
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002500String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002501 MaybeObject* flat = TryFlatten(pretenure);
2502 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002503 if (!flat->ToObject(&successfully_flattened)) return this;
2504 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002505}
2506
2507
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002508uint16_t String::Get(int index) {
2509 ASSERT(index >= 0 && index < length());
2510 switch (StringShape(this).full_representation_tag()) {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002511 case kSeqStringTag | kOneByteStringTag:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002512 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002513 case kSeqStringTag | kTwoByteStringTag:
2514 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002515 case kConsStringTag | kOneByteStringTag:
ager@chromium.org870a0b62008-11-04 11:43:05 +00002516 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002517 return ConsString::cast(this)->ConsStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002518 case kExternalStringTag | kOneByteStringTag:
ager@chromium.org870a0b62008-11-04 11:43:05 +00002519 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2520 case kExternalStringTag | kTwoByteStringTag:
2521 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002522 case kSlicedStringTag | kOneByteStringTag:
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002523 case kSlicedStringTag | kTwoByteStringTag:
2524 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002525 default:
2526 break;
2527 }
2528
2529 UNREACHABLE();
2530 return 0;
2531}
2532
2533
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002534void String::Set(int index, uint16_t value) {
2535 ASSERT(index >= 0 && index < length());
2536 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002537
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00002538 return this->IsOneByteRepresentation()
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002539 ? SeqOneByteString::cast(this)->SeqOneByteStringSet(index, value)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002540 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002541}
2542
2543
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002544bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002545 if (!StringShape(this).IsCons()) return true;
2546 return ConsString::cast(this)->second()->length() == 0;
2547}
2548
2549
2550String* String::GetUnderlying() {
2551 // Giving direct access to underlying string only makes sense if the
2552 // wrapping string is already flattened.
2553 ASSERT(this->IsFlat());
2554 ASSERT(StringShape(this).IsIndirect());
2555 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2556 const int kUnderlyingOffset = SlicedString::kParentOffset;
2557 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002558}
2559
2560
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002561template<class Visitor, class ConsOp>
2562void String::Visit(
2563 String* string,
2564 unsigned offset,
2565 Visitor& visitor,
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002566 ConsOp& cons_op,
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002567 int32_t type,
2568 unsigned length) {
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002569 ASSERT(length == static_cast<unsigned>(string->length()));
2570 ASSERT(offset <= length);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002571 unsigned slice_offset = offset;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002572 while (true) {
2573 ASSERT(type == string->map()->instance_type());
2574
2575 switch (type & (kStringRepresentationMask | kStringEncodingMask)) {
2576 case kSeqStringTag | kOneByteStringTag:
2577 visitor.VisitOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002578 SeqOneByteString::cast(string)->GetChars() + slice_offset,
2579 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002580 return;
2581
2582 case kSeqStringTag | kTwoByteStringTag:
2583 visitor.VisitTwoByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002584 SeqTwoByteString::cast(string)->GetChars() + slice_offset,
2585 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002586 return;
2587
2588 case kExternalStringTag | kOneByteStringTag:
2589 visitor.VisitOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002590 ExternalAsciiString::cast(string)->GetChars() + slice_offset,
2591 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002592 return;
2593
2594 case kExternalStringTag | kTwoByteStringTag:
2595 visitor.VisitTwoByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002596 ExternalTwoByteString::cast(string)->GetChars() + slice_offset,
2597 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002598 return;
2599
2600 case kSlicedStringTag | kOneByteStringTag:
2601 case kSlicedStringTag | kTwoByteStringTag: {
2602 SlicedString* slicedString = SlicedString::cast(string);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002603 slice_offset += slicedString->offset();
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002604 string = slicedString->parent();
2605 type = string->map()->instance_type();
2606 continue;
2607 }
2608
2609 case kConsStringTag | kOneByteStringTag:
2610 case kConsStringTag | kTwoByteStringTag:
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002611 string = cons_op.Operate(string, &offset, &type, &length);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002612 if (string == NULL) return;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002613 slice_offset = offset;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002614 ASSERT(length == static_cast<unsigned>(string->length()));
2615 continue;
2616
2617 default:
2618 UNREACHABLE();
2619 return;
2620 }
2621 }
2622}
2623
2624
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002625uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002626 ASSERT(index >= 0 && index < length());
2627 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2628}
2629
2630
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002631void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002632 ASSERT(index >= 0 && index < length() && value <= kMaxOneByteCharCode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002633 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2634 static_cast<byte>(value));
2635}
2636
2637
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002638Address SeqOneByteString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002639 return FIELD_ADDR(this, kHeaderSize);
2640}
2641
2642
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002643uint8_t* SeqOneByteString::GetChars() {
2644 return reinterpret_cast<uint8_t*>(GetCharsAddress());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002645}
2646
2647
ager@chromium.org7c537e22008-10-16 08:43:32 +00002648Address SeqTwoByteString::GetCharsAddress() {
2649 return FIELD_ADDR(this, kHeaderSize);
2650}
2651
2652
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002653uc16* SeqTwoByteString::GetChars() {
2654 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2655}
2656
2657
ager@chromium.org7c537e22008-10-16 08:43:32 +00002658uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002659 ASSERT(index >= 0 && index < length());
2660 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2661}
2662
2663
ager@chromium.org7c537e22008-10-16 08:43:32 +00002664void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002665 ASSERT(index >= 0 && index < length());
2666 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2667}
2668
2669
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002670int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002671 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002672}
2673
2674
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002675int SeqOneByteString::SeqOneByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002676 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002677}
2678
2679
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002680String* SlicedString::parent() {
2681 return String::cast(READ_FIELD(this, kParentOffset));
2682}
2683
2684
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002685void SlicedString::set_parent(String* parent, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002686 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002687 WRITE_FIELD(this, kParentOffset, parent);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002688 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kParentOffset, parent, mode);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002689}
2690
2691
2692SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2693
2694
ager@chromium.org870a0b62008-11-04 11:43:05 +00002695String* ConsString::first() {
2696 return String::cast(READ_FIELD(this, kFirstOffset));
2697}
2698
2699
2700Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002701 return READ_FIELD(this, kFirstOffset);
2702}
2703
2704
ager@chromium.org870a0b62008-11-04 11:43:05 +00002705void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002706 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002707 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002708}
2709
2710
ager@chromium.org870a0b62008-11-04 11:43:05 +00002711String* ConsString::second() {
2712 return String::cast(READ_FIELD(this, kSecondOffset));
2713}
2714
2715
2716Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002717 return READ_FIELD(this, kSecondOffset);
2718}
2719
2720
ager@chromium.org870a0b62008-11-04 11:43:05 +00002721void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002722 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002723 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002724}
2725
2726
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002727bool ExternalString::is_short() {
2728 InstanceType type = map()->instance_type();
2729 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002730}
2731
2732
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002733const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002734 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2735}
2736
2737
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002738void ExternalAsciiString::update_data_cache() {
2739 if (is_short()) return;
2740 const char** data_field =
2741 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2742 *data_field = resource()->data();
2743}
2744
2745
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002746void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002747 const ExternalAsciiString::Resource* resource) {
2748 *reinterpret_cast<const Resource**>(
2749 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002750 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002751}
2752
2753
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002754const uint8_t* ExternalAsciiString::GetChars() {
2755 return reinterpret_cast<const uint8_t*>(resource()->data());
erikcorry0ad885c2011-11-21 13:51:57 +00002756}
2757
2758
2759uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2760 ASSERT(index >= 0 && index < length());
2761 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002762}
2763
2764
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002765const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002766 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2767}
2768
2769
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002770void ExternalTwoByteString::update_data_cache() {
2771 if (is_short()) return;
2772 const uint16_t** data_field =
2773 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2774 *data_field = resource()->data();
2775}
2776
2777
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002778void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002779 const ExternalTwoByteString::Resource* resource) {
2780 *reinterpret_cast<const Resource**>(
2781 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002782 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002783}
2784
2785
2786const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002787 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002788}
2789
2790
2791uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2792 ASSERT(index >= 0 && index < length());
2793 return GetChars()[index];
2794}
2795
2796
2797const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2798 unsigned start) {
2799 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002800}
2801
2802
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002803String* ConsStringNullOp::Operate(String*, unsigned*, int32_t*, unsigned*) {
2804 return NULL;
2805}
2806
2807
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002808unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) {
2809 return depth & kDepthMask;
2810}
2811
2812
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002813void ConsStringIteratorOp::PushLeft(ConsString* string) {
2814 frames_[depth_++ & kDepthMask] = string;
2815}
2816
2817
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002818void ConsStringIteratorOp::PushRight(ConsString* string) {
2819 // Inplace update.
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002820 frames_[(depth_-1) & kDepthMask] = string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002821}
2822
2823
2824void ConsStringIteratorOp::AdjustMaximumDepth() {
2825 if (depth_ > maximum_depth_) maximum_depth_ = depth_;
2826}
2827
2828
2829void ConsStringIteratorOp::Pop() {
2830 ASSERT(depth_ > 0);
2831 ASSERT(depth_ <= maximum_depth_);
2832 depth_--;
2833}
2834
2835
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002836bool ConsStringIteratorOp::HasMore() {
2837 return depth_ != 0;
2838}
2839
2840
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002841void ConsStringIteratorOp::Reset() {
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002842 depth_ = 0;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002843}
2844
2845
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002846String* ConsStringIteratorOp::ContinueOperation(int32_t* type_out,
2847 unsigned* length_out) {
2848 bool blew_stack = false;
2849 String* string = NextLeaf(&blew_stack, type_out, length_out);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002850 // String found.
2851 if (string != NULL) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002852 // Verify output.
2853 ASSERT(*length_out == static_cast<unsigned>(string->length()));
2854 ASSERT(*type_out == string->map()->instance_type());
2855 return string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002856 }
2857 // Traversal complete.
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002858 if (!blew_stack) return NULL;
2859 // Restart search from root.
2860 unsigned offset_out;
2861 string = Search(&offset_out, type_out, length_out);
2862 // Verify output.
2863 ASSERT(string == NULL || offset_out == 0);
2864 ASSERT(string == NULL ||
2865 *length_out == static_cast<unsigned>(string->length()));
2866 ASSERT(string == NULL || *type_out == string->map()->instance_type());
2867 return string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002868}
2869
2870
2871uint16_t StringCharacterStream::GetNext() {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002872 ASSERT(buffer8_ != NULL && end_ != NULL);
2873 // Advance cursor if needed.
2874 // TODO(dcarney): Ensure uses of the api call HasMore first and avoid this.
2875 if (buffer8_ == end_) HasMore();
2876 ASSERT(buffer8_ < end_);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002877 return is_one_byte_ ? *buffer8_++ : *buffer16_++;
2878}
2879
2880
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002881StringCharacterStream::StringCharacterStream(String* string,
2882 ConsStringIteratorOp* op,
2883 unsigned offset)
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002884 : is_one_byte_(false),
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002885 op_(op) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002886 Reset(string, offset);
2887}
2888
2889
2890void StringCharacterStream::Reset(String* string, unsigned offset) {
2891 op_->Reset();
2892 buffer8_ = NULL;
2893 end_ = NULL;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002894 int32_t type = string->map()->instance_type();
2895 unsigned length = string->length();
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00002896 String::Visit(string, offset, *this, *op_, type, length);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002897}
2898
2899
2900bool StringCharacterStream::HasMore() {
2901 if (buffer8_ != end_) return true;
2902 if (!op_->HasMore()) return false;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002903 unsigned length;
2904 int32_t type;
2905 String* string = op_->ContinueOperation(&type, &length);
2906 if (string == NULL) return false;
2907 ASSERT(!string->IsConsString());
2908 ASSERT(string->length() != 0);
2909 ConsStringNullOp null_op;
2910 String::Visit(string, 0, *this, null_op, type, length);
2911 ASSERT(buffer8_ != end_);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002912 return true;
2913}
2914
2915
2916void StringCharacterStream::VisitOneByteString(
2917 const uint8_t* chars, unsigned length) {
2918 is_one_byte_ = true;
2919 buffer8_ = chars;
2920 end_ = chars + length;
2921}
2922
2923
2924void StringCharacterStream::VisitTwoByteString(
2925 const uint16_t* chars, unsigned length) {
2926 is_one_byte_ = false;
2927 buffer16_ = chars;
2928 end_ = reinterpret_cast<const uint8_t*>(chars + length);
2929}
2930
2931
ager@chromium.orgac091b72010-05-05 07:34:42 +00002932void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002933 set_finger_index(kEntriesIndex);
2934 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002935}
2936
2937
2938void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002939 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002940 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002941 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002942 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002943 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002944 MakeZeroSize();
2945}
2946
2947
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002948int JSFunctionResultCache::size() {
2949 return Smi::cast(get(kCacheSizeIndex))->value();
2950}
2951
2952
2953void JSFunctionResultCache::set_size(int size) {
2954 set(kCacheSizeIndex, Smi::FromInt(size));
2955}
2956
2957
2958int JSFunctionResultCache::finger_index() {
2959 return Smi::cast(get(kFingerIndex))->value();
2960}
2961
2962
2963void JSFunctionResultCache::set_finger_index(int finger_index) {
2964 set(kFingerIndex, Smi::FromInt(finger_index));
2965}
2966
2967
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002968byte ByteArray::get(int index) {
2969 ASSERT(index >= 0 && index < this->length());
2970 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2971}
2972
2973
2974void ByteArray::set(int index, byte value) {
2975 ASSERT(index >= 0 && index < this->length());
2976 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2977}
2978
2979
2980int ByteArray::get_int(int index) {
2981 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2982 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2983}
2984
2985
2986ByteArray* ByteArray::FromDataStartAddress(Address address) {
2987 ASSERT_TAG_ALIGNED(address);
2988 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2989}
2990
2991
2992Address ByteArray::GetDataStartAddress() {
2993 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2994}
2995
2996
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002997uint8_t* ExternalPixelArray::external_pixel_pointer() {
2998 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002999}
3000
3001
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003002uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003003 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003004 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003005 return ptr[index];
3006}
3007
3008
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003009MaybeObject* ExternalPixelArray::get(int index) {
3010 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3011}
3012
3013
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003014void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003015 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003016 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003017 ptr[index] = value;
3018}
3019
3020
ager@chromium.org3811b432009-10-28 14:53:37 +00003021void* ExternalArray::external_pointer() {
3022 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
3023 return reinterpret_cast<void*>(ptr);
3024}
3025
3026
3027void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
3028 intptr_t ptr = reinterpret_cast<intptr_t>(value);
3029 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
3030}
3031
3032
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003033int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003034 ASSERT((index >= 0) && (index < this->length()));
3035 int8_t* ptr = static_cast<int8_t*>(external_pointer());
3036 return ptr[index];
3037}
3038
3039
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003040MaybeObject* ExternalByteArray::get(int index) {
3041 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3042}
3043
3044
ager@chromium.org3811b432009-10-28 14:53:37 +00003045void ExternalByteArray::set(int index, int8_t value) {
3046 ASSERT((index >= 0) && (index < this->length()));
3047 int8_t* ptr = static_cast<int8_t*>(external_pointer());
3048 ptr[index] = value;
3049}
3050
3051
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003052uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003053 ASSERT((index >= 0) && (index < this->length()));
3054 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
3055 return ptr[index];
3056}
3057
3058
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003059MaybeObject* ExternalUnsignedByteArray::get(int index) {
3060 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3061}
3062
3063
ager@chromium.org3811b432009-10-28 14:53:37 +00003064void ExternalUnsignedByteArray::set(int index, uint8_t value) {
3065 ASSERT((index >= 0) && (index < this->length()));
3066 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
3067 ptr[index] = value;
3068}
3069
3070
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003071int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003072 ASSERT((index >= 0) && (index < this->length()));
3073 int16_t* ptr = static_cast<int16_t*>(external_pointer());
3074 return ptr[index];
3075}
3076
3077
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003078MaybeObject* ExternalShortArray::get(int index) {
3079 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3080}
3081
3082
ager@chromium.org3811b432009-10-28 14:53:37 +00003083void ExternalShortArray::set(int index, int16_t value) {
3084 ASSERT((index >= 0) && (index < this->length()));
3085 int16_t* ptr = static_cast<int16_t*>(external_pointer());
3086 ptr[index] = value;
3087}
3088
3089
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003090uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003091 ASSERT((index >= 0) && (index < this->length()));
3092 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
3093 return ptr[index];
3094}
3095
3096
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003097MaybeObject* ExternalUnsignedShortArray::get(int index) {
3098 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3099}
3100
3101
ager@chromium.org3811b432009-10-28 14:53:37 +00003102void ExternalUnsignedShortArray::set(int index, uint16_t value) {
3103 ASSERT((index >= 0) && (index < this->length()));
3104 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
3105 ptr[index] = value;
3106}
3107
3108
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003109int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003110 ASSERT((index >= 0) && (index < this->length()));
3111 int32_t* ptr = static_cast<int32_t*>(external_pointer());
3112 return ptr[index];
3113}
3114
3115
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003116MaybeObject* ExternalIntArray::get(int index) {
3117 return GetHeap()->NumberFromInt32(get_scalar(index));
3118}
3119
3120
ager@chromium.org3811b432009-10-28 14:53:37 +00003121void ExternalIntArray::set(int index, int32_t value) {
3122 ASSERT((index >= 0) && (index < this->length()));
3123 int32_t* ptr = static_cast<int32_t*>(external_pointer());
3124 ptr[index] = value;
3125}
3126
3127
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003128uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003129 ASSERT((index >= 0) && (index < this->length()));
3130 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
3131 return ptr[index];
3132}
3133
3134
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003135MaybeObject* ExternalUnsignedIntArray::get(int index) {
3136 return GetHeap()->NumberFromUint32(get_scalar(index));
3137}
3138
3139
ager@chromium.org3811b432009-10-28 14:53:37 +00003140void ExternalUnsignedIntArray::set(int index, uint32_t value) {
3141 ASSERT((index >= 0) && (index < this->length()));
3142 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
3143 ptr[index] = value;
3144}
3145
3146
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003147float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003148 ASSERT((index >= 0) && (index < this->length()));
3149 float* ptr = static_cast<float*>(external_pointer());
3150 return ptr[index];
3151}
3152
3153
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003154MaybeObject* ExternalFloatArray::get(int index) {
3155 return GetHeap()->NumberFromDouble(get_scalar(index));
3156}
3157
3158
ager@chromium.org3811b432009-10-28 14:53:37 +00003159void ExternalFloatArray::set(int index, float value) {
3160 ASSERT((index >= 0) && (index < this->length()));
3161 float* ptr = static_cast<float*>(external_pointer());
3162 ptr[index] = value;
3163}
3164
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00003165
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003166double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003167 ASSERT((index >= 0) && (index < this->length()));
3168 double* ptr = static_cast<double*>(external_pointer());
3169 return ptr[index];
3170}
3171
3172
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003173MaybeObject* ExternalDoubleArray::get(int index) {
3174 return GetHeap()->NumberFromDouble(get_scalar(index));
3175}
3176
3177
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003178void ExternalDoubleArray::set(int index, double value) {
3179 ASSERT((index >= 0) && (index < this->length()));
3180 double* ptr = static_cast<double*>(external_pointer());
3181 ptr[index] = value;
3182}
3183
3184
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00003185int Map::visitor_id() {
3186 return READ_BYTE_FIELD(this, kVisitorIdOffset);
3187}
3188
3189
3190void Map::set_visitor_id(int id) {
3191 ASSERT(0 <= id && id < 256);
3192 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
3193}
3194
ager@chromium.org3811b432009-10-28 14:53:37 +00003195
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003196int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00003197 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
3198}
3199
3200
3201int Map::inobject_properties() {
3202 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003203}
3204
3205
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003206int Map::pre_allocated_property_fields() {
3207 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
3208}
3209
3210
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003211int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003212 int instance_size = map->instance_size();
3213 if (instance_size != kVariableSizeSentinel) return instance_size;
3214 // We can ignore the "symbol" bit becase it is only set for symbols
3215 // and implies a string type.
3216 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003217 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003218 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003219 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003220 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003221 if (instance_type == ASCII_STRING_TYPE) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003222 return SeqOneByteString::SizeFor(
3223 reinterpret_cast<SeqOneByteString*>(this)->length());
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003224 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003225 if (instance_type == BYTE_ARRAY_TYPE) {
3226 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
3227 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003228 if (instance_type == FREE_SPACE_TYPE) {
3229 return reinterpret_cast<FreeSpace*>(this)->size();
3230 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003231 if (instance_type == STRING_TYPE) {
3232 return SeqTwoByteString::SizeFor(
3233 reinterpret_cast<SeqTwoByteString*>(this)->length());
3234 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003235 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
3236 return FixedDoubleArray::SizeFor(
3237 reinterpret_cast<FixedDoubleArray*>(this)->length());
3238 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003239 ASSERT(instance_type == CODE_TYPE);
3240 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003241}
3242
3243
3244void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003245 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003246 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003247 ASSERT(0 <= value && value < 256);
3248 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
3249}
3250
3251
ager@chromium.org7c537e22008-10-16 08:43:32 +00003252void Map::set_inobject_properties(int value) {
3253 ASSERT(0 <= value && value < 256);
3254 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
3255}
3256
3257
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003258void Map::set_pre_allocated_property_fields(int value) {
3259 ASSERT(0 <= value && value < 256);
3260 WRITE_BYTE_FIELD(this,
3261 kPreAllocatedPropertyFieldsOffset,
3262 static_cast<byte>(value));
3263}
3264
3265
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003266InstanceType Map::instance_type() {
3267 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
3268}
3269
3270
3271void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003272 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
3273}
3274
3275
3276int Map::unused_property_fields() {
3277 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
3278}
3279
3280
3281void Map::set_unused_property_fields(int value) {
3282 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
3283}
3284
3285
3286byte Map::bit_field() {
3287 return READ_BYTE_FIELD(this, kBitFieldOffset);
3288}
3289
3290
3291void Map::set_bit_field(byte value) {
3292 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
3293}
3294
3295
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00003296byte Map::bit_field2() {
3297 return READ_BYTE_FIELD(this, kBitField2Offset);
3298}
3299
3300
3301void Map::set_bit_field2(byte value) {
3302 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
3303}
3304
3305
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003306void Map::set_non_instance_prototype(bool value) {
3307 if (value) {
3308 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
3309 } else {
3310 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
3311 }
3312}
3313
3314
3315bool Map::has_non_instance_prototype() {
3316 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
3317}
3318
3319
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003320void Map::set_function_with_prototype(bool value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003321 set_bit_field3(FunctionWithPrototype::update(bit_field3(), value));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003322}
3323
3324
3325bool Map::function_with_prototype() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003326 return FunctionWithPrototype::decode(bit_field3());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003327}
3328
3329
ager@chromium.org870a0b62008-11-04 11:43:05 +00003330void Map::set_is_access_check_needed(bool access_check_needed) {
3331 if (access_check_needed) {
3332 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
3333 } else {
3334 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
3335 }
3336}
3337
3338
3339bool Map::is_access_check_needed() {
3340 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
3341}
3342
3343
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003344void Map::set_is_extensible(bool value) {
3345 if (value) {
3346 set_bit_field2(bit_field2() | (1 << kIsExtensible));
3347 } else {
3348 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
3349 }
3350}
3351
3352bool Map::is_extensible() {
3353 return ((1 << kIsExtensible) & bit_field2()) != 0;
3354}
3355
3356
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003357void Map::set_attached_to_shared_function_info(bool value) {
3358 if (value) {
3359 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
3360 } else {
3361 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
3362 }
3363}
3364
3365bool Map::attached_to_shared_function_info() {
3366 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
3367}
3368
3369
3370void Map::set_is_shared(bool value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003371 set_bit_field3(IsShared::update(bit_field3(), value));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003372}
3373
erik.corry@gmail.com88767242012-08-08 14:43:45 +00003374
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003375bool Map::is_shared() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003376 return IsShared::decode(bit_field3());
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003377}
3378
3379
erik.corry@gmail.com88767242012-08-08 14:43:45 +00003380void Map::set_dictionary_map(bool value) {
3381 set_bit_field3(DictionaryMap::update(bit_field3(), value));
3382}
3383
3384
3385bool Map::is_dictionary_map() {
3386 return DictionaryMap::decode(bit_field3());
3387}
3388
3389
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003390JSFunction* Map::unchecked_constructor() {
3391 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
3392}
3393
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003394
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003395Code::Flags Code::flags() {
3396 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
3397}
3398
3399
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00003400inline bool Map::CanTrackAllocationSite() {
3401 return instance_type() == JS_ARRAY_TYPE;
3402}
3403
3404
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00003405void Map::set_owns_descriptors(bool is_shared) {
3406 set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
3407}
3408
3409
3410bool Map::owns_descriptors() {
3411 return OwnsDescriptors::decode(bit_field3());
3412}
3413
3414
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00003415void Map::set_is_observed(bool is_observed) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003416 ASSERT(instance_type() < FIRST_JS_OBJECT_TYPE ||
3417 instance_type() > LAST_JS_OBJECT_TYPE ||
3418 has_slow_elements_kind() || has_external_array_elements());
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00003419 set_bit_field3(IsObserved::update(bit_field3(), is_observed));
3420}
3421
3422
3423bool Map::is_observed() {
3424 return IsObserved::decode(bit_field3());
3425}
3426
3427
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003428void Map::AddDependentCode(Handle<Code> code) {
3429 Handle<DependentCodes> codes =
3430 DependentCodes::Append(Handle<DependentCodes>(dependent_codes()), code);
3431 if (*codes != dependent_codes()) {
3432 set_dependent_codes(*codes);
3433 }
3434}
3435
3436
3437int DependentCodes::number_of_codes() {
3438 if (length() == 0) return 0;
3439 return Smi::cast(get(kNumberOfCodesIndex))->value();
3440}
3441
3442
3443void DependentCodes::set_number_of_codes(int value) {
3444 set(kNumberOfCodesIndex, Smi::FromInt(value));
3445}
3446
3447
3448Code* DependentCodes::code_at(int i) {
3449 return Code::cast(get(kCodesIndex + i));
3450}
3451
3452
3453void DependentCodes::set_code_at(int i, Code* value) {
3454 set(kCodesIndex + i, value);
3455}
3456
3457
3458Object** DependentCodes::code_slot_at(int i) {
3459 return HeapObject::RawField(
3460 this, FixedArray::OffsetOfElementAt(kCodesIndex + i));
3461}
3462
3463
3464void DependentCodes::clear_code_at(int i) {
3465 set_undefined(kCodesIndex + i);
3466}
3467
3468
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003469void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003470 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003471 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003472 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
3473 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003474 ExtractArgumentsCountFromFlags(flags) >= 0);
3475 WRITE_INT_FIELD(this, kFlagsOffset, flags);
3476}
3477
3478
3479Code::Kind Code::kind() {
3480 return ExtractKindFromFlags(flags());
3481}
3482
3483
kasper.lund7276f142008-07-30 08:49:36 +00003484InlineCacheState Code::ic_state() {
3485 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003486 // Only allow uninitialized or debugger states for non-IC code
3487 // objects. This is used in the debugger to determine whether or not
3488 // a call to code object has been replaced with a debug break call.
3489 ASSERT(is_inline_cache_stub() ||
3490 result == UNINITIALIZED ||
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003491 result == DEBUG_STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003492 return result;
3493}
3494
3495
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003496Code::ExtraICState Code::extra_ic_state() {
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003497 ASSERT(is_inline_cache_stub() || ic_state() == DEBUG_STUB);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003498 return ExtractExtraICStateFromFlags(flags());
3499}
3500
3501
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003502Code::StubType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003503 return ExtractTypeFromFlags(flags());
3504}
3505
3506
3507int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003508 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003509 return ExtractArgumentsCountFromFlags(flags());
3510}
3511
3512
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003513int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003514 ASSERT(kind() == STUB ||
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003515 kind() == COMPILED_STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003516 kind() == UNARY_OP_IC ||
3517 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003518 kind() == COMPARE_IC ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00003519 kind() == LOAD_IC ||
3520 kind() == KEYED_LOAD_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003521 kind() == TO_BOOLEAN_IC);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003522 return StubMajorKeyField::decode(
3523 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasper.lund7276f142008-07-30 08:49:36 +00003524}
3525
3526
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003527void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003528 ASSERT(kind() == STUB ||
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003529 kind() == COMPILED_STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003530 kind() == UNARY_OP_IC ||
3531 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003532 kind() == COMPARE_IC ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00003533 kind() == LOAD_IC ||
3534 kind() == KEYED_LOAD_IC ||
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00003535 kind() == STORE_IC ||
3536 kind() == KEYED_STORE_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003537 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003538 ASSERT(0 <= major && major < 256);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003539 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3540 int updated = StubMajorKeyField::update(previous, major);
3541 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003542}
3543
3544
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003545bool Code::is_pregenerated() {
3546 return kind() == STUB && IsPregeneratedField::decode(flags());
3547}
3548
3549
3550void Code::set_is_pregenerated(bool value) {
3551 ASSERT(kind() == STUB);
3552 Flags f = flags();
3553 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3554 set_flags(f);
3555}
3556
3557
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003558bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003559 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003560 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3561}
3562
3563
3564void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003565 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003566 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3567}
3568
3569
3570bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003571 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003572 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3573 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003574}
3575
3576
3577void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003578 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003579 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3580 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3581 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3582}
3583
3584
3585bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003586 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003587 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3588 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3589}
3590
3591
3592void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003593 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003594 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3595 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3596 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003597}
3598
3599
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003600bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003601 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003602 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3603 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3604}
3605
3606
3607void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003608 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003609 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3610 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3611 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3612}
3613
3614
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003615int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003616 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003617 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3618}
3619
3620
3621void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003622 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003623 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3624 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3625}
3626
3627
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003628int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003629 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003630 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3631}
3632
3633
3634void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003635 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003636 ASSERT(ticks < 256);
3637 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3638}
3639
3640
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003641unsigned Code::stack_slots() {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003642 ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003643 return StackSlotsField::decode(
3644 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003645}
3646
3647
3648void Code::set_stack_slots(unsigned slots) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003649 CHECK(slots <= (1 << kStackSlotsBitCount));
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003650 ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003651 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3652 int updated = StackSlotsField::update(previous, slots);
3653 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003654}
3655
3656
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003657unsigned Code::safepoint_table_offset() {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003658 ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003659 return SafepointTableOffsetField::decode(
3660 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003661}
3662
3663
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003664void Code::set_safepoint_table_offset(unsigned offset) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003665 CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003666 ASSERT(kind() == OPTIMIZED_FUNCTION || kind() == COMPILED_STUB);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003667 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003668 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3669 int updated = SafepointTableOffsetField::update(previous, offset);
3670 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003671}
3672
3673
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003674unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003675 ASSERT_EQ(FUNCTION, kind());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003676 return StackCheckTableOffsetField::decode(
3677 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003678}
3679
3680
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003681void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003682 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003683 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003684 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3685 int updated = StackCheckTableOffsetField::update(previous, offset);
3686 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003687}
3688
3689
3690CheckType Code::check_type() {
3691 ASSERT(is_call_stub() || is_keyed_call_stub());
3692 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3693 return static_cast<CheckType>(type);
3694}
3695
3696
3697void Code::set_check_type(CheckType value) {
3698 ASSERT(is_call_stub() || is_keyed_call_stub());
3699 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3700}
3701
3702
danno@chromium.org40cb8782011-05-25 07:58:50 +00003703byte Code::unary_op_type() {
3704 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003705 return UnaryOpTypeField::decode(
3706 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003707}
3708
3709
danno@chromium.org40cb8782011-05-25 07:58:50 +00003710void Code::set_unary_op_type(byte value) {
3711 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003712 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3713 int updated = UnaryOpTypeField::update(previous, value);
3714 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003715}
3716
3717
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003718byte Code::to_boolean_state() {
3719 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003720 return ToBooleanStateField::decode(
3721 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003722}
3723
3724
3725void Code::set_to_boolean_state(byte value) {
3726 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003727 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3728 int updated = ToBooleanStateField::update(previous, value);
3729 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003730}
3731
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003732
3733bool Code::has_function_cache() {
3734 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003735 return HasFunctionCacheField::decode(
3736 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003737}
3738
3739
3740void Code::set_has_function_cache(bool flag) {
3741 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003742 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3743 int updated = HasFunctionCacheField::update(previous, flag);
3744 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003745}
3746
3747
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003748bool Code::marked_for_deoptimization() {
3749 ASSERT(kind() == OPTIMIZED_FUNCTION);
3750 return MarkedForDeoptimizationField::decode(
3751 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
3752}
3753
3754
3755void Code::set_marked_for_deoptimization(bool flag) {
3756 ASSERT(kind() == OPTIMIZED_FUNCTION);
3757 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3758 int updated = MarkedForDeoptimizationField::update(previous, flag);
3759 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
3760}
3761
3762
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003763bool Code::is_inline_cache_stub() {
3764 Kind kind = this->kind();
3765 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3766}
3767
3768
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003769bool Code::is_debug_break() {
3770 return ic_state() == DEBUG_STUB && extra_ic_state() == DEBUG_BREAK;
3771}
3772
3773
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003774Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003775 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003776 ExtraICState extra_ic_state,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003777 StubType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003778 int argc,
3779 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003780 // Extra IC state is only allowed for call IC stubs or for store IC
3781 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003782 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003783 kind == CALL_IC ||
3784 kind == STORE_IC ||
3785 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003786 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003787 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003788 | ICStateField::encode(ic_state)
3789 | TypeField::encode(type)
3790 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003791 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003792 | CacheHolderField::encode(holder);
3793 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003794}
3795
3796
3797Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003798 StubType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003799 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003800 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003801 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003802 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003803}
3804
3805
3806Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003807 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003808}
3809
3810
kasper.lund7276f142008-07-30 08:49:36 +00003811InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003812 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003813}
3814
3815
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003816Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003817 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003818}
3819
3820
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003821Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003822 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003823}
3824
3825
3826int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003827 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003828}
3829
3830
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003831InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003832 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003833}
3834
3835
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003836Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003837 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003838 return static_cast<Flags>(bits);
3839}
3840
3841
ager@chromium.org8bb60582008-12-11 12:02:20 +00003842Code* Code::GetCodeFromTargetAddress(Address address) {
3843 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3844 // GetCodeFromTargetAddress might be called when marking objects during mark
3845 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3846 // Code::cast. Code::cast does not work when the object's map is
3847 // marked.
3848 Code* result = reinterpret_cast<Code*>(code);
3849 return result;
3850}
3851
3852
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003853Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3854 return HeapObject::
3855 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3856}
3857
3858
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003859Object* Map::prototype() {
3860 return READ_FIELD(this, kPrototypeOffset);
3861}
3862
3863
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003864void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003865 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003866 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003867 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003868}
3869
3870
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003871// If the descriptor is using the empty transition array, install a new empty
3872// transition array that will have place for an element transition.
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003873static MaybeObject* EnsureHasTransitionArray(Map* map) {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003874 TransitionArray* transitions;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003875 MaybeObject* maybe_transitions;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003876 if (!map->HasTransitionArray()) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003877 maybe_transitions = TransitionArray::Allocate(0);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003878 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3879 transitions->set_back_pointer_storage(map->GetBackPointer());
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003880 } else if (!map->transitions()->IsFullTransitionArray()) {
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003881 maybe_transitions = map->transitions()->ExtendToFullTransitionArray();
3882 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3883 } else {
3884 return map;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003885 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003886 map->set_transitions(transitions);
3887 return transitions;
3888}
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003889
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003890
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003891void Map::InitializeDescriptors(DescriptorArray* descriptors) {
verwaest@chromium.org652f4fa2012-10-08 08:48:51 +00003892 int len = descriptors->number_of_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00003893#ifdef DEBUG
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003894 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003895
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003896 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors];
3897 for (int i = 0; i < len; ++i) used_indices[i] = false;
3898
3899 // Ensure that all enumeration indexes between 1 and length occur uniquely in
3900 // the descriptor array.
3901 for (int i = 0; i < len; ++i) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00003902 int enum_index = descriptors->GetDetails(i).descriptor_index() -
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003903 PropertyDetails::kInitialIndex;
3904 ASSERT(0 <= enum_index && enum_index < len);
3905 ASSERT(!used_indices[enum_index]);
3906 used_indices[enum_index] = true;
3907 }
3908#endif
3909
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003910 set_instance_descriptors(descriptors);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00003911 SetNumberOfOwnDescriptors(len);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003912}
3913
3914
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003915ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003916SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)
danno@chromium.org40cb8782011-05-25 07:58:50 +00003917
3918
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003919void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003920 Object* back_pointer = GetBackPointer();
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00003921
3922 if (Heap::ShouldZapGarbage() && HasTransitionArray()) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003923 ZapTransitions();
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003924 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00003925
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003926 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003927 CONDITIONAL_WRITE_BARRIER(
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003928 heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode);
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003929}
3930
3931
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003932void Map::AppendDescriptor(Descriptor* desc,
3933 const DescriptorArray::WhitenessWitness& witness) {
3934 DescriptorArray* descriptors = instance_descriptors();
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00003935 int number_of_own_descriptors = NumberOfOwnDescriptors();
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003936 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
3937 descriptors->Append(desc, witness);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00003938 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003939}
3940
danno@chromium.org40cb8782011-05-25 07:58:50 +00003941
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003942Object* Map::GetBackPointer() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003943 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003944 if (object->IsDescriptorArray()) {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003945 return TransitionArray::cast(object)->back_pointer_storage();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003946 } else {
3947 ASSERT(object->IsMap() || object->IsUndefined());
3948 return object;
3949 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003950}
3951
3952
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003953bool Map::HasElementsTransition() {
3954 return HasTransitionArray() && transitions()->HasElementsTransition();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003955}
3956
3957
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003958bool Map::HasTransitionArray() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00003959 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
3960 return object->IsTransitionArray();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003961}
3962
3963
3964Map* Map::elements_transition_map() {
3965 return transitions()->elements_transition();
3966}
3967
3968
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +00003969bool Map::CanHaveMoreTransitions() {
3970 if (!HasTransitionArray()) return true;
3971 return FixedArray::SizeFor(transitions()->length() +
3972 TransitionArray::kTransitionSize)
3973 <= Page::kMaxNonCodeHeapObjectSize;
3974}
3975
3976
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003977MaybeObject* Map::AddTransition(String* key,
3978 Map* target,
3979 SimpleTransitionFlag flag) {
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003980 if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003981 return TransitionArray::NewWith(flag, key, target, GetBackPointer());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003982}
3983
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003984
3985void Map::SetTransition(int transition_index, Map* target) {
3986 transitions()->SetTarget(transition_index, target);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00003987}
3988
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003989
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00003990Map* Map::GetTransition(int transition_index) {
3991 return transitions()->GetTarget(transition_index);
3992}
3993
3994
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003995MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00003996 MaybeObject* allow_elements = EnsureHasTransitionArray(this);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003997 if (allow_elements->IsFailure()) return allow_elements;
3998 transitions()->set_elements_transition(transitioned_map);
3999 return this;
4000}
4001
4002
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004003FixedArray* Map::GetPrototypeTransitions() {
4004 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
4005 if (!transitions()->HasPrototypeTransitions()) {
4006 return GetHeap()->empty_fixed_array();
4007 }
4008 return transitions()->GetPrototypeTransitions();
4009}
4010
4011
4012MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004013 MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004014 if (allow_prototype->IsFailure()) return allow_prototype;
4015#ifdef DEBUG
4016 if (HasPrototypeTransitions()) {
4017 ASSERT(GetPrototypeTransitions() != proto_transitions);
4018 ZapPrototypeTransitions();
4019 }
4020#endif
4021 transitions()->SetPrototypeTransitions(proto_transitions);
4022 return this;
4023}
4024
4025
4026bool Map::HasPrototypeTransitions() {
4027 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
4028}
4029
4030
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004031TransitionArray* Map::transitions() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004032 ASSERT(HasTransitionArray());
4033 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4034 return TransitionArray::cast(object);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004035}
4036
4037
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004038void Map::set_transitions(TransitionArray* transition_array,
4039 WriteBarrierMode mode) {
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00004040 // In release mode, only run this code if verify_heap is on.
4041 if (Heap::ShouldZapGarbage() && HasTransitionArray()) {
4042 CHECK(transitions() != transition_array);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004043 ZapTransitions();
4044 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004045
4046 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array);
4047 CONDITIONAL_WRITE_BARRIER(
4048 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004049}
4050
4051
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004052void Map::init_back_pointer(Object* undefined) {
4053 ASSERT(undefined->IsUndefined());
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004054 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, undefined);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004055}
4056
4057
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004058void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004059 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
4060 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
4061 (value->IsMap() && GetBackPointer()->IsUndefined()));
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004062 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4063 if (object->IsTransitionArray()) {
4064 TransitionArray::cast(object)->set_back_pointer_storage(value);
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004065 } else {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004066 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, value);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004067 CONDITIONAL_WRITE_BARRIER(
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004068 GetHeap(), this, kTransitionsOrBackPointerOffset, value, mode);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004069 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004070}
4071
4072
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004073// Can either be Smi (no transitions), normal transition array, or a transition
4074// array with the header overwritten as a Smi (thus iterating).
4075TransitionArray* Map::unchecked_transition_array() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004076 Object* object = *HeapObject::RawField(this,
4077 Map::kTransitionsOrBackPointerOffset);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004078 TransitionArray* transition_array = static_cast<TransitionArray*>(object);
4079 return transition_array;
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004080}
4081
4082
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004083HeapObject* Map::UncheckedPrototypeTransitions() {
4084 ASSERT(HasTransitionArray());
4085 ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
4086 return unchecked_transition_array()->UncheckedPrototypeTransitions();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004087}
4088
4089
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004090ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
yangguo@chromium.org003650e2013-01-24 16:31:08 +00004091ACCESSORS(Map, dependent_codes, DependentCodes, kDependentCodesOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004092ACCESSORS(Map, constructor, Object, kConstructorOffset)
4093
4094ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004095ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004096ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004097
4098ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004099ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset)
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00004100ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004101ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004102
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004103ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004104
4105ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
4106ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
4107ACCESSORS(AccessorInfo, data, Object, kDataOffset)
4108ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004109ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004110ACCESSORS(AccessorInfo, expected_receiver_type, Object,
4111 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004112
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004113ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
4114ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
4115
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004116ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
4117ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
4118ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
4119
4120ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
4121ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
4122ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
4123ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
4124ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
4125ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
4126
4127ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
4128ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
4129
4130ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
4131ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
4132
4133ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
4134ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004135ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
4136 kPropertyAccessorsOffset)
4137ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
4138 kPrototypeTemplateOffset)
4139ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
4140ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
4141 kNamedPropertyHandlerOffset)
4142ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
4143 kIndexedPropertyHandlerOffset)
4144ACCESSORS(FunctionTemplateInfo, instance_template, Object,
4145 kInstanceTemplateOffset)
4146ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
4147ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004148ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
4149 kInstanceCallHandlerOffset)
4150ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
4151 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004152ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004153
4154ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00004155ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
4156 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004157
4158ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
4159ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
4160
4161ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
4162
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00004163ACCESSORS(AllocationSiteInfo, payload, Object, kPayloadOffset)
4164
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004165ACCESSORS(Script, source, Object, kSourceOffset)
4166ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004167ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004168ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
4169ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004170ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00004171ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004172ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004173ACCESSORS_TO_SMI(Script, type, kTypeOffset)
4174ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
4175ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00004176ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00004177ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004178ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
4179 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004180
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004181#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004182ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
4183ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
4184ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
4185ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
4186
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004187ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
4188ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
4189ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004190ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004191#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004192
4193ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004194ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
4195 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004196ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
4197ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004198ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
4199 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004200ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004201ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
4202ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00004203ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004204ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
4205 kThisPropertyAssignmentsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004206SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004207
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00004208
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00004209SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004210BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
4211 kHiddenPrototypeBit)
4212BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
4213BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
4214 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00004215BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
4216 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004217BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
4218 kIsExpressionBit)
4219BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
4220 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004221BOOL_GETTER(SharedFunctionInfo,
4222 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004223 has_only_simple_this_property_assignments,
4224 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004225BOOL_ACCESSORS(SharedFunctionInfo,
4226 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00004227 allows_lazy_compilation,
4228 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004229BOOL_ACCESSORS(SharedFunctionInfo,
4230 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004231 allows_lazy_compilation_without_context,
4232 kAllowLazyCompilationWithoutContext)
4233BOOL_ACCESSORS(SharedFunctionInfo,
4234 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00004235 uses_arguments,
4236 kUsesArguments)
4237BOOL_ACCESSORS(SharedFunctionInfo,
4238 compiler_hints,
4239 has_duplicate_parameters,
4240 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004241
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004242
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004243#if V8_HOST_ARCH_32_BIT
4244SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
4245SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004246 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004247SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004248 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004249SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
4250SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004251 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004252SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
4253SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004254 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004255SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004256 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004257SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004258 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004259SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004260SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
4261SMI_ACCESSORS(SharedFunctionInfo,
4262 stress_deopt_counter,
4263 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004264#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004265
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004266#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004267 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004268 int holder::name() { \
4269 int value = READ_INT_FIELD(this, offset); \
4270 ASSERT(kHeapObjectTag == 1); \
4271 ASSERT((value & kHeapObjectTag) == 0); \
4272 return value >> 1; \
4273 } \
4274 void holder::set_##name(int value) { \
4275 ASSERT(kHeapObjectTag == 1); \
4276 ASSERT((value & 0xC0000000) == 0xC0000000 || \
4277 (value & 0xC0000000) == 0x000000000); \
4278 WRITE_INT_FIELD(this, \
4279 offset, \
4280 (value << 1) & ~kHeapObjectTag); \
4281 }
4282
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004283#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
4284 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004285 INT_ACCESSORS(holder, name, offset)
4286
4287
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004288PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004289PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4290 formal_parameter_count,
4291 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004292
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004293PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4294 expected_nof_properties,
4295 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004296PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
4297
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004298PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
4299PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4300 start_position_and_type,
4301 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004302
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004303PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4304 function_token_position,
4305 kFunctionTokenPositionOffset)
4306PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4307 compiler_hints,
4308 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004309
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004310PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4311 this_property_assignments_count,
4312 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004313PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004314
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004315PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
4316PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4317 stress_deopt_counter,
4318 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004319#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004320
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004321
4322int SharedFunctionInfo::construction_count() {
4323 return READ_BYTE_FIELD(this, kConstructionCountOffset);
4324}
4325
4326
4327void SharedFunctionInfo::set_construction_count(int value) {
4328 ASSERT(0 <= value && value < 256);
4329 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
4330}
4331
4332
whesse@chromium.org7b260152011-06-20 15:33:18 +00004333BOOL_ACCESSORS(SharedFunctionInfo,
4334 compiler_hints,
4335 live_objects_may_exist,
4336 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004337
4338
4339bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004340 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004341}
4342
4343
whesse@chromium.org7b260152011-06-20 15:33:18 +00004344BOOL_GETTER(SharedFunctionInfo,
4345 compiler_hints,
4346 optimization_disabled,
4347 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004348
4349
4350void SharedFunctionInfo::set_optimization_disabled(bool disable) {
4351 set_compiler_hints(BooleanBit::set(compiler_hints(),
4352 kOptimizationDisabled,
4353 disable));
4354 // If disabling optimizations we reflect that in the code object so
4355 // it will not be counted as optimizable code.
4356 if ((code()->kind() == Code::FUNCTION) && disable) {
4357 code()->set_optimizable(false);
4358 }
4359}
4360
4361
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004362int SharedFunctionInfo::profiler_ticks() {
4363 if (code()->kind() != Code::FUNCTION) return 0;
4364 return code()->profiler_ticks();
4365}
4366
4367
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004368LanguageMode SharedFunctionInfo::language_mode() {
4369 int hints = compiler_hints();
4370 if (BooleanBit::get(hints, kExtendedModeFunction)) {
4371 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
4372 return EXTENDED_MODE;
4373 }
4374 return BooleanBit::get(hints, kStrictModeFunction)
4375 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004376}
4377
4378
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004379void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
4380 // We only allow language mode transitions that go set the same language mode
4381 // again or go up in the chain:
4382 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
4383 ASSERT(this->language_mode() == CLASSIC_MODE ||
4384 this->language_mode() == language_mode ||
4385 language_mode == EXTENDED_MODE);
4386 int hints = compiler_hints();
4387 hints = BooleanBit::set(
4388 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
4389 hints = BooleanBit::set(
4390 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
4391 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004392}
4393
4394
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004395bool SharedFunctionInfo::is_classic_mode() {
4396 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
4397}
4398
4399BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
4400 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004401BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
4402BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
4403 name_should_print_as_anonymous,
4404 kNameShouldPrintAsAnonymous)
4405BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
4406BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00004407BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
4408BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
4409 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004410BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004411BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004412
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004413void SharedFunctionInfo::BeforeVisitingPointers() {
4414 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
mstarzinger@chromium.org0ae265a2012-12-11 17:41:11 +00004415}
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004416
mstarzinger@chromium.org0ae265a2012-12-11 17:41:11 +00004417
4418void SharedFunctionInfo::ClearOptimizedCodeMap() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004419 set_optimized_code_map(Smi::FromInt(0));
4420}
4421
4422
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004423ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
4424ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
4425
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00004426ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
4427
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004428bool Script::HasValidSource() {
4429 Object* src = this->source();
4430 if (!src->IsString()) return true;
4431 String* src_str = String::cast(src);
4432 if (!StringShape(src_str).IsExternal()) return true;
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00004433 if (src_str->IsOneByteRepresentation()) {
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004434 return ExternalAsciiString::cast(src)->resource() != NULL;
4435 } else if (src_str->IsTwoByteRepresentation()) {
4436 return ExternalTwoByteString::cast(src)->resource() != NULL;
4437 }
4438 return true;
4439}
4440
4441
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00004442void SharedFunctionInfo::DontAdaptArguments() {
4443 ASSERT(code()->kind() == Code::BUILTIN);
4444 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
4445}
4446
4447
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004448int SharedFunctionInfo::start_position() {
4449 return start_position_and_type() >> kStartPositionShift;
4450}
4451
4452
4453void SharedFunctionInfo::set_start_position(int start_position) {
4454 set_start_position_and_type((start_position << kStartPositionShift)
4455 | (start_position_and_type() & ~kStartPositionMask));
4456}
4457
4458
4459Code* SharedFunctionInfo::code() {
4460 return Code::cast(READ_FIELD(this, kCodeOffset));
4461}
4462
4463
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004464Code* SharedFunctionInfo::unchecked_code() {
4465 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
4466}
4467
4468
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004469void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004470 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004471 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004472}
4473
4474
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00004475void SharedFunctionInfo::ReplaceCode(Code* value) {
4476 // If the GC metadata field is already used then the function was
4477 // enqueued as a code flushing candidate and we remove it now.
4478 if (code()->gc_metadata() != NULL) {
4479 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
4480 flusher->EvictCandidate(this);
4481 }
4482
4483 ASSERT(code()->gc_metadata() == NULL && value->gc_metadata() == NULL);
4484 set_code(value);
4485}
4486
4487
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004488ScopeInfo* SharedFunctionInfo::scope_info() {
4489 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00004490}
4491
4492
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004493void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00004494 WriteBarrierMode mode) {
4495 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004496 CONDITIONAL_WRITE_BARRIER(GetHeap(),
4497 this,
4498 kScopeInfoOffset,
4499 reinterpret_cast<Object*>(value),
4500 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00004501}
4502
4503
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004504bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004505 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004506 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004507}
4508
4509
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004510bool SharedFunctionInfo::IsApiFunction() {
4511 return function_data()->IsFunctionTemplateInfo();
4512}
4513
4514
4515FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
4516 ASSERT(IsApiFunction());
4517 return FunctionTemplateInfo::cast(function_data());
4518}
4519
4520
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004521bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004522 return function_data()->IsSmi();
4523}
4524
4525
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004526BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4527 ASSERT(HasBuiltinFunctionId());
4528 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004529}
4530
4531
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004532int SharedFunctionInfo::code_age() {
4533 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
4534}
4535
4536
4537void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00004538 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
4539 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004540}
4541
4542
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004543int SharedFunctionInfo::ic_age() {
4544 return ICAgeBits::decode(counters());
4545}
4546
4547
4548void SharedFunctionInfo::set_ic_age(int ic_age) {
4549 set_counters(ICAgeBits::update(counters(), ic_age));
4550}
4551
4552
4553int SharedFunctionInfo::deopt_count() {
4554 return DeoptCountBits::decode(counters());
4555}
4556
4557
4558void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4559 set_counters(DeoptCountBits::update(counters(), deopt_count));
4560}
4561
4562
4563void SharedFunctionInfo::increment_deopt_count() {
4564 int value = counters();
4565 int deopt_count = DeoptCountBits::decode(value);
4566 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4567 set_counters(DeoptCountBits::update(value, deopt_count));
4568}
4569
4570
4571int SharedFunctionInfo::opt_reenable_tries() {
4572 return OptReenableTriesBits::decode(counters());
4573}
4574
4575
4576void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4577 set_counters(OptReenableTriesBits::update(counters(), tries));
4578}
4579
4580
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004581bool SharedFunctionInfo::has_deoptimization_support() {
4582 Code* code = this->code();
4583 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4584}
4585
4586
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004587void SharedFunctionInfo::TryReenableOptimization() {
4588 int tries = opt_reenable_tries();
4589 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4590 // We reenable optimization whenever the number of tries is a large
4591 // enough power of 2.
4592 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4593 set_optimization_disabled(false);
4594 set_opt_count(0);
4595 set_deopt_count(0);
4596 code()->set_optimizable(true);
4597 }
4598}
4599
4600
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004601bool JSFunction::IsBuiltin() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004602 return context()->global_object()->IsJSBuiltinsObject();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004603}
4604
4605
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004606bool JSFunction::NeedsArgumentsAdaption() {
4607 return shared()->formal_parameter_count() !=
4608 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4609}
4610
4611
4612bool JSFunction::IsOptimized() {
4613 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4614}
4615
4616
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004617bool JSFunction::IsOptimizable() {
4618 return code()->kind() == Code::FUNCTION && code()->optimizable();
4619}
4620
4621
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004622bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004623 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004624}
4625
4626
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004627bool JSFunction::IsMarkedForParallelRecompilation() {
4628 return code() ==
4629 GetIsolate()->builtins()->builtin(Builtins::kParallelRecompile);
4630}
4631
4632
4633bool JSFunction::IsInRecompileQueue() {
4634 return code() == GetIsolate()->builtins()->builtin(
4635 Builtins::kInRecompileQueue);
4636}
4637
4638
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004639Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004640 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004641}
4642
4643
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004644Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004645 return reinterpret_cast<Code*>(
4646 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004647}
4648
4649
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004650void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004651 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004652 Address entry = value->entry();
4653 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004654 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4655 this,
4656 HeapObject::RawField(this, kCodeEntryOffset),
4657 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004658}
4659
4660
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004661void JSFunction::ReplaceCode(Code* code) {
4662 bool was_optimized = IsOptimized();
4663 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4664
4665 set_code(code);
4666
4667 // Add/remove the function from the list of optimized functions for this
4668 // context based on the state change.
4669 if (!was_optimized && is_optimized) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004670 context()->native_context()->AddOptimizedFunction(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004671 }
4672 if (was_optimized && !is_optimized) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004673 context()->native_context()->RemoveOptimizedFunction(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004674 }
4675}
4676
4677
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004678Context* JSFunction::context() {
4679 return Context::cast(READ_FIELD(this, kContextOffset));
4680}
4681
4682
4683Object* JSFunction::unchecked_context() {
4684 return READ_FIELD(this, kContextOffset);
4685}
4686
4687
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004688SharedFunctionInfo* JSFunction::unchecked_shared() {
4689 return reinterpret_cast<SharedFunctionInfo*>(
4690 READ_FIELD(this, kSharedFunctionInfoOffset));
4691}
4692
4693
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004694void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004695 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004696 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004697 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004698}
4699
4700ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4701 kPrototypeOrInitialMapOffset)
4702
4703
4704Map* JSFunction::initial_map() {
4705 return Map::cast(prototype_or_initial_map());
4706}
4707
4708
4709void JSFunction::set_initial_map(Map* value) {
4710 set_prototype_or_initial_map(value);
4711}
4712
4713
4714bool JSFunction::has_initial_map() {
4715 return prototype_or_initial_map()->IsMap();
4716}
4717
4718
4719bool JSFunction::has_instance_prototype() {
4720 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4721}
4722
4723
4724bool JSFunction::has_prototype() {
4725 return map()->has_non_instance_prototype() || has_instance_prototype();
4726}
4727
4728
4729Object* JSFunction::instance_prototype() {
4730 ASSERT(has_instance_prototype());
4731 if (has_initial_map()) return initial_map()->prototype();
4732 // When there is no initial map and the prototype is a JSObject, the
4733 // initial map field is used for the prototype field.
4734 return prototype_or_initial_map();
4735}
4736
4737
4738Object* JSFunction::prototype() {
4739 ASSERT(has_prototype());
4740 // If the function's prototype property has been set to a non-JSObject
4741 // value, that value is stored in the constructor field of the map.
4742 if (map()->has_non_instance_prototype()) return map()->constructor();
4743 return instance_prototype();
4744}
4745
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004746
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004747bool JSFunction::should_have_prototype() {
4748 return map()->function_with_prototype();
4749}
4750
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004751
4752bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004753 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004754}
4755
4756
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004757FixedArray* JSFunction::literals() {
4758 ASSERT(!shared()->bound());
4759 return literals_or_bindings();
4760}
4761
4762
4763void JSFunction::set_literals(FixedArray* literals) {
4764 ASSERT(!shared()->bound());
4765 set_literals_or_bindings(literals);
4766}
4767
4768
4769FixedArray* JSFunction::function_bindings() {
4770 ASSERT(shared()->bound());
4771 return literals_or_bindings();
4772}
4773
4774
4775void JSFunction::set_function_bindings(FixedArray* bindings) {
4776 ASSERT(shared()->bound());
4777 // Bound function literal may be initialized to the empty fixed array
4778 // before the bindings are set.
4779 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4780 bindings->map() == GetHeap()->fixed_cow_array_map());
4781 set_literals_or_bindings(bindings);
4782}
4783
4784
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004785int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004786 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004787 return literals()->length();
4788}
4789
4790
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004791Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004792 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004793 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004794}
4795
4796
4797void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4798 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004799 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004800 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004801 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004802}
4803
4804
4805Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004806 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004807 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4808}
4809
4810
4811void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4812 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004813 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004814 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004815 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004816}
4817
4818
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004819ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004820ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004821ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4822ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4823
4824
4825void JSProxy::InitializeBody(int object_size, Object* value) {
4826 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4827 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4828 WRITE_FIELD(this, offset, value);
4829 }
4830}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004831
4832
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004833ACCESSORS(JSSet, table, Object, kTableOffset)
4834ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004835ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4836ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004837
4838
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004839Address Foreign::foreign_address() {
4840 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004841}
4842
4843
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004844void Foreign::set_foreign_address(Address value) {
4845 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004846}
4847
4848
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004849ACCESSORS(JSModule, context, Object, kContextOffset)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004850ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004851
4852
4853JSModule* JSModule::cast(Object* obj) {
4854 ASSERT(obj->IsJSModule());
4855 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4856 return reinterpret_cast<JSModule*>(obj);
4857}
4858
4859
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004860ACCESSORS(JSValue, value, Object, kValueOffset)
4861
4862
4863JSValue* JSValue::cast(Object* obj) {
4864 ASSERT(obj->IsJSValue());
4865 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4866 return reinterpret_cast<JSValue*>(obj);
4867}
4868
4869
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004870ACCESSORS(JSDate, value, Object, kValueOffset)
4871ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4872ACCESSORS(JSDate, year, Object, kYearOffset)
4873ACCESSORS(JSDate, month, Object, kMonthOffset)
4874ACCESSORS(JSDate, day, Object, kDayOffset)
4875ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4876ACCESSORS(JSDate, hour, Object, kHourOffset)
4877ACCESSORS(JSDate, min, Object, kMinOffset)
4878ACCESSORS(JSDate, sec, Object, kSecOffset)
4879
4880
4881JSDate* JSDate::cast(Object* obj) {
4882 ASSERT(obj->IsJSDate());
4883 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4884 return reinterpret_cast<JSDate*>(obj);
4885}
4886
4887
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004888ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4889ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4890ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4891ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4892ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4893SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4894SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4895
4896
4897JSMessageObject* JSMessageObject::cast(Object* obj) {
4898 ASSERT(obj->IsJSMessageObject());
4899 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4900 return reinterpret_cast<JSMessageObject*>(obj);
4901}
4902
4903
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004904INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +00004905INT_ACCESSORS(Code, prologue_offset, kPrologueOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004906ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004907ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004908ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004909
4910
4911// Type feedback slot: type_feedback_info for FUNCTIONs, stub_info for STUBs.
4912void Code::InitializeTypeFeedbackInfoNoWriteBarrier(Object* value) {
4913 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
4914}
4915
4916
4917Object* Code::type_feedback_info() {
4918 ASSERT(kind() == FUNCTION);
4919 return Object::cast(READ_FIELD(this, kTypeFeedbackInfoOffset));
4920}
4921
4922
4923void Code::set_type_feedback_info(Object* value, WriteBarrierMode mode) {
4924 ASSERT(kind() == FUNCTION);
4925 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
4926 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kTypeFeedbackInfoOffset,
4927 value, mode);
4928}
4929
4930
4931int Code::stub_info() {
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00004932 ASSERT(kind() == COMPARE_IC || kind() == BINARY_OP_IC || kind() == LOAD_IC);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004933 Object* value = READ_FIELD(this, kTypeFeedbackInfoOffset);
4934 return Smi::cast(value)->value();
4935}
4936
4937
4938void Code::set_stub_info(int value) {
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00004939 ASSERT(kind() == COMPARE_IC ||
4940 kind() == BINARY_OP_IC ||
4941 kind() == LOAD_IC ||
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00004942 kind() == KEYED_LOAD_IC ||
4943 kind() == STORE_IC ||
4944 kind() == KEYED_STORE_IC);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004945 WRITE_FIELD(this, kTypeFeedbackInfoOffset, Smi::FromInt(value));
4946}
4947
4948
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00004949void Code::set_deoptimizing_functions(Object* value) {
4950 ASSERT(kind() == OPTIMIZED_FUNCTION);
4951 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
4952}
4953
4954
4955Object* Code::deoptimizing_functions() {
4956 ASSERT(kind() == OPTIMIZED_FUNCTION);
4957 return Object::cast(READ_FIELD(this, kTypeFeedbackInfoOffset));
4958}
4959
4960
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004961ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004962INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004963
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004964
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004965byte* Code::instruction_start() {
4966 return FIELD_ADDR(this, kHeaderSize);
4967}
4968
4969
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004970byte* Code::instruction_end() {
4971 return instruction_start() + instruction_size();
4972}
4973
4974
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004975int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004976 return RoundUp(instruction_size(), kObjectAlignment);
4977}
4978
4979
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004980FixedArray* Code::unchecked_deoptimization_data() {
4981 return reinterpret_cast<FixedArray*>(
4982 READ_FIELD(this, kDeoptimizationDataOffset));
4983}
4984
4985
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004986ByteArray* Code::unchecked_relocation_info() {
4987 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004988}
4989
4990
4991byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004992 return unchecked_relocation_info()->GetDataStartAddress();
4993}
4994
4995
4996int Code::relocation_size() {
4997 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004998}
4999
5000
5001byte* Code::entry() {
5002 return instruction_start();
5003}
5004
5005
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005006bool Code::contains(byte* inner_pointer) {
5007 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005008}
5009
5010
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005011ACCESSORS(JSArray, length, Object, kLengthOffset)
5012
5013
ager@chromium.org236ad962008-09-25 09:45:57 +00005014ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00005015
5016
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00005017JSRegExp::Type JSRegExp::TypeTag() {
5018 Object* data = this->data();
5019 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
5020 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
5021 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00005022}
5023
5024
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005025JSRegExp::Type JSRegExp::TypeTagUnchecked() {
5026 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
5027 return static_cast<JSRegExp::Type>(smi->value());
5028}
5029
5030
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00005031int JSRegExp::CaptureCount() {
5032 switch (TypeTag()) {
5033 case ATOM:
5034 return 0;
5035 case IRREGEXP:
5036 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
5037 default:
5038 UNREACHABLE();
5039 return -1;
5040 }
5041}
5042
5043
ager@chromium.orga74f0da2008-12-03 16:05:52 +00005044JSRegExp::Flags JSRegExp::GetFlags() {
5045 ASSERT(this->data()->IsFixedArray());
5046 Object* data = this->data();
5047 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
5048 return Flags(smi->value());
5049}
5050
5051
5052String* JSRegExp::Pattern() {
5053 ASSERT(this->data()->IsFixedArray());
5054 Object* data = this->data();
5055 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
5056 return pattern;
5057}
5058
5059
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00005060Object* JSRegExp::DataAt(int index) {
5061 ASSERT(TypeTag() != NOT_COMPILED);
5062 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00005063}
5064
5065
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005066Object* JSRegExp::DataAtUnchecked(int index) {
5067 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
5068 int offset = FixedArray::kHeaderSize + index * kPointerSize;
5069 return READ_FIELD(fa, offset);
5070}
5071
5072
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00005073void JSRegExp::SetDataAt(int index, Object* value) {
5074 ASSERT(TypeTag() != NOT_COMPILED);
5075 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
5076 FixedArray::cast(data())->set(index, value);
5077}
5078
5079
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005080void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
5081 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
5082 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
5083 if (value->IsSmi()) {
5084 fa->set_unchecked(index, Smi::cast(value));
5085 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005086 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005087 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
5088 }
5089}
5090
5091
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005092ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005093 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005094#if DEBUG
5095 FixedArrayBase* fixed_array =
5096 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
5097 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005098 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
5099 (map == GetHeap()->fixed_array_map() ||
5100 map == GetHeap()->fixed_cow_array_map())) ||
5101 (IsFastDoubleElementsKind(kind) &&
5102 (fixed_array->IsFixedDoubleArray() ||
5103 fixed_array == GetHeap()->empty_fixed_array())) ||
5104 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005105 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005106 fixed_array->IsDictionary()) ||
5107 (kind > DICTIONARY_ELEMENTS));
5108 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
5109 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005110#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005111 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005112}
5113
5114
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00005115ElementsAccessor* JSObject::GetElementsAccessor() {
5116 return ElementsAccessor::ForKind(GetElementsKind());
5117}
5118
5119
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005120bool JSObject::HasFastObjectElements() {
5121 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005122}
5123
5124
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005125bool JSObject::HasFastSmiElements() {
5126 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005127}
5128
5129
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005130bool JSObject::HasFastSmiOrObjectElements() {
5131 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005132}
5133
5134
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00005135bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005136 return IsFastDoubleElementsKind(GetElementsKind());
5137}
5138
5139
5140bool JSObject::HasFastHoleyElements() {
5141 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00005142}
5143
5144
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005145bool JSObject::HasFastElements() {
5146 return IsFastElementsKind(GetElementsKind());
5147}
5148
5149
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005150bool JSObject::HasDictionaryElements() {
5151 return GetElementsKind() == DICTIONARY_ELEMENTS;
5152}
5153
5154
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005155bool JSObject::HasNonStrictArgumentsElements() {
5156 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
5157}
5158
5159
ager@chromium.org3811b432009-10-28 14:53:37 +00005160bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005161 HeapObject* array = elements();
5162 ASSERT(array != NULL);
5163 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00005164}
5165
5166
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005167#define EXTERNAL_ELEMENTS_CHECK(name, type) \
5168bool JSObject::HasExternal##name##Elements() { \
5169 HeapObject* array = elements(); \
5170 ASSERT(array != NULL); \
5171 if (!array->IsHeapObject()) \
5172 return false; \
5173 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00005174}
5175
5176
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005177EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
5178EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
5179EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
5180EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
5181 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
5182EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
5183EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
5184 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
5185EXTERNAL_ELEMENTS_CHECK(Float,
5186 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00005187EXTERNAL_ELEMENTS_CHECK(Double,
5188 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005189EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00005190
5191
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005192bool JSObject::HasNamedInterceptor() {
5193 return map()->has_named_interceptor();
5194}
5195
5196
5197bool JSObject::HasIndexedInterceptor() {
5198 return map()->has_indexed_interceptor();
5199}
5200
5201
lrn@chromium.org303ada72010-10-27 09:33:13 +00005202MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005203 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005204 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005205 Isolate* isolate = GetIsolate();
5206 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00005207 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005208 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
5209 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00005210 if (!maybe_writable_elems->ToObject(&writable_elems)) {
5211 return maybe_writable_elems;
5212 }
5213 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005214 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005215 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005216 return writable_elems;
5217}
5218
5219
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005220StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005221 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005222 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005223}
5224
5225
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005226SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005227 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005228 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005229}
5230
5231
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005232bool String::IsHashFieldComputed(uint32_t field) {
5233 return (field & kHashNotComputedMask) == 0;
5234}
5235
5236
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005237bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005238 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005239}
5240
5241
5242uint32_t String::Hash() {
5243 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005244 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005245 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005246 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005247 return ComputeAndSetHash();
5248}
5249
5250
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005251StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00005252 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005253 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00005254 array_index_(0),
5255 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005256 is_first_char_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005257 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005258}
ager@chromium.org7c537e22008-10-16 08:43:32 +00005259
5260
5261bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005262 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005263}
5264
5265
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005266uint32_t StringHasher::AddCharacterCore(uint32_t running_hash, uint16_t c) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005267 running_hash += c;
5268 running_hash += (running_hash << 10);
5269 running_hash ^= (running_hash >> 6);
5270 return running_hash;
5271}
5272
5273
5274uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
5275 running_hash += (running_hash << 3);
5276 running_hash ^= (running_hash >> 11);
5277 running_hash += (running_hash << 15);
5278 if ((running_hash & String::kHashBitMask) == 0) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005279 return kZeroHash;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005280 }
5281 return running_hash;
5282}
5283
5284
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005285void StringHasher::AddCharacter(uint16_t c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005286 // Use the Jenkins one-at-a-time hash function to update the hash
5287 // for the given character.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005288 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005289}
5290
5291
5292bool StringHasher::UpdateIndex(uint16_t c) {
5293 ASSERT(is_array_index_);
5294 if (c < '0' || c > '9') {
5295 is_array_index_ = false;
5296 return false;
5297 }
5298 int d = c - '0';
5299 if (is_first_char_) {
5300 is_first_char_ = false;
5301 if (c == '0' && length_ > 1) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00005302 is_array_index_ = false;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005303 return false;
5304 }
5305 }
5306 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
5307 is_array_index_ = false;
5308 return false;
5309 }
5310 array_index_ = array_index_ * 10 + d;
5311 return true;
5312}
5313
5314
5315template<typename Char>
5316inline void StringHasher::AddCharacters(const Char* chars, int length) {
5317 ASSERT(sizeof(Char) == 1 || sizeof(Char) == 2);
5318 int i = 0;
5319 if (is_array_index_) {
5320 for (; i < length; i++) {
5321 AddCharacter(chars[i]);
5322 if (!UpdateIndex(chars[i])) {
5323 i++;
5324 break;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005325 }
5326 }
5327 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005328 for (; i < length; i++) {
5329 ASSERT(!is_array_index_);
5330 AddCharacter(chars[i]);
yangguo@chromium.org154ff992012-03-13 08:09:54 +00005331 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00005332}
5333
5334
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005335template <typename schar>
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005336uint32_t StringHasher::HashSequentialString(const schar* chars,
5337 int length,
5338 uint32_t seed) {
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005339 StringHasher hasher(length, seed);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005340 if (!hasher.has_trivial_hash()) hasher.AddCharacters(chars, length);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005341 return hasher.GetHashField();
5342}
5343
5344
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005345bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005346 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00005347 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
5348 return false;
5349 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005350 return SlowAsArrayIndex(index);
5351}
5352
5353
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00005354Object* JSReceiver::GetPrototype() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00005355 return map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005356}
5357
5358
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00005359Object* JSReceiver::GetConstructor() {
5360 return map()->constructor();
5361}
5362
5363
rossberg@chromium.org717967f2011-07-20 13:44:42 +00005364bool JSReceiver::HasProperty(String* name) {
5365 if (IsJSProxy()) {
5366 return JSProxy::cast(this)->HasPropertyWithHandler(name);
5367 }
5368 return GetPropertyAttribute(name) != ABSENT;
5369}
5370
5371
5372bool JSReceiver::HasLocalProperty(String* name) {
5373 if (IsJSProxy()) {
5374 return JSProxy::cast(this)->HasPropertyWithHandler(name);
5375 }
5376 return GetLocalPropertyAttribute(name) != ABSENT;
5377}
5378
5379
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00005380PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00005381 uint32_t index;
5382 if (IsJSObject() && key->AsArrayIndex(&index)) {
5383 return GetElementAttribute(index);
5384 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005385 return GetPropertyAttributeWithReceiver(this, key);
5386}
5387
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00005388
5389PropertyAttributes JSReceiver::GetElementAttribute(uint32_t index) {
5390 if (IsJSProxy()) {
5391 return JSProxy::cast(this)->GetElementAttributeWithHandler(this, index);
5392 }
5393 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5394 this, index, true);
5395}
5396
5397
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005398// TODO(504): this may be useful in other places too where JSGlobalProxy
5399// is used.
5400Object* JSObject::BypassGlobalProxy() {
5401 if (IsJSGlobalProxy()) {
5402 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005403 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005404 ASSERT(proto->IsJSGlobalObject());
5405 return proto;
5406 }
5407 return this;
5408}
5409
5410
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005411MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
5412 return IsJSProxy()
5413 ? JSProxy::cast(this)->GetIdentityHash(flag)
5414 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005415}
5416
5417
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005418bool JSReceiver::HasElement(uint32_t index) {
5419 if (IsJSProxy()) {
5420 return JSProxy::cast(this)->HasElementWithHandler(index);
5421 }
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00005422 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5423 this, index, true) != ABSENT;
5424}
5425
5426
5427bool JSReceiver::HasLocalElement(uint32_t index) {
5428 if (IsJSProxy()) {
5429 return JSProxy::cast(this)->HasElementWithHandler(index);
5430 }
5431 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5432 this, index, false) != ABSENT;
5433}
5434
5435
5436PropertyAttributes JSReceiver::GetLocalElementAttribute(uint32_t index) {
5437 if (IsJSProxy()) {
5438 return JSProxy::cast(this)->GetElementAttributeWithHandler(this, index);
5439 }
5440 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5441 this, index, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005442}
5443
5444
5445bool AccessorInfo::all_can_read() {
5446 return BooleanBit::get(flag(), kAllCanReadBit);
5447}
5448
5449
5450void AccessorInfo::set_all_can_read(bool value) {
5451 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
5452}
5453
5454
5455bool AccessorInfo::all_can_write() {
5456 return BooleanBit::get(flag(), kAllCanWriteBit);
5457}
5458
5459
5460void AccessorInfo::set_all_can_write(bool value) {
5461 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
5462}
5463
5464
ager@chromium.org870a0b62008-11-04 11:43:05 +00005465bool AccessorInfo::prohibits_overwriting() {
5466 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
5467}
5468
5469
5470void AccessorInfo::set_prohibits_overwriting(bool value) {
5471 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
5472}
5473
5474
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005475PropertyAttributes AccessorInfo::property_attributes() {
5476 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
5477}
5478
5479
5480void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005481 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005482}
5483
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005484
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005485bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
5486 Object* function_template = expected_receiver_type();
5487 if (!function_template->IsFunctionTemplateInfo()) return true;
5488 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
5489}
5490
5491
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005492template<typename Shape, typename Key>
5493void Dictionary<Shape, Key>::SetEntry(int entry,
5494 Object* key,
5495 Object* value) {
5496 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
5497}
5498
5499
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005500template<typename Shape, typename Key>
5501void Dictionary<Shape, Key>::SetEntry(int entry,
5502 Object* key,
5503 Object* value,
5504 PropertyDetails details) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005505 ASSERT(!key->IsString() ||
5506 details.IsDeleted() ||
5507 details.dictionary_index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005508 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005509 AssertNoAllocation no_gc;
5510 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005511 FixedArray::set(index, key, mode);
5512 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005513 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005514}
5515
5516
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005517bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
5518 ASSERT(other->IsNumber());
5519 return key == static_cast<uint32_t>(other->Number());
5520}
5521
5522
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005523uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
5524 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005525}
5526
5527
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005528uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
5529 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005530 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005531 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005532}
5533
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005534uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
5535 return ComputeIntegerHash(key, seed);
5536}
5537
5538uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
5539 uint32_t seed,
5540 Object* other) {
5541 ASSERT(other->IsNumber());
5542 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
5543}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005544
5545MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
5546 return Isolate::Current()->heap()->NumberFromUint32(key);
5547}
5548
5549
5550bool StringDictionaryShape::IsMatch(String* key, Object* other) {
5551 // We know that all entries in a hash table had their hash keys created.
5552 // Use that knowledge to have fast failure.
5553 if (key->Hash() != String::cast(other)->Hash()) return false;
5554 return key->Equals(String::cast(other));
5555}
5556
5557
5558uint32_t StringDictionaryShape::Hash(String* key) {
5559 return key->Hash();
5560}
5561
5562
5563uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
5564 return String::cast(other)->Hash();
5565}
5566
5567
5568MaybeObject* StringDictionaryShape::AsObject(String* key) {
5569 return key;
5570}
5571
5572
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005573template <int entrysize>
5574bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
5575 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005576}
5577
5578
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005579template <int entrysize>
5580uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005581 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
5582 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005583}
5584
5585
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005586template <int entrysize>
5587uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
5588 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005589 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
5590 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005591}
5592
5593
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005594template <int entrysize>
5595MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005596 return key;
5597}
5598
5599
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005600void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005601 // No write barrier is needed since empty_fixed_array is not in new space.
5602 // Please note this function is used during marking:
5603 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005604 // - IncrementalMarking::Step
danno@chromium.org72204d52012-10-31 10:02:10 +00005605 ASSERT(!heap->InNewSpace(heap->empty_fixed_array()));
5606 WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005607}
5608
5609
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005610void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005611 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005612 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005613 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5614 if (elts->length() < required_size) {
5615 // Doubling in size would be overkill, but leave some slack to avoid
5616 // constantly growing.
5617 Expand(required_size + (required_size >> 3));
5618 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005619 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005620 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5621 // Expand will allocate a new backing store in new space even if the size
5622 // we asked for isn't larger than what we had before.
5623 Expand(required_size);
5624 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005625}
5626
5627
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005628void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005629 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005630 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5631}
5632
5633
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005634bool JSArray::AllowsSetElementsLength() {
5635 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5636 ASSERT(result == !HasExternalArrayElements());
5637 return result;
5638}
5639
5640
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005641MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5642 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005643 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005644 if (maybe_result->IsFailure()) return maybe_result;
5645 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005646 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005647 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005648 (IsFastObjectElementsKind(GetElementsKind()) ||
5649 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005650 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005651 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005652 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005653 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005654}
5655
5656
lrn@chromium.org303ada72010-10-27 09:33:13 +00005657MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005658 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005659 return GetHeap()->CopyFixedArray(this);
5660}
5661
5662
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005663MaybeObject* FixedDoubleArray::Copy() {
5664 if (length() == 0) return this;
5665 return GetHeap()->CopyFixedDoubleArray(this);
5666}
5667
5668
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005669void TypeFeedbackCells::SetAstId(int index, TypeFeedbackId id) {
5670 set(1 + index * 2, Smi::FromInt(id.ToInt()));
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005671}
5672
5673
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005674TypeFeedbackId TypeFeedbackCells::AstId(int index) {
5675 return TypeFeedbackId(Smi::cast(get(1 + index * 2))->value());
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005676}
5677
5678
5679void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
5680 set(index * 2, cell);
5681}
5682
5683
5684JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
5685 return JSGlobalPropertyCell::cast(get(index * 2));
5686}
5687
5688
5689Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5690 return isolate->factory()->the_hole_value();
5691}
5692
5693
5694Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5695 return isolate->factory()->undefined_value();
5696}
5697
5698
5699Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
danno@chromium.org72204d52012-10-31 10:02:10 +00005700 return heap->the_hole_value();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005701}
5702
5703
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005704int TypeFeedbackInfo::ic_total_count() {
5705 int current = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5706 return ICTotalCountField::decode(current);
5707}
5708
5709
5710void TypeFeedbackInfo::set_ic_total_count(int count) {
5711 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5712 value = ICTotalCountField::update(value,
5713 ICTotalCountField::decode(count));
5714 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
5715}
5716
5717
5718int TypeFeedbackInfo::ic_with_type_info_count() {
5719 int current = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5720 return ICsWithTypeInfoCountField::decode(current);
5721}
5722
5723
5724void TypeFeedbackInfo::change_ic_with_type_info_count(int delta) {
5725 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5726 int new_count = ICsWithTypeInfoCountField::decode(value) + delta;
5727 // We can get negative count here when the type-feedback info is
5728 // shared between two code objects. The can only happen when
5729 // the debugger made a shallow copy of code object (see Heap::CopyCode).
5730 // Since we do not optimize when the debugger is active, we can skip
5731 // this counter update.
5732 if (new_count >= 0) {
5733 new_count &= ICsWithTypeInfoCountField::kMask;
5734 value = ICsWithTypeInfoCountField::update(value, new_count);
5735 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
5736 }
5737}
5738
5739
5740void TypeFeedbackInfo::initialize_storage() {
5741 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(0));
5742 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(0));
5743}
5744
5745
5746void TypeFeedbackInfo::change_own_type_change_checksum() {
5747 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5748 int checksum = OwnTypeChangeChecksum::decode(value);
5749 checksum = (checksum + 1) % (1 << kTypeChangeChecksumBits);
5750 value = OwnTypeChangeChecksum::update(value, checksum);
5751 // Ensure packed bit field is in Smi range.
5752 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
5753 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
5754 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
5755}
5756
5757
5758void TypeFeedbackInfo::set_inlined_type_change_checksum(int checksum) {
5759 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5760 int mask = (1 << kTypeChangeChecksumBits) - 1;
5761 value = InlinedTypeChangeChecksum::update(value, checksum & mask);
5762 // Ensure packed bit field is in Smi range.
5763 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
5764 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
5765 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
5766}
5767
5768
5769int TypeFeedbackInfo::own_type_change_checksum() {
5770 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5771 return OwnTypeChangeChecksum::decode(value);
5772}
5773
5774
5775bool TypeFeedbackInfo::matches_inlined_type_change_checksum(int checksum) {
5776 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
5777 int mask = (1 << kTypeChangeChecksumBits) - 1;
5778 return InlinedTypeChangeChecksum::decode(value) == (checksum & mask);
5779}
5780
5781
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005782ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
5783 kTypeFeedbackCellsOffset)
5784
5785
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00005786SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
5787
5788
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005789Relocatable::Relocatable(Isolate* isolate) {
5790 ASSERT(isolate == Isolate::Current());
5791 isolate_ = isolate;
5792 prev_ = isolate->relocatable_top();
5793 isolate->set_relocatable_top(this);
5794}
5795
5796
5797Relocatable::~Relocatable() {
5798 ASSERT(isolate_ == Isolate::Current());
5799 ASSERT_EQ(isolate_->relocatable_top(), this);
5800 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005801}
5802
5803
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005804int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
5805 return map->instance_size();
5806}
5807
5808
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005809void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005810 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005811 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005812}
5813
5814
5815template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005816void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005817 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005818 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005819}
5820
5821
5822void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5823 typedef v8::String::ExternalAsciiStringResource Resource;
5824 v->VisitExternalAsciiString(
5825 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5826}
5827
5828
5829template<typename StaticVisitor>
5830void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5831 typedef v8::String::ExternalAsciiStringResource Resource;
5832 StaticVisitor::VisitExternalAsciiString(
5833 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5834}
5835
5836
5837void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5838 typedef v8::String::ExternalStringResource Resource;
5839 v->VisitExternalTwoByteString(
5840 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5841}
5842
5843
5844template<typename StaticVisitor>
5845void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5846 typedef v8::String::ExternalStringResource Resource;
5847 StaticVisitor::VisitExternalTwoByteString(
5848 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5849}
5850
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005851
5852template<int start_offset, int end_offset, int size>
5853void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5854 HeapObject* obj,
5855 ObjectVisitor* v) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005856 v->VisitPointers(HeapObject::RawField(obj, start_offset),
5857 HeapObject::RawField(obj, end_offset));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005858}
5859
5860
5861template<int start_offset>
5862void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5863 int object_size,
5864 ObjectVisitor* v) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005865 v->VisitPointers(HeapObject::RawField(obj, start_offset),
5866 HeapObject::RawField(obj, object_size));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005867}
5868
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005869
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005870#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005871#undef CAST_ACCESSOR
5872#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005873#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005874#undef ACCESSORS_TO_SMI
5875#undef SMI_ACCESSORS
5876#undef BOOL_GETTER
5877#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005878#undef FIELD_ADDR
5879#undef READ_FIELD
5880#undef WRITE_FIELD
5881#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005882#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005883#undef READ_DOUBLE_FIELD
5884#undef WRITE_DOUBLE_FIELD
5885#undef READ_INT_FIELD
5886#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005887#undef READ_INTPTR_FIELD
5888#undef WRITE_INTPTR_FIELD
5889#undef READ_UINT32_FIELD
5890#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005891#undef READ_SHORT_FIELD
5892#undef WRITE_SHORT_FIELD
5893#undef READ_BYTE_FIELD
5894#undef WRITE_BYTE_FIELD
5895
5896
5897} } // namespace v8::internal
5898
5899#endif // V8_OBJECTS_INL_H_