blob: a5aa5a84ba556428a21ddc01507d6ff30a7cee8f [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)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003709BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_crankshaft,
3710 kDontCrankshaft)
3711BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003712
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003713ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3714ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3715
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003716ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3717
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003718bool Script::HasValidSource() {
3719 Object* src = this->source();
3720 if (!src->IsString()) return true;
3721 String* src_str = String::cast(src);
3722 if (!StringShape(src_str).IsExternal()) return true;
3723 if (src_str->IsAsciiRepresentation()) {
3724 return ExternalAsciiString::cast(src)->resource() != NULL;
3725 } else if (src_str->IsTwoByteRepresentation()) {
3726 return ExternalTwoByteString::cast(src)->resource() != NULL;
3727 }
3728 return true;
3729}
3730
3731
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003732void SharedFunctionInfo::DontAdaptArguments() {
3733 ASSERT(code()->kind() == Code::BUILTIN);
3734 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3735}
3736
3737
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003738int SharedFunctionInfo::start_position() {
3739 return start_position_and_type() >> kStartPositionShift;
3740}
3741
3742
3743void SharedFunctionInfo::set_start_position(int start_position) {
3744 set_start_position_and_type((start_position << kStartPositionShift)
3745 | (start_position_and_type() & ~kStartPositionMask));
3746}
3747
3748
3749Code* SharedFunctionInfo::code() {
3750 return Code::cast(READ_FIELD(this, kCodeOffset));
3751}
3752
3753
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003754Code* SharedFunctionInfo::unchecked_code() {
3755 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3756}
3757
3758
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003759void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003760 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003761 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003762}
3763
3764
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003765ScopeInfo* SharedFunctionInfo::scope_info() {
3766 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003767}
3768
3769
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003770void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003771 WriteBarrierMode mode) {
3772 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003773 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3774 this,
3775 kScopeInfoOffset,
3776 reinterpret_cast<Object*>(value),
3777 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003778}
3779
3780
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003781bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003782 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003783 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003784}
3785
3786
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003787bool SharedFunctionInfo::IsApiFunction() {
3788 return function_data()->IsFunctionTemplateInfo();
3789}
3790
3791
3792FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3793 ASSERT(IsApiFunction());
3794 return FunctionTemplateInfo::cast(function_data());
3795}
3796
3797
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003798bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003799 return function_data()->IsSmi();
3800}
3801
3802
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003803BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3804 ASSERT(HasBuiltinFunctionId());
3805 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003806}
3807
3808
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003809int SharedFunctionInfo::code_age() {
3810 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3811}
3812
3813
3814void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003815 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3816 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003817}
3818
3819
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003820bool SharedFunctionInfo::has_deoptimization_support() {
3821 Code* code = this->code();
3822 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3823}
3824
3825
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003826bool JSFunction::IsBuiltin() {
3827 return context()->global()->IsJSBuiltinsObject();
3828}
3829
3830
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003831bool JSFunction::NeedsArgumentsAdaption() {
3832 return shared()->formal_parameter_count() !=
3833 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3834}
3835
3836
3837bool JSFunction::IsOptimized() {
3838 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3839}
3840
3841
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003842bool JSFunction::IsOptimizable() {
3843 return code()->kind() == Code::FUNCTION && code()->optimizable();
3844}
3845
3846
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003847bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003848 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003849}
3850
3851
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003852Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003853 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003854}
3855
3856
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003857Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003858 return reinterpret_cast<Code*>(
3859 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003860}
3861
3862
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003863void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003864 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003865 Address entry = value->entry();
3866 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003867 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3868 this,
3869 HeapObject::RawField(this, kCodeEntryOffset),
3870 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003871}
3872
3873
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003874void JSFunction::ReplaceCode(Code* code) {
3875 bool was_optimized = IsOptimized();
3876 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3877
3878 set_code(code);
3879
3880 // Add/remove the function from the list of optimized functions for this
3881 // context based on the state change.
3882 if (!was_optimized && is_optimized) {
3883 context()->global_context()->AddOptimizedFunction(this);
3884 }
3885 if (was_optimized && !is_optimized) {
3886 context()->global_context()->RemoveOptimizedFunction(this);
3887 }
3888}
3889
3890
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003891Context* JSFunction::context() {
3892 return Context::cast(READ_FIELD(this, kContextOffset));
3893}
3894
3895
3896Object* JSFunction::unchecked_context() {
3897 return READ_FIELD(this, kContextOffset);
3898}
3899
3900
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003901SharedFunctionInfo* JSFunction::unchecked_shared() {
3902 return reinterpret_cast<SharedFunctionInfo*>(
3903 READ_FIELD(this, kSharedFunctionInfoOffset));
3904}
3905
3906
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003907void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003908 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003909 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003910 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003911}
3912
3913ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3914 kPrototypeOrInitialMapOffset)
3915
3916
3917Map* JSFunction::initial_map() {
3918 return Map::cast(prototype_or_initial_map());
3919}
3920
3921
3922void JSFunction::set_initial_map(Map* value) {
3923 set_prototype_or_initial_map(value);
3924}
3925
3926
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003927MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
3928 Map* initial_map) {
3929 Context* global_context = context()->global_context();
3930 Object* array_function =
3931 global_context->get(Context::ARRAY_FUNCTION_INDEX);
3932 if (array_function->IsJSFunction() &&
3933 this == JSFunction::cast(array_function)) {
3934 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
3935
3936 MaybeObject* maybe_map = initial_map->CopyDropTransitions();
3937 Map* new_double_map = NULL;
3938 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
3939 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
3940 initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS, new_double_map);
3941
3942 maybe_map = new_double_map->CopyDropTransitions();
3943 Map* new_object_map = NULL;
3944 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
3945 new_object_map->set_elements_kind(FAST_ELEMENTS);
3946 new_double_map->AddElementsTransition(FAST_ELEMENTS, new_object_map);
3947
3948 global_context->set_smi_js_array_map(initial_map);
3949 global_context->set_double_js_array_map(new_double_map);
3950 global_context->set_object_js_array_map(new_object_map);
3951 }
3952 set_initial_map(initial_map);
3953 return this;
3954}
3955
3956
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003957bool JSFunction::has_initial_map() {
3958 return prototype_or_initial_map()->IsMap();
3959}
3960
3961
3962bool JSFunction::has_instance_prototype() {
3963 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3964}
3965
3966
3967bool JSFunction::has_prototype() {
3968 return map()->has_non_instance_prototype() || has_instance_prototype();
3969}
3970
3971
3972Object* JSFunction::instance_prototype() {
3973 ASSERT(has_instance_prototype());
3974 if (has_initial_map()) return initial_map()->prototype();
3975 // When there is no initial map and the prototype is a JSObject, the
3976 // initial map field is used for the prototype field.
3977 return prototype_or_initial_map();
3978}
3979
3980
3981Object* JSFunction::prototype() {
3982 ASSERT(has_prototype());
3983 // If the function's prototype property has been set to a non-JSObject
3984 // value, that value is stored in the constructor field of the map.
3985 if (map()->has_non_instance_prototype()) return map()->constructor();
3986 return instance_prototype();
3987}
3988
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003989bool JSFunction::should_have_prototype() {
3990 return map()->function_with_prototype();
3991}
3992
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003993
3994bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003995 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003996}
3997
3998
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003999FixedArray* JSFunction::literals() {
4000 ASSERT(!shared()->bound());
4001 return literals_or_bindings();
4002}
4003
4004
4005void JSFunction::set_literals(FixedArray* literals) {
4006 ASSERT(!shared()->bound());
4007 set_literals_or_bindings(literals);
4008}
4009
4010
4011FixedArray* JSFunction::function_bindings() {
4012 ASSERT(shared()->bound());
4013 return literals_or_bindings();
4014}
4015
4016
4017void JSFunction::set_function_bindings(FixedArray* bindings) {
4018 ASSERT(shared()->bound());
4019 // Bound function literal may be initialized to the empty fixed array
4020 // before the bindings are set.
4021 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4022 bindings->map() == GetHeap()->fixed_cow_array_map());
4023 set_literals_or_bindings(bindings);
4024}
4025
4026
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004027int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004028 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004029 return literals()->length();
4030}
4031
4032
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004033Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004034 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004035 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004036}
4037
4038
4039void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4040 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004041 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004042 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004043 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004044}
4045
4046
4047Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004048 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004049 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4050}
4051
4052
4053void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4054 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004055 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004056 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004057 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004058}
4059
4060
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004061ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004062ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004063ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4064ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4065
4066
4067void JSProxy::InitializeBody(int object_size, Object* value) {
4068 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4069 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4070 WRITE_FIELD(this, offset, value);
4071 }
4072}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004073
4074
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004075ACCESSORS(JSSet, table, Object, kTableOffset)
4076ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004077ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4078ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004079
4080
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004081Address Foreign::foreign_address() {
4082 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004083}
4084
4085
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004086void Foreign::set_foreign_address(Address value) {
4087 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004088}
4089
4090
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004091ACCESSORS(JSValue, value, Object, kValueOffset)
4092
4093
4094JSValue* JSValue::cast(Object* obj) {
4095 ASSERT(obj->IsJSValue());
4096 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4097 return reinterpret_cast<JSValue*>(obj);
4098}
4099
4100
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004101ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4102ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4103ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4104ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4105ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4106SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4107SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4108
4109
4110JSMessageObject* JSMessageObject::cast(Object* obj) {
4111 ASSERT(obj->IsJSMessageObject());
4112 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4113 return reinterpret_cast<JSMessageObject*>(obj);
4114}
4115
4116
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004117INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004118ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004119ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004120ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004121ACCESSORS(Code, type_feedback_cells, TypeFeedbackCells,
4122 kTypeFeedbackCellsOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004123ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004124
4125
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004126byte* Code::instruction_start() {
4127 return FIELD_ADDR(this, kHeaderSize);
4128}
4129
4130
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004131byte* Code::instruction_end() {
4132 return instruction_start() + instruction_size();
4133}
4134
4135
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004136int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004137 return RoundUp(instruction_size(), kObjectAlignment);
4138}
4139
4140
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004141FixedArray* Code::unchecked_deoptimization_data() {
4142 return reinterpret_cast<FixedArray*>(
4143 READ_FIELD(this, kDeoptimizationDataOffset));
4144}
4145
4146
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004147ByteArray* Code::unchecked_relocation_info() {
4148 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004149}
4150
4151
4152byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004153 return unchecked_relocation_info()->GetDataStartAddress();
4154}
4155
4156
4157int Code::relocation_size() {
4158 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004159}
4160
4161
4162byte* Code::entry() {
4163 return instruction_start();
4164}
4165
4166
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004167bool Code::contains(byte* inner_pointer) {
4168 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004169}
4170
4171
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004172ACCESSORS(JSArray, length, Object, kLengthOffset)
4173
4174
ager@chromium.org236ad962008-09-25 09:45:57 +00004175ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004176
4177
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004178JSRegExp::Type JSRegExp::TypeTag() {
4179 Object* data = this->data();
4180 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4181 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4182 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004183}
4184
4185
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004186JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4187 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4188 return static_cast<JSRegExp::Type>(smi->value());
4189}
4190
4191
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004192int JSRegExp::CaptureCount() {
4193 switch (TypeTag()) {
4194 case ATOM:
4195 return 0;
4196 case IRREGEXP:
4197 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4198 default:
4199 UNREACHABLE();
4200 return -1;
4201 }
4202}
4203
4204
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004205JSRegExp::Flags JSRegExp::GetFlags() {
4206 ASSERT(this->data()->IsFixedArray());
4207 Object* data = this->data();
4208 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4209 return Flags(smi->value());
4210}
4211
4212
4213String* JSRegExp::Pattern() {
4214 ASSERT(this->data()->IsFixedArray());
4215 Object* data = this->data();
4216 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4217 return pattern;
4218}
4219
4220
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004221Object* JSRegExp::DataAt(int index) {
4222 ASSERT(TypeTag() != NOT_COMPILED);
4223 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004224}
4225
4226
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004227Object* JSRegExp::DataAtUnchecked(int index) {
4228 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4229 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4230 return READ_FIELD(fa, offset);
4231}
4232
4233
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004234void JSRegExp::SetDataAt(int index, Object* value) {
4235 ASSERT(TypeTag() != NOT_COMPILED);
4236 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4237 FixedArray::cast(data())->set(index, value);
4238}
4239
4240
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004241void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4242 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4243 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4244 if (value->IsSmi()) {
4245 fa->set_unchecked(index, Smi::cast(value));
4246 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004247 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004248 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4249 }
4250}
4251
4252
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004253ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004254 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004255#if DEBUG
4256 FixedArrayBase* fixed_array =
4257 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4258 Map* map = fixed_array->map();
4259 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004260 (map == GetHeap()->fixed_array_map() ||
4261 map == GetHeap()->fixed_cow_array_map())) ||
4262 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004263 (fixed_array->IsFixedDoubleArray() ||
4264 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004265 (kind == DICTIONARY_ELEMENTS &&
4266 fixed_array->IsFixedArray() &&
4267 fixed_array->IsDictionary()) ||
4268 (kind > DICTIONARY_ELEMENTS));
4269 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4270 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004271#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004272 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004273}
4274
4275
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004276ElementsAccessor* JSObject::GetElementsAccessor() {
4277 return ElementsAccessor::ForKind(GetElementsKind());
4278}
4279
4280
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004281bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004282 return GetElementsKind() == FAST_ELEMENTS;
4283}
4284
4285
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004286bool JSObject::HasFastSmiOnlyElements() {
4287 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4288}
4289
4290
4291bool JSObject::HasFastTypeElements() {
4292 ElementsKind elements_kind = GetElementsKind();
4293 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4294 elements_kind == FAST_ELEMENTS;
4295}
4296
4297
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004298bool JSObject::HasFastDoubleElements() {
4299 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4300}
4301
4302
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004303bool JSObject::HasDictionaryElements() {
4304 return GetElementsKind() == DICTIONARY_ELEMENTS;
4305}
4306
4307
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004308bool JSObject::HasNonStrictArgumentsElements() {
4309 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4310}
4311
4312
ager@chromium.org3811b432009-10-28 14:53:37 +00004313bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004314 HeapObject* array = elements();
4315 ASSERT(array != NULL);
4316 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004317}
4318
4319
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004320#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4321bool JSObject::HasExternal##name##Elements() { \
4322 HeapObject* array = elements(); \
4323 ASSERT(array != NULL); \
4324 if (!array->IsHeapObject()) \
4325 return false; \
4326 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004327}
4328
4329
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004330EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4331EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4332EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4333EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4334 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4335EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4336EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4337 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4338EXTERNAL_ELEMENTS_CHECK(Float,
4339 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004340EXTERNAL_ELEMENTS_CHECK(Double,
4341 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004342EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004343
4344
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004345bool JSObject::HasNamedInterceptor() {
4346 return map()->has_named_interceptor();
4347}
4348
4349
4350bool JSObject::HasIndexedInterceptor() {
4351 return map()->has_indexed_interceptor();
4352}
4353
4354
lrn@chromium.org303ada72010-10-27 09:33:13 +00004355MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004356 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004357 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004358 Isolate* isolate = GetIsolate();
4359 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004360 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004361 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4362 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004363 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4364 return maybe_writable_elems;
4365 }
4366 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004367 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004368 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004369 return writable_elems;
4370}
4371
4372
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004373StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004374 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004375 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004376}
4377
4378
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004379SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004380 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004381 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004382}
4383
4384
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004385bool String::IsHashFieldComputed(uint32_t field) {
4386 return (field & kHashNotComputedMask) == 0;
4387}
4388
4389
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004390bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004391 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004392}
4393
4394
4395uint32_t String::Hash() {
4396 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004397 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004398 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004399 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004400 return ComputeAndSetHash();
4401}
4402
4403
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004404StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004405 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004406 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004407 array_index_(0),
4408 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4409 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004410 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004411 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004412}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004413
4414
4415bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004416 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004417}
4418
4419
4420void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004421 // Use the Jenkins one-at-a-time hash function to update the hash
4422 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004423 raw_running_hash_ += c;
4424 raw_running_hash_ += (raw_running_hash_ << 10);
4425 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004426 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004427 if (is_array_index_) {
4428 if (c < '0' || c > '9') {
4429 is_array_index_ = false;
4430 } else {
4431 int d = c - '0';
4432 if (is_first_char_) {
4433 is_first_char_ = false;
4434 if (c == '0' && length_ > 1) {
4435 is_array_index_ = false;
4436 return;
4437 }
4438 }
4439 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4440 is_array_index_ = false;
4441 } else {
4442 array_index_ = array_index_ * 10 + d;
4443 }
4444 }
4445 }
4446}
4447
4448
4449void StringHasher::AddCharacterNoIndex(uc32 c) {
4450 ASSERT(!is_array_index());
4451 raw_running_hash_ += c;
4452 raw_running_hash_ += (raw_running_hash_ << 10);
4453 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4454}
4455
4456
4457uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004458 // Get the calculated raw hash value and do some more bit ops to distribute
4459 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004460 uint32_t result = raw_running_hash_;
4461 result += (result << 3);
4462 result ^= (result >> 11);
4463 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004464 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004465 result = 27;
4466 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004467 return result;
4468}
4469
4470
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004471template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004472uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4473 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004474 if (!hasher.has_trivial_hash()) {
4475 int i;
4476 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4477 hasher.AddCharacter(chars[i]);
4478 }
4479 for (; i < length; i++) {
4480 hasher.AddCharacterNoIndex(chars[i]);
4481 }
4482 }
4483 return hasher.GetHashField();
4484}
4485
4486
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004487bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004488 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004489 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4490 return false;
4491 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004492 return SlowAsArrayIndex(index);
4493}
4494
4495
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004496Object* JSReceiver::GetPrototype() {
4497 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004498}
4499
4500
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004501bool JSReceiver::HasProperty(String* name) {
4502 if (IsJSProxy()) {
4503 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4504 }
4505 return GetPropertyAttribute(name) != ABSENT;
4506}
4507
4508
4509bool JSReceiver::HasLocalProperty(String* name) {
4510 if (IsJSProxy()) {
4511 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4512 }
4513 return GetLocalPropertyAttribute(name) != ABSENT;
4514}
4515
4516
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004517PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004518 return GetPropertyAttributeWithReceiver(this, key);
4519}
4520
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004521// TODO(504): this may be useful in other places too where JSGlobalProxy
4522// is used.
4523Object* JSObject::BypassGlobalProxy() {
4524 if (IsJSGlobalProxy()) {
4525 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004526 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004527 ASSERT(proto->IsJSGlobalObject());
4528 return proto;
4529 }
4530 return this;
4531}
4532
4533
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004534MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4535 return IsJSProxy()
4536 ? JSProxy::cast(this)->GetIdentityHash(flag)
4537 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004538}
4539
4540
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004541bool JSReceiver::HasElement(uint32_t index) {
4542 if (IsJSProxy()) {
4543 return JSProxy::cast(this)->HasElementWithHandler(index);
4544 }
4545 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004546}
4547
4548
4549bool AccessorInfo::all_can_read() {
4550 return BooleanBit::get(flag(), kAllCanReadBit);
4551}
4552
4553
4554void AccessorInfo::set_all_can_read(bool value) {
4555 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4556}
4557
4558
4559bool AccessorInfo::all_can_write() {
4560 return BooleanBit::get(flag(), kAllCanWriteBit);
4561}
4562
4563
4564void AccessorInfo::set_all_can_write(bool value) {
4565 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4566}
4567
4568
ager@chromium.org870a0b62008-11-04 11:43:05 +00004569bool AccessorInfo::prohibits_overwriting() {
4570 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4571}
4572
4573
4574void AccessorInfo::set_prohibits_overwriting(bool value) {
4575 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4576}
4577
4578
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004579PropertyAttributes AccessorInfo::property_attributes() {
4580 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4581}
4582
4583
4584void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004585 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004586}
4587
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004588
4589template<typename Shape, typename Key>
4590void Dictionary<Shape, Key>::SetEntry(int entry,
4591 Object* key,
4592 Object* value) {
4593 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4594}
4595
4596
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004597template<typename Shape, typename Key>
4598void Dictionary<Shape, Key>::SetEntry(int entry,
4599 Object* key,
4600 Object* value,
4601 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004602 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004603 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004604 AssertNoAllocation no_gc;
4605 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004606 FixedArray::set(index, key, mode);
4607 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004608 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004609}
4610
4611
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004612bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4613 ASSERT(other->IsNumber());
4614 return key == static_cast<uint32_t>(other->Number());
4615}
4616
4617
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004618uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4619 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004620}
4621
4622
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004623uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4624 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004625 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004626 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004627}
4628
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004629uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4630 return ComputeIntegerHash(key, seed);
4631}
4632
4633uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4634 uint32_t seed,
4635 Object* other) {
4636 ASSERT(other->IsNumber());
4637 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4638}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004639
4640MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4641 return Isolate::Current()->heap()->NumberFromUint32(key);
4642}
4643
4644
4645bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4646 // We know that all entries in a hash table had their hash keys created.
4647 // Use that knowledge to have fast failure.
4648 if (key->Hash() != String::cast(other)->Hash()) return false;
4649 return key->Equals(String::cast(other));
4650}
4651
4652
4653uint32_t StringDictionaryShape::Hash(String* key) {
4654 return key->Hash();
4655}
4656
4657
4658uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4659 return String::cast(other)->Hash();
4660}
4661
4662
4663MaybeObject* StringDictionaryShape::AsObject(String* key) {
4664 return key;
4665}
4666
4667
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004668template <int entrysize>
4669bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4670 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004671}
4672
4673
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004674template <int entrysize>
4675uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004676 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4677 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004678}
4679
4680
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004681template <int entrysize>
4682uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4683 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004684 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4685 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004686}
4687
4688
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004689template <int entrysize>
4690MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004691 return key;
4692}
4693
4694
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004695void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004696 // No write barrier is needed since empty_fixed_array is not in new space.
4697 // Please note this function is used during marking:
4698 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004699 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4700 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004701}
4702
4703
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004704void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004705 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004706 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004707 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4708 if (elts->length() < required_size) {
4709 // Doubling in size would be overkill, but leave some slack to avoid
4710 // constantly growing.
4711 Expand(required_size + (required_size >> 3));
4712 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004713 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004714 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4715 // Expand will allocate a new backing store in new space even if the size
4716 // we asked for isn't larger than what we had before.
4717 Expand(required_size);
4718 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004719}
4720
4721
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004722void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004723 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004724 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4725}
4726
4727
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004728bool JSArray::AllowsSetElementsLength() {
4729 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4730 ASSERT(result == !HasExternalArrayElements());
4731 return result;
4732}
4733
4734
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004735MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4736 MaybeObject* maybe_result = EnsureCanContainElements(
4737 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4738 if (maybe_result->IsFailure()) return maybe_result;
4739 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4740 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4741 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4742 ((GetElementsKind() == FAST_ELEMENTS) ||
4743 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4744 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004745 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004746 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004747 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004748}
4749
4750
lrn@chromium.org303ada72010-10-27 09:33:13 +00004751MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004752 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004753 return GetHeap()->CopyFixedArray(this);
4754}
4755
4756
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004757MaybeObject* FixedDoubleArray::Copy() {
4758 if (length() == 0) return this;
4759 return GetHeap()->CopyFixedDoubleArray(this);
4760}
4761
4762
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004763void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4764 set(1 + index * 2, id);
4765}
4766
4767
4768Smi* TypeFeedbackCells::AstId(int index) {
4769 return Smi::cast(get(1 + index * 2));
4770}
4771
4772
4773void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4774 set(index * 2, cell);
4775}
4776
4777
4778JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4779 return JSGlobalPropertyCell::cast(get(index * 2));
4780}
4781
4782
4783Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4784 return isolate->factory()->the_hole_value();
4785}
4786
4787
4788Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4789 return isolate->factory()->undefined_value();
4790}
4791
4792
4793Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4794 return heap->raw_unchecked_the_hole_value();
4795}
4796
4797
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004798Relocatable::Relocatable(Isolate* isolate) {
4799 ASSERT(isolate == Isolate::Current());
4800 isolate_ = isolate;
4801 prev_ = isolate->relocatable_top();
4802 isolate->set_relocatable_top(this);
4803}
4804
4805
4806Relocatable::~Relocatable() {
4807 ASSERT(isolate_ == Isolate::Current());
4808 ASSERT_EQ(isolate_->relocatable_top(), this);
4809 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004810}
4811
4812
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004813int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4814 return map->instance_size();
4815}
4816
4817
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004818void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004819 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004820 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004821}
4822
4823
4824template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004825void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004826 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004827 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004828}
4829
4830
4831void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4832 typedef v8::String::ExternalAsciiStringResource Resource;
4833 v->VisitExternalAsciiString(
4834 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4835}
4836
4837
4838template<typename StaticVisitor>
4839void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4840 typedef v8::String::ExternalAsciiStringResource Resource;
4841 StaticVisitor::VisitExternalAsciiString(
4842 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4843}
4844
4845
4846void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4847 typedef v8::String::ExternalStringResource Resource;
4848 v->VisitExternalTwoByteString(
4849 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4850}
4851
4852
4853template<typename StaticVisitor>
4854void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4855 typedef v8::String::ExternalStringResource Resource;
4856 StaticVisitor::VisitExternalTwoByteString(
4857 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4858}
4859
4860#define SLOT_ADDR(obj, offset) \
4861 reinterpret_cast<Object**>((obj)->address() + offset)
4862
4863template<int start_offset, int end_offset, int size>
4864void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4865 HeapObject* obj,
4866 ObjectVisitor* v) {
4867 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4868}
4869
4870
4871template<int start_offset>
4872void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4873 int object_size,
4874 ObjectVisitor* v) {
4875 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4876}
4877
4878#undef SLOT_ADDR
4879
4880
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004881#undef CAST_ACCESSOR
4882#undef INT_ACCESSORS
4883#undef SMI_ACCESSORS
4884#undef ACCESSORS
4885#undef FIELD_ADDR
4886#undef READ_FIELD
4887#undef WRITE_FIELD
4888#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004889#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004890#undef READ_MEMADDR_FIELD
4891#undef WRITE_MEMADDR_FIELD
4892#undef READ_DOUBLE_FIELD
4893#undef WRITE_DOUBLE_FIELD
4894#undef READ_INT_FIELD
4895#undef WRITE_INT_FIELD
4896#undef READ_SHORT_FIELD
4897#undef WRITE_SHORT_FIELD
4898#undef READ_BYTE_FIELD
4899#undef WRITE_BYTE_FIELD
4900
4901
4902} } // namespace v8::internal
4903
4904#endif // V8_OBJECTS_INL_H_