blob: baaa5ab3470585d129ae8906fad1b19e9680ae15 [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() ||
1342 map()->has_fast_smi_only_elements()) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001343 (value->map() == GetHeap()->fixed_array_map() ||
1344 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001345 ASSERT(map()->has_fast_double_elements() ==
1346 value->IsFixedDoubleArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001347 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001348 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001349}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001350
1351
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001352void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1353 set_map_and_elements(NULL, value, mode);
1354}
1355
1356
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001357void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001358 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1359 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001360}
1361
1362
1363void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001364 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001365 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1366 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001367}
1368
1369
lrn@chromium.org303ada72010-10-27 09:33:13 +00001370MaybeObject* JSObject::ResetElements() {
1371 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001372 ElementsKind elements_kind = FLAG_smi_only_arrays
1373 ? FAST_SMI_ONLY_ELEMENTS
1374 : FAST_ELEMENTS;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001375 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1376 elements_kind);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001377 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001378 set_map(Map::cast(obj));
1379 initialize_elements();
1380 return this;
1381}
1382
1383
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001384ACCESSORS(Oddball, to_string, String, kToStringOffset)
1385ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1386
1387
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001388byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001389 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001390}
1391
1392
1393void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001394 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001395}
1396
1397
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001398Object* JSGlobalPropertyCell::value() {
1399 return READ_FIELD(this, kValueOffset);
1400}
1401
1402
1403void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1404 // The write barrier is not used for global property cells.
1405 ASSERT(!val->IsJSGlobalPropertyCell());
1406 WRITE_FIELD(this, kValueOffset, val);
1407}
1408
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001409
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001410int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001411 InstanceType type = map()->instance_type();
1412 // Check for the most common kind of JavaScript object before
1413 // falling into the generic switch. This speeds up the internal
1414 // field operations considerably on average.
1415 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1416 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001417 case JS_GLOBAL_PROXY_TYPE:
1418 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001419 case JS_GLOBAL_OBJECT_TYPE:
1420 return JSGlobalObject::kSize;
1421 case JS_BUILTINS_OBJECT_TYPE:
1422 return JSBuiltinsObject::kSize;
1423 case JS_FUNCTION_TYPE:
1424 return JSFunction::kSize;
1425 case JS_VALUE_TYPE:
1426 return JSValue::kSize;
1427 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001428 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001429 case JS_WEAK_MAP_TYPE:
1430 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001431 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001432 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001433 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001434 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001435 case JS_MESSAGE_OBJECT_TYPE:
1436 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001437 default:
1438 UNREACHABLE();
1439 return 0;
1440 }
1441}
1442
1443
1444int JSObject::GetInternalFieldCount() {
1445 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001446 // Make sure to adjust for the number of in-object properties. These
1447 // properties do contribute to the size, but are not internal fields.
1448 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1449 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001450}
1451
1452
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001453int JSObject::GetInternalFieldOffset(int index) {
1454 ASSERT(index < GetInternalFieldCount() && index >= 0);
1455 return GetHeaderSize() + (kPointerSize * index);
1456}
1457
1458
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001459Object* JSObject::GetInternalField(int index) {
1460 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001461 // Internal objects do follow immediately after the header, whereas in-object
1462 // properties are at the end of the object. Therefore there is no need
1463 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001464 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1465}
1466
1467
1468void JSObject::SetInternalField(int index, Object* value) {
1469 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001470 // Internal objects do follow immediately after the header, whereas in-object
1471 // properties are at the end of the object. Therefore there is no need
1472 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001473 int offset = GetHeaderSize() + (kPointerSize * index);
1474 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001475 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001476}
1477
1478
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001479void JSObject::SetInternalField(int index, Smi* value) {
1480 ASSERT(index < GetInternalFieldCount() && index >= 0);
1481 // Internal objects do follow immediately after the header, whereas in-object
1482 // properties are at the end of the object. Therefore there is no need
1483 // to adjust the index here.
1484 int offset = GetHeaderSize() + (kPointerSize * index);
1485 WRITE_FIELD(this, offset, value);
1486}
1487
1488
ager@chromium.org7c537e22008-10-16 08:43:32 +00001489// Access fast-case object properties at index. The use of these routines
1490// is needed to correctly distinguish between properties stored in-object and
1491// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001492Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001493 // Adjust for the number of properties stored in the object.
1494 index -= map()->inobject_properties();
1495 if (index < 0) {
1496 int offset = map()->instance_size() + (index * kPointerSize);
1497 return READ_FIELD(this, offset);
1498 } else {
1499 ASSERT(index < properties()->length());
1500 return properties()->get(index);
1501 }
1502}
1503
1504
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001505Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001506 // Adjust for the number of properties stored in the object.
1507 index -= map()->inobject_properties();
1508 if (index < 0) {
1509 int offset = map()->instance_size() + (index * kPointerSize);
1510 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001511 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001512 } else {
1513 ASSERT(index < properties()->length());
1514 properties()->set(index, value);
1515 }
1516 return value;
1517}
1518
1519
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001520int JSObject::GetInObjectPropertyOffset(int index) {
1521 // Adjust for the number of properties stored in the object.
1522 index -= map()->inobject_properties();
1523 ASSERT(index < 0);
1524 return map()->instance_size() + (index * kPointerSize);
1525}
1526
1527
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001528Object* JSObject::InObjectPropertyAt(int index) {
1529 // Adjust for the number of properties stored in the object.
1530 index -= map()->inobject_properties();
1531 ASSERT(index < 0);
1532 int offset = map()->instance_size() + (index * kPointerSize);
1533 return READ_FIELD(this, offset);
1534}
1535
1536
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001537Object* JSObject::InObjectPropertyAtPut(int index,
1538 Object* value,
1539 WriteBarrierMode mode) {
1540 // Adjust for the number of properties stored in the object.
1541 index -= map()->inobject_properties();
1542 ASSERT(index < 0);
1543 int offset = map()->instance_size() + (index * kPointerSize);
1544 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001545 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001546 return value;
1547}
1548
1549
1550
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001551void JSObject::InitializeBody(Map* map,
1552 Object* pre_allocated_value,
1553 Object* filler_value) {
1554 ASSERT(!filler_value->IsHeapObject() ||
1555 !GetHeap()->InNewSpace(filler_value));
1556 ASSERT(!pre_allocated_value->IsHeapObject() ||
1557 !GetHeap()->InNewSpace(pre_allocated_value));
1558 int size = map->instance_size();
1559 int offset = kHeaderSize;
1560 if (filler_value != pre_allocated_value) {
1561 int pre_allocated = map->pre_allocated_property_fields();
1562 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1563 for (int i = 0; i < pre_allocated; i++) {
1564 WRITE_FIELD(this, offset, pre_allocated_value);
1565 offset += kPointerSize;
1566 }
1567 }
1568 while (offset < size) {
1569 WRITE_FIELD(this, offset, filler_value);
1570 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001571 }
1572}
1573
1574
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001575bool JSObject::HasFastProperties() {
1576 return !properties()->IsDictionary();
1577}
1578
1579
1580int JSObject::MaxFastProperties() {
1581 // Allow extra fast properties if the object has more than
1582 // kMaxFastProperties in-object properties. When this is the case,
1583 // it is very unlikely that the object is being used as a dictionary
1584 // and there is a good chance that allowing more map transitions
1585 // will be worth it.
1586 return Max(map()->inobject_properties(), kMaxFastProperties);
1587}
1588
1589
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001590void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001591 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001592 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001593 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001594 }
1595}
1596
1597
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001598bool Object::ToArrayIndex(uint32_t* index) {
1599 if (IsSmi()) {
1600 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001601 if (value < 0) return false;
1602 *index = value;
1603 return true;
1604 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001605 if (IsHeapNumber()) {
1606 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001607 uint32_t uint_value = static_cast<uint32_t>(value);
1608 if (value == static_cast<double>(uint_value)) {
1609 *index = uint_value;
1610 return true;
1611 }
1612 }
1613 return false;
1614}
1615
1616
1617bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1618 if (!this->IsJSValue()) return false;
1619
1620 JSValue* js_value = JSValue::cast(this);
1621 if (!js_value->value()->IsString()) return false;
1622
1623 String* str = String::cast(js_value->value());
1624 if (index >= (uint32_t)str->length()) return false;
1625
1626 return true;
1627}
1628
1629
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001630FixedArrayBase* FixedArrayBase::cast(Object* object) {
1631 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1632 return reinterpret_cast<FixedArrayBase*>(object);
1633}
1634
1635
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001636Object* FixedArray::get(int index) {
1637 ASSERT(index >= 0 && index < this->length());
1638 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1639}
1640
1641
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001642void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001643 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001644 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001645 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1646 int offset = kHeaderSize + index * kPointerSize;
1647 WRITE_FIELD(this, offset, value);
1648}
1649
1650
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001651void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001652 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001653 ASSERT(index >= 0 && index < this->length());
1654 int offset = kHeaderSize + index * kPointerSize;
1655 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001656 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001657}
1658
1659
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001660inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1661 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1662}
1663
1664
1665inline double FixedDoubleArray::hole_nan_as_double() {
1666 return BitCast<double, uint64_t>(kHoleNanInt64);
1667}
1668
1669
1670inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1671 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1672 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1673 return OS::nan_value();
1674}
1675
1676
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001677double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001678 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1679 map() != HEAP->fixed_array_map());
1680 ASSERT(index >= 0 && index < this->length());
1681 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1682 ASSERT(!is_the_hole_nan(result));
1683 return result;
1684}
1685
1686
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001687MaybeObject* FixedDoubleArray::get(int index) {
1688 if (is_the_hole(index)) {
1689 return GetHeap()->the_hole_value();
1690 } else {
1691 return GetHeap()->NumberFromDouble(get_scalar(index));
1692 }
1693}
1694
1695
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001696void FixedDoubleArray::set(int index, double value) {
1697 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1698 map() != HEAP->fixed_array_map());
1699 int offset = kHeaderSize + index * kDoubleSize;
1700 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1701 WRITE_DOUBLE_FIELD(this, offset, value);
1702}
1703
1704
1705void FixedDoubleArray::set_the_hole(int index) {
1706 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1707 map() != HEAP->fixed_array_map());
1708 int offset = kHeaderSize + index * kDoubleSize;
1709 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1710}
1711
1712
1713bool FixedDoubleArray::is_the_hole(int index) {
1714 int offset = kHeaderSize + index * kDoubleSize;
1715 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1716}
1717
1718
1719void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1720 int old_length = from->length();
1721 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001722 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1723 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1724 FIELD_ADDR(from, kHeaderSize),
1725 old_length * kDoubleSize);
1726 } else {
1727 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001728 if (from->is_the_hole(i)) {
1729 set_the_hole(i);
1730 } else {
1731 set(i, from->get_scalar(i));
1732 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001733 }
1734 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001735 int offset = kHeaderSize + old_length * kDoubleSize;
1736 for (int current = from->length(); current < length(); ++current) {
1737 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1738 offset += kDoubleSize;
1739 }
1740}
1741
1742
1743void FixedDoubleArray::Initialize(FixedArray* from) {
1744 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001745 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001746 for (int i = 0; i < old_length; i++) {
1747 Object* hole_or_object = from->get(i);
1748 if (hole_or_object->IsTheHole()) {
1749 set_the_hole(i);
1750 } else {
1751 set(i, hole_or_object->Number());
1752 }
1753 }
1754 int offset = kHeaderSize + old_length * kDoubleSize;
1755 for (int current = from->length(); current < length(); ++current) {
1756 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1757 offset += kDoubleSize;
1758 }
1759}
1760
1761
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001762void FixedDoubleArray::Initialize(SeededNumberDictionary* from) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001763 int offset = kHeaderSize;
1764 for (int current = 0; current < length(); ++current) {
1765 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1766 offset += kDoubleSize;
1767 }
1768 for (int i = 0; i < from->Capacity(); i++) {
1769 Object* key = from->KeyAt(i);
1770 if (key->IsNumber()) {
1771 uint32_t entry = static_cast<uint32_t>(key->Number());
1772 set(entry, from->ValueAt(i)->Number());
1773 }
1774 }
1775}
1776
1777
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001778WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001779 Heap* heap = GetHeap();
1780 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1781 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001782 return UPDATE_WRITE_BARRIER;
1783}
1784
1785
1786void FixedArray::set(int index,
1787 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001788 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001789 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001790 ASSERT(index >= 0 && index < this->length());
1791 int offset = kHeaderSize + index * kPointerSize;
1792 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001793 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001794}
1795
1796
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001797void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1798 int index,
1799 Object* value) {
1800 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1801 ASSERT(index >= 0 && index < array->length());
1802 int offset = kHeaderSize + index * kPointerSize;
1803 WRITE_FIELD(array, offset, value);
1804 Heap* heap = array->GetHeap();
1805 if (heap->InNewSpace(value)) {
1806 heap->RecordWrite(array->address(), offset);
1807 }
1808}
1809
1810
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001811void FixedArray::NoWriteBarrierSet(FixedArray* array,
1812 int index,
1813 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001814 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001815 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001816 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001817 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1818}
1819
1820
1821void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001822 ASSERT(map() != HEAP->fixed_cow_array_map());
1823 set_undefined(GetHeap(), index);
1824}
1825
1826
1827void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001828 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001829 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001830 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001831 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001832}
1833
1834
ager@chromium.org236ad962008-09-25 09:45:57 +00001835void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001836 set_null(GetHeap(), index);
1837}
1838
1839
1840void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001841 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001842 ASSERT(!heap->InNewSpace(heap->null_value()));
1843 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001844}
1845
1846
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001847void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001848 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001849 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001850 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1851 WRITE_FIELD(this,
1852 kHeaderSize + index * kPointerSize,
1853 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001854}
1855
1856
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001857void FixedArray::set_unchecked(int index, Smi* value) {
1858 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1859 int offset = kHeaderSize + index * kPointerSize;
1860 WRITE_FIELD(this, offset, value);
1861}
1862
1863
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001864void FixedArray::set_unchecked(Heap* heap,
1865 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001866 Object* value,
1867 WriteBarrierMode mode) {
1868 int offset = kHeaderSize + index * kPointerSize;
1869 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001870 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001871}
1872
1873
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001874void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001875 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001876 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1877 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001878}
1879
1880
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001881Object** FixedArray::data_start() {
1882 return HeapObject::RawField(this, kHeaderSize);
1883}
1884
1885
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001886bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001887 ASSERT(this->IsSmi() ||
1888 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001889 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001890 return this->IsSmi() || length() <= kFirstIndex;
1891}
1892
1893
1894int DescriptorArray::bit_field3_storage() {
1895 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1896 return Smi::cast(storage)->value();
1897}
1898
1899void DescriptorArray::set_bit_field3_storage(int value) {
1900 ASSERT(!IsEmpty());
1901 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001902}
1903
1904
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001905void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1906 int first,
1907 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001908 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001909 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1910 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001911}
1912
1913
1914int DescriptorArray::Search(String* name) {
1915 SLOW_ASSERT(IsSortedNoDuplicates());
1916
1917 // Check for empty descriptor array.
1918 int nof = number_of_descriptors();
1919 if (nof == 0) return kNotFound;
1920
1921 // Fast case: do linear search for small arrays.
1922 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001923 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001924 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001925 }
1926
1927 // Slow case: perform binary search.
1928 return BinarySearch(name, 0, nof - 1);
1929}
1930
1931
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001932int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001933 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001934 if (number == DescriptorLookupCache::kAbsent) {
1935 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001936 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001937 }
1938 return number;
1939}
1940
1941
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001942String* DescriptorArray::GetKey(int descriptor_number) {
1943 ASSERT(descriptor_number < number_of_descriptors());
1944 return String::cast(get(ToKeyIndex(descriptor_number)));
1945}
1946
1947
1948Object* DescriptorArray::GetValue(int descriptor_number) {
1949 ASSERT(descriptor_number < number_of_descriptors());
1950 return GetContentArray()->get(ToValueIndex(descriptor_number));
1951}
1952
1953
1954Smi* DescriptorArray::GetDetails(int descriptor_number) {
1955 ASSERT(descriptor_number < number_of_descriptors());
1956 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1957}
1958
1959
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001960PropertyType DescriptorArray::GetType(int descriptor_number) {
1961 ASSERT(descriptor_number < number_of_descriptors());
1962 return PropertyDetails(GetDetails(descriptor_number)).type();
1963}
1964
1965
1966int DescriptorArray::GetFieldIndex(int descriptor_number) {
1967 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1968}
1969
1970
1971JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1972 return JSFunction::cast(GetValue(descriptor_number));
1973}
1974
1975
1976Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1977 ASSERT(GetType(descriptor_number) == CALLBACKS);
1978 return GetValue(descriptor_number);
1979}
1980
1981
1982AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1983 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001984 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001985 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001986}
1987
1988
1989bool DescriptorArray::IsProperty(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001990 return IsRealProperty(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001991}
1992
1993
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001994bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
1995 switch (GetType(descriptor_number)) {
1996 case MAP_TRANSITION:
1997 case CONSTANT_TRANSITION:
1998 case ELEMENTS_TRANSITION:
1999 return true;
2000 case CALLBACKS: {
2001 Object* value = GetValue(descriptor_number);
2002 if (!value->IsAccessorPair()) return false;
2003 AccessorPair* accessors = AccessorPair::cast(value);
2004 return accessors->getter()->IsMap() && accessors->setter()->IsMap();
2005 }
2006 case NORMAL:
2007 case FIELD:
2008 case CONSTANT_FUNCTION:
2009 case HANDLER:
2010 case INTERCEPTOR:
2011 case NULL_DESCRIPTOR:
2012 return false;
2013 }
2014 UNREACHABLE(); // Keep the compiler happy.
2015 return false;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002016}
2017
2018
2019bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2020 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2021}
2022
2023
2024bool DescriptorArray::IsDontEnum(int descriptor_number) {
2025 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
2026}
2027
2028
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002029void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2030 desc->Init(GetKey(descriptor_number),
2031 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002032 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002033}
2034
2035
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002036void DescriptorArray::Set(int descriptor_number,
2037 Descriptor* desc,
2038 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002039 // Range check.
2040 ASSERT(descriptor_number < number_of_descriptors());
2041
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002042 NoIncrementalWriteBarrierSet(this,
2043 ToKeyIndex(descriptor_number),
2044 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002045 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002046 NoIncrementalWriteBarrierSet(content_array,
2047 ToValueIndex(descriptor_number),
2048 desc->GetValue());
2049 NoIncrementalWriteBarrierSet(content_array,
2050 ToDetailsIndex(descriptor_number),
2051 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002052}
2053
2054
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002055void DescriptorArray::CopyFrom(int index,
2056 DescriptorArray* src,
2057 int src_index,
2058 const WhitenessWitness& witness) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002059 Descriptor desc;
2060 src->Get(src_index, &desc);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002061 Set(index, &desc, witness);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002062}
2063
2064
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002065void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2066 int first, int second) {
2067 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002068 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002069 NoIncrementalWriteBarrierSwap(content_array,
2070 ToValueIndex(first),
2071 ToValueIndex(second));
2072 NoIncrementalWriteBarrierSwap(content_array,
2073 ToDetailsIndex(first),
2074 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002075}
2076
2077
2078DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2079 : marking_(array->GetHeap()->incremental_marking()) {
2080 marking_->EnterNoMarkingScope();
2081 if (array->number_of_descriptors() > 0) {
2082 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2083 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2084 }
2085}
2086
2087
2088DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2089 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002090}
2091
2092
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002093template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002094int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2095 const int kMinCapacity = 32;
2096 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2097 if (capacity < kMinCapacity) {
2098 capacity = kMinCapacity; // Guarantee min capacity.
2099 }
2100 return capacity;
2101}
2102
2103
2104template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002105int HashTable<Shape, Key>::FindEntry(Key key) {
2106 return FindEntry(GetIsolate(), key);
2107}
2108
2109
2110// Find entry for key otherwise return kNotFound.
2111template<typename Shape, typename Key>
2112int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2113 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002114 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002115 uint32_t count = 1;
2116 // EnsureCapacity will guarantee the hash table is never full.
2117 while (true) {
2118 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002119 // Empty entry.
2120 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2121 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002122 Shape::IsMatch(key, element)) return entry;
2123 entry = NextProbe(entry, count++, capacity);
2124 }
2125 return kNotFound;
2126}
2127
2128
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002129bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002130 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002131 if (!max_index_object->IsSmi()) return false;
2132 return 0 !=
2133 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2134}
2135
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002136uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002138 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002139 if (!max_index_object->IsSmi()) return 0;
2140 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2141 return value >> kRequiresSlowElementsTagSize;
2142}
2143
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002144void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002145 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002146}
2147
2148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002149// ------------------------------------
2150// Cast operations
2151
2152
2153CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002154CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002155CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002156CAST_ACCESSOR(DeoptimizationInputData)
2157CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002158CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002159CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002160CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002161CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002162CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002163CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002164CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002165CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002166CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002167CAST_ACCESSOR(String)
2168CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002169CAST_ACCESSOR(SeqAsciiString)
2170CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002171CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002172CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002173CAST_ACCESSOR(ExternalString)
2174CAST_ACCESSOR(ExternalAsciiString)
2175CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002176CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002177CAST_ACCESSOR(JSObject)
2178CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002179CAST_ACCESSOR(HeapObject)
2180CAST_ACCESSOR(HeapNumber)
2181CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002182CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002183CAST_ACCESSOR(SharedFunctionInfo)
2184CAST_ACCESSOR(Map)
2185CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002186CAST_ACCESSOR(GlobalObject)
2187CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002188CAST_ACCESSOR(JSGlobalObject)
2189CAST_ACCESSOR(JSBuiltinsObject)
2190CAST_ACCESSOR(Code)
2191CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002192CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002193CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002194CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002195CAST_ACCESSOR(JSSet)
2196CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002197CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002198CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002199CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002200CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002201CAST_ACCESSOR(ExternalArray)
2202CAST_ACCESSOR(ExternalByteArray)
2203CAST_ACCESSOR(ExternalUnsignedByteArray)
2204CAST_ACCESSOR(ExternalShortArray)
2205CAST_ACCESSOR(ExternalUnsignedShortArray)
2206CAST_ACCESSOR(ExternalIntArray)
2207CAST_ACCESSOR(ExternalUnsignedIntArray)
2208CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002209CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002210CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002211CAST_ACCESSOR(Struct)
2212
2213
2214#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2215 STRUCT_LIST(MAKE_STRUCT_CAST)
2216#undef MAKE_STRUCT_CAST
2217
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002218
2219template <typename Shape, typename Key>
2220HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002221 ASSERT(obj->IsHashTable());
2222 return reinterpret_cast<HashTable*>(obj);
2223}
2224
2225
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002226SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002227SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002228
ager@chromium.orgac091b72010-05-05 07:34:42 +00002229SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002230
2231
2232uint32_t String::hash_field() {
2233 return READ_UINT32_FIELD(this, kHashFieldOffset);
2234}
2235
2236
2237void String::set_hash_field(uint32_t value) {
2238 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002239#if V8_HOST_ARCH_64_BIT
2240 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2241#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002242}
2243
2244
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002245bool String::Equals(String* other) {
2246 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002247 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2248 return false;
2249 }
2250 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002251}
2252
2253
lrn@chromium.org303ada72010-10-27 09:33:13 +00002254MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002255 if (!StringShape(this).IsCons()) return this;
2256 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002257 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002258 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002259}
2260
2261
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002262String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002263 MaybeObject* flat = TryFlatten(pretenure);
2264 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002265 if (!flat->ToObject(&successfully_flattened)) return this;
2266 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002267}
2268
2269
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002270uint16_t String::Get(int index) {
2271 ASSERT(index >= 0 && index < length());
2272 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002273 case kSeqStringTag | kAsciiStringTag:
2274 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2275 case kSeqStringTag | kTwoByteStringTag:
2276 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2277 case kConsStringTag | kAsciiStringTag:
2278 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002279 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002280 case kExternalStringTag | kAsciiStringTag:
2281 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2282 case kExternalStringTag | kTwoByteStringTag:
2283 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002284 case kSlicedStringTag | kAsciiStringTag:
2285 case kSlicedStringTag | kTwoByteStringTag:
2286 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002287 default:
2288 break;
2289 }
2290
2291 UNREACHABLE();
2292 return 0;
2293}
2294
2295
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002296void String::Set(int index, uint16_t value) {
2297 ASSERT(index >= 0 && index < length());
2298 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002299
ager@chromium.org5ec48922009-05-05 07:25:34 +00002300 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002301 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2302 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002303}
2304
2305
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002306bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002307 if (!StringShape(this).IsCons()) return true;
2308 return ConsString::cast(this)->second()->length() == 0;
2309}
2310
2311
2312String* String::GetUnderlying() {
2313 // Giving direct access to underlying string only makes sense if the
2314 // wrapping string is already flattened.
2315 ASSERT(this->IsFlat());
2316 ASSERT(StringShape(this).IsIndirect());
2317 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2318 const int kUnderlyingOffset = SlicedString::kParentOffset;
2319 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002320}
2321
2322
ager@chromium.org7c537e22008-10-16 08:43:32 +00002323uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002324 ASSERT(index >= 0 && index < length());
2325 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2326}
2327
2328
ager@chromium.org7c537e22008-10-16 08:43:32 +00002329void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002330 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2331 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2332 static_cast<byte>(value));
2333}
2334
2335
ager@chromium.org7c537e22008-10-16 08:43:32 +00002336Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002337 return FIELD_ADDR(this, kHeaderSize);
2338}
2339
2340
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002341char* SeqAsciiString::GetChars() {
2342 return reinterpret_cast<char*>(GetCharsAddress());
2343}
2344
2345
ager@chromium.org7c537e22008-10-16 08:43:32 +00002346Address SeqTwoByteString::GetCharsAddress() {
2347 return FIELD_ADDR(this, kHeaderSize);
2348}
2349
2350
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002351uc16* SeqTwoByteString::GetChars() {
2352 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2353}
2354
2355
ager@chromium.org7c537e22008-10-16 08:43:32 +00002356uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002357 ASSERT(index >= 0 && index < length());
2358 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2359}
2360
2361
ager@chromium.org7c537e22008-10-16 08:43:32 +00002362void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002363 ASSERT(index >= 0 && index < length());
2364 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2365}
2366
2367
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002368int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002369 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370}
2371
2372
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002373int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002374 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002375}
2376
2377
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002378String* SlicedString::parent() {
2379 return String::cast(READ_FIELD(this, kParentOffset));
2380}
2381
2382
2383void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002384 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002385 WRITE_FIELD(this, kParentOffset, parent);
2386}
2387
2388
2389SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2390
2391
ager@chromium.org870a0b62008-11-04 11:43:05 +00002392String* ConsString::first() {
2393 return String::cast(READ_FIELD(this, kFirstOffset));
2394}
2395
2396
2397Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002398 return READ_FIELD(this, kFirstOffset);
2399}
2400
2401
ager@chromium.org870a0b62008-11-04 11:43:05 +00002402void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002403 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002404 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002405}
2406
2407
ager@chromium.org870a0b62008-11-04 11:43:05 +00002408String* ConsString::second() {
2409 return String::cast(READ_FIELD(this, kSecondOffset));
2410}
2411
2412
2413Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002414 return READ_FIELD(this, kSecondOffset);
2415}
2416
2417
ager@chromium.org870a0b62008-11-04 11:43:05 +00002418void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002419 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002420 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002421}
2422
2423
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002424bool ExternalString::is_short() {
2425 InstanceType type = map()->instance_type();
2426 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002427}
2428
2429
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002430const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002431 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2432}
2433
2434
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002435void ExternalAsciiString::update_data_cache() {
2436 if (is_short()) return;
2437 const char** data_field =
2438 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2439 *data_field = resource()->data();
2440}
2441
2442
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002443void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002444 const ExternalAsciiString::Resource* resource) {
2445 *reinterpret_cast<const Resource**>(
2446 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002447 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002448}
2449
2450
2451const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002452 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002453}
2454
2455
2456uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2457 ASSERT(index >= 0 && index < length());
2458 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002459}
2460
2461
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002462const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002463 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2464}
2465
2466
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002467void ExternalTwoByteString::update_data_cache() {
2468 if (is_short()) return;
2469 const uint16_t** data_field =
2470 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2471 *data_field = resource()->data();
2472}
2473
2474
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002475void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002476 const ExternalTwoByteString::Resource* resource) {
2477 *reinterpret_cast<const Resource**>(
2478 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002479 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002480}
2481
2482
2483const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002484 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002485}
2486
2487
2488uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2489 ASSERT(index >= 0 && index < length());
2490 return GetChars()[index];
2491}
2492
2493
2494const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2495 unsigned start) {
2496 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002497}
2498
2499
ager@chromium.orgac091b72010-05-05 07:34:42 +00002500void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002501 set_finger_index(kEntriesIndex);
2502 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002503}
2504
2505
2506void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002507 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002508 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002509 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002510 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002511 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002512 MakeZeroSize();
2513}
2514
2515
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002516int JSFunctionResultCache::size() {
2517 return Smi::cast(get(kCacheSizeIndex))->value();
2518}
2519
2520
2521void JSFunctionResultCache::set_size(int size) {
2522 set(kCacheSizeIndex, Smi::FromInt(size));
2523}
2524
2525
2526int JSFunctionResultCache::finger_index() {
2527 return Smi::cast(get(kFingerIndex))->value();
2528}
2529
2530
2531void JSFunctionResultCache::set_finger_index(int finger_index) {
2532 set(kFingerIndex, Smi::FromInt(finger_index));
2533}
2534
2535
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002536byte ByteArray::get(int index) {
2537 ASSERT(index >= 0 && index < this->length());
2538 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2539}
2540
2541
2542void ByteArray::set(int index, byte value) {
2543 ASSERT(index >= 0 && index < this->length());
2544 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2545}
2546
2547
2548int ByteArray::get_int(int index) {
2549 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2550 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2551}
2552
2553
2554ByteArray* ByteArray::FromDataStartAddress(Address address) {
2555 ASSERT_TAG_ALIGNED(address);
2556 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2557}
2558
2559
2560Address ByteArray::GetDataStartAddress() {
2561 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2562}
2563
2564
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002565uint8_t* ExternalPixelArray::external_pixel_pointer() {
2566 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002567}
2568
2569
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002570uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002571 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002572 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002573 return ptr[index];
2574}
2575
2576
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002577MaybeObject* ExternalPixelArray::get(int index) {
2578 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2579}
2580
2581
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002582void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002583 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002584 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002585 ptr[index] = value;
2586}
2587
2588
ager@chromium.org3811b432009-10-28 14:53:37 +00002589void* ExternalArray::external_pointer() {
2590 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2591 return reinterpret_cast<void*>(ptr);
2592}
2593
2594
2595void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2596 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2597 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2598}
2599
2600
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002601int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002602 ASSERT((index >= 0) && (index < this->length()));
2603 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2604 return ptr[index];
2605}
2606
2607
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002608MaybeObject* ExternalByteArray::get(int index) {
2609 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2610}
2611
2612
ager@chromium.org3811b432009-10-28 14:53:37 +00002613void ExternalByteArray::set(int index, int8_t value) {
2614 ASSERT((index >= 0) && (index < this->length()));
2615 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2616 ptr[index] = value;
2617}
2618
2619
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002620uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002621 ASSERT((index >= 0) && (index < this->length()));
2622 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2623 return ptr[index];
2624}
2625
2626
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002627MaybeObject* ExternalUnsignedByteArray::get(int index) {
2628 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2629}
2630
2631
ager@chromium.org3811b432009-10-28 14:53:37 +00002632void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2633 ASSERT((index >= 0) && (index < this->length()));
2634 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2635 ptr[index] = value;
2636}
2637
2638
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002639int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002640 ASSERT((index >= 0) && (index < this->length()));
2641 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2642 return ptr[index];
2643}
2644
2645
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002646MaybeObject* ExternalShortArray::get(int index) {
2647 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2648}
2649
2650
ager@chromium.org3811b432009-10-28 14:53:37 +00002651void ExternalShortArray::set(int index, int16_t value) {
2652 ASSERT((index >= 0) && (index < this->length()));
2653 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2654 ptr[index] = value;
2655}
2656
2657
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002658uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002659 ASSERT((index >= 0) && (index < this->length()));
2660 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2661 return ptr[index];
2662}
2663
2664
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002665MaybeObject* ExternalUnsignedShortArray::get(int index) {
2666 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2667}
2668
2669
ager@chromium.org3811b432009-10-28 14:53:37 +00002670void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2671 ASSERT((index >= 0) && (index < this->length()));
2672 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2673 ptr[index] = value;
2674}
2675
2676
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002677int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002678 ASSERT((index >= 0) && (index < this->length()));
2679 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2680 return ptr[index];
2681}
2682
2683
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002684MaybeObject* ExternalIntArray::get(int index) {
2685 return GetHeap()->NumberFromInt32(get_scalar(index));
2686}
2687
2688
ager@chromium.org3811b432009-10-28 14:53:37 +00002689void ExternalIntArray::set(int index, int32_t value) {
2690 ASSERT((index >= 0) && (index < this->length()));
2691 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2692 ptr[index] = value;
2693}
2694
2695
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002696uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002697 ASSERT((index >= 0) && (index < this->length()));
2698 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2699 return ptr[index];
2700}
2701
2702
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002703MaybeObject* ExternalUnsignedIntArray::get(int index) {
2704 return GetHeap()->NumberFromUint32(get_scalar(index));
2705}
2706
2707
ager@chromium.org3811b432009-10-28 14:53:37 +00002708void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2709 ASSERT((index >= 0) && (index < this->length()));
2710 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2711 ptr[index] = value;
2712}
2713
2714
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002715float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002716 ASSERT((index >= 0) && (index < this->length()));
2717 float* ptr = static_cast<float*>(external_pointer());
2718 return ptr[index];
2719}
2720
2721
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002722MaybeObject* ExternalFloatArray::get(int index) {
2723 return GetHeap()->NumberFromDouble(get_scalar(index));
2724}
2725
2726
ager@chromium.org3811b432009-10-28 14:53:37 +00002727void ExternalFloatArray::set(int index, float value) {
2728 ASSERT((index >= 0) && (index < this->length()));
2729 float* ptr = static_cast<float*>(external_pointer());
2730 ptr[index] = value;
2731}
2732
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002733
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002734double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002735 ASSERT((index >= 0) && (index < this->length()));
2736 double* ptr = static_cast<double*>(external_pointer());
2737 return ptr[index];
2738}
2739
2740
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002741MaybeObject* ExternalDoubleArray::get(int index) {
2742 return GetHeap()->NumberFromDouble(get_scalar(index));
2743}
2744
2745
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002746void ExternalDoubleArray::set(int index, double value) {
2747 ASSERT((index >= 0) && (index < this->length()));
2748 double* ptr = static_cast<double*>(external_pointer());
2749 ptr[index] = value;
2750}
2751
2752
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002753int Map::visitor_id() {
2754 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2755}
2756
2757
2758void Map::set_visitor_id(int id) {
2759 ASSERT(0 <= id && id < 256);
2760 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2761}
2762
ager@chromium.org3811b432009-10-28 14:53:37 +00002763
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002764int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002765 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2766}
2767
2768
2769int Map::inobject_properties() {
2770 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002771}
2772
2773
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002774int Map::pre_allocated_property_fields() {
2775 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2776}
2777
2778
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002779int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002780 int instance_size = map->instance_size();
2781 if (instance_size != kVariableSizeSentinel) return instance_size;
2782 // We can ignore the "symbol" bit becase it is only set for symbols
2783 // and implies a string type.
2784 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002785 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002786 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002787 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002788 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002789 if (instance_type == ASCII_STRING_TYPE) {
2790 return SeqAsciiString::SizeFor(
2791 reinterpret_cast<SeqAsciiString*>(this)->length());
2792 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002793 if (instance_type == BYTE_ARRAY_TYPE) {
2794 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2795 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002796 if (instance_type == FREE_SPACE_TYPE) {
2797 return reinterpret_cast<FreeSpace*>(this)->size();
2798 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002799 if (instance_type == STRING_TYPE) {
2800 return SeqTwoByteString::SizeFor(
2801 reinterpret_cast<SeqTwoByteString*>(this)->length());
2802 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002803 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2804 return FixedDoubleArray::SizeFor(
2805 reinterpret_cast<FixedDoubleArray*>(this)->length());
2806 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002807 ASSERT(instance_type == CODE_TYPE);
2808 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002809}
2810
2811
2812void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002813 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002814 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002815 ASSERT(0 <= value && value < 256);
2816 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2817}
2818
2819
ager@chromium.org7c537e22008-10-16 08:43:32 +00002820void Map::set_inobject_properties(int value) {
2821 ASSERT(0 <= value && value < 256);
2822 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2823}
2824
2825
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002826void Map::set_pre_allocated_property_fields(int value) {
2827 ASSERT(0 <= value && value < 256);
2828 WRITE_BYTE_FIELD(this,
2829 kPreAllocatedPropertyFieldsOffset,
2830 static_cast<byte>(value));
2831}
2832
2833
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002834InstanceType Map::instance_type() {
2835 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2836}
2837
2838
2839void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002840 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2841}
2842
2843
2844int Map::unused_property_fields() {
2845 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2846}
2847
2848
2849void Map::set_unused_property_fields(int value) {
2850 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2851}
2852
2853
2854byte Map::bit_field() {
2855 return READ_BYTE_FIELD(this, kBitFieldOffset);
2856}
2857
2858
2859void Map::set_bit_field(byte value) {
2860 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2861}
2862
2863
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002864byte Map::bit_field2() {
2865 return READ_BYTE_FIELD(this, kBitField2Offset);
2866}
2867
2868
2869void Map::set_bit_field2(byte value) {
2870 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2871}
2872
2873
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002874void Map::set_non_instance_prototype(bool value) {
2875 if (value) {
2876 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2877 } else {
2878 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2879 }
2880}
2881
2882
2883bool Map::has_non_instance_prototype() {
2884 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2885}
2886
2887
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002888void Map::set_function_with_prototype(bool value) {
2889 if (value) {
2890 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2891 } else {
2892 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2893 }
2894}
2895
2896
2897bool Map::function_with_prototype() {
2898 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2899}
2900
2901
ager@chromium.org870a0b62008-11-04 11:43:05 +00002902void Map::set_is_access_check_needed(bool access_check_needed) {
2903 if (access_check_needed) {
2904 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2905 } else {
2906 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2907 }
2908}
2909
2910
2911bool Map::is_access_check_needed() {
2912 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2913}
2914
2915
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002916void Map::set_is_extensible(bool value) {
2917 if (value) {
2918 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2919 } else {
2920 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2921 }
2922}
2923
2924bool Map::is_extensible() {
2925 return ((1 << kIsExtensible) & bit_field2()) != 0;
2926}
2927
2928
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002929void Map::set_attached_to_shared_function_info(bool value) {
2930 if (value) {
2931 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2932 } else {
2933 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2934 }
2935}
2936
2937bool Map::attached_to_shared_function_info() {
2938 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2939}
2940
2941
2942void Map::set_is_shared(bool value) {
2943 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002944 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002945 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002946 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002947 }
2948}
2949
2950bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002951 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002952}
2953
2954
2955JSFunction* Map::unchecked_constructor() {
2956 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2957}
2958
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002959
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002960Code::Flags Code::flags() {
2961 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2962}
2963
2964
2965void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002966 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002967 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002968 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2969 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002970 ExtractArgumentsCountFromFlags(flags) >= 0);
2971 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2972}
2973
2974
2975Code::Kind Code::kind() {
2976 return ExtractKindFromFlags(flags());
2977}
2978
2979
kasper.lund7276f142008-07-30 08:49:36 +00002980InlineCacheState Code::ic_state() {
2981 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002982 // Only allow uninitialized or debugger states for non-IC code
2983 // objects. This is used in the debugger to determine whether or not
2984 // a call to code object has been replaced with a debug break call.
2985 ASSERT(is_inline_cache_stub() ||
2986 result == UNINITIALIZED ||
2987 result == DEBUG_BREAK ||
2988 result == DEBUG_PREPARE_STEP_IN);
2989 return result;
2990}
2991
2992
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002993Code::ExtraICState Code::extra_ic_state() {
2994 ASSERT(is_inline_cache_stub());
2995 return ExtractExtraICStateFromFlags(flags());
2996}
2997
2998
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002999PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003000 return ExtractTypeFromFlags(flags());
3001}
3002
3003
3004int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003005 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003006 return ExtractArgumentsCountFromFlags(flags());
3007}
3008
3009
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003010int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003011 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003012 kind() == UNARY_OP_IC ||
3013 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003014 kind() == COMPARE_IC ||
3015 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003016 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00003017}
3018
3019
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003020void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003021 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003022 kind() == UNARY_OP_IC ||
3023 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003024 kind() == COMPARE_IC ||
3025 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003026 ASSERT(0 <= major && major < 256);
3027 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003028}
3029
3030
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003031bool Code::is_pregenerated() {
3032 return kind() == STUB && IsPregeneratedField::decode(flags());
3033}
3034
3035
3036void Code::set_is_pregenerated(bool value) {
3037 ASSERT(kind() == STUB);
3038 Flags f = flags();
3039 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3040 set_flags(f);
3041}
3042
3043
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003044bool Code::optimizable() {
3045 ASSERT(kind() == FUNCTION);
3046 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3047}
3048
3049
3050void Code::set_optimizable(bool value) {
3051 ASSERT(kind() == FUNCTION);
3052 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3053}
3054
3055
3056bool Code::has_deoptimization_support() {
3057 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003058 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3059 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003060}
3061
3062
3063void Code::set_has_deoptimization_support(bool value) {
3064 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003065 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3066 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3067 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3068}
3069
3070
3071bool Code::has_debug_break_slots() {
3072 ASSERT(kind() == FUNCTION);
3073 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3074 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3075}
3076
3077
3078void Code::set_has_debug_break_slots(bool value) {
3079 ASSERT(kind() == FUNCTION);
3080 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3081 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3082 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003083}
3084
3085
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003086bool Code::is_compiled_optimizable() {
3087 ASSERT(kind() == FUNCTION);
3088 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3089 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3090}
3091
3092
3093void Code::set_compiled_optimizable(bool value) {
3094 ASSERT(kind() == FUNCTION);
3095 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3096 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3097 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3098}
3099
3100
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003101int Code::allow_osr_at_loop_nesting_level() {
3102 ASSERT(kind() == FUNCTION);
3103 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3104}
3105
3106
3107void Code::set_allow_osr_at_loop_nesting_level(int level) {
3108 ASSERT(kind() == FUNCTION);
3109 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3110 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3111}
3112
3113
3114unsigned Code::stack_slots() {
3115 ASSERT(kind() == OPTIMIZED_FUNCTION);
3116 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3117}
3118
3119
3120void Code::set_stack_slots(unsigned slots) {
3121 ASSERT(kind() == OPTIMIZED_FUNCTION);
3122 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3123}
3124
3125
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003126unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003127 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003128 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003129}
3130
3131
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003132void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003133 ASSERT(kind() == OPTIMIZED_FUNCTION);
3134 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003135 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003136}
3137
3138
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003139unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003140 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003141 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003142}
3143
3144
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003145void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003146 ASSERT(kind() == FUNCTION);
3147 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003148 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003149}
3150
3151
3152CheckType Code::check_type() {
3153 ASSERT(is_call_stub() || is_keyed_call_stub());
3154 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3155 return static_cast<CheckType>(type);
3156}
3157
3158
3159void Code::set_check_type(CheckType value) {
3160 ASSERT(is_call_stub() || is_keyed_call_stub());
3161 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3162}
3163
3164
danno@chromium.org40cb8782011-05-25 07:58:50 +00003165byte Code::unary_op_type() {
3166 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003167 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3168}
3169
3170
danno@chromium.org40cb8782011-05-25 07:58:50 +00003171void Code::set_unary_op_type(byte value) {
3172 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003173 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3174}
3175
3176
danno@chromium.org40cb8782011-05-25 07:58:50 +00003177byte Code::binary_op_type() {
3178 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003179 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3180}
3181
3182
danno@chromium.org40cb8782011-05-25 07:58:50 +00003183void Code::set_binary_op_type(byte value) {
3184 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003185 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3186}
3187
3188
danno@chromium.org40cb8782011-05-25 07:58:50 +00003189byte Code::binary_op_result_type() {
3190 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003191 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3192}
3193
3194
danno@chromium.org40cb8782011-05-25 07:58:50 +00003195void Code::set_binary_op_result_type(byte value) {
3196 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003197 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3198}
3199
3200
3201byte Code::compare_state() {
3202 ASSERT(is_compare_ic_stub());
3203 return READ_BYTE_FIELD(this, kCompareStateOffset);
3204}
3205
3206
3207void Code::set_compare_state(byte value) {
3208 ASSERT(is_compare_ic_stub());
3209 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3210}
3211
3212
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003213byte Code::to_boolean_state() {
3214 ASSERT(is_to_boolean_ic_stub());
3215 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3216}
3217
3218
3219void Code::set_to_boolean_state(byte value) {
3220 ASSERT(is_to_boolean_ic_stub());
3221 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3222}
3223
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003224
3225bool Code::has_function_cache() {
3226 ASSERT(kind() == STUB);
3227 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3228}
3229
3230
3231void Code::set_has_function_cache(bool flag) {
3232 ASSERT(kind() == STUB);
3233 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3234}
3235
3236
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003237bool Code::is_inline_cache_stub() {
3238 Kind kind = this->kind();
3239 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3240}
3241
3242
3243Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003244 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003245 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003246 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003247 int argc,
3248 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003249 // Extra IC state is only allowed for call IC stubs or for store IC
3250 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003251 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003252 kind == CALL_IC ||
3253 kind == STORE_IC ||
3254 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003255 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003256 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003257 | ICStateField::encode(ic_state)
3258 | TypeField::encode(type)
3259 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003260 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003261 | CacheHolderField::encode(holder);
3262 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003263}
3264
3265
3266Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3267 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003268 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003269 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003270 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003271 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003272}
3273
3274
3275Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003276 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003277}
3278
3279
kasper.lund7276f142008-07-30 08:49:36 +00003280InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003281 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003282}
3283
3284
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003285Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003286 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003287}
3288
3289
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003290PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003291 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003292}
3293
3294
3295int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003296 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003297}
3298
3299
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003300InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003301 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003302}
3303
3304
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003305Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003306 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003307 return static_cast<Flags>(bits);
3308}
3309
3310
ager@chromium.org8bb60582008-12-11 12:02:20 +00003311Code* Code::GetCodeFromTargetAddress(Address address) {
3312 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3313 // GetCodeFromTargetAddress might be called when marking objects during mark
3314 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3315 // Code::cast. Code::cast does not work when the object's map is
3316 // marked.
3317 Code* result = reinterpret_cast<Code*>(code);
3318 return result;
3319}
3320
3321
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003322Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3323 return HeapObject::
3324 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3325}
3326
3327
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003328Object* Map::prototype() {
3329 return READ_FIELD(this, kPrototypeOffset);
3330}
3331
3332
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003333void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003334 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003335 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003336 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003337}
3338
3339
danno@chromium.org40cb8782011-05-25 07:58:50 +00003340DescriptorArray* Map::instance_descriptors() {
3341 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3342 if (object->IsSmi()) {
3343 return HEAP->empty_descriptor_array();
3344 } else {
3345 return DescriptorArray::cast(object);
3346 }
3347}
3348
3349
3350void Map::init_instance_descriptors() {
3351 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3352}
3353
3354
3355void Map::clear_instance_descriptors() {
3356 Object* object = READ_FIELD(this,
3357 kInstanceDescriptorsOrBitField3Offset);
3358 if (!object->IsSmi()) {
3359 WRITE_FIELD(
3360 this,
3361 kInstanceDescriptorsOrBitField3Offset,
3362 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3363 }
3364}
3365
3366
3367void Map::set_instance_descriptors(DescriptorArray* value,
3368 WriteBarrierMode mode) {
3369 Object* object = READ_FIELD(this,
3370 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003371 Heap* heap = GetHeap();
3372 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003373 clear_instance_descriptors();
3374 return;
3375 } else {
3376 if (object->IsSmi()) {
3377 value->set_bit_field3_storage(Smi::cast(object)->value());
3378 } else {
3379 value->set_bit_field3_storage(
3380 DescriptorArray::cast(object)->bit_field3_storage());
3381 }
3382 }
3383 ASSERT(!is_shared());
3384 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003385 CONDITIONAL_WRITE_BARRIER(
3386 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003387}
3388
3389
3390int Map::bit_field3() {
3391 Object* object = READ_FIELD(this,
3392 kInstanceDescriptorsOrBitField3Offset);
3393 if (object->IsSmi()) {
3394 return Smi::cast(object)->value();
3395 } else {
3396 return DescriptorArray::cast(object)->bit_field3_storage();
3397 }
3398}
3399
3400
3401void Map::set_bit_field3(int value) {
3402 ASSERT(Smi::IsValid(value));
3403 Object* object = READ_FIELD(this,
3404 kInstanceDescriptorsOrBitField3Offset);
3405 if (object->IsSmi()) {
3406 WRITE_FIELD(this,
3407 kInstanceDescriptorsOrBitField3Offset,
3408 Smi::FromInt(value));
3409 } else {
3410 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3411 }
3412}
3413
3414
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003415FixedArray* Map::unchecked_prototype_transitions() {
3416 return reinterpret_cast<FixedArray*>(
3417 READ_FIELD(this, kPrototypeTransitionsOffset));
3418}
3419
3420
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003421ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003422ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003423ACCESSORS(Map, constructor, Object, kConstructorOffset)
3424
3425ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003426ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003427ACCESSORS(JSFunction,
3428 next_function_link,
3429 Object,
3430 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003431
3432ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3433ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003434ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003435
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003436ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003437
3438ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3439ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3440ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3441ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3442ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3443
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003444ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3445ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3446
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003447ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3448ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3449ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3450
3451ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3452ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3453ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3454ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3455ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3456ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3457
3458ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3459ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3460
3461ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3462ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3463
3464ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3465ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003466ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3467 kPropertyAccessorsOffset)
3468ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3469 kPrototypeTemplateOffset)
3470ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3471ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3472 kNamedPropertyHandlerOffset)
3473ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3474 kIndexedPropertyHandlerOffset)
3475ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3476 kInstanceTemplateOffset)
3477ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3478ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003479ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3480 kInstanceCallHandlerOffset)
3481ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3482 kAccessCheckInfoOffset)
3483ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3484
3485ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003486ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3487 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003488
3489ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3490ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3491
3492ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3493
3494ACCESSORS(Script, source, Object, kSourceOffset)
3495ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003496ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003497ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3498ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003499ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003500ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003501ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003502ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003503ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003504ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003505ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003506ACCESSORS(Script, eval_from_instructions_offset, Smi,
3507 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003508
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003509#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003510ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3511ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3512ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3513ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3514
3515ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3516ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3517ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3518ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003519#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003520
3521ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003522ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3523ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003524ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3525 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003526ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003527ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3528ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003529ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003530ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3531 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003532
3533BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3534 kHiddenPrototypeBit)
3535BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3536BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3537 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003538BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3539 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003540BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3541 kIsExpressionBit)
3542BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3543 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003544BOOL_GETTER(SharedFunctionInfo,
3545 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003546 has_only_simple_this_property_assignments,
3547 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003548BOOL_ACCESSORS(SharedFunctionInfo,
3549 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003550 allows_lazy_compilation,
3551 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003552BOOL_ACCESSORS(SharedFunctionInfo,
3553 compiler_hints,
3554 uses_arguments,
3555 kUsesArguments)
3556BOOL_ACCESSORS(SharedFunctionInfo,
3557 compiler_hints,
3558 has_duplicate_parameters,
3559 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003560
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003561
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003562#if V8_HOST_ARCH_32_BIT
3563SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3564SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003565 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003566SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003567 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003568SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3569SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003570 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003571SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3572SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003573 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003574SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003575 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003576SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003577 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003578SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003579SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3580SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003581#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003582
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003583#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003584 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003585 int holder::name() { \
3586 int value = READ_INT_FIELD(this, offset); \
3587 ASSERT(kHeapObjectTag == 1); \
3588 ASSERT((value & kHeapObjectTag) == 0); \
3589 return value >> 1; \
3590 } \
3591 void holder::set_##name(int value) { \
3592 ASSERT(kHeapObjectTag == 1); \
3593 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3594 (value & 0xC0000000) == 0x000000000); \
3595 WRITE_INT_FIELD(this, \
3596 offset, \
3597 (value << 1) & ~kHeapObjectTag); \
3598 }
3599
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003600#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3601 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003602 INT_ACCESSORS(holder, name, offset)
3603
3604
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003605PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003606PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3607 formal_parameter_count,
3608 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003609
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003610PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3611 expected_nof_properties,
3612 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003613PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3614
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003615PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3616PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3617 start_position_and_type,
3618 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003619
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003620PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3621 function_token_position,
3622 kFunctionTokenPositionOffset)
3623PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3624 compiler_hints,
3625 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003626
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003627PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3628 this_property_assignments_count,
3629 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003630PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003631
3632PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3633PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003634#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003635
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003636
3637int SharedFunctionInfo::construction_count() {
3638 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3639}
3640
3641
3642void SharedFunctionInfo::set_construction_count(int value) {
3643 ASSERT(0 <= value && value < 256);
3644 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3645}
3646
3647
whesse@chromium.org7b260152011-06-20 15:33:18 +00003648BOOL_ACCESSORS(SharedFunctionInfo,
3649 compiler_hints,
3650 live_objects_may_exist,
3651 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003652
3653
3654bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003655 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003656}
3657
3658
whesse@chromium.org7b260152011-06-20 15:33:18 +00003659BOOL_GETTER(SharedFunctionInfo,
3660 compiler_hints,
3661 optimization_disabled,
3662 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003663
3664
3665void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3666 set_compiler_hints(BooleanBit::set(compiler_hints(),
3667 kOptimizationDisabled,
3668 disable));
3669 // If disabling optimizations we reflect that in the code object so
3670 // it will not be counted as optimizable code.
3671 if ((code()->kind() == Code::FUNCTION) && disable) {
3672 code()->set_optimizable(false);
3673 }
3674}
3675
3676
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003677LanguageMode SharedFunctionInfo::language_mode() {
3678 int hints = compiler_hints();
3679 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3680 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3681 return EXTENDED_MODE;
3682 }
3683 return BooleanBit::get(hints, kStrictModeFunction)
3684 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003685}
3686
3687
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003688void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3689 // We only allow language mode transitions that go set the same language mode
3690 // again or go up in the chain:
3691 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3692 ASSERT(this->language_mode() == CLASSIC_MODE ||
3693 this->language_mode() == language_mode ||
3694 language_mode == EXTENDED_MODE);
3695 int hints = compiler_hints();
3696 hints = BooleanBit::set(
3697 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3698 hints = BooleanBit::set(
3699 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3700 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003701}
3702
3703
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003704bool SharedFunctionInfo::is_classic_mode() {
3705 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3706}
3707
3708BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3709 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003710BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3711BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3712 name_should_print_as_anonymous,
3713 kNameShouldPrintAsAnonymous)
3714BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3715BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003716BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_crankshaft,
3717 kDontCrankshaft)
3718BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003719
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003720ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3721ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3722
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003723ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3724
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003725bool Script::HasValidSource() {
3726 Object* src = this->source();
3727 if (!src->IsString()) return true;
3728 String* src_str = String::cast(src);
3729 if (!StringShape(src_str).IsExternal()) return true;
3730 if (src_str->IsAsciiRepresentation()) {
3731 return ExternalAsciiString::cast(src)->resource() != NULL;
3732 } else if (src_str->IsTwoByteRepresentation()) {
3733 return ExternalTwoByteString::cast(src)->resource() != NULL;
3734 }
3735 return true;
3736}
3737
3738
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003739void SharedFunctionInfo::DontAdaptArguments() {
3740 ASSERT(code()->kind() == Code::BUILTIN);
3741 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3742}
3743
3744
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003745int SharedFunctionInfo::start_position() {
3746 return start_position_and_type() >> kStartPositionShift;
3747}
3748
3749
3750void SharedFunctionInfo::set_start_position(int start_position) {
3751 set_start_position_and_type((start_position << kStartPositionShift)
3752 | (start_position_and_type() & ~kStartPositionMask));
3753}
3754
3755
3756Code* SharedFunctionInfo::code() {
3757 return Code::cast(READ_FIELD(this, kCodeOffset));
3758}
3759
3760
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003761Code* SharedFunctionInfo::unchecked_code() {
3762 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3763}
3764
3765
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003766void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003767 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003768 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003769}
3770
3771
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003772ScopeInfo* SharedFunctionInfo::scope_info() {
3773 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003774}
3775
3776
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003777void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003778 WriteBarrierMode mode) {
3779 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003780 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3781 this,
3782 kScopeInfoOffset,
3783 reinterpret_cast<Object*>(value),
3784 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003785}
3786
3787
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003788bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003789 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003790 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003791}
3792
3793
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003794bool SharedFunctionInfo::IsApiFunction() {
3795 return function_data()->IsFunctionTemplateInfo();
3796}
3797
3798
3799FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3800 ASSERT(IsApiFunction());
3801 return FunctionTemplateInfo::cast(function_data());
3802}
3803
3804
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003805bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003806 return function_data()->IsSmi();
3807}
3808
3809
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003810BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3811 ASSERT(HasBuiltinFunctionId());
3812 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003813}
3814
3815
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003816int SharedFunctionInfo::code_age() {
3817 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3818}
3819
3820
3821void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003822 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3823 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003824}
3825
3826
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003827bool SharedFunctionInfo::has_deoptimization_support() {
3828 Code* code = this->code();
3829 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3830}
3831
3832
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003833bool JSFunction::IsBuiltin() {
3834 return context()->global()->IsJSBuiltinsObject();
3835}
3836
3837
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003838bool JSFunction::NeedsArgumentsAdaption() {
3839 return shared()->formal_parameter_count() !=
3840 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3841}
3842
3843
3844bool JSFunction::IsOptimized() {
3845 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3846}
3847
3848
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003849bool JSFunction::IsOptimizable() {
3850 return code()->kind() == Code::FUNCTION && code()->optimizable();
3851}
3852
3853
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003854bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003855 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003856}
3857
3858
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003859Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003860 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003861}
3862
3863
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003864Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003865 return reinterpret_cast<Code*>(
3866 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003867}
3868
3869
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003870void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003871 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003872 Address entry = value->entry();
3873 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003874 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3875 this,
3876 HeapObject::RawField(this, kCodeEntryOffset),
3877 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003878}
3879
3880
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003881void JSFunction::ReplaceCode(Code* code) {
3882 bool was_optimized = IsOptimized();
3883 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3884
3885 set_code(code);
3886
3887 // Add/remove the function from the list of optimized functions for this
3888 // context based on the state change.
3889 if (!was_optimized && is_optimized) {
3890 context()->global_context()->AddOptimizedFunction(this);
3891 }
3892 if (was_optimized && !is_optimized) {
3893 context()->global_context()->RemoveOptimizedFunction(this);
3894 }
3895}
3896
3897
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003898Context* JSFunction::context() {
3899 return Context::cast(READ_FIELD(this, kContextOffset));
3900}
3901
3902
3903Object* JSFunction::unchecked_context() {
3904 return READ_FIELD(this, kContextOffset);
3905}
3906
3907
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003908SharedFunctionInfo* JSFunction::unchecked_shared() {
3909 return reinterpret_cast<SharedFunctionInfo*>(
3910 READ_FIELD(this, kSharedFunctionInfoOffset));
3911}
3912
3913
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003914void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003915 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003916 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003917 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003918}
3919
3920ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3921 kPrototypeOrInitialMapOffset)
3922
3923
3924Map* JSFunction::initial_map() {
3925 return Map::cast(prototype_or_initial_map());
3926}
3927
3928
3929void JSFunction::set_initial_map(Map* value) {
3930 set_prototype_or_initial_map(value);
3931}
3932
3933
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003934MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
3935 Map* initial_map) {
3936 Context* global_context = context()->global_context();
3937 Object* array_function =
3938 global_context->get(Context::ARRAY_FUNCTION_INDEX);
3939 if (array_function->IsJSFunction() &&
3940 this == JSFunction::cast(array_function)) {
3941 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
3942
3943 MaybeObject* maybe_map = initial_map->CopyDropTransitions();
3944 Map* new_double_map = NULL;
3945 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
3946 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
3947 initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS, new_double_map);
3948
3949 maybe_map = new_double_map->CopyDropTransitions();
3950 Map* new_object_map = NULL;
3951 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
3952 new_object_map->set_elements_kind(FAST_ELEMENTS);
3953 new_double_map->AddElementsTransition(FAST_ELEMENTS, new_object_map);
3954
3955 global_context->set_smi_js_array_map(initial_map);
3956 global_context->set_double_js_array_map(new_double_map);
3957 global_context->set_object_js_array_map(new_object_map);
3958 }
3959 set_initial_map(initial_map);
3960 return this;
3961}
3962
3963
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003964bool JSFunction::has_initial_map() {
3965 return prototype_or_initial_map()->IsMap();
3966}
3967
3968
3969bool JSFunction::has_instance_prototype() {
3970 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3971}
3972
3973
3974bool JSFunction::has_prototype() {
3975 return map()->has_non_instance_prototype() || has_instance_prototype();
3976}
3977
3978
3979Object* JSFunction::instance_prototype() {
3980 ASSERT(has_instance_prototype());
3981 if (has_initial_map()) return initial_map()->prototype();
3982 // When there is no initial map and the prototype is a JSObject, the
3983 // initial map field is used for the prototype field.
3984 return prototype_or_initial_map();
3985}
3986
3987
3988Object* JSFunction::prototype() {
3989 ASSERT(has_prototype());
3990 // If the function's prototype property has been set to a non-JSObject
3991 // value, that value is stored in the constructor field of the map.
3992 if (map()->has_non_instance_prototype()) return map()->constructor();
3993 return instance_prototype();
3994}
3995
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003996bool JSFunction::should_have_prototype() {
3997 return map()->function_with_prototype();
3998}
3999
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004000
4001bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004002 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004003}
4004
4005
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004006FixedArray* JSFunction::literals() {
4007 ASSERT(!shared()->bound());
4008 return literals_or_bindings();
4009}
4010
4011
4012void JSFunction::set_literals(FixedArray* literals) {
4013 ASSERT(!shared()->bound());
4014 set_literals_or_bindings(literals);
4015}
4016
4017
4018FixedArray* JSFunction::function_bindings() {
4019 ASSERT(shared()->bound());
4020 return literals_or_bindings();
4021}
4022
4023
4024void JSFunction::set_function_bindings(FixedArray* bindings) {
4025 ASSERT(shared()->bound());
4026 // Bound function literal may be initialized to the empty fixed array
4027 // before the bindings are set.
4028 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4029 bindings->map() == GetHeap()->fixed_cow_array_map());
4030 set_literals_or_bindings(bindings);
4031}
4032
4033
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004034int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004035 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004036 return literals()->length();
4037}
4038
4039
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004040Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004041 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004042 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004043}
4044
4045
4046void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4047 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004048 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004049 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004050 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004051}
4052
4053
4054Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004055 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004056 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4057}
4058
4059
4060void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4061 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004062 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004063 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004064 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004065}
4066
4067
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004068ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004069ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004070ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4071ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4072
4073
4074void JSProxy::InitializeBody(int object_size, Object* value) {
4075 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4076 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4077 WRITE_FIELD(this, offset, value);
4078 }
4079}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004080
4081
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004082ACCESSORS(JSSet, table, Object, kTableOffset)
4083ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004084ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4085ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004086
4087
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004088Address Foreign::foreign_address() {
4089 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004090}
4091
4092
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004093void Foreign::set_foreign_address(Address value) {
4094 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004095}
4096
4097
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004098ACCESSORS(JSValue, value, Object, kValueOffset)
4099
4100
4101JSValue* JSValue::cast(Object* obj) {
4102 ASSERT(obj->IsJSValue());
4103 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4104 return reinterpret_cast<JSValue*>(obj);
4105}
4106
4107
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004108ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4109ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4110ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4111ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4112ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4113SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4114SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4115
4116
4117JSMessageObject* JSMessageObject::cast(Object* obj) {
4118 ASSERT(obj->IsJSMessageObject());
4119 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4120 return reinterpret_cast<JSMessageObject*>(obj);
4121}
4122
4123
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004124INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004125ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004126ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004127ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004128ACCESSORS(Code, type_feedback_cells, TypeFeedbackCells,
4129 kTypeFeedbackCellsOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004130ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004131
4132
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004133byte* Code::instruction_start() {
4134 return FIELD_ADDR(this, kHeaderSize);
4135}
4136
4137
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004138byte* Code::instruction_end() {
4139 return instruction_start() + instruction_size();
4140}
4141
4142
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004143int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004144 return RoundUp(instruction_size(), kObjectAlignment);
4145}
4146
4147
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004148FixedArray* Code::unchecked_deoptimization_data() {
4149 return reinterpret_cast<FixedArray*>(
4150 READ_FIELD(this, kDeoptimizationDataOffset));
4151}
4152
4153
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004154ByteArray* Code::unchecked_relocation_info() {
4155 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004156}
4157
4158
4159byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004160 return unchecked_relocation_info()->GetDataStartAddress();
4161}
4162
4163
4164int Code::relocation_size() {
4165 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004166}
4167
4168
4169byte* Code::entry() {
4170 return instruction_start();
4171}
4172
4173
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004174bool Code::contains(byte* inner_pointer) {
4175 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004176}
4177
4178
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004179ACCESSORS(JSArray, length, Object, kLengthOffset)
4180
4181
ager@chromium.org236ad962008-09-25 09:45:57 +00004182ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004183
4184
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004185JSRegExp::Type JSRegExp::TypeTag() {
4186 Object* data = this->data();
4187 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4188 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4189 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004190}
4191
4192
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004193JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4194 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4195 return static_cast<JSRegExp::Type>(smi->value());
4196}
4197
4198
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004199int JSRegExp::CaptureCount() {
4200 switch (TypeTag()) {
4201 case ATOM:
4202 return 0;
4203 case IRREGEXP:
4204 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4205 default:
4206 UNREACHABLE();
4207 return -1;
4208 }
4209}
4210
4211
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004212JSRegExp::Flags JSRegExp::GetFlags() {
4213 ASSERT(this->data()->IsFixedArray());
4214 Object* data = this->data();
4215 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4216 return Flags(smi->value());
4217}
4218
4219
4220String* JSRegExp::Pattern() {
4221 ASSERT(this->data()->IsFixedArray());
4222 Object* data = this->data();
4223 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4224 return pattern;
4225}
4226
4227
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004228Object* JSRegExp::DataAt(int index) {
4229 ASSERT(TypeTag() != NOT_COMPILED);
4230 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004231}
4232
4233
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004234Object* JSRegExp::DataAtUnchecked(int index) {
4235 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4236 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4237 return READ_FIELD(fa, offset);
4238}
4239
4240
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004241void JSRegExp::SetDataAt(int index, Object* value) {
4242 ASSERT(TypeTag() != NOT_COMPILED);
4243 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4244 FixedArray::cast(data())->set(index, value);
4245}
4246
4247
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004248void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4249 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4250 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4251 if (value->IsSmi()) {
4252 fa->set_unchecked(index, Smi::cast(value));
4253 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004254 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004255 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4256 }
4257}
4258
4259
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004260ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004261 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004262#if DEBUG
4263 FixedArrayBase* fixed_array =
4264 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4265 Map* map = fixed_array->map();
4266 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004267 (map == GetHeap()->fixed_array_map() ||
4268 map == GetHeap()->fixed_cow_array_map())) ||
4269 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004270 (fixed_array->IsFixedDoubleArray() ||
4271 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004272 (kind == DICTIONARY_ELEMENTS &&
4273 fixed_array->IsFixedArray() &&
4274 fixed_array->IsDictionary()) ||
4275 (kind > DICTIONARY_ELEMENTS));
4276 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4277 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004278#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004279 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004280}
4281
4282
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004283ElementsAccessor* JSObject::GetElementsAccessor() {
4284 return ElementsAccessor::ForKind(GetElementsKind());
4285}
4286
4287
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004288bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004289 return GetElementsKind() == FAST_ELEMENTS;
4290}
4291
4292
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004293bool JSObject::HasFastSmiOnlyElements() {
4294 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4295}
4296
4297
4298bool JSObject::HasFastTypeElements() {
4299 ElementsKind elements_kind = GetElementsKind();
4300 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4301 elements_kind == FAST_ELEMENTS;
4302}
4303
4304
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004305bool JSObject::HasFastDoubleElements() {
4306 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4307}
4308
4309
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004310bool JSObject::HasDictionaryElements() {
4311 return GetElementsKind() == DICTIONARY_ELEMENTS;
4312}
4313
4314
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004315bool JSObject::HasNonStrictArgumentsElements() {
4316 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4317}
4318
4319
ager@chromium.org3811b432009-10-28 14:53:37 +00004320bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004321 HeapObject* array = elements();
4322 ASSERT(array != NULL);
4323 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004324}
4325
4326
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004327#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4328bool JSObject::HasExternal##name##Elements() { \
4329 HeapObject* array = elements(); \
4330 ASSERT(array != NULL); \
4331 if (!array->IsHeapObject()) \
4332 return false; \
4333 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004334}
4335
4336
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004337EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4338EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4339EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4340EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4341 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4342EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4343EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4344 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4345EXTERNAL_ELEMENTS_CHECK(Float,
4346 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004347EXTERNAL_ELEMENTS_CHECK(Double,
4348 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004349EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004350
4351
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004352bool JSObject::HasNamedInterceptor() {
4353 return map()->has_named_interceptor();
4354}
4355
4356
4357bool JSObject::HasIndexedInterceptor() {
4358 return map()->has_indexed_interceptor();
4359}
4360
4361
lrn@chromium.org303ada72010-10-27 09:33:13 +00004362MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004363 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004364 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004365 Isolate* isolate = GetIsolate();
4366 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004367 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004368 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4369 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004370 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4371 return maybe_writable_elems;
4372 }
4373 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004374 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004375 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004376 return writable_elems;
4377}
4378
4379
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004380StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004381 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004382 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004383}
4384
4385
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004386SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004387 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004388 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004389}
4390
4391
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004392bool String::IsHashFieldComputed(uint32_t field) {
4393 return (field & kHashNotComputedMask) == 0;
4394}
4395
4396
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004397bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004398 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004399}
4400
4401
4402uint32_t String::Hash() {
4403 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004404 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004405 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004406 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004407 return ComputeAndSetHash();
4408}
4409
4410
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004411StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004412 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004413 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004414 array_index_(0),
4415 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4416 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004417 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004418 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004419}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004420
4421
4422bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004423 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004424}
4425
4426
4427void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004428 // Use the Jenkins one-at-a-time hash function to update the hash
4429 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004430 raw_running_hash_ += c;
4431 raw_running_hash_ += (raw_running_hash_ << 10);
4432 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004433 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004434 if (is_array_index_) {
4435 if (c < '0' || c > '9') {
4436 is_array_index_ = false;
4437 } else {
4438 int d = c - '0';
4439 if (is_first_char_) {
4440 is_first_char_ = false;
4441 if (c == '0' && length_ > 1) {
4442 is_array_index_ = false;
4443 return;
4444 }
4445 }
4446 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4447 is_array_index_ = false;
4448 } else {
4449 array_index_ = array_index_ * 10 + d;
4450 }
4451 }
4452 }
4453}
4454
4455
4456void StringHasher::AddCharacterNoIndex(uc32 c) {
4457 ASSERT(!is_array_index());
4458 raw_running_hash_ += c;
4459 raw_running_hash_ += (raw_running_hash_ << 10);
4460 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4461}
4462
4463
4464uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004465 // Get the calculated raw hash value and do some more bit ops to distribute
4466 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004467 uint32_t result = raw_running_hash_;
4468 result += (result << 3);
4469 result ^= (result >> 11);
4470 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004471 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004472 result = 27;
4473 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004474 return result;
4475}
4476
4477
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004478template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004479uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4480 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004481 if (!hasher.has_trivial_hash()) {
4482 int i;
4483 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4484 hasher.AddCharacter(chars[i]);
4485 }
4486 for (; i < length; i++) {
4487 hasher.AddCharacterNoIndex(chars[i]);
4488 }
4489 }
4490 return hasher.GetHashField();
4491}
4492
4493
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004494bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004495 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004496 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4497 return false;
4498 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004499 return SlowAsArrayIndex(index);
4500}
4501
4502
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004503Object* JSReceiver::GetPrototype() {
4504 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004505}
4506
4507
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004508bool JSReceiver::HasProperty(String* name) {
4509 if (IsJSProxy()) {
4510 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4511 }
4512 return GetPropertyAttribute(name) != ABSENT;
4513}
4514
4515
4516bool JSReceiver::HasLocalProperty(String* name) {
4517 if (IsJSProxy()) {
4518 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4519 }
4520 return GetLocalPropertyAttribute(name) != ABSENT;
4521}
4522
4523
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004524PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004525 return GetPropertyAttributeWithReceiver(this, key);
4526}
4527
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004528// TODO(504): this may be useful in other places too where JSGlobalProxy
4529// is used.
4530Object* JSObject::BypassGlobalProxy() {
4531 if (IsJSGlobalProxy()) {
4532 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004533 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004534 ASSERT(proto->IsJSGlobalObject());
4535 return proto;
4536 }
4537 return this;
4538}
4539
4540
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004541MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4542 return IsJSProxy()
4543 ? JSProxy::cast(this)->GetIdentityHash(flag)
4544 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004545}
4546
4547
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004548bool JSReceiver::HasElement(uint32_t index) {
4549 if (IsJSProxy()) {
4550 return JSProxy::cast(this)->HasElementWithHandler(index);
4551 }
4552 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004553}
4554
4555
4556bool AccessorInfo::all_can_read() {
4557 return BooleanBit::get(flag(), kAllCanReadBit);
4558}
4559
4560
4561void AccessorInfo::set_all_can_read(bool value) {
4562 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4563}
4564
4565
4566bool AccessorInfo::all_can_write() {
4567 return BooleanBit::get(flag(), kAllCanWriteBit);
4568}
4569
4570
4571void AccessorInfo::set_all_can_write(bool value) {
4572 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4573}
4574
4575
ager@chromium.org870a0b62008-11-04 11:43:05 +00004576bool AccessorInfo::prohibits_overwriting() {
4577 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4578}
4579
4580
4581void AccessorInfo::set_prohibits_overwriting(bool value) {
4582 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4583}
4584
4585
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004586PropertyAttributes AccessorInfo::property_attributes() {
4587 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4588}
4589
4590
4591void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004592 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004593}
4594
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004595
4596template<typename Shape, typename Key>
4597void Dictionary<Shape, Key>::SetEntry(int entry,
4598 Object* key,
4599 Object* value) {
4600 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4601}
4602
4603
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004604template<typename Shape, typename Key>
4605void Dictionary<Shape, Key>::SetEntry(int entry,
4606 Object* key,
4607 Object* value,
4608 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004609 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004610 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004611 AssertNoAllocation no_gc;
4612 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004613 FixedArray::set(index, key, mode);
4614 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004615 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004616}
4617
4618
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004619bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4620 ASSERT(other->IsNumber());
4621 return key == static_cast<uint32_t>(other->Number());
4622}
4623
4624
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004625uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4626 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004627}
4628
4629
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004630uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4631 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004632 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004633 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004634}
4635
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004636uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4637 return ComputeIntegerHash(key, seed);
4638}
4639
4640uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4641 uint32_t seed,
4642 Object* other) {
4643 ASSERT(other->IsNumber());
4644 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4645}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004646
4647MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4648 return Isolate::Current()->heap()->NumberFromUint32(key);
4649}
4650
4651
4652bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4653 // We know that all entries in a hash table had their hash keys created.
4654 // Use that knowledge to have fast failure.
4655 if (key->Hash() != String::cast(other)->Hash()) return false;
4656 return key->Equals(String::cast(other));
4657}
4658
4659
4660uint32_t StringDictionaryShape::Hash(String* key) {
4661 return key->Hash();
4662}
4663
4664
4665uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4666 return String::cast(other)->Hash();
4667}
4668
4669
4670MaybeObject* StringDictionaryShape::AsObject(String* key) {
4671 return key;
4672}
4673
4674
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004675template <int entrysize>
4676bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4677 return key->SameValue(other);
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>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004683 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4684 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004685}
4686
4687
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004688template <int entrysize>
4689uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4690 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004691 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4692 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004693}
4694
4695
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004696template <int entrysize>
4697MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004698 return key;
4699}
4700
4701
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004702void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004703 // No write barrier is needed since empty_fixed_array is not in new space.
4704 // Please note this function is used during marking:
4705 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004706 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4707 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004708}
4709
4710
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004711void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004712 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004713 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004714 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4715 if (elts->length() < required_size) {
4716 // Doubling in size would be overkill, but leave some slack to avoid
4717 // constantly growing.
4718 Expand(required_size + (required_size >> 3));
4719 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004720 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004721 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4722 // Expand will allocate a new backing store in new space even if the size
4723 // we asked for isn't larger than what we had before.
4724 Expand(required_size);
4725 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004726}
4727
4728
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004729void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004730 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004731 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4732}
4733
4734
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004735bool JSArray::AllowsSetElementsLength() {
4736 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4737 ASSERT(result == !HasExternalArrayElements());
4738 return result;
4739}
4740
4741
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004742MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4743 MaybeObject* maybe_result = EnsureCanContainElements(
4744 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4745 if (maybe_result->IsFailure()) return maybe_result;
4746 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4747 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4748 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4749 ((GetElementsKind() == FAST_ELEMENTS) ||
4750 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4751 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004752 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004753 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004754 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004755}
4756
4757
lrn@chromium.org303ada72010-10-27 09:33:13 +00004758MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004759 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004760 return GetHeap()->CopyFixedArray(this);
4761}
4762
4763
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004764MaybeObject* FixedDoubleArray::Copy() {
4765 if (length() == 0) return this;
4766 return GetHeap()->CopyFixedDoubleArray(this);
4767}
4768
4769
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004770void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4771 set(1 + index * 2, id);
4772}
4773
4774
4775Smi* TypeFeedbackCells::AstId(int index) {
4776 return Smi::cast(get(1 + index * 2));
4777}
4778
4779
4780void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4781 set(index * 2, cell);
4782}
4783
4784
4785JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4786 return JSGlobalPropertyCell::cast(get(index * 2));
4787}
4788
4789
4790Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4791 return isolate->factory()->the_hole_value();
4792}
4793
4794
4795Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4796 return isolate->factory()->undefined_value();
4797}
4798
4799
4800Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4801 return heap->raw_unchecked_the_hole_value();
4802}
4803
4804
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004805Relocatable::Relocatable(Isolate* isolate) {
4806 ASSERT(isolate == Isolate::Current());
4807 isolate_ = isolate;
4808 prev_ = isolate->relocatable_top();
4809 isolate->set_relocatable_top(this);
4810}
4811
4812
4813Relocatable::~Relocatable() {
4814 ASSERT(isolate_ == Isolate::Current());
4815 ASSERT_EQ(isolate_->relocatable_top(), this);
4816 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004817}
4818
4819
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004820int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4821 return map->instance_size();
4822}
4823
4824
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004825void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004826 v->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
4831template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004832void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004833 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004834 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004835}
4836
4837
4838void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4839 typedef v8::String::ExternalAsciiStringResource Resource;
4840 v->VisitExternalAsciiString(
4841 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4842}
4843
4844
4845template<typename StaticVisitor>
4846void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4847 typedef v8::String::ExternalAsciiStringResource Resource;
4848 StaticVisitor::VisitExternalAsciiString(
4849 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4850}
4851
4852
4853void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4854 typedef v8::String::ExternalStringResource Resource;
4855 v->VisitExternalTwoByteString(
4856 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4857}
4858
4859
4860template<typename StaticVisitor>
4861void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4862 typedef v8::String::ExternalStringResource Resource;
4863 StaticVisitor::VisitExternalTwoByteString(
4864 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4865}
4866
4867#define SLOT_ADDR(obj, offset) \
4868 reinterpret_cast<Object**>((obj)->address() + offset)
4869
4870template<int start_offset, int end_offset, int size>
4871void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4872 HeapObject* obj,
4873 ObjectVisitor* v) {
4874 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4875}
4876
4877
4878template<int start_offset>
4879void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4880 int object_size,
4881 ObjectVisitor* v) {
4882 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4883}
4884
4885#undef SLOT_ADDR
4886
4887
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004888#undef CAST_ACCESSOR
4889#undef INT_ACCESSORS
4890#undef SMI_ACCESSORS
4891#undef ACCESSORS
4892#undef FIELD_ADDR
4893#undef READ_FIELD
4894#undef WRITE_FIELD
4895#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004896#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004897#undef READ_MEMADDR_FIELD
4898#undef WRITE_MEMADDR_FIELD
4899#undef READ_DOUBLE_FIELD
4900#undef WRITE_DOUBLE_FIELD
4901#undef READ_INT_FIELD
4902#undef WRITE_INT_FIELD
4903#undef READ_SHORT_FIELD
4904#undef WRITE_SHORT_FIELD
4905#undef READ_BYTE_FIELD
4906#undef WRITE_BYTE_FIELD
4907
4908
4909} } // namespace v8::internal
4910
4911#endif // V8_OBJECTS_INL_H_