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