blob: ee17363acad88af8f2573259d1b2749c24b2f835 [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"
50
kasperl@chromium.org71affb52009-05-26 05:44:31 +000051namespace v8 {
52namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000053
54PropertyDetails::PropertyDetails(Smi* smi) {
55 value_ = smi->value();
56}
57
58
59Smi* PropertyDetails::AsSmi() {
60 return Smi::FromInt(value_);
61}
62
63
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000064PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000065 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000066 return PropertyDetails(smi);
67}
68
69
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000070#define TYPE_CHECKER(type, instancetype) \
71 bool Object::Is##type() { \
72 return Object::IsHeapObject() && \
73 HeapObject::cast(this)->map()->instance_type() == instancetype; \
74 }
75
76
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077#define CAST_ACCESSOR(type) \
78 type* type::cast(Object* object) { \
79 ASSERT(object->Is##type()); \
80 return reinterpret_cast<type*>(object); \
81 }
82
83
84#define INT_ACCESSORS(holder, name, offset) \
85 int holder::name() { return READ_INT_FIELD(this, offset); } \
86 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
87
88
89#define ACCESSORS(holder, name, type, offset) \
90 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000091 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000093 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094 }
95
96
97#define SMI_ACCESSORS(holder, name, offset) \
98 int holder::name() { \
99 Object* value = READ_FIELD(this, offset); \
100 return Smi::cast(value)->value(); \
101 } \
102 void holder::set_##name(int value) { \
103 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
104 }
105
106
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000107#define BOOL_GETTER(holder, field, name, offset) \
108 bool holder::name() { \
109 return BooleanBit::get(field(), offset); \
110 } \
111
112
113#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000114 bool holder::name() { \
115 return BooleanBit::get(field(), offset); \
116 } \
117 void holder::set_##name(bool value) { \
118 set_##field(BooleanBit::set(field(), offset, value)); \
119 }
120
121
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000122bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
123 ElementsKind to_kind) {
124 if (to_kind == FAST_ELEMENTS) {
125 return from_kind == FAST_SMI_ONLY_ELEMENTS ||
126 from_kind == FAST_DOUBLE_ELEMENTS;
127 } else {
128 return to_kind == FAST_DOUBLE_ELEMENTS &&
129 from_kind == FAST_SMI_ONLY_ELEMENTS;
130 }
131}
132
133
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000134bool Object::IsFixedArrayBase() {
135 return IsFixedArray() || IsFixedDoubleArray();
136}
137
138
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000139bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
140 // There is a constraint on the object; check.
141 if (!this->IsJSObject()) return false;
142 // Fetch the constructor function of the object.
143 Object* cons_obj = JSObject::cast(this)->map()->constructor();
144 if (!cons_obj->IsJSFunction()) return false;
145 JSFunction* fun = JSFunction::cast(cons_obj);
146 // Iterate through the chain of inheriting function templates to
147 // see if the required one occurs.
148 for (Object* type = fun->shared()->function_data();
149 type->IsFunctionTemplateInfo();
150 type = FunctionTemplateInfo::cast(type)->parent_template()) {
151 if (type == expected) return true;
152 }
153 // Didn't find the required type in the inheritance chain.
154 return false;
155}
156
157
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000158bool Object::IsSmi() {
159 return HAS_SMI_TAG(this);
160}
161
162
163bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000164 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000165}
166
167
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000168bool Object::NonFailureIsHeapObject() {
169 ASSERT(!this->IsFailure());
170 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
171}
172
173
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000174TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000175
176
177bool Object::IsString() {
178 return Object::IsHeapObject()
179 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
180}
181
182
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000183bool Object::IsSpecObject() {
184 return Object::IsHeapObject()
185 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
186}
187
188
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000189bool Object::IsSpecFunction() {
190 if (!Object::IsHeapObject()) return false;
191 InstanceType type = HeapObject::cast(this)->map()->instance_type();
192 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
193}
194
195
ager@chromium.org870a0b62008-11-04 11:43:05 +0000196bool Object::IsSymbol() {
197 if (!this->IsHeapObject()) return false;
198 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000199 // Because the symbol tag is non-zero and no non-string types have the
200 // symbol bit set we can test for symbols with a very simple test
201 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000202 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000203 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
204 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000205}
206
207
208bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000209 if (!IsString()) return false;
210 return StringShape(String::cast(this)).IsCons();
211}
212
213
214bool Object::IsSlicedString() {
215 if (!IsString()) return false;
216 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000217}
218
219
ager@chromium.org870a0b62008-11-04 11:43:05 +0000220bool Object::IsSeqString() {
221 if (!IsString()) return false;
222 return StringShape(String::cast(this)).IsSequential();
223}
224
225
226bool Object::IsSeqAsciiString() {
227 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000228 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000229 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000230}
231
232
233bool Object::IsSeqTwoByteString() {
234 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000235 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000236 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000237}
238
239
240bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000241 if (!IsString()) return false;
242 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243}
244
245
246bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000247 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000248 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000249 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000250}
251
252
253bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000254 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000255 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000256 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000257}
258
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000259bool Object::HasValidElements() {
260 // Dictionary is covered under FixedArray.
261 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
262}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000263
ager@chromium.org870a0b62008-11-04 11:43:05 +0000264StringShape::StringShape(String* str)
265 : type_(str->map()->instance_type()) {
266 set_valid();
267 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000268}
269
270
ager@chromium.org870a0b62008-11-04 11:43:05 +0000271StringShape::StringShape(Map* map)
272 : type_(map->instance_type()) {
273 set_valid();
274 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000275}
276
277
ager@chromium.org870a0b62008-11-04 11:43:05 +0000278StringShape::StringShape(InstanceType t)
279 : type_(static_cast<uint32_t>(t)) {
280 set_valid();
281 ASSERT((type_ & kIsNotStringMask) == kStringTag);
282}
283
284
285bool StringShape::IsSymbol() {
286 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000287 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000288 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000289}
290
291
ager@chromium.org5ec48922009-05-05 07:25:34 +0000292bool String::IsAsciiRepresentation() {
293 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000294 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000295}
296
297
ager@chromium.org5ec48922009-05-05 07:25:34 +0000298bool String::IsTwoByteRepresentation() {
299 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000300 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000301}
302
303
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000304bool String::IsAsciiRepresentationUnderneath() {
305 uint32_t type = map()->instance_type();
306 STATIC_ASSERT(kIsIndirectStringTag != 0);
307 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
308 ASSERT(IsFlat());
309 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
310 case kAsciiStringTag:
311 return true;
312 case kTwoByteStringTag:
313 return false;
314 default: // Cons or sliced string. Need to go deeper.
315 return GetUnderlying()->IsAsciiRepresentation();
316 }
317}
318
319
320bool String::IsTwoByteRepresentationUnderneath() {
321 uint32_t type = map()->instance_type();
322 STATIC_ASSERT(kIsIndirectStringTag != 0);
323 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
324 ASSERT(IsFlat());
325 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
326 case kAsciiStringTag:
327 return false;
328 case kTwoByteStringTag:
329 return true;
330 default: // Cons or sliced string. Need to go deeper.
331 return GetUnderlying()->IsTwoByteRepresentation();
332 }
333}
334
335
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000336bool String::HasOnlyAsciiChars() {
337 uint32_t type = map()->instance_type();
338 return (type & kStringEncodingMask) == kAsciiStringTag ||
339 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000340}
341
342
ager@chromium.org870a0b62008-11-04 11:43:05 +0000343bool StringShape::IsCons() {
344 return (type_ & kStringRepresentationMask) == kConsStringTag;
345}
346
347
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000348bool StringShape::IsSliced() {
349 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
350}
351
352
353bool StringShape::IsIndirect() {
354 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
355}
356
357
ager@chromium.org870a0b62008-11-04 11:43:05 +0000358bool StringShape::IsExternal() {
359 return (type_ & kStringRepresentationMask) == kExternalStringTag;
360}
361
362
363bool StringShape::IsSequential() {
364 return (type_ & kStringRepresentationMask) == kSeqStringTag;
365}
366
367
368StringRepresentationTag StringShape::representation_tag() {
369 uint32_t tag = (type_ & kStringRepresentationMask);
370 return static_cast<StringRepresentationTag>(tag);
371}
372
373
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000374uint32_t StringShape::encoding_tag() {
375 return type_ & kStringEncodingMask;
376}
377
378
ager@chromium.org870a0b62008-11-04 11:43:05 +0000379uint32_t StringShape::full_representation_tag() {
380 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
381}
382
383
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000384STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
385 Internals::kFullStringRepresentationMask);
386
387
ager@chromium.org870a0b62008-11-04 11:43:05 +0000388bool StringShape::IsSequentialAscii() {
389 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
390}
391
392
393bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000394 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000395}
396
397
398bool StringShape::IsExternalAscii() {
399 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
400}
401
402
403bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000404 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000405}
406
407
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000408STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
409 Internals::kExternalTwoByteRepresentationTag);
410
411
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000412uc32 FlatStringReader::Get(int index) {
413 ASSERT(0 <= index && index <= length_);
414 if (is_ascii_) {
415 return static_cast<const byte*>(start_)[index];
416 } else {
417 return static_cast<const uc16*>(start_)[index];
418 }
419}
420
421
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000422bool Object::IsNumber() {
423 return IsSmi() || IsHeapNumber();
424}
425
426
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000427TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
428TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000429
430
431bool Object::IsFiller() {
432 if (!Object::IsHeapObject()) return false;
433 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
434 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
435}
436
437
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000438TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000439
440
ager@chromium.org3811b432009-10-28 14:53:37 +0000441bool Object::IsExternalArray() {
442 if (!Object::IsHeapObject())
443 return false;
444 InstanceType instance_type =
445 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000446 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
447 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000448}
449
450
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000451TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
452TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
453TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
454TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
455TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
456TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
457TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
458TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000459
460
lrn@chromium.org303ada72010-10-27 09:33:13 +0000461bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000462 return HAS_FAILURE_TAG(this);
463}
464
465
lrn@chromium.org303ada72010-10-27 09:33:13 +0000466bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000467 return HAS_FAILURE_TAG(this)
468 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
469}
470
471
lrn@chromium.org303ada72010-10-27 09:33:13 +0000472bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000473 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000474 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000475}
476
477
lrn@chromium.org303ada72010-10-27 09:33:13 +0000478bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000479 return this == Failure::Exception();
480}
481
482
lrn@chromium.org303ada72010-10-27 09:33:13 +0000483bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000484 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000485}
486
487
488Failure* Failure::cast(MaybeObject* obj) {
489 ASSERT(HAS_FAILURE_TAG(obj));
490 return reinterpret_cast<Failure*>(obj);
491}
492
493
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000494bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000495 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000496 return IsHeapObject() &&
497 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
498}
499
500
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000501bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000502 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
503 return IsHeapObject() &&
504 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000505}
506
507
508bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000509 if (!Object::IsHeapObject()) return false;
510 InstanceType type = HeapObject::cast(this)->map()->instance_type();
511 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000512}
513
514
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000515TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
516TYPE_CHECKER(JSSet, JS_SET_TYPE)
517TYPE_CHECKER(JSMap, JS_MAP_TYPE)
518TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
519TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
520TYPE_CHECKER(Map, MAP_TYPE)
521TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
522TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000523
524
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000525bool Object::IsDescriptorArray() {
526 return IsFixedArray();
527}
528
529
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000530bool Object::IsDeoptimizationInputData() {
531 // Must be a fixed array.
532 if (!IsFixedArray()) return false;
533
534 // There's no sure way to detect the difference between a fixed array and
535 // a deoptimization data array. Since this is used for asserts we can
536 // check that the length is zero or else the fixed size plus a multiple of
537 // the entry size.
538 int length = FixedArray::cast(this)->length();
539 if (length == 0) return true;
540
541 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
542 return length >= 0 &&
543 length % DeoptimizationInputData::kDeoptEntrySize == 0;
544}
545
546
547bool Object::IsDeoptimizationOutputData() {
548 if (!IsFixedArray()) return false;
549 // There's actually no way to see the difference between a fixed array and
550 // a deoptimization data array. Since this is used for asserts we can check
551 // that the length is plausible though.
552 if (FixedArray::cast(this)->length() % 2 != 0) return false;
553 return true;
554}
555
556
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000557bool Object::IsTypeFeedbackCells() {
558 if (!IsFixedArray()) return false;
559 // There's actually no way to see the difference between a fixed array and
560 // a cache cells array. Since this is used for asserts we can check that
561 // the length is plausible though.
562 if (FixedArray::cast(this)->length() % 2 != 0) return false;
563 return true;
564}
565
566
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000567bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000568 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000569 Map* map = HeapObject::cast(this)->map();
570 Heap* heap = map->GetHeap();
571 return (map == heap->function_context_map() ||
572 map == heap->catch_context_map() ||
573 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000574 map == heap->global_context_map() ||
575 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000576 }
577 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000578}
579
580
581bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000582 return Object::IsHeapObject() &&
583 HeapObject::cast(this)->map() ==
584 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000585}
586
587
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000588bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000589 return Object::IsHeapObject() &&
590 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000591 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000592}
593
594
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000595TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000596
597
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000598template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000599 return obj->IsJSFunction();
600}
601
602
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000603TYPE_CHECKER(Code, CODE_TYPE)
604TYPE_CHECKER(Oddball, ODDBALL_TYPE)
605TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
606TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
607TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
608TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000609
610
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000611bool Object::IsStringWrapper() {
612 return IsJSValue() && JSValue::cast(this)->value()->IsString();
613}
614
615
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000616TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000617
618
619bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000620 return IsOddball() &&
621 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000622}
623
624
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000625TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
626TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000627
628
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000629template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000630 return obj->IsJSArray();
631}
632
633
634bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000635 return Object::IsHeapObject() &&
636 HeapObject::cast(this)->map() ==
637 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000638}
639
640
641bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000642 return IsHashTable() &&
643 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000644}
645
646
647bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000648 return IsHashTable() && this ==
649 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000650}
651
652
ager@chromium.orgac091b72010-05-05 07:34:42 +0000653bool Object::IsJSFunctionResultCache() {
654 if (!IsFixedArray()) return false;
655 FixedArray* self = FixedArray::cast(this);
656 int length = self->length();
657 if (length < JSFunctionResultCache::kEntriesIndex) return false;
658 if ((length - JSFunctionResultCache::kEntriesIndex)
659 % JSFunctionResultCache::kEntrySize != 0) {
660 return false;
661 }
662#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000663 if (FLAG_verify_heap) {
664 reinterpret_cast<JSFunctionResultCache*>(this)->
665 JSFunctionResultCacheVerify();
666 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000667#endif
668 return true;
669}
670
671
ricow@chromium.org65fae842010-08-25 15:26:24 +0000672bool Object::IsNormalizedMapCache() {
673 if (!IsFixedArray()) return false;
674 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
675 return false;
676 }
677#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000678 if (FLAG_verify_heap) {
679 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
680 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000681#endif
682 return true;
683}
684
685
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000686bool Object::IsCompilationCacheTable() {
687 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000688}
689
690
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000691bool Object::IsCodeCacheHashTable() {
692 return IsHashTable();
693}
694
695
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000696bool Object::IsPolymorphicCodeCacheHashTable() {
697 return IsHashTable();
698}
699
700
ager@chromium.org236ad962008-09-25 09:45:57 +0000701bool Object::IsMapCache() {
702 return IsHashTable();
703}
704
705
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000706bool Object::IsPrimitive() {
707 return IsOddball() || IsNumber() || IsString();
708}
709
710
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000711bool Object::IsJSGlobalProxy() {
712 bool result = IsHeapObject() &&
713 (HeapObject::cast(this)->map()->instance_type() ==
714 JS_GLOBAL_PROXY_TYPE);
715 ASSERT(!result || IsAccessCheckNeeded());
716 return result;
717}
718
719
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000720bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000721 if (!IsHeapObject()) return false;
722
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000723 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000724 return type == JS_GLOBAL_OBJECT_TYPE ||
725 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000726}
727
728
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000729TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
730TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000731
732
733bool Object::IsUndetectableObject() {
734 return IsHeapObject()
735 && HeapObject::cast(this)->map()->is_undetectable();
736}
737
738
739bool Object::IsAccessCheckNeeded() {
740 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000741 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000742}
743
744
745bool Object::IsStruct() {
746 if (!IsHeapObject()) return false;
747 switch (HeapObject::cast(this)->map()->instance_type()) {
748#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
749 STRUCT_LIST(MAKE_STRUCT_CASE)
750#undef MAKE_STRUCT_CASE
751 default: return false;
752 }
753}
754
755
756#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
757 bool Object::Is##Name() { \
758 return Object::IsHeapObject() \
759 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
760 }
761 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
762#undef MAKE_STRUCT_PREDICATE
763
764
765bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000766 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000767}
768
769
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000770bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000771 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
772}
773
774
775bool Object::IsTheHole() {
776 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777}
778
779
780bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000781 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000782}
783
784
785bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000786 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787}
788
789
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000790bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000791 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000792}
793
794
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000795double Object::Number() {
796 ASSERT(IsNumber());
797 return IsSmi()
798 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
799 : reinterpret_cast<HeapNumber*>(this)->value();
800}
801
802
lrn@chromium.org303ada72010-10-27 09:33:13 +0000803MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804 if (IsSmi()) return this;
805 if (IsHeapNumber()) {
806 double value = HeapNumber::cast(this)->value();
807 int int_value = FastD2I(value);
808 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
809 return Smi::FromInt(int_value);
810 }
811 }
812 return Failure::Exception();
813}
814
815
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000816bool Object::HasSpecificClassOf(String* name) {
817 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
818}
819
820
lrn@chromium.org303ada72010-10-27 09:33:13 +0000821MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000822 // GetElement can trigger a getter which can cause allocation.
823 // This was not always the case. This ASSERT is here to catch
824 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000825 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000826 return GetElementWithReceiver(this, index);
827}
828
829
lrn@chromium.org303ada72010-10-27 09:33:13 +0000830Object* Object::GetElementNoExceptionThrown(uint32_t index) {
831 MaybeObject* maybe = GetElementWithReceiver(this, index);
832 ASSERT(!maybe->IsFailure());
833 Object* result = NULL; // Initialization to please compiler.
834 maybe->ToObject(&result);
835 return result;
836}
837
838
839MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000840 PropertyAttributes attributes;
841 return GetPropertyWithReceiver(this, key, &attributes);
842}
843
844
lrn@chromium.org303ada72010-10-27 09:33:13 +0000845MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000846 return GetPropertyWithReceiver(this, key, attributes);
847}
848
849
850#define FIELD_ADDR(p, offset) \
851 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
852
853#define READ_FIELD(p, offset) \
854 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
855
856#define WRITE_FIELD(p, offset, value) \
857 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
858
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000859#define WRITE_BARRIER(heap, object, offset, value) \
860 heap->incremental_marking()->RecordWrite( \
861 object, HeapObject::RawField(object, offset), value); \
862 if (heap->InNewSpace(value)) { \
863 heap->RecordWrite(object->address(), offset); \
864 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000865
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000866#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
867 if (mode == UPDATE_WRITE_BARRIER) { \
868 heap->incremental_marking()->RecordWrite( \
869 object, HeapObject::RawField(object, offset), value); \
870 if (heap->InNewSpace(value)) { \
871 heap->RecordWrite(object->address(), offset); \
872 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000873 }
874
lrn@chromium.org7516f052011-03-30 08:52:27 +0000875#ifndef V8_TARGET_ARCH_MIPS
876 #define READ_DOUBLE_FIELD(p, offset) \
877 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
878#else // V8_TARGET_ARCH_MIPS
879 // Prevent gcc from using load-double (mips ldc1) on (possibly)
880 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000881 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000882 union conversion {
883 double d;
884 uint32_t u[2];
885 } c;
886 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
887 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
888 return c.d;
889 }
890 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
891#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000892
lrn@chromium.org7516f052011-03-30 08:52:27 +0000893#ifndef V8_TARGET_ARCH_MIPS
894 #define WRITE_DOUBLE_FIELD(p, offset, value) \
895 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
896#else // V8_TARGET_ARCH_MIPS
897 // Prevent gcc from using store-double (mips sdc1) on (possibly)
898 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000899 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000900 double value) {
901 union conversion {
902 double d;
903 uint32_t u[2];
904 } c;
905 c.d = value;
906 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
907 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
908 }
909 #define WRITE_DOUBLE_FIELD(p, offset, value) \
910 write_double_field(p, offset, value)
911#endif // V8_TARGET_ARCH_MIPS
912
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000913
914#define READ_INT_FIELD(p, offset) \
915 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
916
917#define WRITE_INT_FIELD(p, offset, value) \
918 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
919
ager@chromium.org3e875802009-06-29 08:26:34 +0000920#define READ_INTPTR_FIELD(p, offset) \
921 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
922
923#define WRITE_INTPTR_FIELD(p, offset, value) \
924 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
925
ager@chromium.org7c537e22008-10-16 08:43:32 +0000926#define READ_UINT32_FIELD(p, offset) \
927 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
928
929#define WRITE_UINT32_FIELD(p, offset, value) \
930 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
931
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000932#define READ_SHORT_FIELD(p, offset) \
933 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
934
935#define WRITE_SHORT_FIELD(p, offset, value) \
936 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
937
938#define READ_BYTE_FIELD(p, offset) \
939 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
940
941#define WRITE_BYTE_FIELD(p, offset, value) \
942 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
943
944
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000945Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
946 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000947}
948
949
950int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000951 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000952}
953
954
955Smi* Smi::FromInt(int value) {
956 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000957 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000958 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000959 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000960 return reinterpret_cast<Smi*>(tagged_value);
961}
962
963
964Smi* Smi::FromIntptr(intptr_t value) {
965 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000966 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
967 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000968}
969
970
971Failure::Type Failure::type() const {
972 return static_cast<Type>(value() & kFailureTypeTagMask);
973}
974
975
976bool Failure::IsInternalError() const {
977 return type() == INTERNAL_ERROR;
978}
979
980
981bool Failure::IsOutOfMemoryException() const {
982 return type() == OUT_OF_MEMORY_EXCEPTION;
983}
984
985
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000986AllocationSpace Failure::allocation_space() const {
987 ASSERT_EQ(RETRY_AFTER_GC, type());
988 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
989 & kSpaceTagMask);
990}
991
992
993Failure* Failure::InternalError() {
994 return Construct(INTERNAL_ERROR);
995}
996
997
998Failure* Failure::Exception() {
999 return Construct(EXCEPTION);
1000}
1001
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001002
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001003Failure* Failure::OutOfMemoryException() {
1004 return Construct(OUT_OF_MEMORY_EXCEPTION);
1005}
1006
1007
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001008intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001009 return static_cast<intptr_t>(
1010 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001011}
1012
1013
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001014Failure* Failure::RetryAfterGC() {
1015 return RetryAfterGC(NEW_SPACE);
1016}
1017
1018
1019Failure* Failure::RetryAfterGC(AllocationSpace space) {
1020 ASSERT((space & ~kSpaceTagMask) == 0);
1021 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001022}
1023
1024
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001025Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001026 uintptr_t info =
1027 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001028 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001029 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001030}
1031
1032
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001033bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001034#ifdef DEBUG
1035 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1036#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001037
1038#ifdef V8_TARGET_ARCH_X64
1039 // To be representable as a long smi, the value must be a 32-bit integer.
1040 bool result = (value == static_cast<int32_t>(value));
1041#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001042 // To be representable as an tagged small integer, the two
1043 // most-significant bits of 'value' must be either 00 or 11 due to
1044 // sign-extension. To check this we add 01 to the two
1045 // most-significant bits, and check if the most-significant bit is 0
1046 //
1047 // CAUTION: The original code below:
1048 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1049 // may lead to incorrect results according to the C language spec, and
1050 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1051 // compiler may produce undefined results in case of signed integer
1052 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001053 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001054#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001055 ASSERT(result == in_range);
1056 return result;
1057}
1058
1059
kasper.lund7276f142008-07-30 08:49:36 +00001060MapWord MapWord::FromMap(Map* map) {
1061 return MapWord(reinterpret_cast<uintptr_t>(map));
1062}
1063
1064
1065Map* MapWord::ToMap() {
1066 return reinterpret_cast<Map*>(value_);
1067}
1068
1069
1070bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001071 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001072}
1073
1074
1075MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001076 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1077 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001078}
1079
1080
1081HeapObject* MapWord::ToForwardingAddress() {
1082 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001083 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001084}
1085
1086
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001087#ifdef DEBUG
1088void HeapObject::VerifyObjectField(int offset) {
1089 VerifyPointer(READ_FIELD(this, offset));
1090}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001091
1092void HeapObject::VerifySmiField(int offset) {
1093 ASSERT(READ_FIELD(this, offset)->IsSmi());
1094}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001095#endif
1096
1097
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001098Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001099 Heap* heap =
1100 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1101 ASSERT(heap != NULL);
1102 ASSERT(heap->isolate() == Isolate::Current());
1103 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001104}
1105
1106
1107Isolate* HeapObject::GetIsolate() {
1108 return GetHeap()->isolate();
1109}
1110
1111
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001112Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001113 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001114}
1115
1116
1117void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001118 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001119 if (value != NULL) {
1120 // TODO(1600) We are passing NULL as a slot because maps can never be on
1121 // evacuation candidate.
1122 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1123 }
1124}
1125
1126
1127// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001128void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001129 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001130}
1131
1132
kasper.lund7276f142008-07-30 08:49:36 +00001133MapWord HeapObject::map_word() {
1134 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1135}
1136
1137
1138void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001139 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001140 // here.
1141 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1142}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001143
1144
1145HeapObject* HeapObject::FromAddress(Address address) {
1146 ASSERT_TAG_ALIGNED(address);
1147 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1148}
1149
1150
1151Address HeapObject::address() {
1152 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1153}
1154
1155
1156int HeapObject::Size() {
1157 return SizeFromMap(map());
1158}
1159
1160
1161void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1162 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1163 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1164}
1165
1166
1167void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1168 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1169}
1170
1171
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001172double HeapNumber::value() {
1173 return READ_DOUBLE_FIELD(this, kValueOffset);
1174}
1175
1176
1177void HeapNumber::set_value(double value) {
1178 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1179}
1180
1181
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001182int HeapNumber::get_exponent() {
1183 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1184 kExponentShift) - kExponentBias;
1185}
1186
1187
1188int HeapNumber::get_sign() {
1189 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1190}
1191
1192
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001193ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001194
1195
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001196Object** FixedArray::GetFirstElementAddress() {
1197 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1198}
1199
1200
1201bool FixedArray::ContainsOnlySmisOrHoles() {
1202 Object* the_hole = GetHeap()->the_hole_value();
1203 Object** current = GetFirstElementAddress();
1204 for (int i = 0; i < length(); ++i) {
1205 Object* candidate = *current++;
1206 if (!candidate->IsSmi() && candidate != the_hole) return false;
1207 }
1208 return true;
1209}
1210
1211
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001212FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001213 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001214 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001215}
1216
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001217void JSObject::ValidateSmiOnlyElements() {
1218#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001219 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001220 Heap* heap = GetHeap();
1221 // Don't use elements, since integrity checks will fail if there
1222 // are filler pointers in the array.
1223 FixedArray* fixed_array =
1224 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1225 Map* map = fixed_array->map();
1226 // Arrays that have been shifted in place can't be verified.
1227 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1228 map != heap->raw_unchecked_two_pointer_filler_map() &&
1229 map != heap->free_space_map()) {
1230 for (int i = 0; i < fixed_array->length(); i++) {
1231 Object* current = fixed_array->get(i);
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001232 ASSERT(current->IsSmi() || current->IsTheHole());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001233 }
1234 }
1235 }
1236#endif
1237}
1238
1239
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001240MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001241#if DEBUG
1242 ValidateSmiOnlyElements();
1243#endif
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001244 if ((map()->elements_kind() != FAST_ELEMENTS)) {
1245 return TransitionElementsKind(FAST_ELEMENTS);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001246 }
1247 return this;
1248}
1249
1250
1251MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001252 uint32_t count,
1253 EnsureElementsMode mode) {
1254 ElementsKind current_kind = map()->elements_kind();
1255 ElementsKind target_kind = current_kind;
1256 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1257 if (current_kind == FAST_ELEMENTS) return this;
1258
1259 Heap* heap = GetHeap();
1260 Object* the_hole = heap->the_hole_value();
1261 Object* heap_number_map = heap->heap_number_map();
1262 for (uint32_t i = 0; i < count; ++i) {
1263 Object* current = *objects++;
1264 if (!current->IsSmi() && current != the_hole) {
1265 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
1266 HeapObject::cast(current)->map() == heap_number_map) {
1267 target_kind = FAST_DOUBLE_ELEMENTS;
1268 } else {
1269 target_kind = FAST_ELEMENTS;
1270 break;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001271 }
1272 }
1273 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001274
1275 if (target_kind != current_kind) {
1276 return TransitionElementsKind(target_kind);
1277 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001278 return this;
1279}
1280
1281
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001282MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
1283 EnsureElementsMode mode) {
1284 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1285 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1286 elements->map() == GetHeap()->fixed_cow_array_map());
1287 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1288 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1289 }
1290 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
1291 return EnsureCanContainElements(objects, elements->length(), mode);
1292 }
1293
1294 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1295 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1296 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1297 }
1298
1299 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001300}
1301
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001302
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001303MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1304 ElementsKind to_kind) {
1305 Map* current_map = map();
1306 ElementsKind from_kind = current_map->elements_kind();
1307
1308 if (from_kind == to_kind) return current_map;
1309
1310 Context* global_context = isolate->context()->global_context();
1311 if (current_map == global_context->smi_js_array_map()) {
1312 if (to_kind == FAST_ELEMENTS) {
1313 return global_context->object_js_array_map();
1314 } else {
1315 if (to_kind == FAST_DOUBLE_ELEMENTS) {
1316 return global_context->double_js_array_map();
1317 } else {
1318 ASSERT(to_kind == DICTIONARY_ELEMENTS);
1319 }
1320 }
1321 }
1322 return GetElementsTransitionMapSlow(to_kind);
1323}
1324
1325
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001326void JSObject::set_map_and_elements(Map* new_map,
1327 FixedArrayBase* value,
1328 WriteBarrierMode mode) {
1329 ASSERT(value->HasValidElements());
1330#ifdef DEBUG
1331 ValidateSmiOnlyElements();
1332#endif
1333 if (new_map != NULL) {
1334 if (mode == UPDATE_WRITE_BARRIER) {
1335 set_map(new_map);
1336 } else {
1337 ASSERT(mode == SKIP_WRITE_BARRIER);
1338 set_map_no_write_barrier(new_map);
1339 }
1340 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001341 ASSERT((map()->has_fast_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001342 map()->has_fast_smi_only_elements() ||
1343 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001344 (value->map() == GetHeap()->fixed_array_map() ||
1345 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001346 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1347 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001348 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001349 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001350}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001351
1352
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001353void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1354 set_map_and_elements(NULL, value, mode);
1355}
1356
1357
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001358void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001359 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1360 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001361}
1362
1363
1364void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001365 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001366 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1367 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001368}
1369
1370
lrn@chromium.org303ada72010-10-27 09:33:13 +00001371MaybeObject* JSObject::ResetElements() {
1372 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001373 ElementsKind elements_kind = FLAG_smi_only_arrays
1374 ? FAST_SMI_ONLY_ELEMENTS
1375 : FAST_ELEMENTS;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001376 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1377 elements_kind);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001378 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001379 set_map(Map::cast(obj));
1380 initialize_elements();
1381 return this;
1382}
1383
1384
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001385ACCESSORS(Oddball, to_string, String, kToStringOffset)
1386ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1387
1388
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001389byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001390 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001391}
1392
1393
1394void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001395 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001396}
1397
1398
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001399Object* JSGlobalPropertyCell::value() {
1400 return READ_FIELD(this, kValueOffset);
1401}
1402
1403
1404void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1405 // The write barrier is not used for global property cells.
1406 ASSERT(!val->IsJSGlobalPropertyCell());
1407 WRITE_FIELD(this, kValueOffset, val);
1408}
1409
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001410
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001411int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001412 InstanceType type = map()->instance_type();
1413 // Check for the most common kind of JavaScript object before
1414 // falling into the generic switch. This speeds up the internal
1415 // field operations considerably on average.
1416 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1417 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001418 case JS_GLOBAL_PROXY_TYPE:
1419 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001420 case JS_GLOBAL_OBJECT_TYPE:
1421 return JSGlobalObject::kSize;
1422 case JS_BUILTINS_OBJECT_TYPE:
1423 return JSBuiltinsObject::kSize;
1424 case JS_FUNCTION_TYPE:
1425 return JSFunction::kSize;
1426 case JS_VALUE_TYPE:
1427 return JSValue::kSize;
1428 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001429 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001430 case JS_WEAK_MAP_TYPE:
1431 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001432 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001433 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001434 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001435 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001436 case JS_MESSAGE_OBJECT_TYPE:
1437 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001438 default:
1439 UNREACHABLE();
1440 return 0;
1441 }
1442}
1443
1444
1445int JSObject::GetInternalFieldCount() {
1446 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001447 // Make sure to adjust for the number of in-object properties. These
1448 // properties do contribute to the size, but are not internal fields.
1449 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1450 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001451}
1452
1453
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001454int JSObject::GetInternalFieldOffset(int index) {
1455 ASSERT(index < GetInternalFieldCount() && index >= 0);
1456 return GetHeaderSize() + (kPointerSize * index);
1457}
1458
1459
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001460Object* JSObject::GetInternalField(int index) {
1461 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001462 // Internal objects do follow immediately after the header, whereas in-object
1463 // properties are at the end of the object. Therefore there is no need
1464 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001465 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1466}
1467
1468
1469void JSObject::SetInternalField(int index, Object* value) {
1470 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001471 // Internal objects do follow immediately after the header, whereas in-object
1472 // properties are at the end of the object. Therefore there is no need
1473 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001474 int offset = GetHeaderSize() + (kPointerSize * index);
1475 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001476 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001477}
1478
1479
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001480void JSObject::SetInternalField(int index, Smi* value) {
1481 ASSERT(index < GetInternalFieldCount() && index >= 0);
1482 // Internal objects do follow immediately after the header, whereas in-object
1483 // properties are at the end of the object. Therefore there is no need
1484 // to adjust the index here.
1485 int offset = GetHeaderSize() + (kPointerSize * index);
1486 WRITE_FIELD(this, offset, value);
1487}
1488
1489
ager@chromium.org7c537e22008-10-16 08:43:32 +00001490// Access fast-case object properties at index. The use of these routines
1491// is needed to correctly distinguish between properties stored in-object and
1492// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001493Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001494 // Adjust for the number of properties stored in the object.
1495 index -= map()->inobject_properties();
1496 if (index < 0) {
1497 int offset = map()->instance_size() + (index * kPointerSize);
1498 return READ_FIELD(this, offset);
1499 } else {
1500 ASSERT(index < properties()->length());
1501 return properties()->get(index);
1502 }
1503}
1504
1505
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001506Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001507 // Adjust for the number of properties stored in the object.
1508 index -= map()->inobject_properties();
1509 if (index < 0) {
1510 int offset = map()->instance_size() + (index * kPointerSize);
1511 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001512 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001513 } else {
1514 ASSERT(index < properties()->length());
1515 properties()->set(index, value);
1516 }
1517 return value;
1518}
1519
1520
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001521int JSObject::GetInObjectPropertyOffset(int index) {
1522 // Adjust for the number of properties stored in the object.
1523 index -= map()->inobject_properties();
1524 ASSERT(index < 0);
1525 return map()->instance_size() + (index * kPointerSize);
1526}
1527
1528
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001529Object* JSObject::InObjectPropertyAt(int index) {
1530 // Adjust for the number of properties stored in the object.
1531 index -= map()->inobject_properties();
1532 ASSERT(index < 0);
1533 int offset = map()->instance_size() + (index * kPointerSize);
1534 return READ_FIELD(this, offset);
1535}
1536
1537
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001538Object* JSObject::InObjectPropertyAtPut(int index,
1539 Object* value,
1540 WriteBarrierMode mode) {
1541 // Adjust for the number of properties stored in the object.
1542 index -= map()->inobject_properties();
1543 ASSERT(index < 0);
1544 int offset = map()->instance_size() + (index * kPointerSize);
1545 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001546 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001547 return value;
1548}
1549
1550
1551
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001552void JSObject::InitializeBody(Map* map,
1553 Object* pre_allocated_value,
1554 Object* filler_value) {
1555 ASSERT(!filler_value->IsHeapObject() ||
1556 !GetHeap()->InNewSpace(filler_value));
1557 ASSERT(!pre_allocated_value->IsHeapObject() ||
1558 !GetHeap()->InNewSpace(pre_allocated_value));
1559 int size = map->instance_size();
1560 int offset = kHeaderSize;
1561 if (filler_value != pre_allocated_value) {
1562 int pre_allocated = map->pre_allocated_property_fields();
1563 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1564 for (int i = 0; i < pre_allocated; i++) {
1565 WRITE_FIELD(this, offset, pre_allocated_value);
1566 offset += kPointerSize;
1567 }
1568 }
1569 while (offset < size) {
1570 WRITE_FIELD(this, offset, filler_value);
1571 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001572 }
1573}
1574
1575
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001576bool JSObject::HasFastProperties() {
1577 return !properties()->IsDictionary();
1578}
1579
1580
1581int JSObject::MaxFastProperties() {
1582 // Allow extra fast properties if the object has more than
1583 // kMaxFastProperties in-object properties. When this is the case,
1584 // it is very unlikely that the object is being used as a dictionary
1585 // and there is a good chance that allowing more map transitions
1586 // will be worth it.
1587 return Max(map()->inobject_properties(), kMaxFastProperties);
1588}
1589
1590
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001591void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001592 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001593 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001594 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001595 }
1596}
1597
1598
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001599bool Object::ToArrayIndex(uint32_t* index) {
1600 if (IsSmi()) {
1601 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001602 if (value < 0) return false;
1603 *index = value;
1604 return true;
1605 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001606 if (IsHeapNumber()) {
1607 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001608 uint32_t uint_value = static_cast<uint32_t>(value);
1609 if (value == static_cast<double>(uint_value)) {
1610 *index = uint_value;
1611 return true;
1612 }
1613 }
1614 return false;
1615}
1616
1617
1618bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1619 if (!this->IsJSValue()) return false;
1620
1621 JSValue* js_value = JSValue::cast(this);
1622 if (!js_value->value()->IsString()) return false;
1623
1624 String* str = String::cast(js_value->value());
1625 if (index >= (uint32_t)str->length()) return false;
1626
1627 return true;
1628}
1629
1630
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001631FixedArrayBase* FixedArrayBase::cast(Object* object) {
1632 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1633 return reinterpret_cast<FixedArrayBase*>(object);
1634}
1635
1636
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637Object* FixedArray::get(int index) {
1638 ASSERT(index >= 0 && index < this->length());
1639 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1640}
1641
1642
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001643void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001644 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001645 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001646 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1647 int offset = kHeaderSize + index * kPointerSize;
1648 WRITE_FIELD(this, offset, value);
1649}
1650
1651
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001652void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001653 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001654 ASSERT(index >= 0 && index < this->length());
1655 int offset = kHeaderSize + index * kPointerSize;
1656 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001657 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001658}
1659
1660
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001661inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1662 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1663}
1664
1665
1666inline double FixedDoubleArray::hole_nan_as_double() {
1667 return BitCast<double, uint64_t>(kHoleNanInt64);
1668}
1669
1670
1671inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1672 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1673 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1674 return OS::nan_value();
1675}
1676
1677
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001678double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001679 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1680 map() != HEAP->fixed_array_map());
1681 ASSERT(index >= 0 && index < this->length());
1682 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1683 ASSERT(!is_the_hole_nan(result));
1684 return result;
1685}
1686
1687
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001688MaybeObject* FixedDoubleArray::get(int index) {
1689 if (is_the_hole(index)) {
1690 return GetHeap()->the_hole_value();
1691 } else {
1692 return GetHeap()->NumberFromDouble(get_scalar(index));
1693 }
1694}
1695
1696
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001697void FixedDoubleArray::set(int index, double value) {
1698 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1699 map() != HEAP->fixed_array_map());
1700 int offset = kHeaderSize + index * kDoubleSize;
1701 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1702 WRITE_DOUBLE_FIELD(this, offset, value);
1703}
1704
1705
1706void FixedDoubleArray::set_the_hole(int index) {
1707 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1708 map() != HEAP->fixed_array_map());
1709 int offset = kHeaderSize + index * kDoubleSize;
1710 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1711}
1712
1713
1714bool FixedDoubleArray::is_the_hole(int index) {
1715 int offset = kHeaderSize + index * kDoubleSize;
1716 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1717}
1718
1719
1720void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1721 int old_length = from->length();
1722 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001723 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1724 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1725 FIELD_ADDR(from, kHeaderSize),
1726 old_length * kDoubleSize);
1727 } else {
1728 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001729 if (from->is_the_hole(i)) {
1730 set_the_hole(i);
1731 } else {
1732 set(i, from->get_scalar(i));
1733 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001734 }
1735 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001736 int offset = kHeaderSize + old_length * kDoubleSize;
1737 for (int current = from->length(); current < length(); ++current) {
1738 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1739 offset += kDoubleSize;
1740 }
1741}
1742
1743
1744void FixedDoubleArray::Initialize(FixedArray* from) {
1745 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001746 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001747 for (int i = 0; i < old_length; i++) {
1748 Object* hole_or_object = from->get(i);
1749 if (hole_or_object->IsTheHole()) {
1750 set_the_hole(i);
1751 } else {
1752 set(i, hole_or_object->Number());
1753 }
1754 }
1755 int offset = kHeaderSize + old_length * kDoubleSize;
1756 for (int current = from->length(); current < length(); ++current) {
1757 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1758 offset += kDoubleSize;
1759 }
1760}
1761
1762
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001763void FixedDoubleArray::Initialize(SeededNumberDictionary* from) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001764 int offset = kHeaderSize;
1765 for (int current = 0; current < length(); ++current) {
1766 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1767 offset += kDoubleSize;
1768 }
1769 for (int i = 0; i < from->Capacity(); i++) {
1770 Object* key = from->KeyAt(i);
1771 if (key->IsNumber()) {
1772 uint32_t entry = static_cast<uint32_t>(key->Number());
1773 set(entry, from->ValueAt(i)->Number());
1774 }
1775 }
1776}
1777
1778
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001779WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001780 Heap* heap = GetHeap();
1781 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1782 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001783 return UPDATE_WRITE_BARRIER;
1784}
1785
1786
1787void FixedArray::set(int index,
1788 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001789 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001790 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001791 ASSERT(index >= 0 && index < this->length());
1792 int offset = kHeaderSize + index * kPointerSize;
1793 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001794 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001795}
1796
1797
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001798void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1799 int index,
1800 Object* value) {
1801 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1802 ASSERT(index >= 0 && index < array->length());
1803 int offset = kHeaderSize + index * kPointerSize;
1804 WRITE_FIELD(array, offset, value);
1805 Heap* heap = array->GetHeap();
1806 if (heap->InNewSpace(value)) {
1807 heap->RecordWrite(array->address(), offset);
1808 }
1809}
1810
1811
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001812void FixedArray::NoWriteBarrierSet(FixedArray* array,
1813 int index,
1814 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001815 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001816 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001817 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001818 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1819}
1820
1821
1822void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001823 ASSERT(map() != HEAP->fixed_cow_array_map());
1824 set_undefined(GetHeap(), index);
1825}
1826
1827
1828void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001829 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001830 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001831 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001832 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001833}
1834
1835
ager@chromium.org236ad962008-09-25 09:45:57 +00001836void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001837 set_null(GetHeap(), index);
1838}
1839
1840
1841void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001842 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001843 ASSERT(!heap->InNewSpace(heap->null_value()));
1844 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001845}
1846
1847
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001848void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001849 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001850 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001851 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1852 WRITE_FIELD(this,
1853 kHeaderSize + index * kPointerSize,
1854 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001855}
1856
1857
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001858void FixedArray::set_unchecked(int index, Smi* value) {
1859 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1860 int offset = kHeaderSize + index * kPointerSize;
1861 WRITE_FIELD(this, offset, value);
1862}
1863
1864
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001865void FixedArray::set_unchecked(Heap* heap,
1866 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001867 Object* value,
1868 WriteBarrierMode mode) {
1869 int offset = kHeaderSize + index * kPointerSize;
1870 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001871 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001872}
1873
1874
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001875void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001876 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001877 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1878 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001879}
1880
1881
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001882Object** FixedArray::data_start() {
1883 return HeapObject::RawField(this, kHeaderSize);
1884}
1885
1886
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001887bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001888 ASSERT(this->IsSmi() ||
1889 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001890 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001891 return this->IsSmi() || length() <= kFirstIndex;
1892}
1893
1894
1895int DescriptorArray::bit_field3_storage() {
1896 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1897 return Smi::cast(storage)->value();
1898}
1899
1900void DescriptorArray::set_bit_field3_storage(int value) {
1901 ASSERT(!IsEmpty());
1902 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001903}
1904
1905
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001906void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1907 int first,
1908 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001909 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001910 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1911 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001912}
1913
1914
1915int DescriptorArray::Search(String* name) {
1916 SLOW_ASSERT(IsSortedNoDuplicates());
1917
1918 // Check for empty descriptor array.
1919 int nof = number_of_descriptors();
1920 if (nof == 0) return kNotFound;
1921
1922 // Fast case: do linear search for small arrays.
1923 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001924 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001925 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001926 }
1927
1928 // Slow case: perform binary search.
1929 return BinarySearch(name, 0, nof - 1);
1930}
1931
1932
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001933int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001934 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001935 if (number == DescriptorLookupCache::kAbsent) {
1936 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001937 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001938 }
1939 return number;
1940}
1941
1942
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001943String* DescriptorArray::GetKey(int descriptor_number) {
1944 ASSERT(descriptor_number < number_of_descriptors());
1945 return String::cast(get(ToKeyIndex(descriptor_number)));
1946}
1947
1948
1949Object* DescriptorArray::GetValue(int descriptor_number) {
1950 ASSERT(descriptor_number < number_of_descriptors());
1951 return GetContentArray()->get(ToValueIndex(descriptor_number));
1952}
1953
1954
1955Smi* DescriptorArray::GetDetails(int descriptor_number) {
1956 ASSERT(descriptor_number < number_of_descriptors());
1957 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1958}
1959
1960
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001961PropertyType DescriptorArray::GetType(int descriptor_number) {
1962 ASSERT(descriptor_number < number_of_descriptors());
1963 return PropertyDetails(GetDetails(descriptor_number)).type();
1964}
1965
1966
1967int DescriptorArray::GetFieldIndex(int descriptor_number) {
1968 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1969}
1970
1971
1972JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1973 return JSFunction::cast(GetValue(descriptor_number));
1974}
1975
1976
1977Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1978 ASSERT(GetType(descriptor_number) == CALLBACKS);
1979 return GetValue(descriptor_number);
1980}
1981
1982
1983AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1984 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001985 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001986 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001987}
1988
1989
1990bool DescriptorArray::IsProperty(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001991 return IsRealProperty(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001992}
1993
1994
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001995bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
1996 switch (GetType(descriptor_number)) {
1997 case MAP_TRANSITION:
1998 case CONSTANT_TRANSITION:
1999 case ELEMENTS_TRANSITION:
2000 return true;
2001 case CALLBACKS: {
2002 Object* value = GetValue(descriptor_number);
2003 if (!value->IsAccessorPair()) return false;
2004 AccessorPair* accessors = AccessorPair::cast(value);
2005 return accessors->getter()->IsMap() && accessors->setter()->IsMap();
2006 }
2007 case NORMAL:
2008 case FIELD:
2009 case CONSTANT_FUNCTION:
2010 case HANDLER:
2011 case INTERCEPTOR:
2012 case NULL_DESCRIPTOR:
2013 return false;
2014 }
2015 UNREACHABLE(); // Keep the compiler happy.
2016 return false;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002017}
2018
2019
2020bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2021 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2022}
2023
2024
2025bool DescriptorArray::IsDontEnum(int descriptor_number) {
2026 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
2027}
2028
2029
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002030void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2031 desc->Init(GetKey(descriptor_number),
2032 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002033 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002034}
2035
2036
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002037void DescriptorArray::Set(int descriptor_number,
2038 Descriptor* desc,
2039 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002040 // Range check.
2041 ASSERT(descriptor_number < number_of_descriptors());
2042
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002043 NoIncrementalWriteBarrierSet(this,
2044 ToKeyIndex(descriptor_number),
2045 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002046 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002047 NoIncrementalWriteBarrierSet(content_array,
2048 ToValueIndex(descriptor_number),
2049 desc->GetValue());
2050 NoIncrementalWriteBarrierSet(content_array,
2051 ToDetailsIndex(descriptor_number),
2052 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002053}
2054
2055
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002056void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2057 int first, int second) {
2058 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002059 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002060 NoIncrementalWriteBarrierSwap(content_array,
2061 ToValueIndex(first),
2062 ToValueIndex(second));
2063 NoIncrementalWriteBarrierSwap(content_array,
2064 ToDetailsIndex(first),
2065 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002066}
2067
2068
2069DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2070 : marking_(array->GetHeap()->incremental_marking()) {
2071 marking_->EnterNoMarkingScope();
2072 if (array->number_of_descriptors() > 0) {
2073 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2074 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2075 }
2076}
2077
2078
2079DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2080 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002081}
2082
2083
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002084template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002085int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2086 const int kMinCapacity = 32;
2087 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2088 if (capacity < kMinCapacity) {
2089 capacity = kMinCapacity; // Guarantee min capacity.
2090 }
2091 return capacity;
2092}
2093
2094
2095template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002096int HashTable<Shape, Key>::FindEntry(Key key) {
2097 return FindEntry(GetIsolate(), key);
2098}
2099
2100
2101// Find entry for key otherwise return kNotFound.
2102template<typename Shape, typename Key>
2103int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2104 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002105 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002106 uint32_t count = 1;
2107 // EnsureCapacity will guarantee the hash table is never full.
2108 while (true) {
2109 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002110 // Empty entry.
2111 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2112 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002113 Shape::IsMatch(key, element)) return entry;
2114 entry = NextProbe(entry, count++, capacity);
2115 }
2116 return kNotFound;
2117}
2118
2119
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002120bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002121 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002122 if (!max_index_object->IsSmi()) return false;
2123 return 0 !=
2124 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2125}
2126
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002127uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002128 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002129 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002130 if (!max_index_object->IsSmi()) return 0;
2131 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2132 return value >> kRequiresSlowElementsTagSize;
2133}
2134
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002135void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002136 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002137}
2138
2139
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002140// ------------------------------------
2141// Cast operations
2142
2143
2144CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002145CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002146CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002147CAST_ACCESSOR(DeoptimizationInputData)
2148CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002149CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002150CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002151CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002152CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002153CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002154CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002155CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002156CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002157CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002158CAST_ACCESSOR(String)
2159CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002160CAST_ACCESSOR(SeqAsciiString)
2161CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002162CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002163CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002164CAST_ACCESSOR(ExternalString)
2165CAST_ACCESSOR(ExternalAsciiString)
2166CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002167CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002168CAST_ACCESSOR(JSObject)
2169CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002170CAST_ACCESSOR(HeapObject)
2171CAST_ACCESSOR(HeapNumber)
2172CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002173CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002174CAST_ACCESSOR(SharedFunctionInfo)
2175CAST_ACCESSOR(Map)
2176CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002177CAST_ACCESSOR(GlobalObject)
2178CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002179CAST_ACCESSOR(JSGlobalObject)
2180CAST_ACCESSOR(JSBuiltinsObject)
2181CAST_ACCESSOR(Code)
2182CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002183CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002184CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002185CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002186CAST_ACCESSOR(JSSet)
2187CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002188CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002189CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002190CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002191CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002192CAST_ACCESSOR(ExternalArray)
2193CAST_ACCESSOR(ExternalByteArray)
2194CAST_ACCESSOR(ExternalUnsignedByteArray)
2195CAST_ACCESSOR(ExternalShortArray)
2196CAST_ACCESSOR(ExternalUnsignedShortArray)
2197CAST_ACCESSOR(ExternalIntArray)
2198CAST_ACCESSOR(ExternalUnsignedIntArray)
2199CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002200CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002201CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002202CAST_ACCESSOR(Struct)
2203
2204
2205#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2206 STRUCT_LIST(MAKE_STRUCT_CAST)
2207#undef MAKE_STRUCT_CAST
2208
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002209
2210template <typename Shape, typename Key>
2211HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002212 ASSERT(obj->IsHashTable());
2213 return reinterpret_cast<HashTable*>(obj);
2214}
2215
2216
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002217SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002218SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002219
ager@chromium.orgac091b72010-05-05 07:34:42 +00002220SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002221
2222
2223uint32_t String::hash_field() {
2224 return READ_UINT32_FIELD(this, kHashFieldOffset);
2225}
2226
2227
2228void String::set_hash_field(uint32_t value) {
2229 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002230#if V8_HOST_ARCH_64_BIT
2231 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2232#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002233}
2234
2235
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002236bool String::Equals(String* other) {
2237 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002238 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2239 return false;
2240 }
2241 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002242}
2243
2244
lrn@chromium.org303ada72010-10-27 09:33:13 +00002245MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002246 if (!StringShape(this).IsCons()) return this;
2247 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002248 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002249 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002250}
2251
2252
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002253String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002254 MaybeObject* flat = TryFlatten(pretenure);
2255 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002256 if (!flat->ToObject(&successfully_flattened)) return this;
2257 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002258}
2259
2260
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002261uint16_t String::Get(int index) {
2262 ASSERT(index >= 0 && index < length());
2263 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002264 case kSeqStringTag | kAsciiStringTag:
2265 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2266 case kSeqStringTag | kTwoByteStringTag:
2267 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2268 case kConsStringTag | kAsciiStringTag:
2269 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002270 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002271 case kExternalStringTag | kAsciiStringTag:
2272 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2273 case kExternalStringTag | kTwoByteStringTag:
2274 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002275 case kSlicedStringTag | kAsciiStringTag:
2276 case kSlicedStringTag | kTwoByteStringTag:
2277 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002278 default:
2279 break;
2280 }
2281
2282 UNREACHABLE();
2283 return 0;
2284}
2285
2286
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002287void String::Set(int index, uint16_t value) {
2288 ASSERT(index >= 0 && index < length());
2289 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002290
ager@chromium.org5ec48922009-05-05 07:25:34 +00002291 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002292 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2293 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002294}
2295
2296
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002297bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002298 if (!StringShape(this).IsCons()) return true;
2299 return ConsString::cast(this)->second()->length() == 0;
2300}
2301
2302
2303String* String::GetUnderlying() {
2304 // Giving direct access to underlying string only makes sense if the
2305 // wrapping string is already flattened.
2306 ASSERT(this->IsFlat());
2307 ASSERT(StringShape(this).IsIndirect());
2308 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2309 const int kUnderlyingOffset = SlicedString::kParentOffset;
2310 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002311}
2312
2313
ager@chromium.org7c537e22008-10-16 08:43:32 +00002314uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002315 ASSERT(index >= 0 && index < length());
2316 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2317}
2318
2319
ager@chromium.org7c537e22008-10-16 08:43:32 +00002320void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002321 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2322 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2323 static_cast<byte>(value));
2324}
2325
2326
ager@chromium.org7c537e22008-10-16 08:43:32 +00002327Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002328 return FIELD_ADDR(this, kHeaderSize);
2329}
2330
2331
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002332char* SeqAsciiString::GetChars() {
2333 return reinterpret_cast<char*>(GetCharsAddress());
2334}
2335
2336
ager@chromium.org7c537e22008-10-16 08:43:32 +00002337Address SeqTwoByteString::GetCharsAddress() {
2338 return FIELD_ADDR(this, kHeaderSize);
2339}
2340
2341
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002342uc16* SeqTwoByteString::GetChars() {
2343 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2344}
2345
2346
ager@chromium.org7c537e22008-10-16 08:43:32 +00002347uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002348 ASSERT(index >= 0 && index < length());
2349 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2350}
2351
2352
ager@chromium.org7c537e22008-10-16 08:43:32 +00002353void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002354 ASSERT(index >= 0 && index < length());
2355 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2356}
2357
2358
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002359int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002360 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002361}
2362
2363
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002364int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002365 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002366}
2367
2368
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002369String* SlicedString::parent() {
2370 return String::cast(READ_FIELD(this, kParentOffset));
2371}
2372
2373
2374void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002375 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002376 WRITE_FIELD(this, kParentOffset, parent);
2377}
2378
2379
2380SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2381
2382
ager@chromium.org870a0b62008-11-04 11:43:05 +00002383String* ConsString::first() {
2384 return String::cast(READ_FIELD(this, kFirstOffset));
2385}
2386
2387
2388Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002389 return READ_FIELD(this, kFirstOffset);
2390}
2391
2392
ager@chromium.org870a0b62008-11-04 11:43:05 +00002393void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002394 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002395 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002396}
2397
2398
ager@chromium.org870a0b62008-11-04 11:43:05 +00002399String* ConsString::second() {
2400 return String::cast(READ_FIELD(this, kSecondOffset));
2401}
2402
2403
2404Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002405 return READ_FIELD(this, kSecondOffset);
2406}
2407
2408
ager@chromium.org870a0b62008-11-04 11:43:05 +00002409void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002410 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002411 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002412}
2413
2414
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002415bool ExternalString::is_short() {
2416 InstanceType type = map()->instance_type();
2417 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002418}
2419
2420
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002421const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002422 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2423}
2424
2425
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002426void ExternalAsciiString::update_data_cache() {
2427 if (is_short()) return;
2428 const char** data_field =
2429 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2430 *data_field = resource()->data();
2431}
2432
2433
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002434void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002435 const ExternalAsciiString::Resource* resource) {
2436 *reinterpret_cast<const Resource**>(
2437 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002438 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002439}
2440
2441
2442const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002443 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002444}
2445
2446
2447uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2448 ASSERT(index >= 0 && index < length());
2449 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002450}
2451
2452
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002453const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002454 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2455}
2456
2457
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002458void ExternalTwoByteString::update_data_cache() {
2459 if (is_short()) return;
2460 const uint16_t** data_field =
2461 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2462 *data_field = resource()->data();
2463}
2464
2465
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002466void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002467 const ExternalTwoByteString::Resource* resource) {
2468 *reinterpret_cast<const Resource**>(
2469 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002470 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002471}
2472
2473
2474const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002475 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002476}
2477
2478
2479uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2480 ASSERT(index >= 0 && index < length());
2481 return GetChars()[index];
2482}
2483
2484
2485const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2486 unsigned start) {
2487 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002488}
2489
2490
ager@chromium.orgac091b72010-05-05 07:34:42 +00002491void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002492 set_finger_index(kEntriesIndex);
2493 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002494}
2495
2496
2497void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002498 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002499 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002500 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002501 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002502 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002503 MakeZeroSize();
2504}
2505
2506
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002507int JSFunctionResultCache::size() {
2508 return Smi::cast(get(kCacheSizeIndex))->value();
2509}
2510
2511
2512void JSFunctionResultCache::set_size(int size) {
2513 set(kCacheSizeIndex, Smi::FromInt(size));
2514}
2515
2516
2517int JSFunctionResultCache::finger_index() {
2518 return Smi::cast(get(kFingerIndex))->value();
2519}
2520
2521
2522void JSFunctionResultCache::set_finger_index(int finger_index) {
2523 set(kFingerIndex, Smi::FromInt(finger_index));
2524}
2525
2526
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002527byte ByteArray::get(int index) {
2528 ASSERT(index >= 0 && index < this->length());
2529 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2530}
2531
2532
2533void ByteArray::set(int index, byte value) {
2534 ASSERT(index >= 0 && index < this->length());
2535 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2536}
2537
2538
2539int ByteArray::get_int(int index) {
2540 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2541 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2542}
2543
2544
2545ByteArray* ByteArray::FromDataStartAddress(Address address) {
2546 ASSERT_TAG_ALIGNED(address);
2547 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2548}
2549
2550
2551Address ByteArray::GetDataStartAddress() {
2552 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2553}
2554
2555
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002556uint8_t* ExternalPixelArray::external_pixel_pointer() {
2557 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002558}
2559
2560
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002561uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002562 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002563 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002564 return ptr[index];
2565}
2566
2567
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002568MaybeObject* ExternalPixelArray::get(int index) {
2569 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2570}
2571
2572
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002573void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002574 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002575 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002576 ptr[index] = value;
2577}
2578
2579
ager@chromium.org3811b432009-10-28 14:53:37 +00002580void* ExternalArray::external_pointer() {
2581 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2582 return reinterpret_cast<void*>(ptr);
2583}
2584
2585
2586void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2587 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2588 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2589}
2590
2591
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002592int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002593 ASSERT((index >= 0) && (index < this->length()));
2594 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2595 return ptr[index];
2596}
2597
2598
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002599MaybeObject* ExternalByteArray::get(int index) {
2600 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2601}
2602
2603
ager@chromium.org3811b432009-10-28 14:53:37 +00002604void ExternalByteArray::set(int index, int8_t value) {
2605 ASSERT((index >= 0) && (index < this->length()));
2606 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2607 ptr[index] = value;
2608}
2609
2610
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002611uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002612 ASSERT((index >= 0) && (index < this->length()));
2613 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2614 return ptr[index];
2615}
2616
2617
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002618MaybeObject* ExternalUnsignedByteArray::get(int index) {
2619 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2620}
2621
2622
ager@chromium.org3811b432009-10-28 14:53:37 +00002623void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2624 ASSERT((index >= 0) && (index < this->length()));
2625 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2626 ptr[index] = value;
2627}
2628
2629
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002630int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002631 ASSERT((index >= 0) && (index < this->length()));
2632 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2633 return ptr[index];
2634}
2635
2636
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002637MaybeObject* ExternalShortArray::get(int index) {
2638 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2639}
2640
2641
ager@chromium.org3811b432009-10-28 14:53:37 +00002642void ExternalShortArray::set(int index, int16_t value) {
2643 ASSERT((index >= 0) && (index < this->length()));
2644 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2645 ptr[index] = value;
2646}
2647
2648
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002649uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002650 ASSERT((index >= 0) && (index < this->length()));
2651 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2652 return ptr[index];
2653}
2654
2655
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002656MaybeObject* ExternalUnsignedShortArray::get(int index) {
2657 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2658}
2659
2660
ager@chromium.org3811b432009-10-28 14:53:37 +00002661void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2662 ASSERT((index >= 0) && (index < this->length()));
2663 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2664 ptr[index] = value;
2665}
2666
2667
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002668int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002669 ASSERT((index >= 0) && (index < this->length()));
2670 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2671 return ptr[index];
2672}
2673
2674
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002675MaybeObject* ExternalIntArray::get(int index) {
2676 return GetHeap()->NumberFromInt32(get_scalar(index));
2677}
2678
2679
ager@chromium.org3811b432009-10-28 14:53:37 +00002680void ExternalIntArray::set(int index, int32_t value) {
2681 ASSERT((index >= 0) && (index < this->length()));
2682 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2683 ptr[index] = value;
2684}
2685
2686
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002687uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002688 ASSERT((index >= 0) && (index < this->length()));
2689 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2690 return ptr[index];
2691}
2692
2693
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002694MaybeObject* ExternalUnsignedIntArray::get(int index) {
2695 return GetHeap()->NumberFromUint32(get_scalar(index));
2696}
2697
2698
ager@chromium.org3811b432009-10-28 14:53:37 +00002699void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2700 ASSERT((index >= 0) && (index < this->length()));
2701 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2702 ptr[index] = value;
2703}
2704
2705
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002706float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002707 ASSERT((index >= 0) && (index < this->length()));
2708 float* ptr = static_cast<float*>(external_pointer());
2709 return ptr[index];
2710}
2711
2712
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002713MaybeObject* ExternalFloatArray::get(int index) {
2714 return GetHeap()->NumberFromDouble(get_scalar(index));
2715}
2716
2717
ager@chromium.org3811b432009-10-28 14:53:37 +00002718void ExternalFloatArray::set(int index, float value) {
2719 ASSERT((index >= 0) && (index < this->length()));
2720 float* ptr = static_cast<float*>(external_pointer());
2721 ptr[index] = value;
2722}
2723
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002724
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002725double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002726 ASSERT((index >= 0) && (index < this->length()));
2727 double* ptr = static_cast<double*>(external_pointer());
2728 return ptr[index];
2729}
2730
2731
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002732MaybeObject* ExternalDoubleArray::get(int index) {
2733 return GetHeap()->NumberFromDouble(get_scalar(index));
2734}
2735
2736
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002737void ExternalDoubleArray::set(int index, double value) {
2738 ASSERT((index >= 0) && (index < this->length()));
2739 double* ptr = static_cast<double*>(external_pointer());
2740 ptr[index] = value;
2741}
2742
2743
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002744int Map::visitor_id() {
2745 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2746}
2747
2748
2749void Map::set_visitor_id(int id) {
2750 ASSERT(0 <= id && id < 256);
2751 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2752}
2753
ager@chromium.org3811b432009-10-28 14:53:37 +00002754
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002755int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002756 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2757}
2758
2759
2760int Map::inobject_properties() {
2761 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002762}
2763
2764
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002765int Map::pre_allocated_property_fields() {
2766 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2767}
2768
2769
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002770int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002771 int instance_size = map->instance_size();
2772 if (instance_size != kVariableSizeSentinel) return instance_size;
2773 // We can ignore the "symbol" bit becase it is only set for symbols
2774 // and implies a string type.
2775 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002776 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002777 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002778 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002779 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002780 if (instance_type == ASCII_STRING_TYPE) {
2781 return SeqAsciiString::SizeFor(
2782 reinterpret_cast<SeqAsciiString*>(this)->length());
2783 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002784 if (instance_type == BYTE_ARRAY_TYPE) {
2785 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2786 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002787 if (instance_type == FREE_SPACE_TYPE) {
2788 return reinterpret_cast<FreeSpace*>(this)->size();
2789 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002790 if (instance_type == STRING_TYPE) {
2791 return SeqTwoByteString::SizeFor(
2792 reinterpret_cast<SeqTwoByteString*>(this)->length());
2793 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002794 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2795 return FixedDoubleArray::SizeFor(
2796 reinterpret_cast<FixedDoubleArray*>(this)->length());
2797 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002798 ASSERT(instance_type == CODE_TYPE);
2799 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002800}
2801
2802
2803void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002804 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002805 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002806 ASSERT(0 <= value && value < 256);
2807 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2808}
2809
2810
ager@chromium.org7c537e22008-10-16 08:43:32 +00002811void Map::set_inobject_properties(int value) {
2812 ASSERT(0 <= value && value < 256);
2813 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2814}
2815
2816
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002817void Map::set_pre_allocated_property_fields(int value) {
2818 ASSERT(0 <= value && value < 256);
2819 WRITE_BYTE_FIELD(this,
2820 kPreAllocatedPropertyFieldsOffset,
2821 static_cast<byte>(value));
2822}
2823
2824
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002825InstanceType Map::instance_type() {
2826 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2827}
2828
2829
2830void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002831 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2832}
2833
2834
2835int Map::unused_property_fields() {
2836 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2837}
2838
2839
2840void Map::set_unused_property_fields(int value) {
2841 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2842}
2843
2844
2845byte Map::bit_field() {
2846 return READ_BYTE_FIELD(this, kBitFieldOffset);
2847}
2848
2849
2850void Map::set_bit_field(byte value) {
2851 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2852}
2853
2854
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002855byte Map::bit_field2() {
2856 return READ_BYTE_FIELD(this, kBitField2Offset);
2857}
2858
2859
2860void Map::set_bit_field2(byte value) {
2861 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2862}
2863
2864
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002865void Map::set_non_instance_prototype(bool value) {
2866 if (value) {
2867 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2868 } else {
2869 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2870 }
2871}
2872
2873
2874bool Map::has_non_instance_prototype() {
2875 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2876}
2877
2878
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002879void Map::set_function_with_prototype(bool value) {
2880 if (value) {
2881 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2882 } else {
2883 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2884 }
2885}
2886
2887
2888bool Map::function_with_prototype() {
2889 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2890}
2891
2892
ager@chromium.org870a0b62008-11-04 11:43:05 +00002893void Map::set_is_access_check_needed(bool access_check_needed) {
2894 if (access_check_needed) {
2895 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2896 } else {
2897 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2898 }
2899}
2900
2901
2902bool Map::is_access_check_needed() {
2903 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2904}
2905
2906
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002907void Map::set_is_extensible(bool value) {
2908 if (value) {
2909 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2910 } else {
2911 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2912 }
2913}
2914
2915bool Map::is_extensible() {
2916 return ((1 << kIsExtensible) & bit_field2()) != 0;
2917}
2918
2919
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002920void Map::set_attached_to_shared_function_info(bool value) {
2921 if (value) {
2922 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2923 } else {
2924 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2925 }
2926}
2927
2928bool Map::attached_to_shared_function_info() {
2929 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2930}
2931
2932
2933void Map::set_is_shared(bool value) {
2934 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002935 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002936 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002937 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002938 }
2939}
2940
2941bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002942 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002943}
2944
2945
2946JSFunction* Map::unchecked_constructor() {
2947 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2948}
2949
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002950
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002951Code::Flags Code::flags() {
2952 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2953}
2954
2955
2956void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002957 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002958 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002959 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2960 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002961 ExtractArgumentsCountFromFlags(flags) >= 0);
2962 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2963}
2964
2965
2966Code::Kind Code::kind() {
2967 return ExtractKindFromFlags(flags());
2968}
2969
2970
kasper.lund7276f142008-07-30 08:49:36 +00002971InlineCacheState Code::ic_state() {
2972 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002973 // Only allow uninitialized or debugger states for non-IC code
2974 // objects. This is used in the debugger to determine whether or not
2975 // a call to code object has been replaced with a debug break call.
2976 ASSERT(is_inline_cache_stub() ||
2977 result == UNINITIALIZED ||
2978 result == DEBUG_BREAK ||
2979 result == DEBUG_PREPARE_STEP_IN);
2980 return result;
2981}
2982
2983
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002984Code::ExtraICState Code::extra_ic_state() {
2985 ASSERT(is_inline_cache_stub());
2986 return ExtractExtraICStateFromFlags(flags());
2987}
2988
2989
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002990PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002991 return ExtractTypeFromFlags(flags());
2992}
2993
2994
2995int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002996 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002997 return ExtractArgumentsCountFromFlags(flags());
2998}
2999
3000
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003001int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003002 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003003 kind() == UNARY_OP_IC ||
3004 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003005 kind() == COMPARE_IC ||
3006 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003007 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00003008}
3009
3010
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003011void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003012 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003013 kind() == UNARY_OP_IC ||
3014 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003015 kind() == COMPARE_IC ||
3016 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003017 ASSERT(0 <= major && major < 256);
3018 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003019}
3020
3021
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003022bool Code::is_pregenerated() {
3023 return kind() == STUB && IsPregeneratedField::decode(flags());
3024}
3025
3026
3027void Code::set_is_pregenerated(bool value) {
3028 ASSERT(kind() == STUB);
3029 Flags f = flags();
3030 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3031 set_flags(f);
3032}
3033
3034
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003035bool Code::optimizable() {
3036 ASSERT(kind() == FUNCTION);
3037 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3038}
3039
3040
3041void Code::set_optimizable(bool value) {
3042 ASSERT(kind() == FUNCTION);
3043 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3044}
3045
3046
3047bool Code::has_deoptimization_support() {
3048 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003049 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3050 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003051}
3052
3053
3054void Code::set_has_deoptimization_support(bool value) {
3055 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003056 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3057 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3058 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3059}
3060
3061
3062bool Code::has_debug_break_slots() {
3063 ASSERT(kind() == FUNCTION);
3064 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3065 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3066}
3067
3068
3069void Code::set_has_debug_break_slots(bool value) {
3070 ASSERT(kind() == FUNCTION);
3071 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3072 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3073 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003074}
3075
3076
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003077bool Code::is_compiled_optimizable() {
3078 ASSERT(kind() == FUNCTION);
3079 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3080 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3081}
3082
3083
3084void Code::set_compiled_optimizable(bool value) {
3085 ASSERT(kind() == FUNCTION);
3086 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3087 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3088 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3089}
3090
3091
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003092int Code::allow_osr_at_loop_nesting_level() {
3093 ASSERT(kind() == FUNCTION);
3094 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3095}
3096
3097
3098void Code::set_allow_osr_at_loop_nesting_level(int level) {
3099 ASSERT(kind() == FUNCTION);
3100 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3101 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3102}
3103
3104
3105unsigned Code::stack_slots() {
3106 ASSERT(kind() == OPTIMIZED_FUNCTION);
3107 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3108}
3109
3110
3111void Code::set_stack_slots(unsigned slots) {
3112 ASSERT(kind() == OPTIMIZED_FUNCTION);
3113 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3114}
3115
3116
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003117unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003118 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003119 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003120}
3121
3122
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003123void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003124 ASSERT(kind() == OPTIMIZED_FUNCTION);
3125 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003126 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003127}
3128
3129
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003130unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003131 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003132 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003133}
3134
3135
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003136void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003137 ASSERT(kind() == FUNCTION);
3138 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003139 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003140}
3141
3142
3143CheckType Code::check_type() {
3144 ASSERT(is_call_stub() || is_keyed_call_stub());
3145 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3146 return static_cast<CheckType>(type);
3147}
3148
3149
3150void Code::set_check_type(CheckType value) {
3151 ASSERT(is_call_stub() || is_keyed_call_stub());
3152 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3153}
3154
3155
danno@chromium.org40cb8782011-05-25 07:58:50 +00003156byte Code::unary_op_type() {
3157 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003158 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3159}
3160
3161
danno@chromium.org40cb8782011-05-25 07:58:50 +00003162void Code::set_unary_op_type(byte value) {
3163 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003164 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3165}
3166
3167
danno@chromium.org40cb8782011-05-25 07:58:50 +00003168byte Code::binary_op_type() {
3169 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003170 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3171}
3172
3173
danno@chromium.org40cb8782011-05-25 07:58:50 +00003174void Code::set_binary_op_type(byte value) {
3175 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003176 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3177}
3178
3179
danno@chromium.org40cb8782011-05-25 07:58:50 +00003180byte Code::binary_op_result_type() {
3181 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3183}
3184
3185
danno@chromium.org40cb8782011-05-25 07:58:50 +00003186void Code::set_binary_op_result_type(byte value) {
3187 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003188 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3189}
3190
3191
3192byte Code::compare_state() {
3193 ASSERT(is_compare_ic_stub());
3194 return READ_BYTE_FIELD(this, kCompareStateOffset);
3195}
3196
3197
3198void Code::set_compare_state(byte value) {
3199 ASSERT(is_compare_ic_stub());
3200 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3201}
3202
3203
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003204byte Code::to_boolean_state() {
3205 ASSERT(is_to_boolean_ic_stub());
3206 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3207}
3208
3209
3210void Code::set_to_boolean_state(byte value) {
3211 ASSERT(is_to_boolean_ic_stub());
3212 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3213}
3214
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003215
3216bool Code::has_function_cache() {
3217 ASSERT(kind() == STUB);
3218 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3219}
3220
3221
3222void Code::set_has_function_cache(bool flag) {
3223 ASSERT(kind() == STUB);
3224 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3225}
3226
3227
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003228bool Code::is_inline_cache_stub() {
3229 Kind kind = this->kind();
3230 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3231}
3232
3233
3234Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003235 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003236 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003237 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003238 int argc,
3239 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003240 // Extra IC state is only allowed for call IC stubs or for store IC
3241 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003242 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003243 kind == CALL_IC ||
3244 kind == STORE_IC ||
3245 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003246 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003247 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003248 | ICStateField::encode(ic_state)
3249 | TypeField::encode(type)
3250 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003251 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003252 | CacheHolderField::encode(holder);
3253 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003254}
3255
3256
3257Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3258 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003259 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003260 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003261 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003262 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003263}
3264
3265
3266Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003267 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003268}
3269
3270
kasper.lund7276f142008-07-30 08:49:36 +00003271InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003272 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003273}
3274
3275
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003276Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003277 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003278}
3279
3280
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003281PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003282 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003283}
3284
3285
3286int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003287 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003288}
3289
3290
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003291InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003292 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003293}
3294
3295
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003296Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003297 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003298 return static_cast<Flags>(bits);
3299}
3300
3301
ager@chromium.org8bb60582008-12-11 12:02:20 +00003302Code* Code::GetCodeFromTargetAddress(Address address) {
3303 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3304 // GetCodeFromTargetAddress might be called when marking objects during mark
3305 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3306 // Code::cast. Code::cast does not work when the object's map is
3307 // marked.
3308 Code* result = reinterpret_cast<Code*>(code);
3309 return result;
3310}
3311
3312
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003313Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3314 return HeapObject::
3315 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3316}
3317
3318
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003319Object* Map::prototype() {
3320 return READ_FIELD(this, kPrototypeOffset);
3321}
3322
3323
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003324void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003325 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003326 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003327 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003328}
3329
3330
danno@chromium.org40cb8782011-05-25 07:58:50 +00003331DescriptorArray* Map::instance_descriptors() {
3332 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3333 if (object->IsSmi()) {
3334 return HEAP->empty_descriptor_array();
3335 } else {
3336 return DescriptorArray::cast(object);
3337 }
3338}
3339
3340
3341void Map::init_instance_descriptors() {
3342 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3343}
3344
3345
3346void Map::clear_instance_descriptors() {
3347 Object* object = READ_FIELD(this,
3348 kInstanceDescriptorsOrBitField3Offset);
3349 if (!object->IsSmi()) {
3350 WRITE_FIELD(
3351 this,
3352 kInstanceDescriptorsOrBitField3Offset,
3353 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3354 }
3355}
3356
3357
3358void Map::set_instance_descriptors(DescriptorArray* value,
3359 WriteBarrierMode mode) {
3360 Object* object = READ_FIELD(this,
3361 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003362 Heap* heap = GetHeap();
3363 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003364 clear_instance_descriptors();
3365 return;
3366 } else {
3367 if (object->IsSmi()) {
3368 value->set_bit_field3_storage(Smi::cast(object)->value());
3369 } else {
3370 value->set_bit_field3_storage(
3371 DescriptorArray::cast(object)->bit_field3_storage());
3372 }
3373 }
3374 ASSERT(!is_shared());
3375 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003376 CONDITIONAL_WRITE_BARRIER(
3377 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003378}
3379
3380
3381int Map::bit_field3() {
3382 Object* object = READ_FIELD(this,
3383 kInstanceDescriptorsOrBitField3Offset);
3384 if (object->IsSmi()) {
3385 return Smi::cast(object)->value();
3386 } else {
3387 return DescriptorArray::cast(object)->bit_field3_storage();
3388 }
3389}
3390
3391
3392void Map::set_bit_field3(int value) {
3393 ASSERT(Smi::IsValid(value));
3394 Object* object = READ_FIELD(this,
3395 kInstanceDescriptorsOrBitField3Offset);
3396 if (object->IsSmi()) {
3397 WRITE_FIELD(this,
3398 kInstanceDescriptorsOrBitField3Offset,
3399 Smi::FromInt(value));
3400 } else {
3401 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3402 }
3403}
3404
3405
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003406FixedArray* Map::unchecked_prototype_transitions() {
3407 return reinterpret_cast<FixedArray*>(
3408 READ_FIELD(this, kPrototypeTransitionsOffset));
3409}
3410
3411
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003412ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003413ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003414ACCESSORS(Map, constructor, Object, kConstructorOffset)
3415
3416ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003417ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003418ACCESSORS(JSFunction,
3419 next_function_link,
3420 Object,
3421 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003422
3423ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3424ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003425ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003426
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003427ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003428
3429ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3430ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3431ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3432ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3433ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3434
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003435ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3436ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3437
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003438ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3439ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3440ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3441
3442ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3443ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3444ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3445ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3446ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3447ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3448
3449ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3450ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3451
3452ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3453ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3454
3455ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3456ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003457ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3458 kPropertyAccessorsOffset)
3459ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3460 kPrototypeTemplateOffset)
3461ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3462ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3463 kNamedPropertyHandlerOffset)
3464ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3465 kIndexedPropertyHandlerOffset)
3466ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3467 kInstanceTemplateOffset)
3468ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3469ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003470ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3471 kInstanceCallHandlerOffset)
3472ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3473 kAccessCheckInfoOffset)
3474ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3475
3476ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003477ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3478 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003479
3480ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3481ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3482
3483ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3484
3485ACCESSORS(Script, source, Object, kSourceOffset)
3486ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003487ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003488ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3489ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003490ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003491ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003492ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003493ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003494ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003495ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003496ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003497ACCESSORS(Script, eval_from_instructions_offset, Smi,
3498 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003499
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003500#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003501ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3502ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3503ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3504ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3505
3506ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3507ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3508ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3509ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003510#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003511
3512ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003513ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3514ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003515ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3516 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003517ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003518ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3519ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003520ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003521ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3522 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003523
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003524SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
3525
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003526BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3527 kHiddenPrototypeBit)
3528BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3529BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3530 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003531BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3532 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003533BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3534 kIsExpressionBit)
3535BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3536 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003537BOOL_GETTER(SharedFunctionInfo,
3538 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003539 has_only_simple_this_property_assignments,
3540 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003541BOOL_ACCESSORS(SharedFunctionInfo,
3542 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003543 allows_lazy_compilation,
3544 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003545BOOL_ACCESSORS(SharedFunctionInfo,
3546 compiler_hints,
3547 uses_arguments,
3548 kUsesArguments)
3549BOOL_ACCESSORS(SharedFunctionInfo,
3550 compiler_hints,
3551 has_duplicate_parameters,
3552 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003553
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003554
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003555#if V8_HOST_ARCH_32_BIT
3556SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3557SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003558 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003559SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003560 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003561SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3562SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003563 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003564SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3565SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003566 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003567SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003568 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003569SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003570 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003571SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003572SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3573SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003574#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003575
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003576#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003577 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003578 int holder::name() { \
3579 int value = READ_INT_FIELD(this, offset); \
3580 ASSERT(kHeapObjectTag == 1); \
3581 ASSERT((value & kHeapObjectTag) == 0); \
3582 return value >> 1; \
3583 } \
3584 void holder::set_##name(int value) { \
3585 ASSERT(kHeapObjectTag == 1); \
3586 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3587 (value & 0xC0000000) == 0x000000000); \
3588 WRITE_INT_FIELD(this, \
3589 offset, \
3590 (value << 1) & ~kHeapObjectTag); \
3591 }
3592
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003593#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3594 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003595 INT_ACCESSORS(holder, name, offset)
3596
3597
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003598PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003599PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3600 formal_parameter_count,
3601 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003602
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003603PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3604 expected_nof_properties,
3605 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003606PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3607
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003608PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3609PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3610 start_position_and_type,
3611 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003612
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003613PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3614 function_token_position,
3615 kFunctionTokenPositionOffset)
3616PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3617 compiler_hints,
3618 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003619
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003620PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3621 this_property_assignments_count,
3622 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003623PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003624
3625PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3626PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003627#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003628
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003629
3630int SharedFunctionInfo::construction_count() {
3631 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3632}
3633
3634
3635void SharedFunctionInfo::set_construction_count(int value) {
3636 ASSERT(0 <= value && value < 256);
3637 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3638}
3639
3640
whesse@chromium.org7b260152011-06-20 15:33:18 +00003641BOOL_ACCESSORS(SharedFunctionInfo,
3642 compiler_hints,
3643 live_objects_may_exist,
3644 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003645
3646
3647bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003648 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003649}
3650
3651
whesse@chromium.org7b260152011-06-20 15:33:18 +00003652BOOL_GETTER(SharedFunctionInfo,
3653 compiler_hints,
3654 optimization_disabled,
3655 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003656
3657
3658void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3659 set_compiler_hints(BooleanBit::set(compiler_hints(),
3660 kOptimizationDisabled,
3661 disable));
3662 // If disabling optimizations we reflect that in the code object so
3663 // it will not be counted as optimizable code.
3664 if ((code()->kind() == Code::FUNCTION) && disable) {
3665 code()->set_optimizable(false);
3666 }
3667}
3668
3669
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003670LanguageMode SharedFunctionInfo::language_mode() {
3671 int hints = compiler_hints();
3672 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3673 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3674 return EXTENDED_MODE;
3675 }
3676 return BooleanBit::get(hints, kStrictModeFunction)
3677 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003678}
3679
3680
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003681void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3682 // We only allow language mode transitions that go set the same language mode
3683 // again or go up in the chain:
3684 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3685 ASSERT(this->language_mode() == CLASSIC_MODE ||
3686 this->language_mode() == language_mode ||
3687 language_mode == EXTENDED_MODE);
3688 int hints = compiler_hints();
3689 hints = BooleanBit::set(
3690 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3691 hints = BooleanBit::set(
3692 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3693 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003694}
3695
3696
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003697bool SharedFunctionInfo::is_classic_mode() {
3698 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3699}
3700
3701BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3702 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003703BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3704BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3705 name_should_print_as_anonymous,
3706 kNameShouldPrintAsAnonymous)
3707BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3708BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003709BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3710BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3711 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003712BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003713
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003714ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3715ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3716
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003717ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3718
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003719bool Script::HasValidSource() {
3720 Object* src = this->source();
3721 if (!src->IsString()) return true;
3722 String* src_str = String::cast(src);
3723 if (!StringShape(src_str).IsExternal()) return true;
3724 if (src_str->IsAsciiRepresentation()) {
3725 return ExternalAsciiString::cast(src)->resource() != NULL;
3726 } else if (src_str->IsTwoByteRepresentation()) {
3727 return ExternalTwoByteString::cast(src)->resource() != NULL;
3728 }
3729 return true;
3730}
3731
3732
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003733void SharedFunctionInfo::DontAdaptArguments() {
3734 ASSERT(code()->kind() == Code::BUILTIN);
3735 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3736}
3737
3738
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003739int SharedFunctionInfo::start_position() {
3740 return start_position_and_type() >> kStartPositionShift;
3741}
3742
3743
3744void SharedFunctionInfo::set_start_position(int start_position) {
3745 set_start_position_and_type((start_position << kStartPositionShift)
3746 | (start_position_and_type() & ~kStartPositionMask));
3747}
3748
3749
3750Code* SharedFunctionInfo::code() {
3751 return Code::cast(READ_FIELD(this, kCodeOffset));
3752}
3753
3754
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003755Code* SharedFunctionInfo::unchecked_code() {
3756 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3757}
3758
3759
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003760void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003761 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003762 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003763}
3764
3765
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003766ScopeInfo* SharedFunctionInfo::scope_info() {
3767 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003768}
3769
3770
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003771void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003772 WriteBarrierMode mode) {
3773 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003774 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3775 this,
3776 kScopeInfoOffset,
3777 reinterpret_cast<Object*>(value),
3778 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003779}
3780
3781
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003782bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003783 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003784 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003785}
3786
3787
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003788bool SharedFunctionInfo::IsApiFunction() {
3789 return function_data()->IsFunctionTemplateInfo();
3790}
3791
3792
3793FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3794 ASSERT(IsApiFunction());
3795 return FunctionTemplateInfo::cast(function_data());
3796}
3797
3798
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003799bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003800 return function_data()->IsSmi();
3801}
3802
3803
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003804BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3805 ASSERT(HasBuiltinFunctionId());
3806 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003807}
3808
3809
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003810int SharedFunctionInfo::code_age() {
3811 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3812}
3813
3814
3815void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003816 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3817 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003818}
3819
3820
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003821bool SharedFunctionInfo::has_deoptimization_support() {
3822 Code* code = this->code();
3823 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3824}
3825
3826
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003827bool JSFunction::IsBuiltin() {
3828 return context()->global()->IsJSBuiltinsObject();
3829}
3830
3831
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003832bool JSFunction::NeedsArgumentsAdaption() {
3833 return shared()->formal_parameter_count() !=
3834 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3835}
3836
3837
3838bool JSFunction::IsOptimized() {
3839 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3840}
3841
3842
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003843bool JSFunction::IsOptimizable() {
3844 return code()->kind() == Code::FUNCTION && code()->optimizable();
3845}
3846
3847
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003848bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003849 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003850}
3851
3852
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003853Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003854 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003855}
3856
3857
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003858Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003859 return reinterpret_cast<Code*>(
3860 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003861}
3862
3863
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003864void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003865 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003866 Address entry = value->entry();
3867 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003868 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3869 this,
3870 HeapObject::RawField(this, kCodeEntryOffset),
3871 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003872}
3873
3874
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003875void JSFunction::ReplaceCode(Code* code) {
3876 bool was_optimized = IsOptimized();
3877 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3878
3879 set_code(code);
3880
3881 // Add/remove the function from the list of optimized functions for this
3882 // context based on the state change.
3883 if (!was_optimized && is_optimized) {
3884 context()->global_context()->AddOptimizedFunction(this);
3885 }
3886 if (was_optimized && !is_optimized) {
3887 context()->global_context()->RemoveOptimizedFunction(this);
3888 }
3889}
3890
3891
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003892Context* JSFunction::context() {
3893 return Context::cast(READ_FIELD(this, kContextOffset));
3894}
3895
3896
3897Object* JSFunction::unchecked_context() {
3898 return READ_FIELD(this, kContextOffset);
3899}
3900
3901
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003902SharedFunctionInfo* JSFunction::unchecked_shared() {
3903 return reinterpret_cast<SharedFunctionInfo*>(
3904 READ_FIELD(this, kSharedFunctionInfoOffset));
3905}
3906
3907
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003908void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003909 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003910 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003911 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003912}
3913
3914ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3915 kPrototypeOrInitialMapOffset)
3916
3917
3918Map* JSFunction::initial_map() {
3919 return Map::cast(prototype_or_initial_map());
3920}
3921
3922
3923void JSFunction::set_initial_map(Map* value) {
3924 set_prototype_or_initial_map(value);
3925}
3926
3927
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003928MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
3929 Map* initial_map) {
3930 Context* global_context = context()->global_context();
3931 Object* array_function =
3932 global_context->get(Context::ARRAY_FUNCTION_INDEX);
3933 if (array_function->IsJSFunction() &&
3934 this == JSFunction::cast(array_function)) {
3935 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
3936
3937 MaybeObject* maybe_map = initial_map->CopyDropTransitions();
3938 Map* new_double_map = NULL;
3939 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
3940 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
3941 initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS, new_double_map);
3942
3943 maybe_map = new_double_map->CopyDropTransitions();
3944 Map* new_object_map = NULL;
3945 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
3946 new_object_map->set_elements_kind(FAST_ELEMENTS);
3947 new_double_map->AddElementsTransition(FAST_ELEMENTS, new_object_map);
3948
3949 global_context->set_smi_js_array_map(initial_map);
3950 global_context->set_double_js_array_map(new_double_map);
3951 global_context->set_object_js_array_map(new_object_map);
3952 }
3953 set_initial_map(initial_map);
3954 return this;
3955}
3956
3957
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003958bool JSFunction::has_initial_map() {
3959 return prototype_or_initial_map()->IsMap();
3960}
3961
3962
3963bool JSFunction::has_instance_prototype() {
3964 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3965}
3966
3967
3968bool JSFunction::has_prototype() {
3969 return map()->has_non_instance_prototype() || has_instance_prototype();
3970}
3971
3972
3973Object* JSFunction::instance_prototype() {
3974 ASSERT(has_instance_prototype());
3975 if (has_initial_map()) return initial_map()->prototype();
3976 // When there is no initial map and the prototype is a JSObject, the
3977 // initial map field is used for the prototype field.
3978 return prototype_or_initial_map();
3979}
3980
3981
3982Object* JSFunction::prototype() {
3983 ASSERT(has_prototype());
3984 // If the function's prototype property has been set to a non-JSObject
3985 // value, that value is stored in the constructor field of the map.
3986 if (map()->has_non_instance_prototype()) return map()->constructor();
3987 return instance_prototype();
3988}
3989
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003990bool JSFunction::should_have_prototype() {
3991 return map()->function_with_prototype();
3992}
3993
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003994
3995bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003996 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003997}
3998
3999
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004000FixedArray* JSFunction::literals() {
4001 ASSERT(!shared()->bound());
4002 return literals_or_bindings();
4003}
4004
4005
4006void JSFunction::set_literals(FixedArray* literals) {
4007 ASSERT(!shared()->bound());
4008 set_literals_or_bindings(literals);
4009}
4010
4011
4012FixedArray* JSFunction::function_bindings() {
4013 ASSERT(shared()->bound());
4014 return literals_or_bindings();
4015}
4016
4017
4018void JSFunction::set_function_bindings(FixedArray* bindings) {
4019 ASSERT(shared()->bound());
4020 // Bound function literal may be initialized to the empty fixed array
4021 // before the bindings are set.
4022 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4023 bindings->map() == GetHeap()->fixed_cow_array_map());
4024 set_literals_or_bindings(bindings);
4025}
4026
4027
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004028int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004029 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004030 return literals()->length();
4031}
4032
4033
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004034Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004035 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004036 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004037}
4038
4039
4040void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4041 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004042 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004043 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004044 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004045}
4046
4047
4048Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004049 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004050 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4051}
4052
4053
4054void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4055 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004056 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004057 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004058 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004059}
4060
4061
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004062ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004063ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004064ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4065ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4066
4067
4068void JSProxy::InitializeBody(int object_size, Object* value) {
4069 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4070 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4071 WRITE_FIELD(this, offset, value);
4072 }
4073}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004074
4075
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004076ACCESSORS(JSSet, table, Object, kTableOffset)
4077ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004078ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4079ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004080
4081
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004082Address Foreign::foreign_address() {
4083 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004084}
4085
4086
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004087void Foreign::set_foreign_address(Address value) {
4088 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004089}
4090
4091
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004092ACCESSORS(JSValue, value, Object, kValueOffset)
4093
4094
4095JSValue* JSValue::cast(Object* obj) {
4096 ASSERT(obj->IsJSValue());
4097 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4098 return reinterpret_cast<JSValue*>(obj);
4099}
4100
4101
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004102ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4103ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4104ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4105ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4106ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4107SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4108SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4109
4110
4111JSMessageObject* JSMessageObject::cast(Object* obj) {
4112 ASSERT(obj->IsJSMessageObject());
4113 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4114 return reinterpret_cast<JSMessageObject*>(obj);
4115}
4116
4117
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004118INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004119ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004120ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004121ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004122ACCESSORS(Code, type_feedback_cells, TypeFeedbackCells,
4123 kTypeFeedbackCellsOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004124ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004125
4126
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004127byte* Code::instruction_start() {
4128 return FIELD_ADDR(this, kHeaderSize);
4129}
4130
4131
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004132byte* Code::instruction_end() {
4133 return instruction_start() + instruction_size();
4134}
4135
4136
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004137int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004138 return RoundUp(instruction_size(), kObjectAlignment);
4139}
4140
4141
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004142FixedArray* Code::unchecked_deoptimization_data() {
4143 return reinterpret_cast<FixedArray*>(
4144 READ_FIELD(this, kDeoptimizationDataOffset));
4145}
4146
4147
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004148ByteArray* Code::unchecked_relocation_info() {
4149 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004150}
4151
4152
4153byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004154 return unchecked_relocation_info()->GetDataStartAddress();
4155}
4156
4157
4158int Code::relocation_size() {
4159 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004160}
4161
4162
4163byte* Code::entry() {
4164 return instruction_start();
4165}
4166
4167
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004168bool Code::contains(byte* inner_pointer) {
4169 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004170}
4171
4172
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004173ACCESSORS(JSArray, length, Object, kLengthOffset)
4174
4175
ager@chromium.org236ad962008-09-25 09:45:57 +00004176ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004177
4178
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004179JSRegExp::Type JSRegExp::TypeTag() {
4180 Object* data = this->data();
4181 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4182 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4183 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004184}
4185
4186
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004187JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4188 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4189 return static_cast<JSRegExp::Type>(smi->value());
4190}
4191
4192
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004193int JSRegExp::CaptureCount() {
4194 switch (TypeTag()) {
4195 case ATOM:
4196 return 0;
4197 case IRREGEXP:
4198 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4199 default:
4200 UNREACHABLE();
4201 return -1;
4202 }
4203}
4204
4205
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004206JSRegExp::Flags JSRegExp::GetFlags() {
4207 ASSERT(this->data()->IsFixedArray());
4208 Object* data = this->data();
4209 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4210 return Flags(smi->value());
4211}
4212
4213
4214String* JSRegExp::Pattern() {
4215 ASSERT(this->data()->IsFixedArray());
4216 Object* data = this->data();
4217 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4218 return pattern;
4219}
4220
4221
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004222Object* JSRegExp::DataAt(int index) {
4223 ASSERT(TypeTag() != NOT_COMPILED);
4224 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004225}
4226
4227
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004228Object* JSRegExp::DataAtUnchecked(int index) {
4229 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4230 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4231 return READ_FIELD(fa, offset);
4232}
4233
4234
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004235void JSRegExp::SetDataAt(int index, Object* value) {
4236 ASSERT(TypeTag() != NOT_COMPILED);
4237 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4238 FixedArray::cast(data())->set(index, value);
4239}
4240
4241
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004242void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4243 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4244 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4245 if (value->IsSmi()) {
4246 fa->set_unchecked(index, Smi::cast(value));
4247 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004248 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004249 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4250 }
4251}
4252
4253
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004254ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004255 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004256#if DEBUG
4257 FixedArrayBase* fixed_array =
4258 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4259 Map* map = fixed_array->map();
4260 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004261 (map == GetHeap()->fixed_array_map() ||
4262 map == GetHeap()->fixed_cow_array_map())) ||
4263 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004264 (fixed_array->IsFixedDoubleArray() ||
4265 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004266 (kind == DICTIONARY_ELEMENTS &&
4267 fixed_array->IsFixedArray() &&
4268 fixed_array->IsDictionary()) ||
4269 (kind > DICTIONARY_ELEMENTS));
4270 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4271 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004272#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004273 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004274}
4275
4276
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004277ElementsAccessor* JSObject::GetElementsAccessor() {
4278 return ElementsAccessor::ForKind(GetElementsKind());
4279}
4280
4281
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004282bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004283 return GetElementsKind() == FAST_ELEMENTS;
4284}
4285
4286
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004287bool JSObject::HasFastSmiOnlyElements() {
4288 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4289}
4290
4291
4292bool JSObject::HasFastTypeElements() {
4293 ElementsKind elements_kind = GetElementsKind();
4294 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4295 elements_kind == FAST_ELEMENTS;
4296}
4297
4298
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004299bool JSObject::HasFastDoubleElements() {
4300 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4301}
4302
4303
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004304bool JSObject::HasDictionaryElements() {
4305 return GetElementsKind() == DICTIONARY_ELEMENTS;
4306}
4307
4308
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004309bool JSObject::HasNonStrictArgumentsElements() {
4310 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4311}
4312
4313
ager@chromium.org3811b432009-10-28 14:53:37 +00004314bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004315 HeapObject* array = elements();
4316 ASSERT(array != NULL);
4317 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004318}
4319
4320
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004321#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4322bool JSObject::HasExternal##name##Elements() { \
4323 HeapObject* array = elements(); \
4324 ASSERT(array != NULL); \
4325 if (!array->IsHeapObject()) \
4326 return false; \
4327 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004328}
4329
4330
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004331EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4332EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4333EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4334EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4335 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4336EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4337EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4338 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4339EXTERNAL_ELEMENTS_CHECK(Float,
4340 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004341EXTERNAL_ELEMENTS_CHECK(Double,
4342 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004343EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004344
4345
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004346bool JSObject::HasNamedInterceptor() {
4347 return map()->has_named_interceptor();
4348}
4349
4350
4351bool JSObject::HasIndexedInterceptor() {
4352 return map()->has_indexed_interceptor();
4353}
4354
4355
lrn@chromium.org303ada72010-10-27 09:33:13 +00004356MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004357 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004358 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004359 Isolate* isolate = GetIsolate();
4360 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004361 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004362 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4363 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004364 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4365 return maybe_writable_elems;
4366 }
4367 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004368 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004369 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004370 return writable_elems;
4371}
4372
4373
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004374StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004375 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004376 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004377}
4378
4379
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004380SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004381 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004382 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004383}
4384
4385
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004386bool String::IsHashFieldComputed(uint32_t field) {
4387 return (field & kHashNotComputedMask) == 0;
4388}
4389
4390
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004391bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004392 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004393}
4394
4395
4396uint32_t String::Hash() {
4397 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004398 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004399 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004400 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004401 return ComputeAndSetHash();
4402}
4403
4404
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004405StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004406 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004407 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004408 array_index_(0),
4409 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4410 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004411 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004412 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004413}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004414
4415
4416bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004417 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004418}
4419
4420
4421void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004422 // Use the Jenkins one-at-a-time hash function to update the hash
4423 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004424 raw_running_hash_ += c;
4425 raw_running_hash_ += (raw_running_hash_ << 10);
4426 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004427 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004428 if (is_array_index_) {
4429 if (c < '0' || c > '9') {
4430 is_array_index_ = false;
4431 } else {
4432 int d = c - '0';
4433 if (is_first_char_) {
4434 is_first_char_ = false;
4435 if (c == '0' && length_ > 1) {
4436 is_array_index_ = false;
4437 return;
4438 }
4439 }
4440 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4441 is_array_index_ = false;
4442 } else {
4443 array_index_ = array_index_ * 10 + d;
4444 }
4445 }
4446 }
4447}
4448
4449
4450void StringHasher::AddCharacterNoIndex(uc32 c) {
4451 ASSERT(!is_array_index());
4452 raw_running_hash_ += c;
4453 raw_running_hash_ += (raw_running_hash_ << 10);
4454 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4455}
4456
4457
4458uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004459 // Get the calculated raw hash value and do some more bit ops to distribute
4460 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004461 uint32_t result = raw_running_hash_;
4462 result += (result << 3);
4463 result ^= (result >> 11);
4464 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004465 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004466 result = 27;
4467 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004468 return result;
4469}
4470
4471
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004472template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004473uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4474 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004475 if (!hasher.has_trivial_hash()) {
4476 int i;
4477 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4478 hasher.AddCharacter(chars[i]);
4479 }
4480 for (; i < length; i++) {
4481 hasher.AddCharacterNoIndex(chars[i]);
4482 }
4483 }
4484 return hasher.GetHashField();
4485}
4486
4487
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004488bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004489 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004490 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4491 return false;
4492 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004493 return SlowAsArrayIndex(index);
4494}
4495
4496
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004497Object* JSReceiver::GetPrototype() {
4498 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004499}
4500
4501
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004502bool JSReceiver::HasProperty(String* name) {
4503 if (IsJSProxy()) {
4504 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4505 }
4506 return GetPropertyAttribute(name) != ABSENT;
4507}
4508
4509
4510bool JSReceiver::HasLocalProperty(String* name) {
4511 if (IsJSProxy()) {
4512 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4513 }
4514 return GetLocalPropertyAttribute(name) != ABSENT;
4515}
4516
4517
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004518PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004519 return GetPropertyAttributeWithReceiver(this, key);
4520}
4521
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004522// TODO(504): this may be useful in other places too where JSGlobalProxy
4523// is used.
4524Object* JSObject::BypassGlobalProxy() {
4525 if (IsJSGlobalProxy()) {
4526 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004527 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004528 ASSERT(proto->IsJSGlobalObject());
4529 return proto;
4530 }
4531 return this;
4532}
4533
4534
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004535MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4536 return IsJSProxy()
4537 ? JSProxy::cast(this)->GetIdentityHash(flag)
4538 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004539}
4540
4541
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004542bool JSReceiver::HasElement(uint32_t index) {
4543 if (IsJSProxy()) {
4544 return JSProxy::cast(this)->HasElementWithHandler(index);
4545 }
4546 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004547}
4548
4549
4550bool AccessorInfo::all_can_read() {
4551 return BooleanBit::get(flag(), kAllCanReadBit);
4552}
4553
4554
4555void AccessorInfo::set_all_can_read(bool value) {
4556 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4557}
4558
4559
4560bool AccessorInfo::all_can_write() {
4561 return BooleanBit::get(flag(), kAllCanWriteBit);
4562}
4563
4564
4565void AccessorInfo::set_all_can_write(bool value) {
4566 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4567}
4568
4569
ager@chromium.org870a0b62008-11-04 11:43:05 +00004570bool AccessorInfo::prohibits_overwriting() {
4571 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4572}
4573
4574
4575void AccessorInfo::set_prohibits_overwriting(bool value) {
4576 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4577}
4578
4579
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004580PropertyAttributes AccessorInfo::property_attributes() {
4581 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4582}
4583
4584
4585void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004586 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004587}
4588
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004589
4590template<typename Shape, typename Key>
4591void Dictionary<Shape, Key>::SetEntry(int entry,
4592 Object* key,
4593 Object* value) {
4594 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4595}
4596
4597
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004598template<typename Shape, typename Key>
4599void Dictionary<Shape, Key>::SetEntry(int entry,
4600 Object* key,
4601 Object* value,
4602 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004603 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004604 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004605 AssertNoAllocation no_gc;
4606 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004607 FixedArray::set(index, key, mode);
4608 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004609 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004610}
4611
4612
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004613bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4614 ASSERT(other->IsNumber());
4615 return key == static_cast<uint32_t>(other->Number());
4616}
4617
4618
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004619uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4620 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004621}
4622
4623
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004624uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4625 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004626 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004627 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004628}
4629
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004630uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4631 return ComputeIntegerHash(key, seed);
4632}
4633
4634uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4635 uint32_t seed,
4636 Object* other) {
4637 ASSERT(other->IsNumber());
4638 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4639}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004640
4641MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4642 return Isolate::Current()->heap()->NumberFromUint32(key);
4643}
4644
4645
4646bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4647 // We know that all entries in a hash table had their hash keys created.
4648 // Use that knowledge to have fast failure.
4649 if (key->Hash() != String::cast(other)->Hash()) return false;
4650 return key->Equals(String::cast(other));
4651}
4652
4653
4654uint32_t StringDictionaryShape::Hash(String* key) {
4655 return key->Hash();
4656}
4657
4658
4659uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4660 return String::cast(other)->Hash();
4661}
4662
4663
4664MaybeObject* StringDictionaryShape::AsObject(String* key) {
4665 return key;
4666}
4667
4668
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004669template <int entrysize>
4670bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4671 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004672}
4673
4674
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004675template <int entrysize>
4676uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004677 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4678 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004679}
4680
4681
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004682template <int entrysize>
4683uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4684 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004685 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4686 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004687}
4688
4689
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004690template <int entrysize>
4691MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004692 return key;
4693}
4694
4695
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004696void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004697 // No write barrier is needed since empty_fixed_array is not in new space.
4698 // Please note this function is used during marking:
4699 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004700 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4701 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004702}
4703
4704
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004705void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004706 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004707 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004708 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4709 if (elts->length() < required_size) {
4710 // Doubling in size would be overkill, but leave some slack to avoid
4711 // constantly growing.
4712 Expand(required_size + (required_size >> 3));
4713 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004714 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004715 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4716 // Expand will allocate a new backing store in new space even if the size
4717 // we asked for isn't larger than what we had before.
4718 Expand(required_size);
4719 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004720}
4721
4722
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004723void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004724 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004725 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4726}
4727
4728
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004729bool JSArray::AllowsSetElementsLength() {
4730 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4731 ASSERT(result == !HasExternalArrayElements());
4732 return result;
4733}
4734
4735
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004736MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4737 MaybeObject* maybe_result = EnsureCanContainElements(
4738 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4739 if (maybe_result->IsFailure()) return maybe_result;
4740 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4741 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4742 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4743 ((GetElementsKind() == FAST_ELEMENTS) ||
4744 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4745 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004746 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004747 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004748 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004749}
4750
4751
lrn@chromium.org303ada72010-10-27 09:33:13 +00004752MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004753 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004754 return GetHeap()->CopyFixedArray(this);
4755}
4756
4757
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004758MaybeObject* FixedDoubleArray::Copy() {
4759 if (length() == 0) return this;
4760 return GetHeap()->CopyFixedDoubleArray(this);
4761}
4762
4763
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004764void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4765 set(1 + index * 2, id);
4766}
4767
4768
4769Smi* TypeFeedbackCells::AstId(int index) {
4770 return Smi::cast(get(1 + index * 2));
4771}
4772
4773
4774void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4775 set(index * 2, cell);
4776}
4777
4778
4779JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4780 return JSGlobalPropertyCell::cast(get(index * 2));
4781}
4782
4783
4784Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4785 return isolate->factory()->the_hole_value();
4786}
4787
4788
4789Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4790 return isolate->factory()->undefined_value();
4791}
4792
4793
4794Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4795 return heap->raw_unchecked_the_hole_value();
4796}
4797
4798
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004799Relocatable::Relocatable(Isolate* isolate) {
4800 ASSERT(isolate == Isolate::Current());
4801 isolate_ = isolate;
4802 prev_ = isolate->relocatable_top();
4803 isolate->set_relocatable_top(this);
4804}
4805
4806
4807Relocatable::~Relocatable() {
4808 ASSERT(isolate_ == Isolate::Current());
4809 ASSERT_EQ(isolate_->relocatable_top(), this);
4810 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004811}
4812
4813
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004814int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4815 return map->instance_size();
4816}
4817
4818
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004819void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004820 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004821 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004822}
4823
4824
4825template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004826void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004827 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004828 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004829}
4830
4831
4832void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4833 typedef v8::String::ExternalAsciiStringResource Resource;
4834 v->VisitExternalAsciiString(
4835 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4836}
4837
4838
4839template<typename StaticVisitor>
4840void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4841 typedef v8::String::ExternalAsciiStringResource Resource;
4842 StaticVisitor::VisitExternalAsciiString(
4843 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4844}
4845
4846
4847void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4848 typedef v8::String::ExternalStringResource Resource;
4849 v->VisitExternalTwoByteString(
4850 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4851}
4852
4853
4854template<typename StaticVisitor>
4855void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4856 typedef v8::String::ExternalStringResource Resource;
4857 StaticVisitor::VisitExternalTwoByteString(
4858 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4859}
4860
4861#define SLOT_ADDR(obj, offset) \
4862 reinterpret_cast<Object**>((obj)->address() + offset)
4863
4864template<int start_offset, int end_offset, int size>
4865void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4866 HeapObject* obj,
4867 ObjectVisitor* v) {
4868 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4869}
4870
4871
4872template<int start_offset>
4873void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4874 int object_size,
4875 ObjectVisitor* v) {
4876 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4877}
4878
4879#undef SLOT_ADDR
4880
4881
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004882#undef CAST_ACCESSOR
4883#undef INT_ACCESSORS
4884#undef SMI_ACCESSORS
4885#undef ACCESSORS
4886#undef FIELD_ADDR
4887#undef READ_FIELD
4888#undef WRITE_FIELD
4889#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004890#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004891#undef READ_MEMADDR_FIELD
4892#undef WRITE_MEMADDR_FIELD
4893#undef READ_DOUBLE_FIELD
4894#undef WRITE_DOUBLE_FIELD
4895#undef READ_INT_FIELD
4896#undef WRITE_INT_FIELD
4897#undef READ_SHORT_FIELD
4898#undef WRITE_SHORT_FIELD
4899#undef READ_BYTE_FIELD
4900#undef WRITE_BYTE_FIELD
4901
4902
4903} } // namespace v8::internal
4904
4905#endif // V8_OBJECTS_INL_H_