blob: 7901f0892d94ea7361b23c22fc98877bfd3af666 [file] [log] [blame]
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000038#include "elements.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000039#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040#include "contexts.h"
41#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000042#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000043#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000045#include "spaces.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000046#include "store-buffer.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000047#include "v8memory.h"
danno@chromium.orgfa458e42012-02-01 10:48:36 +000048#include "factory.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000049#include "incremental-marking.h"
50
kasperl@chromium.org71affb52009-05-26 05:44:31 +000051namespace v8 {
52namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000053
54PropertyDetails::PropertyDetails(Smi* smi) {
55 value_ = smi->value();
56}
57
58
59Smi* PropertyDetails::AsSmi() {
60 return Smi::FromInt(value_);
61}
62
63
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000064PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000065 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000066 return PropertyDetails(smi);
67}
68
69
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000070#define TYPE_CHECKER(type, instancetype) \
71 bool Object::Is##type() { \
72 return Object::IsHeapObject() && \
73 HeapObject::cast(this)->map()->instance_type() == instancetype; \
74 }
75
76
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077#define CAST_ACCESSOR(type) \
78 type* type::cast(Object* object) { \
79 ASSERT(object->Is##type()); \
80 return reinterpret_cast<type*>(object); \
81 }
82
83
84#define INT_ACCESSORS(holder, name, offset) \
85 int holder::name() { return READ_INT_FIELD(this, offset); } \
86 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
87
88
89#define ACCESSORS(holder, name, type, offset) \
90 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000091 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000093 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094 }
95
96
97#define SMI_ACCESSORS(holder, name, offset) \
98 int holder::name() { \
99 Object* value = READ_FIELD(this, offset); \
100 return Smi::cast(value)->value(); \
101 } \
102 void holder::set_##name(int value) { \
103 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
104 }
105
106
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000107#define BOOL_GETTER(holder, field, name, offset) \
108 bool holder::name() { \
109 return BooleanBit::get(field(), offset); \
110 } \
111
112
113#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000114 bool holder::name() { \
115 return BooleanBit::get(field(), offset); \
116 } \
117 void holder::set_##name(bool value) { \
118 set_##field(BooleanBit::set(field(), offset, value)); \
119 }
120
121
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000122bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
123 ElementsKind to_kind) {
124 if (to_kind == FAST_ELEMENTS) {
125 return from_kind == FAST_SMI_ONLY_ELEMENTS ||
126 from_kind == FAST_DOUBLE_ELEMENTS;
127 } else {
128 return to_kind == FAST_DOUBLE_ELEMENTS &&
129 from_kind == FAST_SMI_ONLY_ELEMENTS;
130 }
131}
132
133
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000134bool Object::IsFixedArrayBase() {
135 return IsFixedArray() || IsFixedDoubleArray();
136}
137
138
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000139bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
140 // There is a constraint on the object; check.
141 if (!this->IsJSObject()) return false;
142 // Fetch the constructor function of the object.
143 Object* cons_obj = JSObject::cast(this)->map()->constructor();
144 if (!cons_obj->IsJSFunction()) return false;
145 JSFunction* fun = JSFunction::cast(cons_obj);
146 // Iterate through the chain of inheriting function templates to
147 // see if the required one occurs.
148 for (Object* type = fun->shared()->function_data();
149 type->IsFunctionTemplateInfo();
150 type = FunctionTemplateInfo::cast(type)->parent_template()) {
151 if (type == expected) return true;
152 }
153 // Didn't find the required type in the inheritance chain.
154 return false;
155}
156
157
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000158bool Object::IsSmi() {
159 return HAS_SMI_TAG(this);
160}
161
162
163bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000164 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000165}
166
167
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000168bool Object::NonFailureIsHeapObject() {
169 ASSERT(!this->IsFailure());
170 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
171}
172
173
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000174TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000175
176
177bool Object::IsString() {
178 return Object::IsHeapObject()
179 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
180}
181
182
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000183bool Object::IsSpecObject() {
184 return Object::IsHeapObject()
185 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
186}
187
188
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000189bool Object::IsSpecFunction() {
190 if (!Object::IsHeapObject()) return false;
191 InstanceType type = HeapObject::cast(this)->map()->instance_type();
192 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
193}
194
195
ager@chromium.org870a0b62008-11-04 11:43:05 +0000196bool Object::IsSymbol() {
197 if (!this->IsHeapObject()) return false;
198 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000199 // Because the symbol tag is non-zero and no non-string types have the
200 // symbol bit set we can test for symbols with a very simple test
201 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000202 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000203 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
204 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000205}
206
207
208bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000209 if (!IsString()) return false;
210 return StringShape(String::cast(this)).IsCons();
211}
212
213
214bool Object::IsSlicedString() {
215 if (!IsString()) return false;
216 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000217}
218
219
ager@chromium.org870a0b62008-11-04 11:43:05 +0000220bool Object::IsSeqString() {
221 if (!IsString()) return false;
222 return StringShape(String::cast(this)).IsSequential();
223}
224
225
226bool Object::IsSeqAsciiString() {
227 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000228 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000229 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000230}
231
232
233bool Object::IsSeqTwoByteString() {
234 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000235 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000236 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000237}
238
239
240bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000241 if (!IsString()) return false;
242 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243}
244
245
246bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000247 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000248 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000249 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000250}
251
252
253bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000254 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000255 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000256 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000257}
258
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000259bool Object::HasValidElements() {
260 // Dictionary is covered under FixedArray.
261 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
262}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000263
ager@chromium.org870a0b62008-11-04 11:43:05 +0000264StringShape::StringShape(String* str)
265 : type_(str->map()->instance_type()) {
266 set_valid();
267 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000268}
269
270
ager@chromium.org870a0b62008-11-04 11:43:05 +0000271StringShape::StringShape(Map* map)
272 : type_(map->instance_type()) {
273 set_valid();
274 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000275}
276
277
ager@chromium.org870a0b62008-11-04 11:43:05 +0000278StringShape::StringShape(InstanceType t)
279 : type_(static_cast<uint32_t>(t)) {
280 set_valid();
281 ASSERT((type_ & kIsNotStringMask) == kStringTag);
282}
283
284
285bool StringShape::IsSymbol() {
286 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000287 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000288 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000289}
290
291
ager@chromium.org5ec48922009-05-05 07:25:34 +0000292bool String::IsAsciiRepresentation() {
293 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000294 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000295}
296
297
ager@chromium.org5ec48922009-05-05 07:25:34 +0000298bool String::IsTwoByteRepresentation() {
299 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000300 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000301}
302
303
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000304bool String::IsAsciiRepresentationUnderneath() {
305 uint32_t type = map()->instance_type();
306 STATIC_ASSERT(kIsIndirectStringTag != 0);
307 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
308 ASSERT(IsFlat());
309 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
310 case kAsciiStringTag:
311 return true;
312 case kTwoByteStringTag:
313 return false;
314 default: // Cons or sliced string. Need to go deeper.
315 return GetUnderlying()->IsAsciiRepresentation();
316 }
317}
318
319
320bool String::IsTwoByteRepresentationUnderneath() {
321 uint32_t type = map()->instance_type();
322 STATIC_ASSERT(kIsIndirectStringTag != 0);
323 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
324 ASSERT(IsFlat());
325 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
326 case kAsciiStringTag:
327 return false;
328 case kTwoByteStringTag:
329 return true;
330 default: // Cons or sliced string. Need to go deeper.
331 return GetUnderlying()->IsTwoByteRepresentation();
332 }
333}
334
335
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000336bool String::HasOnlyAsciiChars() {
337 uint32_t type = map()->instance_type();
338 return (type & kStringEncodingMask) == kAsciiStringTag ||
339 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000340}
341
342
ager@chromium.org870a0b62008-11-04 11:43:05 +0000343bool StringShape::IsCons() {
344 return (type_ & kStringRepresentationMask) == kConsStringTag;
345}
346
347
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000348bool StringShape::IsSliced() {
349 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
350}
351
352
353bool StringShape::IsIndirect() {
354 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
355}
356
357
ager@chromium.org870a0b62008-11-04 11:43:05 +0000358bool StringShape::IsExternal() {
359 return (type_ & kStringRepresentationMask) == kExternalStringTag;
360}
361
362
363bool StringShape::IsSequential() {
364 return (type_ & kStringRepresentationMask) == kSeqStringTag;
365}
366
367
368StringRepresentationTag StringShape::representation_tag() {
369 uint32_t tag = (type_ & kStringRepresentationMask);
370 return static_cast<StringRepresentationTag>(tag);
371}
372
373
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000374uint32_t StringShape::encoding_tag() {
375 return type_ & kStringEncodingMask;
376}
377
378
ager@chromium.org870a0b62008-11-04 11:43:05 +0000379uint32_t StringShape::full_representation_tag() {
380 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
381}
382
383
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000384STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
385 Internals::kFullStringRepresentationMask);
386
387
ager@chromium.org870a0b62008-11-04 11:43:05 +0000388bool StringShape::IsSequentialAscii() {
389 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
390}
391
392
393bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000394 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000395}
396
397
398bool StringShape::IsExternalAscii() {
399 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
400}
401
402
403bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000404 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000405}
406
407
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000408STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
409 Internals::kExternalTwoByteRepresentationTag);
410
411
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000412uc32 FlatStringReader::Get(int index) {
413 ASSERT(0 <= index && index <= length_);
414 if (is_ascii_) {
415 return static_cast<const byte*>(start_)[index];
416 } else {
417 return static_cast<const uc16*>(start_)[index];
418 }
419}
420
421
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000422bool Object::IsNumber() {
423 return IsSmi() || IsHeapNumber();
424}
425
426
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000427TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
428TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000429
430
431bool Object::IsFiller() {
432 if (!Object::IsHeapObject()) return false;
433 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
434 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
435}
436
437
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000438TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000439
440
ager@chromium.org3811b432009-10-28 14:53:37 +0000441bool Object::IsExternalArray() {
442 if (!Object::IsHeapObject())
443 return false;
444 InstanceType instance_type =
445 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000446 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
447 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000448}
449
450
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000451TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
452TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
453TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
454TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
455TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
456TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
457TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
458TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000459
460
lrn@chromium.org303ada72010-10-27 09:33:13 +0000461bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000462 return HAS_FAILURE_TAG(this);
463}
464
465
lrn@chromium.org303ada72010-10-27 09:33:13 +0000466bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000467 return HAS_FAILURE_TAG(this)
468 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
469}
470
471
lrn@chromium.org303ada72010-10-27 09:33:13 +0000472bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000473 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000474 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000475}
476
477
lrn@chromium.org303ada72010-10-27 09:33:13 +0000478bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000479 return this == Failure::Exception();
480}
481
482
lrn@chromium.org303ada72010-10-27 09:33:13 +0000483bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000484 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000485}
486
487
488Failure* Failure::cast(MaybeObject* obj) {
489 ASSERT(HAS_FAILURE_TAG(obj));
490 return reinterpret_cast<Failure*>(obj);
491}
492
493
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000494bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000495 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000496 return IsHeapObject() &&
497 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
498}
499
500
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000501bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000502 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
503 return IsHeapObject() &&
504 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000505}
506
507
508bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000509 if (!Object::IsHeapObject()) return false;
510 InstanceType type = HeapObject::cast(this)->map()->instance_type();
511 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000512}
513
514
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000515TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
516TYPE_CHECKER(JSSet, JS_SET_TYPE)
517TYPE_CHECKER(JSMap, JS_MAP_TYPE)
518TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
519TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
520TYPE_CHECKER(Map, MAP_TYPE)
521TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
522TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000523
524
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000525bool Object::IsDescriptorArray() {
526 return IsFixedArray();
527}
528
529
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000530bool Object::IsDeoptimizationInputData() {
531 // Must be a fixed array.
532 if (!IsFixedArray()) return false;
533
534 // There's no sure way to detect the difference between a fixed array and
535 // a deoptimization data array. Since this is used for asserts we can
536 // check that the length is zero or else the fixed size plus a multiple of
537 // the entry size.
538 int length = FixedArray::cast(this)->length();
539 if (length == 0) return true;
540
541 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
542 return length >= 0 &&
543 length % DeoptimizationInputData::kDeoptEntrySize == 0;
544}
545
546
547bool Object::IsDeoptimizationOutputData() {
548 if (!IsFixedArray()) return false;
549 // There's actually no way to see the difference between a fixed array and
550 // a deoptimization data array. Since this is used for asserts we can check
551 // that the length is plausible though.
552 if (FixedArray::cast(this)->length() % 2 != 0) return false;
553 return true;
554}
555
556
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000557bool Object::IsTypeFeedbackCells() {
558 if (!IsFixedArray()) return false;
559 // There's actually no way to see the difference between a fixed array and
560 // a cache cells array. Since this is used for asserts we can check that
561 // the length is plausible though.
562 if (FixedArray::cast(this)->length() % 2 != 0) return false;
563 return true;
564}
565
566
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000567bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000568 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000569 Map* map = HeapObject::cast(this)->map();
570 Heap* heap = map->GetHeap();
571 return (map == heap->function_context_map() ||
572 map == heap->catch_context_map() ||
573 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000574 map == heap->global_context_map() ||
575 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000576 }
577 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000578}
579
580
581bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000582 return Object::IsHeapObject() &&
583 HeapObject::cast(this)->map() ==
584 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000585}
586
587
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000588bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000589 return Object::IsHeapObject() &&
590 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000591 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000592}
593
594
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000595TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000596
597
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000598template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000599 return obj->IsJSFunction();
600}
601
602
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000603TYPE_CHECKER(Code, CODE_TYPE)
604TYPE_CHECKER(Oddball, ODDBALL_TYPE)
605TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
606TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
607TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
608TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000609
610
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000611bool Object::IsStringWrapper() {
612 return IsJSValue() && JSValue::cast(this)->value()->IsString();
613}
614
615
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000616TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000617
618
619bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000620 return IsOddball() &&
621 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000622}
623
624
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000625TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
626TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000627
628
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000629template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000630 return obj->IsJSArray();
631}
632
633
634bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000635 return Object::IsHeapObject() &&
636 HeapObject::cast(this)->map() ==
637 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000638}
639
640
641bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000642 return IsHashTable() &&
643 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000644}
645
646
647bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000648 return IsHashTable() && this ==
649 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000650}
651
652
ager@chromium.orgac091b72010-05-05 07:34:42 +0000653bool Object::IsJSFunctionResultCache() {
654 if (!IsFixedArray()) return false;
655 FixedArray* self = FixedArray::cast(this);
656 int length = self->length();
657 if (length < JSFunctionResultCache::kEntriesIndex) return false;
658 if ((length - JSFunctionResultCache::kEntriesIndex)
659 % JSFunctionResultCache::kEntrySize != 0) {
660 return false;
661 }
662#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000663 if (FLAG_verify_heap) {
664 reinterpret_cast<JSFunctionResultCache*>(this)->
665 JSFunctionResultCacheVerify();
666 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000667#endif
668 return true;
669}
670
671
ricow@chromium.org65fae842010-08-25 15:26:24 +0000672bool Object::IsNormalizedMapCache() {
673 if (!IsFixedArray()) return false;
674 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
675 return false;
676 }
677#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000678 if (FLAG_verify_heap) {
679 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
680 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000681#endif
682 return true;
683}
684
685
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000686bool Object::IsCompilationCacheTable() {
687 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000688}
689
690
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000691bool Object::IsCodeCacheHashTable() {
692 return IsHashTable();
693}
694
695
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000696bool Object::IsPolymorphicCodeCacheHashTable() {
697 return IsHashTable();
698}
699
700
ager@chromium.org236ad962008-09-25 09:45:57 +0000701bool Object::IsMapCache() {
702 return IsHashTable();
703}
704
705
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000706bool Object::IsPrimitive() {
707 return IsOddball() || IsNumber() || IsString();
708}
709
710
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000711bool Object::IsJSGlobalProxy() {
712 bool result = IsHeapObject() &&
713 (HeapObject::cast(this)->map()->instance_type() ==
714 JS_GLOBAL_PROXY_TYPE);
715 ASSERT(!result || IsAccessCheckNeeded());
716 return result;
717}
718
719
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000720bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000721 if (!IsHeapObject()) return false;
722
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000723 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000724 return type == JS_GLOBAL_OBJECT_TYPE ||
725 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000726}
727
728
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000729TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
730TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000731
732
733bool Object::IsUndetectableObject() {
734 return IsHeapObject()
735 && HeapObject::cast(this)->map()->is_undetectable();
736}
737
738
739bool Object::IsAccessCheckNeeded() {
740 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000741 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000742}
743
744
745bool Object::IsStruct() {
746 if (!IsHeapObject()) return false;
747 switch (HeapObject::cast(this)->map()->instance_type()) {
748#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
749 STRUCT_LIST(MAKE_STRUCT_CASE)
750#undef MAKE_STRUCT_CASE
751 default: return false;
752 }
753}
754
755
756#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
757 bool Object::Is##Name() { \
758 return Object::IsHeapObject() \
759 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
760 }
761 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
762#undef MAKE_STRUCT_PREDICATE
763
764
765bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000766 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000767}
768
769
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000770bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000771 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
772}
773
774
775bool Object::IsTheHole() {
776 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777}
778
779
780bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000781 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000782}
783
784
785bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000786 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787}
788
789
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000790bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000791 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000792}
793
794
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000795double Object::Number() {
796 ASSERT(IsNumber());
797 return IsSmi()
798 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
799 : reinterpret_cast<HeapNumber*>(this)->value();
800}
801
802
lrn@chromium.org303ada72010-10-27 09:33:13 +0000803MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804 if (IsSmi()) return this;
805 if (IsHeapNumber()) {
806 double value = HeapNumber::cast(this)->value();
807 int int_value = FastD2I(value);
808 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
809 return Smi::FromInt(int_value);
810 }
811 }
812 return Failure::Exception();
813}
814
815
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000816bool Object::HasSpecificClassOf(String* name) {
817 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
818}
819
820
lrn@chromium.org303ada72010-10-27 09:33:13 +0000821MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000822 // GetElement can trigger a getter which can cause allocation.
823 // This was not always the case. This ASSERT is here to catch
824 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000825 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000826 return GetElementWithReceiver(this, index);
827}
828
829
lrn@chromium.org303ada72010-10-27 09:33:13 +0000830Object* Object::GetElementNoExceptionThrown(uint32_t index) {
831 MaybeObject* maybe = GetElementWithReceiver(this, index);
832 ASSERT(!maybe->IsFailure());
833 Object* result = NULL; // Initialization to please compiler.
834 maybe->ToObject(&result);
835 return result;
836}
837
838
839MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000840 PropertyAttributes attributes;
841 return GetPropertyWithReceiver(this, key, &attributes);
842}
843
844
lrn@chromium.org303ada72010-10-27 09:33:13 +0000845MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000846 return GetPropertyWithReceiver(this, key, attributes);
847}
848
849
850#define FIELD_ADDR(p, offset) \
851 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
852
853#define READ_FIELD(p, offset) \
854 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
855
856#define WRITE_FIELD(p, offset, value) \
857 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
858
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000859#define WRITE_BARRIER(heap, object, offset, value) \
860 heap->incremental_marking()->RecordWrite( \
861 object, HeapObject::RawField(object, offset), value); \
862 if (heap->InNewSpace(value)) { \
863 heap->RecordWrite(object->address(), offset); \
864 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000865
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000866#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
867 if (mode == UPDATE_WRITE_BARRIER) { \
868 heap->incremental_marking()->RecordWrite( \
869 object, HeapObject::RawField(object, offset), value); \
870 if (heap->InNewSpace(value)) { \
871 heap->RecordWrite(object->address(), offset); \
872 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000873 }
874
lrn@chromium.org7516f052011-03-30 08:52:27 +0000875#ifndef V8_TARGET_ARCH_MIPS
876 #define READ_DOUBLE_FIELD(p, offset) \
877 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
878#else // V8_TARGET_ARCH_MIPS
879 // Prevent gcc from using load-double (mips ldc1) on (possibly)
880 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000881 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000882 union conversion {
883 double d;
884 uint32_t u[2];
885 } c;
886 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
887 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
888 return c.d;
889 }
890 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
891#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000892
lrn@chromium.org7516f052011-03-30 08:52:27 +0000893#ifndef V8_TARGET_ARCH_MIPS
894 #define WRITE_DOUBLE_FIELD(p, offset, value) \
895 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
896#else // V8_TARGET_ARCH_MIPS
897 // Prevent gcc from using store-double (mips sdc1) on (possibly)
898 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000899 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000900 double value) {
901 union conversion {
902 double d;
903 uint32_t u[2];
904 } c;
905 c.d = value;
906 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
907 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
908 }
909 #define WRITE_DOUBLE_FIELD(p, offset, value) \
910 write_double_field(p, offset, value)
911#endif // V8_TARGET_ARCH_MIPS
912
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000913
914#define READ_INT_FIELD(p, offset) \
915 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
916
917#define WRITE_INT_FIELD(p, offset, value) \
918 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
919
ager@chromium.org3e875802009-06-29 08:26:34 +0000920#define READ_INTPTR_FIELD(p, offset) \
921 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
922
923#define WRITE_INTPTR_FIELD(p, offset, value) \
924 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
925
ager@chromium.org7c537e22008-10-16 08:43:32 +0000926#define READ_UINT32_FIELD(p, offset) \
927 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
928
929#define WRITE_UINT32_FIELD(p, offset, value) \
930 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
931
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000932#define READ_SHORT_FIELD(p, offset) \
933 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
934
935#define WRITE_SHORT_FIELD(p, offset, value) \
936 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
937
938#define READ_BYTE_FIELD(p, offset) \
939 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
940
941#define WRITE_BYTE_FIELD(p, offset, value) \
942 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
943
944
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000945Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
946 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000947}
948
949
950int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000951 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000952}
953
954
955Smi* Smi::FromInt(int value) {
956 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000957 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000958 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000959 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000960 return reinterpret_cast<Smi*>(tagged_value);
961}
962
963
964Smi* Smi::FromIntptr(intptr_t value) {
965 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000966 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
967 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000968}
969
970
971Failure::Type Failure::type() const {
972 return static_cast<Type>(value() & kFailureTypeTagMask);
973}
974
975
976bool Failure::IsInternalError() const {
977 return type() == INTERNAL_ERROR;
978}
979
980
981bool Failure::IsOutOfMemoryException() const {
982 return type() == OUT_OF_MEMORY_EXCEPTION;
983}
984
985
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000986AllocationSpace Failure::allocation_space() const {
987 ASSERT_EQ(RETRY_AFTER_GC, type());
988 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
989 & kSpaceTagMask);
990}
991
992
993Failure* Failure::InternalError() {
994 return Construct(INTERNAL_ERROR);
995}
996
997
998Failure* Failure::Exception() {
999 return Construct(EXCEPTION);
1000}
1001
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001002
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001003Failure* Failure::OutOfMemoryException() {
1004 return Construct(OUT_OF_MEMORY_EXCEPTION);
1005}
1006
1007
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001008intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001009 return static_cast<intptr_t>(
1010 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001011}
1012
1013
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001014Failure* Failure::RetryAfterGC() {
1015 return RetryAfterGC(NEW_SPACE);
1016}
1017
1018
1019Failure* Failure::RetryAfterGC(AllocationSpace space) {
1020 ASSERT((space & ~kSpaceTagMask) == 0);
1021 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001022}
1023
1024
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001025Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001026 uintptr_t info =
1027 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001028 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001029 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001030}
1031
1032
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001033bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001034#ifdef DEBUG
1035 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1036#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001037
1038#ifdef V8_TARGET_ARCH_X64
1039 // To be representable as a long smi, the value must be a 32-bit integer.
1040 bool result = (value == static_cast<int32_t>(value));
1041#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001042 // To be representable as an tagged small integer, the two
1043 // most-significant bits of 'value' must be either 00 or 11 due to
1044 // sign-extension. To check this we add 01 to the two
1045 // most-significant bits, and check if the most-significant bit is 0
1046 //
1047 // CAUTION: The original code below:
1048 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1049 // may lead to incorrect results according to the C language spec, and
1050 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1051 // compiler may produce undefined results in case of signed integer
1052 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001053 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001054#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001055 ASSERT(result == in_range);
1056 return result;
1057}
1058
1059
kasper.lund7276f142008-07-30 08:49:36 +00001060MapWord MapWord::FromMap(Map* map) {
1061 return MapWord(reinterpret_cast<uintptr_t>(map));
1062}
1063
1064
1065Map* MapWord::ToMap() {
1066 return reinterpret_cast<Map*>(value_);
1067}
1068
1069
1070bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001071 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001072}
1073
1074
1075MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001076 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1077 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001078}
1079
1080
1081HeapObject* MapWord::ToForwardingAddress() {
1082 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001083 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001084}
1085
1086
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001087#ifdef DEBUG
1088void HeapObject::VerifyObjectField(int offset) {
1089 VerifyPointer(READ_FIELD(this, offset));
1090}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001091
1092void HeapObject::VerifySmiField(int offset) {
1093 ASSERT(READ_FIELD(this, offset)->IsSmi());
1094}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001095#endif
1096
1097
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001098Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001099 Heap* heap =
1100 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1101 ASSERT(heap != NULL);
1102 ASSERT(heap->isolate() == Isolate::Current());
1103 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001104}
1105
1106
1107Isolate* HeapObject::GetIsolate() {
1108 return GetHeap()->isolate();
1109}
1110
1111
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001112Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001113 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001114}
1115
1116
1117void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001118 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001119 if (value != NULL) {
1120 // TODO(1600) We are passing NULL as a slot because maps can never be on
1121 // evacuation candidate.
1122 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1123 }
1124}
1125
1126
1127// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001128void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001129 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001130}
1131
1132
kasper.lund7276f142008-07-30 08:49:36 +00001133MapWord HeapObject::map_word() {
1134 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1135}
1136
1137
1138void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001139 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001140 // here.
1141 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1142}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001143
1144
1145HeapObject* HeapObject::FromAddress(Address address) {
1146 ASSERT_TAG_ALIGNED(address);
1147 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1148}
1149
1150
1151Address HeapObject::address() {
1152 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1153}
1154
1155
1156int HeapObject::Size() {
1157 return SizeFromMap(map());
1158}
1159
1160
1161void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1162 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1163 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1164}
1165
1166
1167void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1168 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1169}
1170
1171
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001172double HeapNumber::value() {
1173 return READ_DOUBLE_FIELD(this, kValueOffset);
1174}
1175
1176
1177void HeapNumber::set_value(double value) {
1178 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1179}
1180
1181
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001182int HeapNumber::get_exponent() {
1183 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1184 kExponentShift) - kExponentBias;
1185}
1186
1187
1188int HeapNumber::get_sign() {
1189 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1190}
1191
1192
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001193ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001194
1195
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001196Object** FixedArray::GetFirstElementAddress() {
1197 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1198}
1199
1200
1201bool FixedArray::ContainsOnlySmisOrHoles() {
1202 Object* the_hole = GetHeap()->the_hole_value();
1203 Object** current = GetFirstElementAddress();
1204 for (int i = 0; i < length(); ++i) {
1205 Object* candidate = *current++;
1206 if (!candidate->IsSmi() && candidate != the_hole) return false;
1207 }
1208 return true;
1209}
1210
1211
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001212FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001213 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001214 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001215}
1216
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001217void JSObject::ValidateSmiOnlyElements() {
1218#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001219 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001220 Heap* heap = GetHeap();
1221 // Don't use elements, since integrity checks will fail if there
1222 // are filler pointers in the array.
1223 FixedArray* fixed_array =
1224 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1225 Map* map = fixed_array->map();
1226 // Arrays that have been shifted in place can't be verified.
1227 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1228 map != heap->raw_unchecked_two_pointer_filler_map() &&
1229 map != heap->free_space_map()) {
1230 for (int i = 0; i < fixed_array->length(); i++) {
1231 Object* current = fixed_array->get(i);
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001232 ASSERT(current->IsSmi() || current->IsTheHole());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001233 }
1234 }
1235 }
1236#endif
1237}
1238
1239
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001240MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001241#if DEBUG
1242 ValidateSmiOnlyElements();
1243#endif
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001244 if ((map()->elements_kind() != FAST_ELEMENTS)) {
1245 return TransitionElementsKind(FAST_ELEMENTS);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001246 }
1247 return this;
1248}
1249
1250
1251MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001252 uint32_t count,
1253 EnsureElementsMode mode) {
1254 ElementsKind current_kind = map()->elements_kind();
1255 ElementsKind target_kind = current_kind;
1256 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1257 if (current_kind == FAST_ELEMENTS) return this;
1258
1259 Heap* heap = GetHeap();
1260 Object* the_hole = heap->the_hole_value();
1261 Object* heap_number_map = heap->heap_number_map();
1262 for (uint32_t i = 0; i < count; ++i) {
1263 Object* current = *objects++;
1264 if (!current->IsSmi() && current != the_hole) {
1265 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
1266 HeapObject::cast(current)->map() == heap_number_map) {
1267 target_kind = FAST_DOUBLE_ELEMENTS;
1268 } else {
1269 target_kind = FAST_ELEMENTS;
1270 break;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001271 }
1272 }
1273 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001274
1275 if (target_kind != current_kind) {
1276 return TransitionElementsKind(target_kind);
1277 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001278 return this;
1279}
1280
1281
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001282MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
1283 EnsureElementsMode mode) {
1284 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1285 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1286 elements->map() == GetHeap()->fixed_cow_array_map());
1287 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1288 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1289 }
1290 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
1291 return EnsureCanContainElements(objects, elements->length(), mode);
1292 }
1293
1294 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1295 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1296 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1297 }
1298
1299 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001300}
1301
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001302
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001303MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1304 ElementsKind to_kind) {
1305 Map* current_map = map();
1306 ElementsKind from_kind = current_map->elements_kind();
1307
1308 if (from_kind == to_kind) return current_map;
1309
1310 Context* global_context = isolate->context()->global_context();
1311 if (current_map == global_context->smi_js_array_map()) {
1312 if (to_kind == FAST_ELEMENTS) {
1313 return global_context->object_js_array_map();
1314 } else {
1315 if (to_kind == FAST_DOUBLE_ELEMENTS) {
1316 return global_context->double_js_array_map();
1317 } else {
1318 ASSERT(to_kind == DICTIONARY_ELEMENTS);
1319 }
1320 }
1321 }
1322 return GetElementsTransitionMapSlow(to_kind);
1323}
1324
1325
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001326void JSObject::set_map_and_elements(Map* new_map,
1327 FixedArrayBase* value,
1328 WriteBarrierMode mode) {
1329 ASSERT(value->HasValidElements());
1330#ifdef DEBUG
1331 ValidateSmiOnlyElements();
1332#endif
1333 if (new_map != NULL) {
1334 if (mode == UPDATE_WRITE_BARRIER) {
1335 set_map(new_map);
1336 } else {
1337 ASSERT(mode == SKIP_WRITE_BARRIER);
1338 set_map_no_write_barrier(new_map);
1339 }
1340 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001341 ASSERT((map()->has_fast_elements() ||
1342 map()->has_fast_smi_only_elements()) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001343 (value->map() == GetHeap()->fixed_array_map() ||
1344 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001345 ASSERT(map()->has_fast_double_elements() ==
1346 value->IsFixedDoubleArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001347 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001348 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001349}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001350
1351
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001352void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1353 set_map_and_elements(NULL, value, mode);
1354}
1355
1356
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001357void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001358 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1359 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001360}
1361
1362
1363void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001364 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001365 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1366 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001367}
1368
1369
lrn@chromium.org303ada72010-10-27 09:33:13 +00001370MaybeObject* JSObject::ResetElements() {
1371 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001372 ElementsKind elements_kind = FLAG_smi_only_arrays
1373 ? FAST_SMI_ONLY_ELEMENTS
1374 : FAST_ELEMENTS;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001375 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1376 elements_kind);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001377 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001378 set_map(Map::cast(obj));
1379 initialize_elements();
1380 return this;
1381}
1382
1383
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001384ACCESSORS(Oddball, to_string, String, kToStringOffset)
1385ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1386
1387
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001388byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001389 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001390}
1391
1392
1393void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001394 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001395}
1396
1397
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001398Object* JSGlobalPropertyCell::value() {
1399 return READ_FIELD(this, kValueOffset);
1400}
1401
1402
1403void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1404 // The write barrier is not used for global property cells.
1405 ASSERT(!val->IsJSGlobalPropertyCell());
1406 WRITE_FIELD(this, kValueOffset, val);
1407}
1408
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001409
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001410int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001411 InstanceType type = map()->instance_type();
1412 // Check for the most common kind of JavaScript object before
1413 // falling into the generic switch. This speeds up the internal
1414 // field operations considerably on average.
1415 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1416 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001417 case JS_GLOBAL_PROXY_TYPE:
1418 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001419 case JS_GLOBAL_OBJECT_TYPE:
1420 return JSGlobalObject::kSize;
1421 case JS_BUILTINS_OBJECT_TYPE:
1422 return JSBuiltinsObject::kSize;
1423 case JS_FUNCTION_TYPE:
1424 return JSFunction::kSize;
1425 case JS_VALUE_TYPE:
1426 return JSValue::kSize;
1427 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001428 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001429 case JS_WEAK_MAP_TYPE:
1430 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001431 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001432 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001433 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001434 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001435 case JS_MESSAGE_OBJECT_TYPE:
1436 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001437 default:
1438 UNREACHABLE();
1439 return 0;
1440 }
1441}
1442
1443
1444int JSObject::GetInternalFieldCount() {
1445 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001446 // Make sure to adjust for the number of in-object properties. These
1447 // properties do contribute to the size, but are not internal fields.
1448 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1449 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001450}
1451
1452
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001453int JSObject::GetInternalFieldOffset(int index) {
1454 ASSERT(index < GetInternalFieldCount() && index >= 0);
1455 return GetHeaderSize() + (kPointerSize * index);
1456}
1457
1458
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001459Object* JSObject::GetInternalField(int index) {
1460 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001461 // Internal objects do follow immediately after the header, whereas in-object
1462 // properties are at the end of the object. Therefore there is no need
1463 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001464 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1465}
1466
1467
1468void JSObject::SetInternalField(int index, Object* value) {
1469 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001470 // Internal objects do follow immediately after the header, whereas in-object
1471 // properties are at the end of the object. Therefore there is no need
1472 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001473 int offset = GetHeaderSize() + (kPointerSize * index);
1474 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001475 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001476}
1477
1478
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001479void JSObject::SetInternalField(int index, Smi* value) {
1480 ASSERT(index < GetInternalFieldCount() && index >= 0);
1481 // Internal objects do follow immediately after the header, whereas in-object
1482 // properties are at the end of the object. Therefore there is no need
1483 // to adjust the index here.
1484 int offset = GetHeaderSize() + (kPointerSize * index);
1485 WRITE_FIELD(this, offset, value);
1486}
1487
1488
ager@chromium.org7c537e22008-10-16 08:43:32 +00001489// Access fast-case object properties at index. The use of these routines
1490// is needed to correctly distinguish between properties stored in-object and
1491// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001492Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001493 // Adjust for the number of properties stored in the object.
1494 index -= map()->inobject_properties();
1495 if (index < 0) {
1496 int offset = map()->instance_size() + (index * kPointerSize);
1497 return READ_FIELD(this, offset);
1498 } else {
1499 ASSERT(index < properties()->length());
1500 return properties()->get(index);
1501 }
1502}
1503
1504
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001505Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001506 // Adjust for the number of properties stored in the object.
1507 index -= map()->inobject_properties();
1508 if (index < 0) {
1509 int offset = map()->instance_size() + (index * kPointerSize);
1510 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001511 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001512 } else {
1513 ASSERT(index < properties()->length());
1514 properties()->set(index, value);
1515 }
1516 return value;
1517}
1518
1519
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001520int JSObject::GetInObjectPropertyOffset(int index) {
1521 // Adjust for the number of properties stored in the object.
1522 index -= map()->inobject_properties();
1523 ASSERT(index < 0);
1524 return map()->instance_size() + (index * kPointerSize);
1525}
1526
1527
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001528Object* JSObject::InObjectPropertyAt(int index) {
1529 // Adjust for the number of properties stored in the object.
1530 index -= map()->inobject_properties();
1531 ASSERT(index < 0);
1532 int offset = map()->instance_size() + (index * kPointerSize);
1533 return READ_FIELD(this, offset);
1534}
1535
1536
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001537Object* JSObject::InObjectPropertyAtPut(int index,
1538 Object* value,
1539 WriteBarrierMode mode) {
1540 // Adjust for the number of properties stored in the object.
1541 index -= map()->inobject_properties();
1542 ASSERT(index < 0);
1543 int offset = map()->instance_size() + (index * kPointerSize);
1544 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001545 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001546 return value;
1547}
1548
1549
1550
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001551void JSObject::InitializeBody(Map* map,
1552 Object* pre_allocated_value,
1553 Object* filler_value) {
1554 ASSERT(!filler_value->IsHeapObject() ||
1555 !GetHeap()->InNewSpace(filler_value));
1556 ASSERT(!pre_allocated_value->IsHeapObject() ||
1557 !GetHeap()->InNewSpace(pre_allocated_value));
1558 int size = map->instance_size();
1559 int offset = kHeaderSize;
1560 if (filler_value != pre_allocated_value) {
1561 int pre_allocated = map->pre_allocated_property_fields();
1562 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1563 for (int i = 0; i < pre_allocated; i++) {
1564 WRITE_FIELD(this, offset, pre_allocated_value);
1565 offset += kPointerSize;
1566 }
1567 }
1568 while (offset < size) {
1569 WRITE_FIELD(this, offset, filler_value);
1570 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001571 }
1572}
1573
1574
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001575bool JSObject::HasFastProperties() {
1576 return !properties()->IsDictionary();
1577}
1578
1579
1580int JSObject::MaxFastProperties() {
1581 // Allow extra fast properties if the object has more than
1582 // kMaxFastProperties in-object properties. When this is the case,
1583 // it is very unlikely that the object is being used as a dictionary
1584 // and there is a good chance that allowing more map transitions
1585 // will be worth it.
1586 return Max(map()->inobject_properties(), kMaxFastProperties);
1587}
1588
1589
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001590void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001591 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001592 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001593 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001594 }
1595}
1596
1597
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001598bool Object::ToArrayIndex(uint32_t* index) {
1599 if (IsSmi()) {
1600 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001601 if (value < 0) return false;
1602 *index = value;
1603 return true;
1604 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001605 if (IsHeapNumber()) {
1606 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001607 uint32_t uint_value = static_cast<uint32_t>(value);
1608 if (value == static_cast<double>(uint_value)) {
1609 *index = uint_value;
1610 return true;
1611 }
1612 }
1613 return false;
1614}
1615
1616
1617bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1618 if (!this->IsJSValue()) return false;
1619
1620 JSValue* js_value = JSValue::cast(this);
1621 if (!js_value->value()->IsString()) return false;
1622
1623 String* str = String::cast(js_value->value());
1624 if (index >= (uint32_t)str->length()) return false;
1625
1626 return true;
1627}
1628
1629
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001630FixedArrayBase* FixedArrayBase::cast(Object* object) {
1631 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1632 return reinterpret_cast<FixedArrayBase*>(object);
1633}
1634
1635
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001636Object* FixedArray::get(int index) {
1637 ASSERT(index >= 0 && index < this->length());
1638 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1639}
1640
1641
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001642void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001643 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001644 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001645 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1646 int offset = kHeaderSize + index * kPointerSize;
1647 WRITE_FIELD(this, offset, value);
1648}
1649
1650
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001651void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001652 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001653 ASSERT(index >= 0 && index < this->length());
1654 int offset = kHeaderSize + index * kPointerSize;
1655 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001656 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001657}
1658
1659
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001660inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1661 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1662}
1663
1664
1665inline double FixedDoubleArray::hole_nan_as_double() {
1666 return BitCast<double, uint64_t>(kHoleNanInt64);
1667}
1668
1669
1670inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1671 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1672 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1673 return OS::nan_value();
1674}
1675
1676
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001677double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001678 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1679 map() != HEAP->fixed_array_map());
1680 ASSERT(index >= 0 && index < this->length());
1681 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1682 ASSERT(!is_the_hole_nan(result));
1683 return result;
1684}
1685
1686
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001687MaybeObject* FixedDoubleArray::get(int index) {
1688 if (is_the_hole(index)) {
1689 return GetHeap()->the_hole_value();
1690 } else {
1691 return GetHeap()->NumberFromDouble(get_scalar(index));
1692 }
1693}
1694
1695
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001696void FixedDoubleArray::set(int index, double value) {
1697 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1698 map() != HEAP->fixed_array_map());
1699 int offset = kHeaderSize + index * kDoubleSize;
1700 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1701 WRITE_DOUBLE_FIELD(this, offset, value);
1702}
1703
1704
1705void FixedDoubleArray::set_the_hole(int index) {
1706 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1707 map() != HEAP->fixed_array_map());
1708 int offset = kHeaderSize + index * kDoubleSize;
1709 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1710}
1711
1712
1713bool FixedDoubleArray::is_the_hole(int index) {
1714 int offset = kHeaderSize + index * kDoubleSize;
1715 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1716}
1717
1718
1719void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1720 int old_length = from->length();
1721 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001722 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1723 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1724 FIELD_ADDR(from, kHeaderSize),
1725 old_length * kDoubleSize);
1726 } else {
1727 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001728 if (from->is_the_hole(i)) {
1729 set_the_hole(i);
1730 } else {
1731 set(i, from->get_scalar(i));
1732 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001733 }
1734 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001735 int offset = kHeaderSize + old_length * kDoubleSize;
1736 for (int current = from->length(); current < length(); ++current) {
1737 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1738 offset += kDoubleSize;
1739 }
1740}
1741
1742
1743void FixedDoubleArray::Initialize(FixedArray* from) {
1744 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001745 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001746 for (int i = 0; i < old_length; i++) {
1747 Object* hole_or_object = from->get(i);
1748 if (hole_or_object->IsTheHole()) {
1749 set_the_hole(i);
1750 } else {
1751 set(i, hole_or_object->Number());
1752 }
1753 }
1754 int offset = kHeaderSize + old_length * kDoubleSize;
1755 for (int current = from->length(); current < length(); ++current) {
1756 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1757 offset += kDoubleSize;
1758 }
1759}
1760
1761
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001762void FixedDoubleArray::Initialize(SeededNumberDictionary* from) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001763 int offset = kHeaderSize;
1764 for (int current = 0; current < length(); ++current) {
1765 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1766 offset += kDoubleSize;
1767 }
1768 for (int i = 0; i < from->Capacity(); i++) {
1769 Object* key = from->KeyAt(i);
1770 if (key->IsNumber()) {
1771 uint32_t entry = static_cast<uint32_t>(key->Number());
1772 set(entry, from->ValueAt(i)->Number());
1773 }
1774 }
1775}
1776
1777
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001778WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001779 Heap* heap = GetHeap();
1780 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1781 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001782 return UPDATE_WRITE_BARRIER;
1783}
1784
1785
1786void FixedArray::set(int index,
1787 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001788 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001789 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001790 ASSERT(index >= 0 && index < this->length());
1791 int offset = kHeaderSize + index * kPointerSize;
1792 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001793 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001794}
1795
1796
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001797void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1798 int index,
1799 Object* value) {
1800 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1801 ASSERT(index >= 0 && index < array->length());
1802 int offset = kHeaderSize + index * kPointerSize;
1803 WRITE_FIELD(array, offset, value);
1804 Heap* heap = array->GetHeap();
1805 if (heap->InNewSpace(value)) {
1806 heap->RecordWrite(array->address(), offset);
1807 }
1808}
1809
1810
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001811void FixedArray::NoWriteBarrierSet(FixedArray* array,
1812 int index,
1813 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001814 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001815 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001816 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001817 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1818}
1819
1820
1821void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001822 ASSERT(map() != HEAP->fixed_cow_array_map());
1823 set_undefined(GetHeap(), index);
1824}
1825
1826
1827void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001828 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001829 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001830 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001831 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001832}
1833
1834
ager@chromium.org236ad962008-09-25 09:45:57 +00001835void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001836 set_null(GetHeap(), index);
1837}
1838
1839
1840void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001841 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001842 ASSERT(!heap->InNewSpace(heap->null_value()));
1843 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001844}
1845
1846
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001847void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001848 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001849 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001850 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1851 WRITE_FIELD(this,
1852 kHeaderSize + index * kPointerSize,
1853 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001854}
1855
1856
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001857void FixedArray::set_unchecked(int index, Smi* value) {
1858 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1859 int offset = kHeaderSize + index * kPointerSize;
1860 WRITE_FIELD(this, offset, value);
1861}
1862
1863
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001864void FixedArray::set_unchecked(Heap* heap,
1865 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001866 Object* value,
1867 WriteBarrierMode mode) {
1868 int offset = kHeaderSize + index * kPointerSize;
1869 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001870 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001871}
1872
1873
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001874void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001875 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001876 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1877 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001878}
1879
1880
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001881Object** FixedArray::data_start() {
1882 return HeapObject::RawField(this, kHeaderSize);
1883}
1884
1885
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001886bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001887 ASSERT(this->IsSmi() ||
1888 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001889 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001890 return this->IsSmi() || length() <= kFirstIndex;
1891}
1892
1893
1894int DescriptorArray::bit_field3_storage() {
1895 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1896 return Smi::cast(storage)->value();
1897}
1898
1899void DescriptorArray::set_bit_field3_storage(int value) {
1900 ASSERT(!IsEmpty());
1901 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001902}
1903
1904
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001905void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1906 int first,
1907 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001908 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001909 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1910 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001911}
1912
1913
1914int DescriptorArray::Search(String* name) {
1915 SLOW_ASSERT(IsSortedNoDuplicates());
1916
1917 // Check for empty descriptor array.
1918 int nof = number_of_descriptors();
1919 if (nof == 0) return kNotFound;
1920
1921 // Fast case: do linear search for small arrays.
1922 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001923 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001924 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001925 }
1926
1927 // Slow case: perform binary search.
1928 return BinarySearch(name, 0, nof - 1);
1929}
1930
1931
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001932int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001933 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001934 if (number == DescriptorLookupCache::kAbsent) {
1935 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001936 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001937 }
1938 return number;
1939}
1940
1941
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001942String* DescriptorArray::GetKey(int descriptor_number) {
1943 ASSERT(descriptor_number < number_of_descriptors());
1944 return String::cast(get(ToKeyIndex(descriptor_number)));
1945}
1946
1947
1948Object* DescriptorArray::GetValue(int descriptor_number) {
1949 ASSERT(descriptor_number < number_of_descriptors());
1950 return GetContentArray()->get(ToValueIndex(descriptor_number));
1951}
1952
1953
1954Smi* DescriptorArray::GetDetails(int descriptor_number) {
1955 ASSERT(descriptor_number < number_of_descriptors());
1956 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1957}
1958
1959
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001960PropertyType DescriptorArray::GetType(int descriptor_number) {
1961 ASSERT(descriptor_number < number_of_descriptors());
1962 return PropertyDetails(GetDetails(descriptor_number)).type();
1963}
1964
1965
1966int DescriptorArray::GetFieldIndex(int descriptor_number) {
1967 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1968}
1969
1970
1971JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1972 return JSFunction::cast(GetValue(descriptor_number));
1973}
1974
1975
1976Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1977 ASSERT(GetType(descriptor_number) == CALLBACKS);
1978 return GetValue(descriptor_number);
1979}
1980
1981
1982AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1983 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001984 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001985 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001986}
1987
1988
1989bool DescriptorArray::IsProperty(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001990 return IsRealProperty(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001991}
1992
1993
1994bool DescriptorArray::IsTransition(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001995 return IsTransitionType(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001996}
1997
1998
1999bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2000 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2001}
2002
2003
2004bool DescriptorArray::IsDontEnum(int descriptor_number) {
2005 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
2006}
2007
2008
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002009void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2010 desc->Init(GetKey(descriptor_number),
2011 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002012 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002013}
2014
2015
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002016void DescriptorArray::Set(int descriptor_number,
2017 Descriptor* desc,
2018 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002019 // Range check.
2020 ASSERT(descriptor_number < number_of_descriptors());
2021
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002022 NoIncrementalWriteBarrierSet(this,
2023 ToKeyIndex(descriptor_number),
2024 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002025 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002026 NoIncrementalWriteBarrierSet(content_array,
2027 ToValueIndex(descriptor_number),
2028 desc->GetValue());
2029 NoIncrementalWriteBarrierSet(content_array,
2030 ToDetailsIndex(descriptor_number),
2031 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002032}
2033
2034
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002035void DescriptorArray::CopyFrom(int index,
2036 DescriptorArray* src,
2037 int src_index,
2038 const WhitenessWitness& witness) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002039 Descriptor desc;
2040 src->Get(src_index, &desc);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002041 Set(index, &desc, witness);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002042}
2043
2044
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002045void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2046 int first, int second) {
2047 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002048 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002049 NoIncrementalWriteBarrierSwap(content_array,
2050 ToValueIndex(first),
2051 ToValueIndex(second));
2052 NoIncrementalWriteBarrierSwap(content_array,
2053 ToDetailsIndex(first),
2054 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002055}
2056
2057
2058DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2059 : marking_(array->GetHeap()->incremental_marking()) {
2060 marking_->EnterNoMarkingScope();
2061 if (array->number_of_descriptors() > 0) {
2062 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2063 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2064 }
2065}
2066
2067
2068DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2069 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002070}
2071
2072
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002073template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002074int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2075 const int kMinCapacity = 32;
2076 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2077 if (capacity < kMinCapacity) {
2078 capacity = kMinCapacity; // Guarantee min capacity.
2079 }
2080 return capacity;
2081}
2082
2083
2084template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002085int HashTable<Shape, Key>::FindEntry(Key key) {
2086 return FindEntry(GetIsolate(), key);
2087}
2088
2089
2090// Find entry for key otherwise return kNotFound.
2091template<typename Shape, typename Key>
2092int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2093 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002094 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002095 uint32_t count = 1;
2096 // EnsureCapacity will guarantee the hash table is never full.
2097 while (true) {
2098 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002099 // Empty entry.
2100 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2101 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002102 Shape::IsMatch(key, element)) return entry;
2103 entry = NextProbe(entry, count++, capacity);
2104 }
2105 return kNotFound;
2106}
2107
2108
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002109bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002110 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002111 if (!max_index_object->IsSmi()) return false;
2112 return 0 !=
2113 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2114}
2115
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002116uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002118 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002119 if (!max_index_object->IsSmi()) return 0;
2120 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2121 return value >> kRequiresSlowElementsTagSize;
2122}
2123
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002124void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002125 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002126}
2127
2128
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002129// ------------------------------------
2130// Cast operations
2131
2132
2133CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002134CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002135CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002136CAST_ACCESSOR(DeoptimizationInputData)
2137CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002138CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002139CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002140CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002141CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002142CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002143CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002144CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002145CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002146CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002147CAST_ACCESSOR(String)
2148CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002149CAST_ACCESSOR(SeqAsciiString)
2150CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002151CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002152CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002153CAST_ACCESSOR(ExternalString)
2154CAST_ACCESSOR(ExternalAsciiString)
2155CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002156CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002157CAST_ACCESSOR(JSObject)
2158CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002159CAST_ACCESSOR(HeapObject)
2160CAST_ACCESSOR(HeapNumber)
2161CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002162CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002163CAST_ACCESSOR(SharedFunctionInfo)
2164CAST_ACCESSOR(Map)
2165CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002166CAST_ACCESSOR(GlobalObject)
2167CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002168CAST_ACCESSOR(JSGlobalObject)
2169CAST_ACCESSOR(JSBuiltinsObject)
2170CAST_ACCESSOR(Code)
2171CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002172CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002173CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002174CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002175CAST_ACCESSOR(JSSet)
2176CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002177CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002178CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002179CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002180CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002181CAST_ACCESSOR(ExternalArray)
2182CAST_ACCESSOR(ExternalByteArray)
2183CAST_ACCESSOR(ExternalUnsignedByteArray)
2184CAST_ACCESSOR(ExternalShortArray)
2185CAST_ACCESSOR(ExternalUnsignedShortArray)
2186CAST_ACCESSOR(ExternalIntArray)
2187CAST_ACCESSOR(ExternalUnsignedIntArray)
2188CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002189CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002190CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002191CAST_ACCESSOR(Struct)
2192
2193
2194#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2195 STRUCT_LIST(MAKE_STRUCT_CAST)
2196#undef MAKE_STRUCT_CAST
2197
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002198
2199template <typename Shape, typename Key>
2200HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002201 ASSERT(obj->IsHashTable());
2202 return reinterpret_cast<HashTable*>(obj);
2203}
2204
2205
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002206SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002207SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002208
ager@chromium.orgac091b72010-05-05 07:34:42 +00002209SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002210
2211
2212uint32_t String::hash_field() {
2213 return READ_UINT32_FIELD(this, kHashFieldOffset);
2214}
2215
2216
2217void String::set_hash_field(uint32_t value) {
2218 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002219#if V8_HOST_ARCH_64_BIT
2220 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2221#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002222}
2223
2224
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002225bool String::Equals(String* other) {
2226 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002227 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2228 return false;
2229 }
2230 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002231}
2232
2233
lrn@chromium.org303ada72010-10-27 09:33:13 +00002234MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002235 if (!StringShape(this).IsCons()) return this;
2236 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002237 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002238 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002239}
2240
2241
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002242String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002243 MaybeObject* flat = TryFlatten(pretenure);
2244 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002245 if (!flat->ToObject(&successfully_flattened)) return this;
2246 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002247}
2248
2249
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002250uint16_t String::Get(int index) {
2251 ASSERT(index >= 0 && index < length());
2252 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002253 case kSeqStringTag | kAsciiStringTag:
2254 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2255 case kSeqStringTag | kTwoByteStringTag:
2256 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2257 case kConsStringTag | kAsciiStringTag:
2258 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002259 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002260 case kExternalStringTag | kAsciiStringTag:
2261 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2262 case kExternalStringTag | kTwoByteStringTag:
2263 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002264 case kSlicedStringTag | kAsciiStringTag:
2265 case kSlicedStringTag | kTwoByteStringTag:
2266 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002267 default:
2268 break;
2269 }
2270
2271 UNREACHABLE();
2272 return 0;
2273}
2274
2275
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002276void String::Set(int index, uint16_t value) {
2277 ASSERT(index >= 0 && index < length());
2278 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002279
ager@chromium.org5ec48922009-05-05 07:25:34 +00002280 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002281 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2282 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002283}
2284
2285
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002286bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002287 if (!StringShape(this).IsCons()) return true;
2288 return ConsString::cast(this)->second()->length() == 0;
2289}
2290
2291
2292String* String::GetUnderlying() {
2293 // Giving direct access to underlying string only makes sense if the
2294 // wrapping string is already flattened.
2295 ASSERT(this->IsFlat());
2296 ASSERT(StringShape(this).IsIndirect());
2297 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2298 const int kUnderlyingOffset = SlicedString::kParentOffset;
2299 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002300}
2301
2302
ager@chromium.org7c537e22008-10-16 08:43:32 +00002303uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002304 ASSERT(index >= 0 && index < length());
2305 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2306}
2307
2308
ager@chromium.org7c537e22008-10-16 08:43:32 +00002309void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002310 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2311 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2312 static_cast<byte>(value));
2313}
2314
2315
ager@chromium.org7c537e22008-10-16 08:43:32 +00002316Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002317 return FIELD_ADDR(this, kHeaderSize);
2318}
2319
2320
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002321char* SeqAsciiString::GetChars() {
2322 return reinterpret_cast<char*>(GetCharsAddress());
2323}
2324
2325
ager@chromium.org7c537e22008-10-16 08:43:32 +00002326Address SeqTwoByteString::GetCharsAddress() {
2327 return FIELD_ADDR(this, kHeaderSize);
2328}
2329
2330
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002331uc16* SeqTwoByteString::GetChars() {
2332 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2333}
2334
2335
ager@chromium.org7c537e22008-10-16 08:43:32 +00002336uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002337 ASSERT(index >= 0 && index < length());
2338 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2339}
2340
2341
ager@chromium.org7c537e22008-10-16 08:43:32 +00002342void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002343 ASSERT(index >= 0 && index < length());
2344 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2345}
2346
2347
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002348int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002349 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002350}
2351
2352
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002353int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002354 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002355}
2356
2357
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002358String* SlicedString::parent() {
2359 return String::cast(READ_FIELD(this, kParentOffset));
2360}
2361
2362
2363void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002364 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002365 WRITE_FIELD(this, kParentOffset, parent);
2366}
2367
2368
2369SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2370
2371
ager@chromium.org870a0b62008-11-04 11:43:05 +00002372String* ConsString::first() {
2373 return String::cast(READ_FIELD(this, kFirstOffset));
2374}
2375
2376
2377Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002378 return READ_FIELD(this, kFirstOffset);
2379}
2380
2381
ager@chromium.org870a0b62008-11-04 11:43:05 +00002382void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002383 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002384 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002385}
2386
2387
ager@chromium.org870a0b62008-11-04 11:43:05 +00002388String* ConsString::second() {
2389 return String::cast(READ_FIELD(this, kSecondOffset));
2390}
2391
2392
2393Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002394 return READ_FIELD(this, kSecondOffset);
2395}
2396
2397
ager@chromium.org870a0b62008-11-04 11:43:05 +00002398void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002399 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002400 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002401}
2402
2403
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002404bool ExternalString::is_short() {
2405 InstanceType type = map()->instance_type();
2406 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002407}
2408
2409
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002410const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002411 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2412}
2413
2414
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002415void ExternalAsciiString::update_data_cache() {
2416 if (is_short()) return;
2417 const char** data_field =
2418 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2419 *data_field = resource()->data();
2420}
2421
2422
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002423void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002424 const ExternalAsciiString::Resource* resource) {
2425 *reinterpret_cast<const Resource**>(
2426 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002427 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002428}
2429
2430
2431const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002432 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002433}
2434
2435
2436uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2437 ASSERT(index >= 0 && index < length());
2438 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002439}
2440
2441
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002442const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002443 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2444}
2445
2446
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002447void ExternalTwoByteString::update_data_cache() {
2448 if (is_short()) return;
2449 const uint16_t** data_field =
2450 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2451 *data_field = resource()->data();
2452}
2453
2454
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002455void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002456 const ExternalTwoByteString::Resource* resource) {
2457 *reinterpret_cast<const Resource**>(
2458 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002459 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002460}
2461
2462
2463const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002464 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002465}
2466
2467
2468uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2469 ASSERT(index >= 0 && index < length());
2470 return GetChars()[index];
2471}
2472
2473
2474const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2475 unsigned start) {
2476 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002477}
2478
2479
ager@chromium.orgac091b72010-05-05 07:34:42 +00002480void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002481 set_finger_index(kEntriesIndex);
2482 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002483}
2484
2485
2486void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002487 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002488 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002489 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002490 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002491 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002492 MakeZeroSize();
2493}
2494
2495
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002496int JSFunctionResultCache::size() {
2497 return Smi::cast(get(kCacheSizeIndex))->value();
2498}
2499
2500
2501void JSFunctionResultCache::set_size(int size) {
2502 set(kCacheSizeIndex, Smi::FromInt(size));
2503}
2504
2505
2506int JSFunctionResultCache::finger_index() {
2507 return Smi::cast(get(kFingerIndex))->value();
2508}
2509
2510
2511void JSFunctionResultCache::set_finger_index(int finger_index) {
2512 set(kFingerIndex, Smi::FromInt(finger_index));
2513}
2514
2515
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002516byte ByteArray::get(int index) {
2517 ASSERT(index >= 0 && index < this->length());
2518 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2519}
2520
2521
2522void ByteArray::set(int index, byte value) {
2523 ASSERT(index >= 0 && index < this->length());
2524 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2525}
2526
2527
2528int ByteArray::get_int(int index) {
2529 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2530 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2531}
2532
2533
2534ByteArray* ByteArray::FromDataStartAddress(Address address) {
2535 ASSERT_TAG_ALIGNED(address);
2536 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2537}
2538
2539
2540Address ByteArray::GetDataStartAddress() {
2541 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2542}
2543
2544
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002545uint8_t* ExternalPixelArray::external_pixel_pointer() {
2546 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002547}
2548
2549
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002550uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002551 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002552 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002553 return ptr[index];
2554}
2555
2556
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002557MaybeObject* ExternalPixelArray::get(int index) {
2558 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2559}
2560
2561
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002562void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002563 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002564 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002565 ptr[index] = value;
2566}
2567
2568
ager@chromium.org3811b432009-10-28 14:53:37 +00002569void* ExternalArray::external_pointer() {
2570 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2571 return reinterpret_cast<void*>(ptr);
2572}
2573
2574
2575void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2576 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2577 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2578}
2579
2580
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002581int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002582 ASSERT((index >= 0) && (index < this->length()));
2583 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2584 return ptr[index];
2585}
2586
2587
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002588MaybeObject* ExternalByteArray::get(int index) {
2589 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2590}
2591
2592
ager@chromium.org3811b432009-10-28 14:53:37 +00002593void ExternalByteArray::set(int index, int8_t value) {
2594 ASSERT((index >= 0) && (index < this->length()));
2595 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2596 ptr[index] = value;
2597}
2598
2599
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002600uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002601 ASSERT((index >= 0) && (index < this->length()));
2602 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2603 return ptr[index];
2604}
2605
2606
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002607MaybeObject* ExternalUnsignedByteArray::get(int index) {
2608 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2609}
2610
2611
ager@chromium.org3811b432009-10-28 14:53:37 +00002612void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2613 ASSERT((index >= 0) && (index < this->length()));
2614 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2615 ptr[index] = value;
2616}
2617
2618
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002619int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002620 ASSERT((index >= 0) && (index < this->length()));
2621 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2622 return ptr[index];
2623}
2624
2625
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002626MaybeObject* ExternalShortArray::get(int index) {
2627 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2628}
2629
2630
ager@chromium.org3811b432009-10-28 14:53:37 +00002631void ExternalShortArray::set(int index, int16_t value) {
2632 ASSERT((index >= 0) && (index < this->length()));
2633 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2634 ptr[index] = value;
2635}
2636
2637
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002638uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002639 ASSERT((index >= 0) && (index < this->length()));
2640 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2641 return ptr[index];
2642}
2643
2644
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002645MaybeObject* ExternalUnsignedShortArray::get(int index) {
2646 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2647}
2648
2649
ager@chromium.org3811b432009-10-28 14:53:37 +00002650void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2651 ASSERT((index >= 0) && (index < this->length()));
2652 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2653 ptr[index] = value;
2654}
2655
2656
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002657int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002658 ASSERT((index >= 0) && (index < this->length()));
2659 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2660 return ptr[index];
2661}
2662
2663
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002664MaybeObject* ExternalIntArray::get(int index) {
2665 return GetHeap()->NumberFromInt32(get_scalar(index));
2666}
2667
2668
ager@chromium.org3811b432009-10-28 14:53:37 +00002669void ExternalIntArray::set(int index, int32_t value) {
2670 ASSERT((index >= 0) && (index < this->length()));
2671 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2672 ptr[index] = value;
2673}
2674
2675
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002676uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002677 ASSERT((index >= 0) && (index < this->length()));
2678 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2679 return ptr[index];
2680}
2681
2682
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002683MaybeObject* ExternalUnsignedIntArray::get(int index) {
2684 return GetHeap()->NumberFromUint32(get_scalar(index));
2685}
2686
2687
ager@chromium.org3811b432009-10-28 14:53:37 +00002688void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2689 ASSERT((index >= 0) && (index < this->length()));
2690 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2691 ptr[index] = value;
2692}
2693
2694
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002695float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002696 ASSERT((index >= 0) && (index < this->length()));
2697 float* ptr = static_cast<float*>(external_pointer());
2698 return ptr[index];
2699}
2700
2701
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002702MaybeObject* ExternalFloatArray::get(int index) {
2703 return GetHeap()->NumberFromDouble(get_scalar(index));
2704}
2705
2706
ager@chromium.org3811b432009-10-28 14:53:37 +00002707void ExternalFloatArray::set(int index, float value) {
2708 ASSERT((index >= 0) && (index < this->length()));
2709 float* ptr = static_cast<float*>(external_pointer());
2710 ptr[index] = value;
2711}
2712
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002713
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002714double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002715 ASSERT((index >= 0) && (index < this->length()));
2716 double* ptr = static_cast<double*>(external_pointer());
2717 return ptr[index];
2718}
2719
2720
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002721MaybeObject* ExternalDoubleArray::get(int index) {
2722 return GetHeap()->NumberFromDouble(get_scalar(index));
2723}
2724
2725
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002726void ExternalDoubleArray::set(int index, double value) {
2727 ASSERT((index >= 0) && (index < this->length()));
2728 double* ptr = static_cast<double*>(external_pointer());
2729 ptr[index] = value;
2730}
2731
2732
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002733int Map::visitor_id() {
2734 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2735}
2736
2737
2738void Map::set_visitor_id(int id) {
2739 ASSERT(0 <= id && id < 256);
2740 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2741}
2742
ager@chromium.org3811b432009-10-28 14:53:37 +00002743
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002744int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002745 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2746}
2747
2748
2749int Map::inobject_properties() {
2750 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002751}
2752
2753
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002754int Map::pre_allocated_property_fields() {
2755 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2756}
2757
2758
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002759int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002760 int instance_size = map->instance_size();
2761 if (instance_size != kVariableSizeSentinel) return instance_size;
2762 // We can ignore the "symbol" bit becase it is only set for symbols
2763 // and implies a string type.
2764 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002765 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002766 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002767 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002768 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002769 if (instance_type == ASCII_STRING_TYPE) {
2770 return SeqAsciiString::SizeFor(
2771 reinterpret_cast<SeqAsciiString*>(this)->length());
2772 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002773 if (instance_type == BYTE_ARRAY_TYPE) {
2774 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2775 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002776 if (instance_type == FREE_SPACE_TYPE) {
2777 return reinterpret_cast<FreeSpace*>(this)->size();
2778 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002779 if (instance_type == STRING_TYPE) {
2780 return SeqTwoByteString::SizeFor(
2781 reinterpret_cast<SeqTwoByteString*>(this)->length());
2782 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002783 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2784 return FixedDoubleArray::SizeFor(
2785 reinterpret_cast<FixedDoubleArray*>(this)->length());
2786 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002787 ASSERT(instance_type == CODE_TYPE);
2788 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002789}
2790
2791
2792void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002793 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002794 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002795 ASSERT(0 <= value && value < 256);
2796 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2797}
2798
2799
ager@chromium.org7c537e22008-10-16 08:43:32 +00002800void Map::set_inobject_properties(int value) {
2801 ASSERT(0 <= value && value < 256);
2802 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2803}
2804
2805
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002806void Map::set_pre_allocated_property_fields(int value) {
2807 ASSERT(0 <= value && value < 256);
2808 WRITE_BYTE_FIELD(this,
2809 kPreAllocatedPropertyFieldsOffset,
2810 static_cast<byte>(value));
2811}
2812
2813
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002814InstanceType Map::instance_type() {
2815 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2816}
2817
2818
2819void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002820 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2821}
2822
2823
2824int Map::unused_property_fields() {
2825 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2826}
2827
2828
2829void Map::set_unused_property_fields(int value) {
2830 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2831}
2832
2833
2834byte Map::bit_field() {
2835 return READ_BYTE_FIELD(this, kBitFieldOffset);
2836}
2837
2838
2839void Map::set_bit_field(byte value) {
2840 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2841}
2842
2843
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002844byte Map::bit_field2() {
2845 return READ_BYTE_FIELD(this, kBitField2Offset);
2846}
2847
2848
2849void Map::set_bit_field2(byte value) {
2850 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2851}
2852
2853
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002854void Map::set_non_instance_prototype(bool value) {
2855 if (value) {
2856 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2857 } else {
2858 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2859 }
2860}
2861
2862
2863bool Map::has_non_instance_prototype() {
2864 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2865}
2866
2867
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002868void Map::set_function_with_prototype(bool value) {
2869 if (value) {
2870 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2871 } else {
2872 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2873 }
2874}
2875
2876
2877bool Map::function_with_prototype() {
2878 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2879}
2880
2881
ager@chromium.org870a0b62008-11-04 11:43:05 +00002882void Map::set_is_access_check_needed(bool access_check_needed) {
2883 if (access_check_needed) {
2884 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2885 } else {
2886 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2887 }
2888}
2889
2890
2891bool Map::is_access_check_needed() {
2892 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2893}
2894
2895
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002896void Map::set_is_extensible(bool value) {
2897 if (value) {
2898 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2899 } else {
2900 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2901 }
2902}
2903
2904bool Map::is_extensible() {
2905 return ((1 << kIsExtensible) & bit_field2()) != 0;
2906}
2907
2908
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002909void Map::set_attached_to_shared_function_info(bool value) {
2910 if (value) {
2911 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2912 } else {
2913 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2914 }
2915}
2916
2917bool Map::attached_to_shared_function_info() {
2918 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2919}
2920
2921
2922void Map::set_is_shared(bool value) {
2923 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002924 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002925 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002926 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002927 }
2928}
2929
2930bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002931 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002932}
2933
2934
2935JSFunction* Map::unchecked_constructor() {
2936 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2937}
2938
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002939
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002940Code::Flags Code::flags() {
2941 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2942}
2943
2944
2945void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002946 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002947 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002948 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2949 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002950 ExtractArgumentsCountFromFlags(flags) >= 0);
2951 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2952}
2953
2954
2955Code::Kind Code::kind() {
2956 return ExtractKindFromFlags(flags());
2957}
2958
2959
kasper.lund7276f142008-07-30 08:49:36 +00002960InlineCacheState Code::ic_state() {
2961 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002962 // Only allow uninitialized or debugger states for non-IC code
2963 // objects. This is used in the debugger to determine whether or not
2964 // a call to code object has been replaced with a debug break call.
2965 ASSERT(is_inline_cache_stub() ||
2966 result == UNINITIALIZED ||
2967 result == DEBUG_BREAK ||
2968 result == DEBUG_PREPARE_STEP_IN);
2969 return result;
2970}
2971
2972
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002973Code::ExtraICState Code::extra_ic_state() {
2974 ASSERT(is_inline_cache_stub());
2975 return ExtractExtraICStateFromFlags(flags());
2976}
2977
2978
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002979PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002980 return ExtractTypeFromFlags(flags());
2981}
2982
2983
2984int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002985 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002986 return ExtractArgumentsCountFromFlags(flags());
2987}
2988
2989
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002990int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002991 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002992 kind() == UNARY_OP_IC ||
2993 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002994 kind() == COMPARE_IC ||
2995 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002996 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002997}
2998
2999
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003000void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003001 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003002 kind() == UNARY_OP_IC ||
3003 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003004 kind() == COMPARE_IC ||
3005 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003006 ASSERT(0 <= major && major < 256);
3007 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003008}
3009
3010
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003011bool Code::is_pregenerated() {
3012 return kind() == STUB && IsPregeneratedField::decode(flags());
3013}
3014
3015
3016void Code::set_is_pregenerated(bool value) {
3017 ASSERT(kind() == STUB);
3018 Flags f = flags();
3019 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3020 set_flags(f);
3021}
3022
3023
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003024bool Code::optimizable() {
3025 ASSERT(kind() == FUNCTION);
3026 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3027}
3028
3029
3030void Code::set_optimizable(bool value) {
3031 ASSERT(kind() == FUNCTION);
3032 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3033}
3034
3035
3036bool Code::has_deoptimization_support() {
3037 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003038 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3039 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003040}
3041
3042
3043void Code::set_has_deoptimization_support(bool value) {
3044 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003045 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3046 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3047 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3048}
3049
3050
3051bool Code::has_debug_break_slots() {
3052 ASSERT(kind() == FUNCTION);
3053 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3054 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3055}
3056
3057
3058void Code::set_has_debug_break_slots(bool value) {
3059 ASSERT(kind() == FUNCTION);
3060 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3061 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3062 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003063}
3064
3065
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003066bool Code::is_compiled_optimizable() {
3067 ASSERT(kind() == FUNCTION);
3068 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3069 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3070}
3071
3072
3073void Code::set_compiled_optimizable(bool value) {
3074 ASSERT(kind() == FUNCTION);
3075 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3076 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3077 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3078}
3079
3080
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003081int Code::allow_osr_at_loop_nesting_level() {
3082 ASSERT(kind() == FUNCTION);
3083 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3084}
3085
3086
3087void Code::set_allow_osr_at_loop_nesting_level(int level) {
3088 ASSERT(kind() == FUNCTION);
3089 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3090 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3091}
3092
3093
3094unsigned Code::stack_slots() {
3095 ASSERT(kind() == OPTIMIZED_FUNCTION);
3096 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3097}
3098
3099
3100void Code::set_stack_slots(unsigned slots) {
3101 ASSERT(kind() == OPTIMIZED_FUNCTION);
3102 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3103}
3104
3105
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003106unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003107 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003108 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003109}
3110
3111
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003112void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003113 ASSERT(kind() == OPTIMIZED_FUNCTION);
3114 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003115 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003116}
3117
3118
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003119unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003120 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003121 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003122}
3123
3124
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003125void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003126 ASSERT(kind() == FUNCTION);
3127 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003128 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003129}
3130
3131
3132CheckType Code::check_type() {
3133 ASSERT(is_call_stub() || is_keyed_call_stub());
3134 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3135 return static_cast<CheckType>(type);
3136}
3137
3138
3139void Code::set_check_type(CheckType value) {
3140 ASSERT(is_call_stub() || is_keyed_call_stub());
3141 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3142}
3143
3144
danno@chromium.org40cb8782011-05-25 07:58:50 +00003145byte Code::unary_op_type() {
3146 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003147 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3148}
3149
3150
danno@chromium.org40cb8782011-05-25 07:58:50 +00003151void Code::set_unary_op_type(byte value) {
3152 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003153 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3154}
3155
3156
danno@chromium.org40cb8782011-05-25 07:58:50 +00003157byte Code::binary_op_type() {
3158 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003159 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3160}
3161
3162
danno@chromium.org40cb8782011-05-25 07:58:50 +00003163void Code::set_binary_op_type(byte value) {
3164 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003165 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3166}
3167
3168
danno@chromium.org40cb8782011-05-25 07:58:50 +00003169byte Code::binary_op_result_type() {
3170 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003171 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3172}
3173
3174
danno@chromium.org40cb8782011-05-25 07:58:50 +00003175void Code::set_binary_op_result_type(byte value) {
3176 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003177 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3178}
3179
3180
3181byte Code::compare_state() {
3182 ASSERT(is_compare_ic_stub());
3183 return READ_BYTE_FIELD(this, kCompareStateOffset);
3184}
3185
3186
3187void Code::set_compare_state(byte value) {
3188 ASSERT(is_compare_ic_stub());
3189 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3190}
3191
3192
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003193byte Code::to_boolean_state() {
3194 ASSERT(is_to_boolean_ic_stub());
3195 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3196}
3197
3198
3199void Code::set_to_boolean_state(byte value) {
3200 ASSERT(is_to_boolean_ic_stub());
3201 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3202}
3203
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003204
3205bool Code::has_function_cache() {
3206 ASSERT(kind() == STUB);
3207 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3208}
3209
3210
3211void Code::set_has_function_cache(bool flag) {
3212 ASSERT(kind() == STUB);
3213 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3214}
3215
3216
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003217bool Code::is_inline_cache_stub() {
3218 Kind kind = this->kind();
3219 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3220}
3221
3222
3223Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003224 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003225 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003226 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003227 int argc,
3228 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003229 // Extra IC state is only allowed for call IC stubs or for store IC
3230 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003231 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003232 kind == CALL_IC ||
3233 kind == STORE_IC ||
3234 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003235 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003236 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003237 | ICStateField::encode(ic_state)
3238 | TypeField::encode(type)
3239 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003240 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003241 | CacheHolderField::encode(holder);
3242 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003243}
3244
3245
3246Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3247 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003248 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003249 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003250 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003251 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003252}
3253
3254
3255Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003256 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003257}
3258
3259
kasper.lund7276f142008-07-30 08:49:36 +00003260InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003261 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003262}
3263
3264
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003265Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003266 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003267}
3268
3269
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003270PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003271 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003272}
3273
3274
3275int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003276 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003277}
3278
3279
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003280InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003281 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003282}
3283
3284
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003285Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003286 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003287 return static_cast<Flags>(bits);
3288}
3289
3290
ager@chromium.org8bb60582008-12-11 12:02:20 +00003291Code* Code::GetCodeFromTargetAddress(Address address) {
3292 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3293 // GetCodeFromTargetAddress might be called when marking objects during mark
3294 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3295 // Code::cast. Code::cast does not work when the object's map is
3296 // marked.
3297 Code* result = reinterpret_cast<Code*>(code);
3298 return result;
3299}
3300
3301
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003302Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3303 return HeapObject::
3304 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3305}
3306
3307
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003308Object* Map::prototype() {
3309 return READ_FIELD(this, kPrototypeOffset);
3310}
3311
3312
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003313void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003314 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003315 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003316 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003317}
3318
3319
danno@chromium.org40cb8782011-05-25 07:58:50 +00003320DescriptorArray* Map::instance_descriptors() {
3321 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3322 if (object->IsSmi()) {
3323 return HEAP->empty_descriptor_array();
3324 } else {
3325 return DescriptorArray::cast(object);
3326 }
3327}
3328
3329
3330void Map::init_instance_descriptors() {
3331 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3332}
3333
3334
3335void Map::clear_instance_descriptors() {
3336 Object* object = READ_FIELD(this,
3337 kInstanceDescriptorsOrBitField3Offset);
3338 if (!object->IsSmi()) {
3339 WRITE_FIELD(
3340 this,
3341 kInstanceDescriptorsOrBitField3Offset,
3342 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3343 }
3344}
3345
3346
3347void Map::set_instance_descriptors(DescriptorArray* value,
3348 WriteBarrierMode mode) {
3349 Object* object = READ_FIELD(this,
3350 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003351 Heap* heap = GetHeap();
3352 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003353 clear_instance_descriptors();
3354 return;
3355 } else {
3356 if (object->IsSmi()) {
3357 value->set_bit_field3_storage(Smi::cast(object)->value());
3358 } else {
3359 value->set_bit_field3_storage(
3360 DescriptorArray::cast(object)->bit_field3_storage());
3361 }
3362 }
3363 ASSERT(!is_shared());
3364 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003365 CONDITIONAL_WRITE_BARRIER(
3366 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003367}
3368
3369
3370int Map::bit_field3() {
3371 Object* object = READ_FIELD(this,
3372 kInstanceDescriptorsOrBitField3Offset);
3373 if (object->IsSmi()) {
3374 return Smi::cast(object)->value();
3375 } else {
3376 return DescriptorArray::cast(object)->bit_field3_storage();
3377 }
3378}
3379
3380
3381void Map::set_bit_field3(int value) {
3382 ASSERT(Smi::IsValid(value));
3383 Object* object = READ_FIELD(this,
3384 kInstanceDescriptorsOrBitField3Offset);
3385 if (object->IsSmi()) {
3386 WRITE_FIELD(this,
3387 kInstanceDescriptorsOrBitField3Offset,
3388 Smi::FromInt(value));
3389 } else {
3390 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3391 }
3392}
3393
3394
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003395FixedArray* Map::unchecked_prototype_transitions() {
3396 return reinterpret_cast<FixedArray*>(
3397 READ_FIELD(this, kPrototypeTransitionsOffset));
3398}
3399
3400
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003401ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003402ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003403ACCESSORS(Map, constructor, Object, kConstructorOffset)
3404
3405ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003406ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003407ACCESSORS(JSFunction,
3408 next_function_link,
3409 Object,
3410 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003411
3412ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3413ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003414ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003415
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003416ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003417
3418ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3419ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3420ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3421ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3422ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3423
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003424ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3425ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3426
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003427ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3428ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3429ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3430
3431ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3432ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3433ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3434ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3435ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3436ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3437
3438ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3439ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3440
3441ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3442ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3443
3444ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3445ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003446ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3447 kPropertyAccessorsOffset)
3448ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3449 kPrototypeTemplateOffset)
3450ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3451ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3452 kNamedPropertyHandlerOffset)
3453ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3454 kIndexedPropertyHandlerOffset)
3455ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3456 kInstanceTemplateOffset)
3457ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3458ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003459ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3460 kInstanceCallHandlerOffset)
3461ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3462 kAccessCheckInfoOffset)
3463ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3464
3465ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003466ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3467 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003468
3469ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3470ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3471
3472ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3473
3474ACCESSORS(Script, source, Object, kSourceOffset)
3475ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003476ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003477ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3478ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003479ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003480ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003481ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003482ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003483ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003484ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003485ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003486ACCESSORS(Script, eval_from_instructions_offset, Smi,
3487 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003488
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003489#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003490ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3491ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3492ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3493ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3494
3495ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3496ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3497ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3498ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003499#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003500
3501ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003502ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3503ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003504ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3505 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003506ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003507ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3508ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003509ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003510ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3511 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003512
3513BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3514 kHiddenPrototypeBit)
3515BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3516BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3517 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003518BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3519 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003520BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3521 kIsExpressionBit)
3522BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3523 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003524BOOL_GETTER(SharedFunctionInfo,
3525 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003526 has_only_simple_this_property_assignments,
3527 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003528BOOL_ACCESSORS(SharedFunctionInfo,
3529 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003530 allows_lazy_compilation,
3531 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003532BOOL_ACCESSORS(SharedFunctionInfo,
3533 compiler_hints,
3534 uses_arguments,
3535 kUsesArguments)
3536BOOL_ACCESSORS(SharedFunctionInfo,
3537 compiler_hints,
3538 has_duplicate_parameters,
3539 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003540
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003541
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003542#if V8_HOST_ARCH_32_BIT
3543SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3544SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003545 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003546SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003547 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003548SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3549SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003550 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003551SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3552SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003553 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003554SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003555 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003556SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003557 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003558SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003559#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003560
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003561#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003562 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003563 int holder::name() { \
3564 int value = READ_INT_FIELD(this, offset); \
3565 ASSERT(kHeapObjectTag == 1); \
3566 ASSERT((value & kHeapObjectTag) == 0); \
3567 return value >> 1; \
3568 } \
3569 void holder::set_##name(int value) { \
3570 ASSERT(kHeapObjectTag == 1); \
3571 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3572 (value & 0xC0000000) == 0x000000000); \
3573 WRITE_INT_FIELD(this, \
3574 offset, \
3575 (value << 1) & ~kHeapObjectTag); \
3576 }
3577
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003578#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3579 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003580 INT_ACCESSORS(holder, name, offset)
3581
3582
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003583PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003584PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3585 formal_parameter_count,
3586 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003587
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003588PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3589 expected_nof_properties,
3590 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003591PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3592
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003593PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3594PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3595 start_position_and_type,
3596 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003597
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003598PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3599 function_token_position,
3600 kFunctionTokenPositionOffset)
3601PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3602 compiler_hints,
3603 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003604
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003605PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3606 this_property_assignments_count,
3607 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003608PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003609#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003610
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003611
3612int SharedFunctionInfo::construction_count() {
3613 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3614}
3615
3616
3617void SharedFunctionInfo::set_construction_count(int value) {
3618 ASSERT(0 <= value && value < 256);
3619 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3620}
3621
3622
whesse@chromium.org7b260152011-06-20 15:33:18 +00003623BOOL_ACCESSORS(SharedFunctionInfo,
3624 compiler_hints,
3625 live_objects_may_exist,
3626 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003627
3628
3629bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003630 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003631}
3632
3633
whesse@chromium.org7b260152011-06-20 15:33:18 +00003634BOOL_GETTER(SharedFunctionInfo,
3635 compiler_hints,
3636 optimization_disabled,
3637 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003638
3639
3640void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3641 set_compiler_hints(BooleanBit::set(compiler_hints(),
3642 kOptimizationDisabled,
3643 disable));
3644 // If disabling optimizations we reflect that in the code object so
3645 // it will not be counted as optimizable code.
3646 if ((code()->kind() == Code::FUNCTION) && disable) {
3647 code()->set_optimizable(false);
3648 }
3649}
3650
3651
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003652LanguageMode SharedFunctionInfo::language_mode() {
3653 int hints = compiler_hints();
3654 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3655 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3656 return EXTENDED_MODE;
3657 }
3658 return BooleanBit::get(hints, kStrictModeFunction)
3659 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003660}
3661
3662
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003663void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3664 // We only allow language mode transitions that go set the same language mode
3665 // again or go up in the chain:
3666 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3667 ASSERT(this->language_mode() == CLASSIC_MODE ||
3668 this->language_mode() == language_mode ||
3669 language_mode == EXTENDED_MODE);
3670 int hints = compiler_hints();
3671 hints = BooleanBit::set(
3672 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3673 hints = BooleanBit::set(
3674 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3675 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003676}
3677
3678
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003679bool SharedFunctionInfo::is_classic_mode() {
3680 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3681}
3682
3683BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3684 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003685BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3686BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3687 name_should_print_as_anonymous,
3688 kNameShouldPrintAsAnonymous)
3689BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3690BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003691
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003692ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3693ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3694
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003695ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3696
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003697bool Script::HasValidSource() {
3698 Object* src = this->source();
3699 if (!src->IsString()) return true;
3700 String* src_str = String::cast(src);
3701 if (!StringShape(src_str).IsExternal()) return true;
3702 if (src_str->IsAsciiRepresentation()) {
3703 return ExternalAsciiString::cast(src)->resource() != NULL;
3704 } else if (src_str->IsTwoByteRepresentation()) {
3705 return ExternalTwoByteString::cast(src)->resource() != NULL;
3706 }
3707 return true;
3708}
3709
3710
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003711void SharedFunctionInfo::DontAdaptArguments() {
3712 ASSERT(code()->kind() == Code::BUILTIN);
3713 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3714}
3715
3716
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003717int SharedFunctionInfo::start_position() {
3718 return start_position_and_type() >> kStartPositionShift;
3719}
3720
3721
3722void SharedFunctionInfo::set_start_position(int start_position) {
3723 set_start_position_and_type((start_position << kStartPositionShift)
3724 | (start_position_and_type() & ~kStartPositionMask));
3725}
3726
3727
3728Code* SharedFunctionInfo::code() {
3729 return Code::cast(READ_FIELD(this, kCodeOffset));
3730}
3731
3732
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003733Code* SharedFunctionInfo::unchecked_code() {
3734 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3735}
3736
3737
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003738void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003739 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003740 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003741}
3742
3743
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003744ScopeInfo* SharedFunctionInfo::scope_info() {
3745 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003746}
3747
3748
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003749void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003750 WriteBarrierMode mode) {
3751 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003752 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3753 this,
3754 kScopeInfoOffset,
3755 reinterpret_cast<Object*>(value),
3756 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003757}
3758
3759
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003760Smi* SharedFunctionInfo::deopt_counter() {
3761 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3762}
3763
3764
3765void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3766 WRITE_FIELD(this, kDeoptCounterOffset, value);
3767}
3768
3769
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003770bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003771 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003772 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003773}
3774
3775
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003776bool SharedFunctionInfo::IsApiFunction() {
3777 return function_data()->IsFunctionTemplateInfo();
3778}
3779
3780
3781FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3782 ASSERT(IsApiFunction());
3783 return FunctionTemplateInfo::cast(function_data());
3784}
3785
3786
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003787bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003788 return function_data()->IsSmi();
3789}
3790
3791
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003792BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3793 ASSERT(HasBuiltinFunctionId());
3794 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003795}
3796
3797
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003798int SharedFunctionInfo::code_age() {
3799 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3800}
3801
3802
3803void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003804 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3805 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003806}
3807
3808
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003809bool SharedFunctionInfo::has_deoptimization_support() {
3810 Code* code = this->code();
3811 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3812}
3813
3814
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003815bool JSFunction::IsBuiltin() {
3816 return context()->global()->IsJSBuiltinsObject();
3817}
3818
3819
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003820bool JSFunction::NeedsArgumentsAdaption() {
3821 return shared()->formal_parameter_count() !=
3822 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3823}
3824
3825
3826bool JSFunction::IsOptimized() {
3827 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3828}
3829
3830
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003831bool JSFunction::IsOptimizable() {
3832 return code()->kind() == Code::FUNCTION && code()->optimizable();
3833}
3834
3835
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003836bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003837 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003838}
3839
3840
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003841Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003842 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003843}
3844
3845
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003846Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003847 return reinterpret_cast<Code*>(
3848 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003849}
3850
3851
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003852void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003853 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003854 Address entry = value->entry();
3855 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003856 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3857 this,
3858 HeapObject::RawField(this, kCodeEntryOffset),
3859 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003860}
3861
3862
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003863void JSFunction::ReplaceCode(Code* code) {
3864 bool was_optimized = IsOptimized();
3865 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3866
3867 set_code(code);
3868
3869 // Add/remove the function from the list of optimized functions for this
3870 // context based on the state change.
3871 if (!was_optimized && is_optimized) {
3872 context()->global_context()->AddOptimizedFunction(this);
3873 }
3874 if (was_optimized && !is_optimized) {
3875 context()->global_context()->RemoveOptimizedFunction(this);
3876 }
3877}
3878
3879
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003880Context* JSFunction::context() {
3881 return Context::cast(READ_FIELD(this, kContextOffset));
3882}
3883
3884
3885Object* JSFunction::unchecked_context() {
3886 return READ_FIELD(this, kContextOffset);
3887}
3888
3889
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003890SharedFunctionInfo* JSFunction::unchecked_shared() {
3891 return reinterpret_cast<SharedFunctionInfo*>(
3892 READ_FIELD(this, kSharedFunctionInfoOffset));
3893}
3894
3895
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003896void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003897 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003898 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003899 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003900}
3901
3902ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3903 kPrototypeOrInitialMapOffset)
3904
3905
3906Map* JSFunction::initial_map() {
3907 return Map::cast(prototype_or_initial_map());
3908}
3909
3910
3911void JSFunction::set_initial_map(Map* value) {
3912 set_prototype_or_initial_map(value);
3913}
3914
3915
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003916MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
3917 Map* initial_map) {
3918 Context* global_context = context()->global_context();
3919 Object* array_function =
3920 global_context->get(Context::ARRAY_FUNCTION_INDEX);
3921 if (array_function->IsJSFunction() &&
3922 this == JSFunction::cast(array_function)) {
3923 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
3924
3925 MaybeObject* maybe_map = initial_map->CopyDropTransitions();
3926 Map* new_double_map = NULL;
3927 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
3928 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
3929 initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS, new_double_map);
3930
3931 maybe_map = new_double_map->CopyDropTransitions();
3932 Map* new_object_map = NULL;
3933 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
3934 new_object_map->set_elements_kind(FAST_ELEMENTS);
3935 new_double_map->AddElementsTransition(FAST_ELEMENTS, new_object_map);
3936
3937 global_context->set_smi_js_array_map(initial_map);
3938 global_context->set_double_js_array_map(new_double_map);
3939 global_context->set_object_js_array_map(new_object_map);
3940 }
3941 set_initial_map(initial_map);
3942 return this;
3943}
3944
3945
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003946bool JSFunction::has_initial_map() {
3947 return prototype_or_initial_map()->IsMap();
3948}
3949
3950
3951bool JSFunction::has_instance_prototype() {
3952 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3953}
3954
3955
3956bool JSFunction::has_prototype() {
3957 return map()->has_non_instance_prototype() || has_instance_prototype();
3958}
3959
3960
3961Object* JSFunction::instance_prototype() {
3962 ASSERT(has_instance_prototype());
3963 if (has_initial_map()) return initial_map()->prototype();
3964 // When there is no initial map and the prototype is a JSObject, the
3965 // initial map field is used for the prototype field.
3966 return prototype_or_initial_map();
3967}
3968
3969
3970Object* JSFunction::prototype() {
3971 ASSERT(has_prototype());
3972 // If the function's prototype property has been set to a non-JSObject
3973 // value, that value is stored in the constructor field of the map.
3974 if (map()->has_non_instance_prototype()) return map()->constructor();
3975 return instance_prototype();
3976}
3977
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003978bool JSFunction::should_have_prototype() {
3979 return map()->function_with_prototype();
3980}
3981
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003982
3983bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003984 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003985}
3986
3987
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003988FixedArray* JSFunction::literals() {
3989 ASSERT(!shared()->bound());
3990 return literals_or_bindings();
3991}
3992
3993
3994void JSFunction::set_literals(FixedArray* literals) {
3995 ASSERT(!shared()->bound());
3996 set_literals_or_bindings(literals);
3997}
3998
3999
4000FixedArray* JSFunction::function_bindings() {
4001 ASSERT(shared()->bound());
4002 return literals_or_bindings();
4003}
4004
4005
4006void JSFunction::set_function_bindings(FixedArray* bindings) {
4007 ASSERT(shared()->bound());
4008 // Bound function literal may be initialized to the empty fixed array
4009 // before the bindings are set.
4010 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4011 bindings->map() == GetHeap()->fixed_cow_array_map());
4012 set_literals_or_bindings(bindings);
4013}
4014
4015
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004016int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004017 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004018 return literals()->length();
4019}
4020
4021
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004022Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004023 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004024 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004025}
4026
4027
4028void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4029 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004030 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004031 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004032 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004033}
4034
4035
4036Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004037 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004038 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4039}
4040
4041
4042void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4043 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004044 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004045 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004046 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004047}
4048
4049
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004050ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004051ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004052ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4053ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4054
4055
4056void JSProxy::InitializeBody(int object_size, Object* value) {
4057 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4058 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4059 WRITE_FIELD(this, offset, value);
4060 }
4061}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004062
4063
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004064ACCESSORS(JSSet, table, Object, kTableOffset)
4065ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004066ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4067ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004068
4069
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004070Address Foreign::foreign_address() {
4071 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004072}
4073
4074
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004075void Foreign::set_foreign_address(Address value) {
4076 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004077}
4078
4079
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004080ACCESSORS(JSValue, value, Object, kValueOffset)
4081
4082
4083JSValue* JSValue::cast(Object* obj) {
4084 ASSERT(obj->IsJSValue());
4085 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4086 return reinterpret_cast<JSValue*>(obj);
4087}
4088
4089
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004090ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4091ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4092ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4093ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4094ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4095SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4096SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4097
4098
4099JSMessageObject* JSMessageObject::cast(Object* obj) {
4100 ASSERT(obj->IsJSMessageObject());
4101 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4102 return reinterpret_cast<JSMessageObject*>(obj);
4103}
4104
4105
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004106INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004107ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004108ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004109ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004110ACCESSORS(Code, type_feedback_cells, TypeFeedbackCells,
4111 kTypeFeedbackCellsOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004112ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004113
4114
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004115byte* Code::instruction_start() {
4116 return FIELD_ADDR(this, kHeaderSize);
4117}
4118
4119
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004120byte* Code::instruction_end() {
4121 return instruction_start() + instruction_size();
4122}
4123
4124
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004125int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004126 return RoundUp(instruction_size(), kObjectAlignment);
4127}
4128
4129
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004130FixedArray* Code::unchecked_deoptimization_data() {
4131 return reinterpret_cast<FixedArray*>(
4132 READ_FIELD(this, kDeoptimizationDataOffset));
4133}
4134
4135
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004136ByteArray* Code::unchecked_relocation_info() {
4137 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004138}
4139
4140
4141byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004142 return unchecked_relocation_info()->GetDataStartAddress();
4143}
4144
4145
4146int Code::relocation_size() {
4147 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004148}
4149
4150
4151byte* Code::entry() {
4152 return instruction_start();
4153}
4154
4155
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004156bool Code::contains(byte* inner_pointer) {
4157 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004158}
4159
4160
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004161ACCESSORS(JSArray, length, Object, kLengthOffset)
4162
4163
ager@chromium.org236ad962008-09-25 09:45:57 +00004164ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004165
4166
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004167JSRegExp::Type JSRegExp::TypeTag() {
4168 Object* data = this->data();
4169 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4170 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4171 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004172}
4173
4174
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004175JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4176 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4177 return static_cast<JSRegExp::Type>(smi->value());
4178}
4179
4180
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004181int JSRegExp::CaptureCount() {
4182 switch (TypeTag()) {
4183 case ATOM:
4184 return 0;
4185 case IRREGEXP:
4186 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4187 default:
4188 UNREACHABLE();
4189 return -1;
4190 }
4191}
4192
4193
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004194JSRegExp::Flags JSRegExp::GetFlags() {
4195 ASSERT(this->data()->IsFixedArray());
4196 Object* data = this->data();
4197 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4198 return Flags(smi->value());
4199}
4200
4201
4202String* JSRegExp::Pattern() {
4203 ASSERT(this->data()->IsFixedArray());
4204 Object* data = this->data();
4205 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4206 return pattern;
4207}
4208
4209
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004210Object* JSRegExp::DataAt(int index) {
4211 ASSERT(TypeTag() != NOT_COMPILED);
4212 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004213}
4214
4215
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004216Object* JSRegExp::DataAtUnchecked(int index) {
4217 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4218 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4219 return READ_FIELD(fa, offset);
4220}
4221
4222
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004223void JSRegExp::SetDataAt(int index, Object* value) {
4224 ASSERT(TypeTag() != NOT_COMPILED);
4225 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4226 FixedArray::cast(data())->set(index, value);
4227}
4228
4229
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004230void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4231 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4232 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4233 if (value->IsSmi()) {
4234 fa->set_unchecked(index, Smi::cast(value));
4235 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004236 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004237 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4238 }
4239}
4240
4241
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004242ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004243 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004244#if DEBUG
4245 FixedArrayBase* fixed_array =
4246 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4247 Map* map = fixed_array->map();
4248 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004249 (map == GetHeap()->fixed_array_map() ||
4250 map == GetHeap()->fixed_cow_array_map())) ||
4251 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004252 (fixed_array->IsFixedDoubleArray() ||
4253 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004254 (kind == DICTIONARY_ELEMENTS &&
4255 fixed_array->IsFixedArray() &&
4256 fixed_array->IsDictionary()) ||
4257 (kind > DICTIONARY_ELEMENTS));
4258 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4259 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004260#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004261 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004262}
4263
4264
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004265ElementsAccessor* JSObject::GetElementsAccessor() {
4266 return ElementsAccessor::ForKind(GetElementsKind());
4267}
4268
4269
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004270bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004271 return GetElementsKind() == FAST_ELEMENTS;
4272}
4273
4274
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004275bool JSObject::HasFastSmiOnlyElements() {
4276 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4277}
4278
4279
4280bool JSObject::HasFastTypeElements() {
4281 ElementsKind elements_kind = GetElementsKind();
4282 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4283 elements_kind == FAST_ELEMENTS;
4284}
4285
4286
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004287bool JSObject::HasFastDoubleElements() {
4288 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4289}
4290
4291
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004292bool JSObject::HasDictionaryElements() {
4293 return GetElementsKind() == DICTIONARY_ELEMENTS;
4294}
4295
4296
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004297bool JSObject::HasNonStrictArgumentsElements() {
4298 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4299}
4300
4301
ager@chromium.org3811b432009-10-28 14:53:37 +00004302bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004303 HeapObject* array = elements();
4304 ASSERT(array != NULL);
4305 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004306}
4307
4308
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004309#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4310bool JSObject::HasExternal##name##Elements() { \
4311 HeapObject* array = elements(); \
4312 ASSERT(array != NULL); \
4313 if (!array->IsHeapObject()) \
4314 return false; \
4315 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004316}
4317
4318
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004319EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4320EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4321EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4322EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4323 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4324EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4325EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4326 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4327EXTERNAL_ELEMENTS_CHECK(Float,
4328 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004329EXTERNAL_ELEMENTS_CHECK(Double,
4330 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004331EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004332
4333
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004334bool JSObject::HasNamedInterceptor() {
4335 return map()->has_named_interceptor();
4336}
4337
4338
4339bool JSObject::HasIndexedInterceptor() {
4340 return map()->has_indexed_interceptor();
4341}
4342
4343
lrn@chromium.org303ada72010-10-27 09:33:13 +00004344MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004345 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004346 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004347 Isolate* isolate = GetIsolate();
4348 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004349 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004350 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4351 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004352 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4353 return maybe_writable_elems;
4354 }
4355 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004356 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004357 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004358 return writable_elems;
4359}
4360
4361
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004362StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004363 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004364 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004365}
4366
4367
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004368SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004369 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004370 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004371}
4372
4373
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004374bool String::IsHashFieldComputed(uint32_t field) {
4375 return (field & kHashNotComputedMask) == 0;
4376}
4377
4378
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004379bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004380 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004381}
4382
4383
4384uint32_t String::Hash() {
4385 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004386 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004387 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004388 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004389 return ComputeAndSetHash();
4390}
4391
4392
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004393StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004394 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004395 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004396 array_index_(0),
4397 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4398 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004399 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004400 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004401}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004402
4403
4404bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004405 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004406}
4407
4408
4409void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004410 // Use the Jenkins one-at-a-time hash function to update the hash
4411 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004412 raw_running_hash_ += c;
4413 raw_running_hash_ += (raw_running_hash_ << 10);
4414 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004415 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004416 if (is_array_index_) {
4417 if (c < '0' || c > '9') {
4418 is_array_index_ = false;
4419 } else {
4420 int d = c - '0';
4421 if (is_first_char_) {
4422 is_first_char_ = false;
4423 if (c == '0' && length_ > 1) {
4424 is_array_index_ = false;
4425 return;
4426 }
4427 }
4428 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4429 is_array_index_ = false;
4430 } else {
4431 array_index_ = array_index_ * 10 + d;
4432 }
4433 }
4434 }
4435}
4436
4437
4438void StringHasher::AddCharacterNoIndex(uc32 c) {
4439 ASSERT(!is_array_index());
4440 raw_running_hash_ += c;
4441 raw_running_hash_ += (raw_running_hash_ << 10);
4442 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4443}
4444
4445
4446uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004447 // Get the calculated raw hash value and do some more bit ops to distribute
4448 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004449 uint32_t result = raw_running_hash_;
4450 result += (result << 3);
4451 result ^= (result >> 11);
4452 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004453 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004454 result = 27;
4455 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004456 return result;
4457}
4458
4459
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004460template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004461uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4462 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004463 if (!hasher.has_trivial_hash()) {
4464 int i;
4465 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4466 hasher.AddCharacter(chars[i]);
4467 }
4468 for (; i < length; i++) {
4469 hasher.AddCharacterNoIndex(chars[i]);
4470 }
4471 }
4472 return hasher.GetHashField();
4473}
4474
4475
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004476bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004477 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004478 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4479 return false;
4480 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004481 return SlowAsArrayIndex(index);
4482}
4483
4484
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004485Object* JSReceiver::GetPrototype() {
4486 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004487}
4488
4489
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004490bool JSReceiver::HasProperty(String* name) {
4491 if (IsJSProxy()) {
4492 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4493 }
4494 return GetPropertyAttribute(name) != ABSENT;
4495}
4496
4497
4498bool JSReceiver::HasLocalProperty(String* name) {
4499 if (IsJSProxy()) {
4500 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4501 }
4502 return GetLocalPropertyAttribute(name) != ABSENT;
4503}
4504
4505
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004506PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004507 return GetPropertyAttributeWithReceiver(this, key);
4508}
4509
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004510// TODO(504): this may be useful in other places too where JSGlobalProxy
4511// is used.
4512Object* JSObject::BypassGlobalProxy() {
4513 if (IsJSGlobalProxy()) {
4514 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004515 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004516 ASSERT(proto->IsJSGlobalObject());
4517 return proto;
4518 }
4519 return this;
4520}
4521
4522
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004523MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4524 return IsJSProxy()
4525 ? JSProxy::cast(this)->GetIdentityHash(flag)
4526 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004527}
4528
4529
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004530bool JSReceiver::HasElement(uint32_t index) {
4531 if (IsJSProxy()) {
4532 return JSProxy::cast(this)->HasElementWithHandler(index);
4533 }
4534 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004535}
4536
4537
4538bool AccessorInfo::all_can_read() {
4539 return BooleanBit::get(flag(), kAllCanReadBit);
4540}
4541
4542
4543void AccessorInfo::set_all_can_read(bool value) {
4544 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4545}
4546
4547
4548bool AccessorInfo::all_can_write() {
4549 return BooleanBit::get(flag(), kAllCanWriteBit);
4550}
4551
4552
4553void AccessorInfo::set_all_can_write(bool value) {
4554 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4555}
4556
4557
ager@chromium.org870a0b62008-11-04 11:43:05 +00004558bool AccessorInfo::prohibits_overwriting() {
4559 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4560}
4561
4562
4563void AccessorInfo::set_prohibits_overwriting(bool value) {
4564 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4565}
4566
4567
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004568PropertyAttributes AccessorInfo::property_attributes() {
4569 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4570}
4571
4572
4573void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004574 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004575}
4576
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004577
4578template<typename Shape, typename Key>
4579void Dictionary<Shape, Key>::SetEntry(int entry,
4580 Object* key,
4581 Object* value) {
4582 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4583}
4584
4585
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004586template<typename Shape, typename Key>
4587void Dictionary<Shape, Key>::SetEntry(int entry,
4588 Object* key,
4589 Object* value,
4590 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004591 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004592 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004593 AssertNoAllocation no_gc;
4594 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004595 FixedArray::set(index, key, mode);
4596 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004597 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004598}
4599
4600
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004601bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4602 ASSERT(other->IsNumber());
4603 return key == static_cast<uint32_t>(other->Number());
4604}
4605
4606
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004607uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4608 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004609}
4610
4611
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004612uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4613 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004614 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004615 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004616}
4617
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004618uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4619 return ComputeIntegerHash(key, seed);
4620}
4621
4622uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4623 uint32_t seed,
4624 Object* other) {
4625 ASSERT(other->IsNumber());
4626 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4627}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004628
4629MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4630 return Isolate::Current()->heap()->NumberFromUint32(key);
4631}
4632
4633
4634bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4635 // We know that all entries in a hash table had their hash keys created.
4636 // Use that knowledge to have fast failure.
4637 if (key->Hash() != String::cast(other)->Hash()) return false;
4638 return key->Equals(String::cast(other));
4639}
4640
4641
4642uint32_t StringDictionaryShape::Hash(String* key) {
4643 return key->Hash();
4644}
4645
4646
4647uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4648 return String::cast(other)->Hash();
4649}
4650
4651
4652MaybeObject* StringDictionaryShape::AsObject(String* key) {
4653 return key;
4654}
4655
4656
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004657template <int entrysize>
4658bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4659 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004660}
4661
4662
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004663template <int entrysize>
4664uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004665 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4666 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004667}
4668
4669
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004670template <int entrysize>
4671uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4672 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004673 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4674 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004675}
4676
4677
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004678template <int entrysize>
4679MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004680 return key;
4681}
4682
4683
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004684void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004685 // No write barrier is needed since empty_fixed_array is not in new space.
4686 // Please note this function is used during marking:
4687 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004688 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4689 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004690}
4691
4692
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004693void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004694 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004695 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004696 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4697 if (elts->length() < required_size) {
4698 // Doubling in size would be overkill, but leave some slack to avoid
4699 // constantly growing.
4700 Expand(required_size + (required_size >> 3));
4701 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004702 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004703 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4704 // Expand will allocate a new backing store in new space even if the size
4705 // we asked for isn't larger than what we had before.
4706 Expand(required_size);
4707 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004708}
4709
4710
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004711void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004712 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004713 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4714}
4715
4716
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004717bool JSArray::AllowsSetElementsLength() {
4718 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4719 ASSERT(result == !HasExternalArrayElements());
4720 return result;
4721}
4722
4723
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004724MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4725 MaybeObject* maybe_result = EnsureCanContainElements(
4726 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4727 if (maybe_result->IsFailure()) return maybe_result;
4728 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4729 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4730 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4731 ((GetElementsKind() == FAST_ELEMENTS) ||
4732 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4733 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004734 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004735 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004736 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004737}
4738
4739
lrn@chromium.org303ada72010-10-27 09:33:13 +00004740MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004741 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004742 return GetHeap()->CopyFixedArray(this);
4743}
4744
4745
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004746MaybeObject* FixedDoubleArray::Copy() {
4747 if (length() == 0) return this;
4748 return GetHeap()->CopyFixedDoubleArray(this);
4749}
4750
4751
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004752void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4753 set(1 + index * 2, id);
4754}
4755
4756
4757Smi* TypeFeedbackCells::AstId(int index) {
4758 return Smi::cast(get(1 + index * 2));
4759}
4760
4761
4762void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4763 set(index * 2, cell);
4764}
4765
4766
4767JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4768 return JSGlobalPropertyCell::cast(get(index * 2));
4769}
4770
4771
4772Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4773 return isolate->factory()->the_hole_value();
4774}
4775
4776
4777Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4778 return isolate->factory()->undefined_value();
4779}
4780
4781
4782Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4783 return heap->raw_unchecked_the_hole_value();
4784}
4785
4786
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004787Relocatable::Relocatable(Isolate* isolate) {
4788 ASSERT(isolate == Isolate::Current());
4789 isolate_ = isolate;
4790 prev_ = isolate->relocatable_top();
4791 isolate->set_relocatable_top(this);
4792}
4793
4794
4795Relocatable::~Relocatable() {
4796 ASSERT(isolate_ == Isolate::Current());
4797 ASSERT_EQ(isolate_->relocatable_top(), this);
4798 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004799}
4800
4801
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004802int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4803 return map->instance_size();
4804}
4805
4806
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004807void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004808 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004809 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004810}
4811
4812
4813template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004814void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004815 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004816 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004817}
4818
4819
4820void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4821 typedef v8::String::ExternalAsciiStringResource Resource;
4822 v->VisitExternalAsciiString(
4823 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4824}
4825
4826
4827template<typename StaticVisitor>
4828void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4829 typedef v8::String::ExternalAsciiStringResource Resource;
4830 StaticVisitor::VisitExternalAsciiString(
4831 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4832}
4833
4834
4835void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4836 typedef v8::String::ExternalStringResource Resource;
4837 v->VisitExternalTwoByteString(
4838 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4839}
4840
4841
4842template<typename StaticVisitor>
4843void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4844 typedef v8::String::ExternalStringResource Resource;
4845 StaticVisitor::VisitExternalTwoByteString(
4846 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4847}
4848
4849#define SLOT_ADDR(obj, offset) \
4850 reinterpret_cast<Object**>((obj)->address() + offset)
4851
4852template<int start_offset, int end_offset, int size>
4853void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4854 HeapObject* obj,
4855 ObjectVisitor* v) {
4856 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4857}
4858
4859
4860template<int start_offset>
4861void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4862 int object_size,
4863 ObjectVisitor* v) {
4864 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4865}
4866
4867#undef SLOT_ADDR
4868
4869
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004870#undef CAST_ACCESSOR
4871#undef INT_ACCESSORS
4872#undef SMI_ACCESSORS
4873#undef ACCESSORS
4874#undef FIELD_ADDR
4875#undef READ_FIELD
4876#undef WRITE_FIELD
4877#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004878#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004879#undef READ_MEMADDR_FIELD
4880#undef WRITE_MEMADDR_FIELD
4881#undef READ_DOUBLE_FIELD
4882#undef WRITE_DOUBLE_FIELD
4883#undef READ_INT_FIELD
4884#undef WRITE_INT_FIELD
4885#undef READ_SHORT_FIELD
4886#undef WRITE_SHORT_FIELD
4887#undef READ_BYTE_FIELD
4888#undef WRITE_BYTE_FIELD
4889
4890
4891} } // namespace v8::internal
4892
4893#endif // V8_OBJECTS_INL_H_