blob: 39d6e0413f7530372faccd7da8562ae2feb35c27 [file] [log] [blame]
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001// Copyright 2011 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"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
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
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000557bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000558 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000559 Map* map = HeapObject::cast(this)->map();
560 Heap* heap = map->GetHeap();
561 return (map == heap->function_context_map() ||
562 map == heap->catch_context_map() ||
563 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000564 map == heap->global_context_map() ||
565 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000566 }
567 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000568}
569
570
571bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000572 return Object::IsHeapObject() &&
573 HeapObject::cast(this)->map() ==
574 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000575}
576
577
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000578bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000579 return Object::IsHeapObject() &&
580 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000581 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000582}
583
584
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000585TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000586
587
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000588template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000589 return obj->IsJSFunction();
590}
591
592
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000593TYPE_CHECKER(Code, CODE_TYPE)
594TYPE_CHECKER(Oddball, ODDBALL_TYPE)
595TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
596TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
597TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
598TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000599
600
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000601bool Object::IsStringWrapper() {
602 return IsJSValue() && JSValue::cast(this)->value()->IsString();
603}
604
605
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000606TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000607
608
609bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000610 return IsOddball() &&
611 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000612}
613
614
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000615TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
616TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000617
618
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000619template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620 return obj->IsJSArray();
621}
622
623
624bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000625 return Object::IsHeapObject() &&
626 HeapObject::cast(this)->map() ==
627 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000628}
629
630
631bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000632 return IsHashTable() &&
633 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000634}
635
636
637bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000638 return IsHashTable() && this ==
639 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000640}
641
642
ager@chromium.orgac091b72010-05-05 07:34:42 +0000643bool Object::IsJSFunctionResultCache() {
644 if (!IsFixedArray()) return false;
645 FixedArray* self = FixedArray::cast(this);
646 int length = self->length();
647 if (length < JSFunctionResultCache::kEntriesIndex) return false;
648 if ((length - JSFunctionResultCache::kEntriesIndex)
649 % JSFunctionResultCache::kEntrySize != 0) {
650 return false;
651 }
652#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000653 if (FLAG_verify_heap) {
654 reinterpret_cast<JSFunctionResultCache*>(this)->
655 JSFunctionResultCacheVerify();
656 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000657#endif
658 return true;
659}
660
661
ricow@chromium.org65fae842010-08-25 15:26:24 +0000662bool Object::IsNormalizedMapCache() {
663 if (!IsFixedArray()) return false;
664 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
665 return false;
666 }
667#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000668 if (FLAG_verify_heap) {
669 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
670 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000671#endif
672 return true;
673}
674
675
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000676bool Object::IsCompilationCacheTable() {
677 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000678}
679
680
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000681bool Object::IsCodeCacheHashTable() {
682 return IsHashTable();
683}
684
685
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000686bool Object::IsPolymorphicCodeCacheHashTable() {
687 return IsHashTable();
688}
689
690
ager@chromium.org236ad962008-09-25 09:45:57 +0000691bool Object::IsMapCache() {
692 return IsHashTable();
693}
694
695
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000696bool Object::IsPrimitive() {
697 return IsOddball() || IsNumber() || IsString();
698}
699
700
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000701bool Object::IsJSGlobalProxy() {
702 bool result = IsHeapObject() &&
703 (HeapObject::cast(this)->map()->instance_type() ==
704 JS_GLOBAL_PROXY_TYPE);
705 ASSERT(!result || IsAccessCheckNeeded());
706 return result;
707}
708
709
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000710bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000711 if (!IsHeapObject()) return false;
712
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000713 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000714 return type == JS_GLOBAL_OBJECT_TYPE ||
715 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000716}
717
718
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000719TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
720TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000721
722
723bool Object::IsUndetectableObject() {
724 return IsHeapObject()
725 && HeapObject::cast(this)->map()->is_undetectable();
726}
727
728
729bool Object::IsAccessCheckNeeded() {
730 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000731 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000732}
733
734
735bool Object::IsStruct() {
736 if (!IsHeapObject()) return false;
737 switch (HeapObject::cast(this)->map()->instance_type()) {
738#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
739 STRUCT_LIST(MAKE_STRUCT_CASE)
740#undef MAKE_STRUCT_CASE
741 default: return false;
742 }
743}
744
745
746#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
747 bool Object::Is##Name() { \
748 return Object::IsHeapObject() \
749 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
750 }
751 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
752#undef MAKE_STRUCT_PREDICATE
753
754
755bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000756 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000757}
758
759
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000760bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000761 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
762}
763
764
765bool Object::IsTheHole() {
766 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000767}
768
769
770bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000771 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000772}
773
774
775bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000776 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777}
778
779
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000780bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000781 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000782}
783
784
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000785double Object::Number() {
786 ASSERT(IsNumber());
787 return IsSmi()
788 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
789 : reinterpret_cast<HeapNumber*>(this)->value();
790}
791
792
lrn@chromium.org303ada72010-10-27 09:33:13 +0000793MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000794 if (IsSmi()) return this;
795 if (IsHeapNumber()) {
796 double value = HeapNumber::cast(this)->value();
797 int int_value = FastD2I(value);
798 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
799 return Smi::FromInt(int_value);
800 }
801 }
802 return Failure::Exception();
803}
804
805
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000806bool Object::HasSpecificClassOf(String* name) {
807 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
808}
809
810
lrn@chromium.org303ada72010-10-27 09:33:13 +0000811MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000812 // GetElement can trigger a getter which can cause allocation.
813 // This was not always the case. This ASSERT is here to catch
814 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000815 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000816 return GetElementWithReceiver(this, index);
817}
818
819
lrn@chromium.org303ada72010-10-27 09:33:13 +0000820Object* Object::GetElementNoExceptionThrown(uint32_t index) {
821 MaybeObject* maybe = GetElementWithReceiver(this, index);
822 ASSERT(!maybe->IsFailure());
823 Object* result = NULL; // Initialization to please compiler.
824 maybe->ToObject(&result);
825 return result;
826}
827
828
829MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000830 PropertyAttributes attributes;
831 return GetPropertyWithReceiver(this, key, &attributes);
832}
833
834
lrn@chromium.org303ada72010-10-27 09:33:13 +0000835MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000836 return GetPropertyWithReceiver(this, key, attributes);
837}
838
839
840#define FIELD_ADDR(p, offset) \
841 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
842
843#define READ_FIELD(p, offset) \
844 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
845
846#define WRITE_FIELD(p, offset, value) \
847 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
848
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000849#define WRITE_BARRIER(heap, object, offset, value) \
850 heap->incremental_marking()->RecordWrite( \
851 object, HeapObject::RawField(object, offset), value); \
852 if (heap->InNewSpace(value)) { \
853 heap->RecordWrite(object->address(), offset); \
854 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000855
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000856#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
857 if (mode == UPDATE_WRITE_BARRIER) { \
858 heap->incremental_marking()->RecordWrite( \
859 object, HeapObject::RawField(object, offset), value); \
860 if (heap->InNewSpace(value)) { \
861 heap->RecordWrite(object->address(), offset); \
862 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000863 }
864
lrn@chromium.org7516f052011-03-30 08:52:27 +0000865#ifndef V8_TARGET_ARCH_MIPS
866 #define READ_DOUBLE_FIELD(p, offset) \
867 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
868#else // V8_TARGET_ARCH_MIPS
869 // Prevent gcc from using load-double (mips ldc1) on (possibly)
870 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000871 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000872 union conversion {
873 double d;
874 uint32_t u[2];
875 } c;
876 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
877 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
878 return c.d;
879 }
880 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
881#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000882
lrn@chromium.org7516f052011-03-30 08:52:27 +0000883#ifndef V8_TARGET_ARCH_MIPS
884 #define WRITE_DOUBLE_FIELD(p, offset, value) \
885 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
886#else // V8_TARGET_ARCH_MIPS
887 // Prevent gcc from using store-double (mips sdc1) on (possibly)
888 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000889 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000890 double value) {
891 union conversion {
892 double d;
893 uint32_t u[2];
894 } c;
895 c.d = value;
896 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
897 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
898 }
899 #define WRITE_DOUBLE_FIELD(p, offset, value) \
900 write_double_field(p, offset, value)
901#endif // V8_TARGET_ARCH_MIPS
902
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000903
904#define READ_INT_FIELD(p, offset) \
905 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
906
907#define WRITE_INT_FIELD(p, offset, value) \
908 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
909
ager@chromium.org3e875802009-06-29 08:26:34 +0000910#define READ_INTPTR_FIELD(p, offset) \
911 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
912
913#define WRITE_INTPTR_FIELD(p, offset, value) \
914 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
915
ager@chromium.org7c537e22008-10-16 08:43:32 +0000916#define READ_UINT32_FIELD(p, offset) \
917 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
918
919#define WRITE_UINT32_FIELD(p, offset, value) \
920 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000922#define READ_SHORT_FIELD(p, offset) \
923 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
924
925#define WRITE_SHORT_FIELD(p, offset, value) \
926 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
927
928#define READ_BYTE_FIELD(p, offset) \
929 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
930
931#define WRITE_BYTE_FIELD(p, offset, value) \
932 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
933
934
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000935Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
936 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000937}
938
939
940int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000941 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000942}
943
944
945Smi* Smi::FromInt(int value) {
946 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000947 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000948 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000949 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000950 return reinterpret_cast<Smi*>(tagged_value);
951}
952
953
954Smi* Smi::FromIntptr(intptr_t value) {
955 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000956 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
957 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958}
959
960
961Failure::Type Failure::type() const {
962 return static_cast<Type>(value() & kFailureTypeTagMask);
963}
964
965
966bool Failure::IsInternalError() const {
967 return type() == INTERNAL_ERROR;
968}
969
970
971bool Failure::IsOutOfMemoryException() const {
972 return type() == OUT_OF_MEMORY_EXCEPTION;
973}
974
975
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000976AllocationSpace Failure::allocation_space() const {
977 ASSERT_EQ(RETRY_AFTER_GC, type());
978 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
979 & kSpaceTagMask);
980}
981
982
983Failure* Failure::InternalError() {
984 return Construct(INTERNAL_ERROR);
985}
986
987
988Failure* Failure::Exception() {
989 return Construct(EXCEPTION);
990}
991
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000992
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000993Failure* Failure::OutOfMemoryException() {
994 return Construct(OUT_OF_MEMORY_EXCEPTION);
995}
996
997
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000998intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000999 return static_cast<intptr_t>(
1000 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001001}
1002
1003
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001004Failure* Failure::RetryAfterGC() {
1005 return RetryAfterGC(NEW_SPACE);
1006}
1007
1008
1009Failure* Failure::RetryAfterGC(AllocationSpace space) {
1010 ASSERT((space & ~kSpaceTagMask) == 0);
1011 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001012}
1013
1014
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001015Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001016 uintptr_t info =
1017 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001018 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001019 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020}
1021
1022
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001023bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001024#ifdef DEBUG
1025 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1026#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001027
1028#ifdef V8_TARGET_ARCH_X64
1029 // To be representable as a long smi, the value must be a 32-bit integer.
1030 bool result = (value == static_cast<int32_t>(value));
1031#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001032 // To be representable as an tagged small integer, the two
1033 // most-significant bits of 'value' must be either 00 or 11 due to
1034 // sign-extension. To check this we add 01 to the two
1035 // most-significant bits, and check if the most-significant bit is 0
1036 //
1037 // CAUTION: The original code below:
1038 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1039 // may lead to incorrect results according to the C language spec, and
1040 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1041 // compiler may produce undefined results in case of signed integer
1042 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001043 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001044#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001045 ASSERT(result == in_range);
1046 return result;
1047}
1048
1049
kasper.lund7276f142008-07-30 08:49:36 +00001050MapWord MapWord::FromMap(Map* map) {
1051 return MapWord(reinterpret_cast<uintptr_t>(map));
1052}
1053
1054
1055Map* MapWord::ToMap() {
1056 return reinterpret_cast<Map*>(value_);
1057}
1058
1059
1060bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001061 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001062}
1063
1064
1065MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001066 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1067 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001068}
1069
1070
1071HeapObject* MapWord::ToForwardingAddress() {
1072 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001073 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001074}
1075
1076
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001077#ifdef DEBUG
1078void HeapObject::VerifyObjectField(int offset) {
1079 VerifyPointer(READ_FIELD(this, offset));
1080}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001081
1082void HeapObject::VerifySmiField(int offset) {
1083 ASSERT(READ_FIELD(this, offset)->IsSmi());
1084}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001085#endif
1086
1087
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001088Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001089 Heap* heap =
1090 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1091 ASSERT(heap != NULL);
1092 ASSERT(heap->isolate() == Isolate::Current());
1093 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001094}
1095
1096
1097Isolate* HeapObject::GetIsolate() {
1098 return GetHeap()->isolate();
1099}
1100
1101
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001102Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001103 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001104}
1105
1106
1107void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001108 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001109 if (value != NULL) {
1110 // TODO(1600) We are passing NULL as a slot because maps can never be on
1111 // evacuation candidate.
1112 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1113 }
1114}
1115
1116
1117// Unsafe accessor omitting write barrier.
1118void HeapObject::set_map_unsafe(Map* value) {
1119 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001120}
1121
1122
kasper.lund7276f142008-07-30 08:49:36 +00001123MapWord HeapObject::map_word() {
1124 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1125}
1126
1127
1128void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001129 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001130 // here.
1131 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1132}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001133
1134
1135HeapObject* HeapObject::FromAddress(Address address) {
1136 ASSERT_TAG_ALIGNED(address);
1137 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1138}
1139
1140
1141Address HeapObject::address() {
1142 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1143}
1144
1145
1146int HeapObject::Size() {
1147 return SizeFromMap(map());
1148}
1149
1150
1151void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1152 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1153 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1154}
1155
1156
1157void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1158 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1159}
1160
1161
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001162double HeapNumber::value() {
1163 return READ_DOUBLE_FIELD(this, kValueOffset);
1164}
1165
1166
1167void HeapNumber::set_value(double value) {
1168 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1169}
1170
1171
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001172int HeapNumber::get_exponent() {
1173 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1174 kExponentShift) - kExponentBias;
1175}
1176
1177
1178int HeapNumber::get_sign() {
1179 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1180}
1181
1182
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001183ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001184
1185
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001186FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001187 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001188 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001189}
1190
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001191void JSObject::ValidateSmiOnlyElements() {
1192#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001193 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001194 Heap* heap = GetHeap();
1195 // Don't use elements, since integrity checks will fail if there
1196 // are filler pointers in the array.
1197 FixedArray* fixed_array =
1198 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1199 Map* map = fixed_array->map();
1200 // Arrays that have been shifted in place can't be verified.
1201 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1202 map != heap->raw_unchecked_two_pointer_filler_map() &&
1203 map != heap->free_space_map()) {
1204 for (int i = 0; i < fixed_array->length(); i++) {
1205 Object* current = fixed_array->get(i);
1206 ASSERT(current->IsSmi() || current == heap->the_hole_value());
1207 }
1208 }
1209 }
1210#endif
1211}
1212
1213
1214MaybeObject* JSObject::EnsureCanContainNonSmiElements() {
1215#if DEBUG
1216 ValidateSmiOnlyElements();
1217#endif
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001218 if ((map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001219 Object* obj;
1220 MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS);
1221 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1222 set_map(Map::cast(obj));
1223 }
1224 return this;
1225}
1226
1227
1228MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
1229 uint32_t count) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001230 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001231 for (uint32_t i = 0; i < count; ++i) {
1232 Object* current = *objects++;
1233 if (!current->IsSmi() && current != GetHeap()->the_hole_value()) {
1234 return EnsureCanContainNonSmiElements();
1235 }
1236 }
1237 }
1238 return this;
1239}
1240
1241
1242MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001243 Object** objects = reinterpret_cast<Object**>(
1244 FIELD_ADDR(elements, elements->OffsetOfElementAt(0)));
1245 return EnsureCanContainElements(objects, elements->length());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001246}
1247
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001248
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001249void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001250 ASSERT((map()->has_fast_elements() ||
1251 map()->has_fast_smi_only_elements()) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001252 (value->map() == GetHeap()->fixed_array_map() ||
1253 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001254 ASSERT(map()->has_fast_double_elements() ==
1255 value->IsFixedDoubleArray());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001256 ASSERT(value->HasValidElements());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001257#ifdef DEBUG
1258 ValidateSmiOnlyElements();
1259#endif
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001260 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001261 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001262}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001263
1264
1265void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001266 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1267 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001268}
1269
1270
1271void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001272 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001273 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1274 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001275}
1276
1277
lrn@chromium.org303ada72010-10-27 09:33:13 +00001278MaybeObject* JSObject::ResetElements() {
1279 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001280 ElementsKind elements_kind = FLAG_smi_only_arrays
1281 ? FAST_SMI_ONLY_ELEMENTS
1282 : FAST_ELEMENTS;
1283 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind);
1284 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001285 set_map(Map::cast(obj));
1286 initialize_elements();
1287 return this;
1288}
1289
1290
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001291ACCESSORS(Oddball, to_string, String, kToStringOffset)
1292ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1293
1294
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001295byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001296 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001297}
1298
1299
1300void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001301 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001302}
1303
1304
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001305Object* JSGlobalPropertyCell::value() {
1306 return READ_FIELD(this, kValueOffset);
1307}
1308
1309
1310void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1311 // The write barrier is not used for global property cells.
1312 ASSERT(!val->IsJSGlobalPropertyCell());
1313 WRITE_FIELD(this, kValueOffset, val);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001314 GetHeap()->incremental_marking()->RecordWrite(
1315 this, HeapObject::RawField(this, kValueOffset), val);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001316}
1317
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001318
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001319int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001320 InstanceType type = map()->instance_type();
1321 // Check for the most common kind of JavaScript object before
1322 // falling into the generic switch. This speeds up the internal
1323 // field operations considerably on average.
1324 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1325 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001326 case JS_GLOBAL_PROXY_TYPE:
1327 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001328 case JS_GLOBAL_OBJECT_TYPE:
1329 return JSGlobalObject::kSize;
1330 case JS_BUILTINS_OBJECT_TYPE:
1331 return JSBuiltinsObject::kSize;
1332 case JS_FUNCTION_TYPE:
1333 return JSFunction::kSize;
1334 case JS_VALUE_TYPE:
1335 return JSValue::kSize;
1336 case JS_ARRAY_TYPE:
1337 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001338 case JS_WEAK_MAP_TYPE:
1339 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001340 case JS_REGEXP_TYPE:
1341 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001342 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001343 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001344 case JS_MESSAGE_OBJECT_TYPE:
1345 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001346 default:
1347 UNREACHABLE();
1348 return 0;
1349 }
1350}
1351
1352
1353int JSObject::GetInternalFieldCount() {
1354 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001355 // Make sure to adjust for the number of in-object properties. These
1356 // properties do contribute to the size, but are not internal fields.
1357 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1358 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001359}
1360
1361
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001362int JSObject::GetInternalFieldOffset(int index) {
1363 ASSERT(index < GetInternalFieldCount() && index >= 0);
1364 return GetHeaderSize() + (kPointerSize * index);
1365}
1366
1367
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001368Object* JSObject::GetInternalField(int index) {
1369 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001370 // Internal objects do follow immediately after the header, whereas in-object
1371 // properties are at the end of the object. Therefore there is no need
1372 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001373 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1374}
1375
1376
1377void JSObject::SetInternalField(int index, Object* value) {
1378 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001379 // Internal objects do follow immediately after the header, whereas in-object
1380 // properties are at the end of the object. Therefore there is no need
1381 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001382 int offset = GetHeaderSize() + (kPointerSize * index);
1383 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001384 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001385}
1386
1387
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001388void JSObject::SetInternalField(int index, Smi* value) {
1389 ASSERT(index < GetInternalFieldCount() && index >= 0);
1390 // Internal objects do follow immediately after the header, whereas in-object
1391 // properties are at the end of the object. Therefore there is no need
1392 // to adjust the index here.
1393 int offset = GetHeaderSize() + (kPointerSize * index);
1394 WRITE_FIELD(this, offset, value);
1395}
1396
1397
ager@chromium.org7c537e22008-10-16 08:43:32 +00001398// Access fast-case object properties at index. The use of these routines
1399// is needed to correctly distinguish between properties stored in-object and
1400// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001401Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001402 // Adjust for the number of properties stored in the object.
1403 index -= map()->inobject_properties();
1404 if (index < 0) {
1405 int offset = map()->instance_size() + (index * kPointerSize);
1406 return READ_FIELD(this, offset);
1407 } else {
1408 ASSERT(index < properties()->length());
1409 return properties()->get(index);
1410 }
1411}
1412
1413
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001414Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001415 // Adjust for the number of properties stored in the object.
1416 index -= map()->inobject_properties();
1417 if (index < 0) {
1418 int offset = map()->instance_size() + (index * kPointerSize);
1419 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001420 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001421 } else {
1422 ASSERT(index < properties()->length());
1423 properties()->set(index, value);
1424 }
1425 return value;
1426}
1427
1428
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001429int JSObject::GetInObjectPropertyOffset(int index) {
1430 // Adjust for the number of properties stored in the object.
1431 index -= map()->inobject_properties();
1432 ASSERT(index < 0);
1433 return map()->instance_size() + (index * kPointerSize);
1434}
1435
1436
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001437Object* JSObject::InObjectPropertyAt(int index) {
1438 // Adjust for the number of properties stored in the object.
1439 index -= map()->inobject_properties();
1440 ASSERT(index < 0);
1441 int offset = map()->instance_size() + (index * kPointerSize);
1442 return READ_FIELD(this, offset);
1443}
1444
1445
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001446Object* JSObject::InObjectPropertyAtPut(int index,
1447 Object* value,
1448 WriteBarrierMode mode) {
1449 // Adjust for the number of properties stored in the object.
1450 index -= map()->inobject_properties();
1451 ASSERT(index < 0);
1452 int offset = map()->instance_size() + (index * kPointerSize);
1453 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001454 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001455 return value;
1456}
1457
1458
1459
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001460void JSObject::InitializeBody(Map* map,
1461 Object* pre_allocated_value,
1462 Object* filler_value) {
1463 ASSERT(!filler_value->IsHeapObject() ||
1464 !GetHeap()->InNewSpace(filler_value));
1465 ASSERT(!pre_allocated_value->IsHeapObject() ||
1466 !GetHeap()->InNewSpace(pre_allocated_value));
1467 int size = map->instance_size();
1468 int offset = kHeaderSize;
1469 if (filler_value != pre_allocated_value) {
1470 int pre_allocated = map->pre_allocated_property_fields();
1471 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1472 for (int i = 0; i < pre_allocated; i++) {
1473 WRITE_FIELD(this, offset, pre_allocated_value);
1474 offset += kPointerSize;
1475 }
1476 }
1477 while (offset < size) {
1478 WRITE_FIELD(this, offset, filler_value);
1479 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001480 }
1481}
1482
1483
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001484bool JSObject::HasFastProperties() {
1485 return !properties()->IsDictionary();
1486}
1487
1488
1489int JSObject::MaxFastProperties() {
1490 // Allow extra fast properties if the object has more than
1491 // kMaxFastProperties in-object properties. When this is the case,
1492 // it is very unlikely that the object is being used as a dictionary
1493 // and there is a good chance that allowing more map transitions
1494 // will be worth it.
1495 return Max(map()->inobject_properties(), kMaxFastProperties);
1496}
1497
1498
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001499void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001500 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001501 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001502 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001503 }
1504}
1505
1506
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001507bool Object::ToArrayIndex(uint32_t* index) {
1508 if (IsSmi()) {
1509 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001510 if (value < 0) return false;
1511 *index = value;
1512 return true;
1513 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001514 if (IsHeapNumber()) {
1515 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001516 uint32_t uint_value = static_cast<uint32_t>(value);
1517 if (value == static_cast<double>(uint_value)) {
1518 *index = uint_value;
1519 return true;
1520 }
1521 }
1522 return false;
1523}
1524
1525
1526bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1527 if (!this->IsJSValue()) return false;
1528
1529 JSValue* js_value = JSValue::cast(this);
1530 if (!js_value->value()->IsString()) return false;
1531
1532 String* str = String::cast(js_value->value());
1533 if (index >= (uint32_t)str->length()) return false;
1534
1535 return true;
1536}
1537
1538
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001539FixedArrayBase* FixedArrayBase::cast(Object* object) {
1540 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1541 return reinterpret_cast<FixedArrayBase*>(object);
1542}
1543
1544
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001545Object* FixedArray::get(int index) {
1546 ASSERT(index >= 0 && index < this->length());
1547 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1548}
1549
1550
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001551void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001552 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001553 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001554 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1555 int offset = kHeaderSize + index * kPointerSize;
1556 WRITE_FIELD(this, offset, value);
1557}
1558
1559
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001560void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001561 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001562 ASSERT(index >= 0 && index < this->length());
1563 int offset = kHeaderSize + index * kPointerSize;
1564 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001565 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001566}
1567
1568
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001569inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1570 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1571}
1572
1573
1574inline double FixedDoubleArray::hole_nan_as_double() {
1575 return BitCast<double, uint64_t>(kHoleNanInt64);
1576}
1577
1578
1579inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1580 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1581 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1582 return OS::nan_value();
1583}
1584
1585
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001586double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001587 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1588 map() != HEAP->fixed_array_map());
1589 ASSERT(index >= 0 && index < this->length());
1590 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1591 ASSERT(!is_the_hole_nan(result));
1592 return result;
1593}
1594
1595
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001596MaybeObject* FixedDoubleArray::get(int index) {
1597 if (is_the_hole(index)) {
1598 return GetHeap()->the_hole_value();
1599 } else {
1600 return GetHeap()->NumberFromDouble(get_scalar(index));
1601 }
1602}
1603
1604
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001605void FixedDoubleArray::set(int index, double value) {
1606 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1607 map() != HEAP->fixed_array_map());
1608 int offset = kHeaderSize + index * kDoubleSize;
1609 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1610 WRITE_DOUBLE_FIELD(this, offset, value);
1611}
1612
1613
1614void FixedDoubleArray::set_the_hole(int index) {
1615 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1616 map() != HEAP->fixed_array_map());
1617 int offset = kHeaderSize + index * kDoubleSize;
1618 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1619}
1620
1621
1622bool FixedDoubleArray::is_the_hole(int index) {
1623 int offset = kHeaderSize + index * kDoubleSize;
1624 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1625}
1626
1627
1628void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1629 int old_length = from->length();
1630 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001631 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1632 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1633 FIELD_ADDR(from, kHeaderSize),
1634 old_length * kDoubleSize);
1635 } else {
1636 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001637 if (from->is_the_hole(i)) {
1638 set_the_hole(i);
1639 } else {
1640 set(i, from->get_scalar(i));
1641 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001642 }
1643 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001644 int offset = kHeaderSize + old_length * kDoubleSize;
1645 for (int current = from->length(); current < length(); ++current) {
1646 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1647 offset += kDoubleSize;
1648 }
1649}
1650
1651
1652void FixedDoubleArray::Initialize(FixedArray* from) {
1653 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001654 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001655 for (int i = 0; i < old_length; i++) {
1656 Object* hole_or_object = from->get(i);
1657 if (hole_or_object->IsTheHole()) {
1658 set_the_hole(i);
1659 } else {
1660 set(i, hole_or_object->Number());
1661 }
1662 }
1663 int offset = kHeaderSize + old_length * kDoubleSize;
1664 for (int current = from->length(); current < length(); ++current) {
1665 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1666 offset += kDoubleSize;
1667 }
1668}
1669
1670
1671void FixedDoubleArray::Initialize(NumberDictionary* from) {
1672 int offset = kHeaderSize;
1673 for (int current = 0; current < length(); ++current) {
1674 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1675 offset += kDoubleSize;
1676 }
1677 for (int i = 0; i < from->Capacity(); i++) {
1678 Object* key = from->KeyAt(i);
1679 if (key->IsNumber()) {
1680 uint32_t entry = static_cast<uint32_t>(key->Number());
1681 set(entry, from->ValueAt(i)->Number());
1682 }
1683 }
1684}
1685
1686
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001687WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001688 Heap* heap = GetHeap();
1689 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1690 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001691 return UPDATE_WRITE_BARRIER;
1692}
1693
1694
1695void FixedArray::set(int index,
1696 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001697 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001698 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001699 ASSERT(index >= 0 && index < this->length());
1700 int offset = kHeaderSize + index * kPointerSize;
1701 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001702 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001703}
1704
1705
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001706void FixedArray::NoWriteBarrierSet(FixedArray* array,
1707 int index,
1708 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001709 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001710 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001711 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001712 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1713}
1714
1715
1716void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001717 ASSERT(map() != HEAP->fixed_cow_array_map());
1718 set_undefined(GetHeap(), index);
1719}
1720
1721
1722void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001723 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001724 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001725 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001726 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001727}
1728
1729
ager@chromium.org236ad962008-09-25 09:45:57 +00001730void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001731 set_null(GetHeap(), index);
1732}
1733
1734
1735void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001736 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001737 ASSERT(!heap->InNewSpace(heap->null_value()));
1738 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001739}
1740
1741
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001742void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001743 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001744 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001745 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1746 WRITE_FIELD(this,
1747 kHeaderSize + index * kPointerSize,
1748 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001749}
1750
1751
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001752void FixedArray::set_unchecked(int index, Smi* value) {
1753 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1754 int offset = kHeaderSize + index * kPointerSize;
1755 WRITE_FIELD(this, offset, value);
1756}
1757
1758
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001759void FixedArray::set_unchecked(Heap* heap,
1760 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001761 Object* value,
1762 WriteBarrierMode mode) {
1763 int offset = kHeaderSize + index * kPointerSize;
1764 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001765 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001766}
1767
1768
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001769void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001770 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001771 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1772 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001773}
1774
1775
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001776Object** FixedArray::data_start() {
1777 return HeapObject::RawField(this, kHeaderSize);
1778}
1779
1780
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001781bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001782 ASSERT(this->IsSmi() ||
1783 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001784 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001785 return this->IsSmi() || length() <= kFirstIndex;
1786}
1787
1788
1789int DescriptorArray::bit_field3_storage() {
1790 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1791 return Smi::cast(storage)->value();
1792}
1793
1794void DescriptorArray::set_bit_field3_storage(int value) {
1795 ASSERT(!IsEmpty());
1796 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001797}
1798
1799
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001800void DescriptorArray::NoWriteBarrierSwap(FixedArray* array,
1801 int first,
1802 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001803 Object* tmp = array->get(first);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001804 NoWriteBarrierSet(array, first, array->get(second));
1805 NoWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001806}
1807
1808
1809int DescriptorArray::Search(String* name) {
1810 SLOW_ASSERT(IsSortedNoDuplicates());
1811
1812 // Check for empty descriptor array.
1813 int nof = number_of_descriptors();
1814 if (nof == 0) return kNotFound;
1815
1816 // Fast case: do linear search for small arrays.
1817 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001818 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001819 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820 }
1821
1822 // Slow case: perform binary search.
1823 return BinarySearch(name, 0, nof - 1);
1824}
1825
1826
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001827int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001828 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001829 if (number == DescriptorLookupCache::kAbsent) {
1830 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001831 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001832 }
1833 return number;
1834}
1835
1836
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001837String* DescriptorArray::GetKey(int descriptor_number) {
1838 ASSERT(descriptor_number < number_of_descriptors());
1839 return String::cast(get(ToKeyIndex(descriptor_number)));
1840}
1841
1842
1843Object* DescriptorArray::GetValue(int descriptor_number) {
1844 ASSERT(descriptor_number < number_of_descriptors());
1845 return GetContentArray()->get(ToValueIndex(descriptor_number));
1846}
1847
1848
1849Smi* DescriptorArray::GetDetails(int descriptor_number) {
1850 ASSERT(descriptor_number < number_of_descriptors());
1851 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1852}
1853
1854
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001855PropertyType DescriptorArray::GetType(int descriptor_number) {
1856 ASSERT(descriptor_number < number_of_descriptors());
1857 return PropertyDetails(GetDetails(descriptor_number)).type();
1858}
1859
1860
1861int DescriptorArray::GetFieldIndex(int descriptor_number) {
1862 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1863}
1864
1865
1866JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1867 return JSFunction::cast(GetValue(descriptor_number));
1868}
1869
1870
1871Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1872 ASSERT(GetType(descriptor_number) == CALLBACKS);
1873 return GetValue(descriptor_number);
1874}
1875
1876
1877AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1878 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001879 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001880 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001881}
1882
1883
1884bool DescriptorArray::IsProperty(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001885 return IsRealProperty(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001886}
1887
1888
1889bool DescriptorArray::IsTransition(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001890 return IsTransitionType(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001891}
1892
1893
1894bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1895 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1896}
1897
1898
1899bool DescriptorArray::IsDontEnum(int descriptor_number) {
1900 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1901}
1902
1903
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001904void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1905 desc->Init(GetKey(descriptor_number),
1906 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001907 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001908}
1909
1910
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001911void DescriptorArray::Set(int descriptor_number,
1912 Descriptor* desc,
1913 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001914 // Range check.
1915 ASSERT(descriptor_number < number_of_descriptors());
1916
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001917 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001918 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1919 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001920
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001921 NoWriteBarrierSet(this,
1922 ToKeyIndex(descriptor_number),
1923 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001924 FixedArray* content_array = GetContentArray();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001925 NoWriteBarrierSet(content_array,
1926 ToValueIndex(descriptor_number),
1927 desc->GetValue());
1928 NoWriteBarrierSet(content_array,
1929 ToDetailsIndex(descriptor_number),
1930 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001931}
1932
1933
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001934void DescriptorArray::CopyFrom(int index,
1935 DescriptorArray* src,
1936 int src_index,
1937 const WhitenessWitness& witness) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001938 Descriptor desc;
1939 src->Get(src_index, &desc);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001940 Set(index, &desc, witness);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001941}
1942
1943
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001944void DescriptorArray::NoWriteBarrierSwapDescriptors(int first, int second) {
1945 NoWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001946 FixedArray* content_array = GetContentArray();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001947 NoWriteBarrierSwap(content_array,
1948 ToValueIndex(first),
1949 ToValueIndex(second));
1950 NoWriteBarrierSwap(content_array,
1951 ToDetailsIndex(first),
1952 ToDetailsIndex(second));
1953}
1954
1955
1956DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
1957 : marking_(array->GetHeap()->incremental_marking()) {
1958 marking_->EnterNoMarkingScope();
1959 if (array->number_of_descriptors() > 0) {
1960 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
1961 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
1962 }
1963}
1964
1965
1966DescriptorArray::WhitenessWitness::~WhitenessWitness() {
1967 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001968}
1969
1970
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001971template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001972int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
1973 const int kMinCapacity = 32;
1974 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
1975 if (capacity < kMinCapacity) {
1976 capacity = kMinCapacity; // Guarantee min capacity.
1977 }
1978 return capacity;
1979}
1980
1981
1982template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001983int HashTable<Shape, Key>::FindEntry(Key key) {
1984 return FindEntry(GetIsolate(), key);
1985}
1986
1987
1988// Find entry for key otherwise return kNotFound.
1989template<typename Shape, typename Key>
1990int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1991 uint32_t capacity = Capacity();
1992 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1993 uint32_t count = 1;
1994 // EnsureCapacity will guarantee the hash table is never full.
1995 while (true) {
1996 Object* element = KeyAt(entry);
1997 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001998 if (element != isolate->heap()->the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001999 Shape::IsMatch(key, element)) return entry;
2000 entry = NextProbe(entry, count++, capacity);
2001 }
2002 return kNotFound;
2003}
2004
2005
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002006bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002007 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002008 if (!max_index_object->IsSmi()) return false;
2009 return 0 !=
2010 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2011}
2012
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002013uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002014 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002015 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002016 if (!max_index_object->IsSmi()) return 0;
2017 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2018 return value >> kRequiresSlowElementsTagSize;
2019}
2020
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002021void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002022 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002023}
2024
2025
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002026// ------------------------------------
2027// Cast operations
2028
2029
2030CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002031CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002032CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002033CAST_ACCESSOR(DeoptimizationInputData)
2034CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002035CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002036CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002037CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002038CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002039CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002040CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002041CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002042CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002043CAST_ACCESSOR(String)
2044CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002045CAST_ACCESSOR(SeqAsciiString)
2046CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002047CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002048CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049CAST_ACCESSOR(ExternalString)
2050CAST_ACCESSOR(ExternalAsciiString)
2051CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002052CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002053CAST_ACCESSOR(JSObject)
2054CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055CAST_ACCESSOR(HeapObject)
2056CAST_ACCESSOR(HeapNumber)
2057CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002058CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002059CAST_ACCESSOR(SharedFunctionInfo)
2060CAST_ACCESSOR(Map)
2061CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002062CAST_ACCESSOR(GlobalObject)
2063CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002064CAST_ACCESSOR(JSGlobalObject)
2065CAST_ACCESSOR(JSBuiltinsObject)
2066CAST_ACCESSOR(Code)
2067CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002068CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002069CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002070CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002071CAST_ACCESSOR(JSSet)
2072CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002073CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002074CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002075CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002076CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002077CAST_ACCESSOR(ExternalArray)
2078CAST_ACCESSOR(ExternalByteArray)
2079CAST_ACCESSOR(ExternalUnsignedByteArray)
2080CAST_ACCESSOR(ExternalShortArray)
2081CAST_ACCESSOR(ExternalUnsignedShortArray)
2082CAST_ACCESSOR(ExternalIntArray)
2083CAST_ACCESSOR(ExternalUnsignedIntArray)
2084CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002085CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002086CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002087CAST_ACCESSOR(Struct)
2088
2089
2090#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2091 STRUCT_LIST(MAKE_STRUCT_CAST)
2092#undef MAKE_STRUCT_CAST
2093
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002094
2095template <typename Shape, typename Key>
2096HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002097 ASSERT(obj->IsHashTable());
2098 return reinterpret_cast<HashTable*>(obj);
2099}
2100
2101
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002102SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002103SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002104
ager@chromium.orgac091b72010-05-05 07:34:42 +00002105SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002106
2107
2108uint32_t String::hash_field() {
2109 return READ_UINT32_FIELD(this, kHashFieldOffset);
2110}
2111
2112
2113void String::set_hash_field(uint32_t value) {
2114 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002115#if V8_HOST_ARCH_64_BIT
2116 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2117#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002118}
2119
2120
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002121bool String::Equals(String* other) {
2122 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002123 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2124 return false;
2125 }
2126 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002127}
2128
2129
lrn@chromium.org303ada72010-10-27 09:33:13 +00002130MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002131 if (!StringShape(this).IsCons()) return this;
2132 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002133 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002134 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002135}
2136
2137
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002138String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002139 MaybeObject* flat = TryFlatten(pretenure);
2140 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002141 if (!flat->ToObject(&successfully_flattened)) return this;
2142 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002143}
2144
2145
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002146uint16_t String::Get(int index) {
2147 ASSERT(index >= 0 && index < length());
2148 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002149 case kSeqStringTag | kAsciiStringTag:
2150 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2151 case kSeqStringTag | kTwoByteStringTag:
2152 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2153 case kConsStringTag | kAsciiStringTag:
2154 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002155 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002156 case kExternalStringTag | kAsciiStringTag:
2157 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2158 case kExternalStringTag | kTwoByteStringTag:
2159 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002160 case kSlicedStringTag | kAsciiStringTag:
2161 case kSlicedStringTag | kTwoByteStringTag:
2162 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002163 default:
2164 break;
2165 }
2166
2167 UNREACHABLE();
2168 return 0;
2169}
2170
2171
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002172void String::Set(int index, uint16_t value) {
2173 ASSERT(index >= 0 && index < length());
2174 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002175
ager@chromium.org5ec48922009-05-05 07:25:34 +00002176 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002177 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2178 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002179}
2180
2181
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002182bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002183 if (!StringShape(this).IsCons()) return true;
2184 return ConsString::cast(this)->second()->length() == 0;
2185}
2186
2187
2188String* String::GetUnderlying() {
2189 // Giving direct access to underlying string only makes sense if the
2190 // wrapping string is already flattened.
2191 ASSERT(this->IsFlat());
2192 ASSERT(StringShape(this).IsIndirect());
2193 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2194 const int kUnderlyingOffset = SlicedString::kParentOffset;
2195 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002196}
2197
2198
ager@chromium.org7c537e22008-10-16 08:43:32 +00002199uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002200 ASSERT(index >= 0 && index < length());
2201 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2202}
2203
2204
ager@chromium.org7c537e22008-10-16 08:43:32 +00002205void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002206 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2207 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2208 static_cast<byte>(value));
2209}
2210
2211
ager@chromium.org7c537e22008-10-16 08:43:32 +00002212Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002213 return FIELD_ADDR(this, kHeaderSize);
2214}
2215
2216
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002217char* SeqAsciiString::GetChars() {
2218 return reinterpret_cast<char*>(GetCharsAddress());
2219}
2220
2221
ager@chromium.org7c537e22008-10-16 08:43:32 +00002222Address SeqTwoByteString::GetCharsAddress() {
2223 return FIELD_ADDR(this, kHeaderSize);
2224}
2225
2226
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002227uc16* SeqTwoByteString::GetChars() {
2228 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2229}
2230
2231
ager@chromium.org7c537e22008-10-16 08:43:32 +00002232uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002233 ASSERT(index >= 0 && index < length());
2234 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2235}
2236
2237
ager@chromium.org7c537e22008-10-16 08:43:32 +00002238void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002239 ASSERT(index >= 0 && index < length());
2240 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2241}
2242
2243
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002244int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002245 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002246}
2247
2248
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002249int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002250 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002251}
2252
2253
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002254String* SlicedString::parent() {
2255 return String::cast(READ_FIELD(this, kParentOffset));
2256}
2257
2258
2259void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002260 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002261 WRITE_FIELD(this, kParentOffset, parent);
2262}
2263
2264
2265SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2266
2267
ager@chromium.org870a0b62008-11-04 11:43:05 +00002268String* ConsString::first() {
2269 return String::cast(READ_FIELD(this, kFirstOffset));
2270}
2271
2272
2273Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002274 return READ_FIELD(this, kFirstOffset);
2275}
2276
2277
ager@chromium.org870a0b62008-11-04 11:43:05 +00002278void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002279 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002280 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002281}
2282
2283
ager@chromium.org870a0b62008-11-04 11:43:05 +00002284String* ConsString::second() {
2285 return String::cast(READ_FIELD(this, kSecondOffset));
2286}
2287
2288
2289Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002290 return READ_FIELD(this, kSecondOffset);
2291}
2292
2293
ager@chromium.org870a0b62008-11-04 11:43:05 +00002294void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002295 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002296 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002297}
2298
2299
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002300bool ExternalString::is_short() {
2301 InstanceType type = map()->instance_type();
2302 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002303}
2304
2305
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002306const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002307 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2308}
2309
2310
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002311void ExternalAsciiString::update_data_cache() {
2312 if (is_short()) return;
2313 const char** data_field =
2314 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2315 *data_field = resource()->data();
2316}
2317
2318
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002319void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002320 const ExternalAsciiString::Resource* resource) {
2321 *reinterpret_cast<const Resource**>(
2322 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002323 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002324}
2325
2326
2327const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002328 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002329}
2330
2331
2332uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2333 ASSERT(index >= 0 && index < length());
2334 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002335}
2336
2337
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002338const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002339 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2340}
2341
2342
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002343void ExternalTwoByteString::update_data_cache() {
2344 if (is_short()) return;
2345 const uint16_t** data_field =
2346 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2347 *data_field = resource()->data();
2348}
2349
2350
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002351void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002352 const ExternalTwoByteString::Resource* resource) {
2353 *reinterpret_cast<const Resource**>(
2354 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002355 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002356}
2357
2358
2359const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002360 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002361}
2362
2363
2364uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2365 ASSERT(index >= 0 && index < length());
2366 return GetChars()[index];
2367}
2368
2369
2370const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2371 unsigned start) {
2372 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002373}
2374
2375
ager@chromium.orgac091b72010-05-05 07:34:42 +00002376void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002377 set_finger_index(kEntriesIndex);
2378 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002379}
2380
2381
2382void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002383 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002384 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002385 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002386 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002387 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002388 MakeZeroSize();
2389}
2390
2391
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002392int JSFunctionResultCache::size() {
2393 return Smi::cast(get(kCacheSizeIndex))->value();
2394}
2395
2396
2397void JSFunctionResultCache::set_size(int size) {
2398 set(kCacheSizeIndex, Smi::FromInt(size));
2399}
2400
2401
2402int JSFunctionResultCache::finger_index() {
2403 return Smi::cast(get(kFingerIndex))->value();
2404}
2405
2406
2407void JSFunctionResultCache::set_finger_index(int finger_index) {
2408 set(kFingerIndex, Smi::FromInt(finger_index));
2409}
2410
2411
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002412byte ByteArray::get(int index) {
2413 ASSERT(index >= 0 && index < this->length());
2414 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2415}
2416
2417
2418void ByteArray::set(int index, byte value) {
2419 ASSERT(index >= 0 && index < this->length());
2420 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2421}
2422
2423
2424int ByteArray::get_int(int index) {
2425 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2426 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2427}
2428
2429
2430ByteArray* ByteArray::FromDataStartAddress(Address address) {
2431 ASSERT_TAG_ALIGNED(address);
2432 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2433}
2434
2435
2436Address ByteArray::GetDataStartAddress() {
2437 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2438}
2439
2440
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002441uint8_t* ExternalPixelArray::external_pixel_pointer() {
2442 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002443}
2444
2445
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002446uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002447 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002448 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002449 return ptr[index];
2450}
2451
2452
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002453MaybeObject* ExternalPixelArray::get(int index) {
2454 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2455}
2456
2457
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002458void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002459 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002460 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002461 ptr[index] = value;
2462}
2463
2464
ager@chromium.org3811b432009-10-28 14:53:37 +00002465void* ExternalArray::external_pointer() {
2466 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2467 return reinterpret_cast<void*>(ptr);
2468}
2469
2470
2471void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2472 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2473 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2474}
2475
2476
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002477int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002478 ASSERT((index >= 0) && (index < this->length()));
2479 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2480 return ptr[index];
2481}
2482
2483
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002484MaybeObject* ExternalByteArray::get(int index) {
2485 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2486}
2487
2488
ager@chromium.org3811b432009-10-28 14:53:37 +00002489void ExternalByteArray::set(int index, int8_t value) {
2490 ASSERT((index >= 0) && (index < this->length()));
2491 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2492 ptr[index] = value;
2493}
2494
2495
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002496uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002497 ASSERT((index >= 0) && (index < this->length()));
2498 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2499 return ptr[index];
2500}
2501
2502
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002503MaybeObject* ExternalUnsignedByteArray::get(int index) {
2504 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2505}
2506
2507
ager@chromium.org3811b432009-10-28 14:53:37 +00002508void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2509 ASSERT((index >= 0) && (index < this->length()));
2510 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2511 ptr[index] = value;
2512}
2513
2514
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002515int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002516 ASSERT((index >= 0) && (index < this->length()));
2517 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2518 return ptr[index];
2519}
2520
2521
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002522MaybeObject* ExternalShortArray::get(int index) {
2523 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2524}
2525
2526
ager@chromium.org3811b432009-10-28 14:53:37 +00002527void ExternalShortArray::set(int index, int16_t value) {
2528 ASSERT((index >= 0) && (index < this->length()));
2529 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2530 ptr[index] = value;
2531}
2532
2533
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002534uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002535 ASSERT((index >= 0) && (index < this->length()));
2536 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2537 return ptr[index];
2538}
2539
2540
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002541MaybeObject* ExternalUnsignedShortArray::get(int index) {
2542 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2543}
2544
2545
ager@chromium.org3811b432009-10-28 14:53:37 +00002546void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2547 ASSERT((index >= 0) && (index < this->length()));
2548 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2549 ptr[index] = value;
2550}
2551
2552
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002553int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002554 ASSERT((index >= 0) && (index < this->length()));
2555 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2556 return ptr[index];
2557}
2558
2559
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002560MaybeObject* ExternalIntArray::get(int index) {
2561 return GetHeap()->NumberFromInt32(get_scalar(index));
2562}
2563
2564
ager@chromium.org3811b432009-10-28 14:53:37 +00002565void ExternalIntArray::set(int index, int32_t value) {
2566 ASSERT((index >= 0) && (index < this->length()));
2567 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2568 ptr[index] = value;
2569}
2570
2571
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002572uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002573 ASSERT((index >= 0) && (index < this->length()));
2574 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2575 return ptr[index];
2576}
2577
2578
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002579MaybeObject* ExternalUnsignedIntArray::get(int index) {
2580 return GetHeap()->NumberFromUint32(get_scalar(index));
2581}
2582
2583
ager@chromium.org3811b432009-10-28 14:53:37 +00002584void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2585 ASSERT((index >= 0) && (index < this->length()));
2586 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2587 ptr[index] = value;
2588}
2589
2590
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002591float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002592 ASSERT((index >= 0) && (index < this->length()));
2593 float* ptr = static_cast<float*>(external_pointer());
2594 return ptr[index];
2595}
2596
2597
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002598MaybeObject* ExternalFloatArray::get(int index) {
2599 return GetHeap()->NumberFromDouble(get_scalar(index));
2600}
2601
2602
ager@chromium.org3811b432009-10-28 14:53:37 +00002603void ExternalFloatArray::set(int index, float value) {
2604 ASSERT((index >= 0) && (index < this->length()));
2605 float* ptr = static_cast<float*>(external_pointer());
2606 ptr[index] = value;
2607}
2608
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002609
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002610double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002611 ASSERT((index >= 0) && (index < this->length()));
2612 double* ptr = static_cast<double*>(external_pointer());
2613 return ptr[index];
2614}
2615
2616
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002617MaybeObject* ExternalDoubleArray::get(int index) {
2618 return GetHeap()->NumberFromDouble(get_scalar(index));
2619}
2620
2621
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002622void ExternalDoubleArray::set(int index, double value) {
2623 ASSERT((index >= 0) && (index < this->length()));
2624 double* ptr = static_cast<double*>(external_pointer());
2625 ptr[index] = value;
2626}
2627
2628
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002629int Map::visitor_id() {
2630 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2631}
2632
2633
2634void Map::set_visitor_id(int id) {
2635 ASSERT(0 <= id && id < 256);
2636 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2637}
2638
ager@chromium.org3811b432009-10-28 14:53:37 +00002639
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002640int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002641 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2642}
2643
2644
2645int Map::inobject_properties() {
2646 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002647}
2648
2649
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002650int Map::pre_allocated_property_fields() {
2651 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2652}
2653
2654
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002655int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002656 int instance_size = map->instance_size();
2657 if (instance_size != kVariableSizeSentinel) return instance_size;
2658 // We can ignore the "symbol" bit becase it is only set for symbols
2659 // and implies a string type.
2660 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002661 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002662 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002663 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002664 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002665 if (instance_type == ASCII_STRING_TYPE) {
2666 return SeqAsciiString::SizeFor(
2667 reinterpret_cast<SeqAsciiString*>(this)->length());
2668 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002669 if (instance_type == BYTE_ARRAY_TYPE) {
2670 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2671 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002672 if (instance_type == FREE_SPACE_TYPE) {
2673 return reinterpret_cast<FreeSpace*>(this)->size();
2674 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002675 if (instance_type == STRING_TYPE) {
2676 return SeqTwoByteString::SizeFor(
2677 reinterpret_cast<SeqTwoByteString*>(this)->length());
2678 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002679 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2680 return FixedDoubleArray::SizeFor(
2681 reinterpret_cast<FixedDoubleArray*>(this)->length());
2682 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002683 ASSERT(instance_type == CODE_TYPE);
2684 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002685}
2686
2687
2688void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002689 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002690 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002691 ASSERT(0 <= value && value < 256);
2692 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2693}
2694
2695
ager@chromium.org7c537e22008-10-16 08:43:32 +00002696void Map::set_inobject_properties(int value) {
2697 ASSERT(0 <= value && value < 256);
2698 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2699}
2700
2701
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002702void Map::set_pre_allocated_property_fields(int value) {
2703 ASSERT(0 <= value && value < 256);
2704 WRITE_BYTE_FIELD(this,
2705 kPreAllocatedPropertyFieldsOffset,
2706 static_cast<byte>(value));
2707}
2708
2709
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002710InstanceType Map::instance_type() {
2711 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2712}
2713
2714
2715void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002716 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2717}
2718
2719
2720int Map::unused_property_fields() {
2721 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2722}
2723
2724
2725void Map::set_unused_property_fields(int value) {
2726 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2727}
2728
2729
2730byte Map::bit_field() {
2731 return READ_BYTE_FIELD(this, kBitFieldOffset);
2732}
2733
2734
2735void Map::set_bit_field(byte value) {
2736 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2737}
2738
2739
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002740byte Map::bit_field2() {
2741 return READ_BYTE_FIELD(this, kBitField2Offset);
2742}
2743
2744
2745void Map::set_bit_field2(byte value) {
2746 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2747}
2748
2749
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002750void Map::set_non_instance_prototype(bool value) {
2751 if (value) {
2752 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2753 } else {
2754 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2755 }
2756}
2757
2758
2759bool Map::has_non_instance_prototype() {
2760 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2761}
2762
2763
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002764void Map::set_function_with_prototype(bool value) {
2765 if (value) {
2766 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2767 } else {
2768 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2769 }
2770}
2771
2772
2773bool Map::function_with_prototype() {
2774 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2775}
2776
2777
ager@chromium.org870a0b62008-11-04 11:43:05 +00002778void Map::set_is_access_check_needed(bool access_check_needed) {
2779 if (access_check_needed) {
2780 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2781 } else {
2782 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2783 }
2784}
2785
2786
2787bool Map::is_access_check_needed() {
2788 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2789}
2790
2791
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002792void Map::set_is_extensible(bool value) {
2793 if (value) {
2794 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2795 } else {
2796 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2797 }
2798}
2799
2800bool Map::is_extensible() {
2801 return ((1 << kIsExtensible) & bit_field2()) != 0;
2802}
2803
2804
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002805void Map::set_attached_to_shared_function_info(bool value) {
2806 if (value) {
2807 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2808 } else {
2809 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2810 }
2811}
2812
2813bool Map::attached_to_shared_function_info() {
2814 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2815}
2816
2817
2818void Map::set_is_shared(bool value) {
2819 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002820 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002821 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002822 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002823 }
2824}
2825
2826bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002827 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002828}
2829
2830
2831JSFunction* Map::unchecked_constructor() {
2832 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2833}
2834
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002835
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002836Code::Flags Code::flags() {
2837 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2838}
2839
2840
2841void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002842 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002843 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002844 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2845 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002846 ExtractArgumentsCountFromFlags(flags) >= 0);
2847 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2848}
2849
2850
2851Code::Kind Code::kind() {
2852 return ExtractKindFromFlags(flags());
2853}
2854
2855
kasper.lund7276f142008-07-30 08:49:36 +00002856InlineCacheState Code::ic_state() {
2857 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002858 // Only allow uninitialized or debugger states for non-IC code
2859 // objects. This is used in the debugger to determine whether or not
2860 // a call to code object has been replaced with a debug break call.
2861 ASSERT(is_inline_cache_stub() ||
2862 result == UNINITIALIZED ||
2863 result == DEBUG_BREAK ||
2864 result == DEBUG_PREPARE_STEP_IN);
2865 return result;
2866}
2867
2868
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002869Code::ExtraICState Code::extra_ic_state() {
2870 ASSERT(is_inline_cache_stub());
2871 return ExtractExtraICStateFromFlags(flags());
2872}
2873
2874
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002875PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002876 return ExtractTypeFromFlags(flags());
2877}
2878
2879
2880int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002881 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002882 return ExtractArgumentsCountFromFlags(flags());
2883}
2884
2885
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002886int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002887 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002888 kind() == UNARY_OP_IC ||
2889 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002890 kind() == COMPARE_IC ||
2891 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002892 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002893}
2894
2895
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002896void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002897 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002898 kind() == UNARY_OP_IC ||
2899 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002900 kind() == COMPARE_IC ||
2901 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002902 ASSERT(0 <= major && major < 256);
2903 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002904}
2905
2906
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002907bool Code::is_pregenerated() {
2908 return kind() == STUB && IsPregeneratedField::decode(flags());
2909}
2910
2911
2912void Code::set_is_pregenerated(bool value) {
2913 ASSERT(kind() == STUB);
2914 Flags f = flags();
2915 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2916 set_flags(f);
2917}
2918
2919
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002920bool Code::optimizable() {
2921 ASSERT(kind() == FUNCTION);
2922 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2923}
2924
2925
2926void Code::set_optimizable(bool value) {
2927 ASSERT(kind() == FUNCTION);
2928 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2929}
2930
2931
2932bool Code::has_deoptimization_support() {
2933 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002934 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2935 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002936}
2937
2938
2939void Code::set_has_deoptimization_support(bool value) {
2940 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002941 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2942 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
2943 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2944}
2945
2946
2947bool Code::has_debug_break_slots() {
2948 ASSERT(kind() == FUNCTION);
2949 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2950 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
2951}
2952
2953
2954void Code::set_has_debug_break_slots(bool value) {
2955 ASSERT(kind() == FUNCTION);
2956 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2957 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
2958 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002959}
2960
2961
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002962bool Code::is_compiled_optimizable() {
2963 ASSERT(kind() == FUNCTION);
2964 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2965 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
2966}
2967
2968
2969void Code::set_compiled_optimizable(bool value) {
2970 ASSERT(kind() == FUNCTION);
2971 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2972 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
2973 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2974}
2975
2976
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002977int Code::allow_osr_at_loop_nesting_level() {
2978 ASSERT(kind() == FUNCTION);
2979 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2980}
2981
2982
2983void Code::set_allow_osr_at_loop_nesting_level(int level) {
2984 ASSERT(kind() == FUNCTION);
2985 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2986 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2987}
2988
2989
2990unsigned Code::stack_slots() {
2991 ASSERT(kind() == OPTIMIZED_FUNCTION);
2992 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2993}
2994
2995
2996void Code::set_stack_slots(unsigned slots) {
2997 ASSERT(kind() == OPTIMIZED_FUNCTION);
2998 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2999}
3000
3001
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003002unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003003 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003004 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003005}
3006
3007
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003008void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003009 ASSERT(kind() == OPTIMIZED_FUNCTION);
3010 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003011 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003012}
3013
3014
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003015unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003016 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003017 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003018}
3019
3020
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003021void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003022 ASSERT(kind() == FUNCTION);
3023 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003024 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003025}
3026
3027
3028CheckType Code::check_type() {
3029 ASSERT(is_call_stub() || is_keyed_call_stub());
3030 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3031 return static_cast<CheckType>(type);
3032}
3033
3034
3035void Code::set_check_type(CheckType value) {
3036 ASSERT(is_call_stub() || is_keyed_call_stub());
3037 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3038}
3039
3040
danno@chromium.org40cb8782011-05-25 07:58:50 +00003041byte Code::unary_op_type() {
3042 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003043 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3044}
3045
3046
danno@chromium.org40cb8782011-05-25 07:58:50 +00003047void Code::set_unary_op_type(byte value) {
3048 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003049 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3050}
3051
3052
danno@chromium.org40cb8782011-05-25 07:58:50 +00003053byte Code::binary_op_type() {
3054 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003055 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3056}
3057
3058
danno@chromium.org40cb8782011-05-25 07:58:50 +00003059void Code::set_binary_op_type(byte value) {
3060 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003061 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3062}
3063
3064
danno@chromium.org40cb8782011-05-25 07:58:50 +00003065byte Code::binary_op_result_type() {
3066 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003067 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3068}
3069
3070
danno@chromium.org40cb8782011-05-25 07:58:50 +00003071void Code::set_binary_op_result_type(byte value) {
3072 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003073 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3074}
3075
3076
3077byte Code::compare_state() {
3078 ASSERT(is_compare_ic_stub());
3079 return READ_BYTE_FIELD(this, kCompareStateOffset);
3080}
3081
3082
3083void Code::set_compare_state(byte value) {
3084 ASSERT(is_compare_ic_stub());
3085 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3086}
3087
3088
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003089byte Code::to_boolean_state() {
3090 ASSERT(is_to_boolean_ic_stub());
3091 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3092}
3093
3094
3095void Code::set_to_boolean_state(byte value) {
3096 ASSERT(is_to_boolean_ic_stub());
3097 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3098}
3099
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003100
3101bool Code::has_function_cache() {
3102 ASSERT(kind() == STUB);
3103 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3104}
3105
3106
3107void Code::set_has_function_cache(bool flag) {
3108 ASSERT(kind() == STUB);
3109 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3110}
3111
3112
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003113bool Code::is_inline_cache_stub() {
3114 Kind kind = this->kind();
3115 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3116}
3117
3118
3119Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003120 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003121 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003122 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003123 int argc,
3124 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003125 // Extra IC state is only allowed for call IC stubs or for store IC
3126 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003127 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003128 kind == CALL_IC ||
3129 kind == STORE_IC ||
3130 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003131 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003132 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003133 | ICStateField::encode(ic_state)
3134 | TypeField::encode(type)
3135 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003136 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003137 | CacheHolderField::encode(holder);
3138 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003139}
3140
3141
3142Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3143 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003144 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003145 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003146 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003147 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003148}
3149
3150
3151Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003152 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003153}
3154
3155
kasper.lund7276f142008-07-30 08:49:36 +00003156InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003157 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003158}
3159
3160
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003161Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003162 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003163}
3164
3165
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003166PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003167 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003168}
3169
3170
3171int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003172 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003173}
3174
3175
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003176InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003177 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003178}
3179
3180
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003181Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003182 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003183 return static_cast<Flags>(bits);
3184}
3185
3186
ager@chromium.org8bb60582008-12-11 12:02:20 +00003187Code* Code::GetCodeFromTargetAddress(Address address) {
3188 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3189 // GetCodeFromTargetAddress might be called when marking objects during mark
3190 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3191 // Code::cast. Code::cast does not work when the object's map is
3192 // marked.
3193 Code* result = reinterpret_cast<Code*>(code);
3194 return result;
3195}
3196
3197
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003198Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3199 return HeapObject::
3200 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3201}
3202
3203
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003204Object* Map::prototype() {
3205 return READ_FIELD(this, kPrototypeOffset);
3206}
3207
3208
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003209void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003210 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003211 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003212 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003213}
3214
3215
danno@chromium.org40cb8782011-05-25 07:58:50 +00003216DescriptorArray* Map::instance_descriptors() {
3217 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3218 if (object->IsSmi()) {
3219 return HEAP->empty_descriptor_array();
3220 } else {
3221 return DescriptorArray::cast(object);
3222 }
3223}
3224
3225
3226void Map::init_instance_descriptors() {
3227 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3228}
3229
3230
3231void Map::clear_instance_descriptors() {
3232 Object* object = READ_FIELD(this,
3233 kInstanceDescriptorsOrBitField3Offset);
3234 if (!object->IsSmi()) {
3235 WRITE_FIELD(
3236 this,
3237 kInstanceDescriptorsOrBitField3Offset,
3238 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3239 }
3240}
3241
3242
3243void Map::set_instance_descriptors(DescriptorArray* value,
3244 WriteBarrierMode mode) {
3245 Object* object = READ_FIELD(this,
3246 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003247 Heap* heap = GetHeap();
3248 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003249 clear_instance_descriptors();
3250 return;
3251 } else {
3252 if (object->IsSmi()) {
3253 value->set_bit_field3_storage(Smi::cast(object)->value());
3254 } else {
3255 value->set_bit_field3_storage(
3256 DescriptorArray::cast(object)->bit_field3_storage());
3257 }
3258 }
3259 ASSERT(!is_shared());
3260 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003261 CONDITIONAL_WRITE_BARRIER(
3262 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003263}
3264
3265
3266int Map::bit_field3() {
3267 Object* object = READ_FIELD(this,
3268 kInstanceDescriptorsOrBitField3Offset);
3269 if (object->IsSmi()) {
3270 return Smi::cast(object)->value();
3271 } else {
3272 return DescriptorArray::cast(object)->bit_field3_storage();
3273 }
3274}
3275
3276
3277void Map::set_bit_field3(int value) {
3278 ASSERT(Smi::IsValid(value));
3279 Object* object = READ_FIELD(this,
3280 kInstanceDescriptorsOrBitField3Offset);
3281 if (object->IsSmi()) {
3282 WRITE_FIELD(this,
3283 kInstanceDescriptorsOrBitField3Offset,
3284 Smi::FromInt(value));
3285 } else {
3286 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3287 }
3288}
3289
3290
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003291FixedArray* Map::unchecked_prototype_transitions() {
3292 return reinterpret_cast<FixedArray*>(
3293 READ_FIELD(this, kPrototypeTransitionsOffset));
3294}
3295
3296
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003297ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003298ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003299ACCESSORS(Map, constructor, Object, kConstructorOffset)
3300
3301ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003302ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003303ACCESSORS(JSFunction,
3304 next_function_link,
3305 Object,
3306 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003307
3308ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3309ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003310ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003311
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003312ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003313
3314ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3315ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3316ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3317ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3318ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3319
3320ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3321ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3322ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3323
3324ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3325ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3326ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3327ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3328ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3329ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3330
3331ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3332ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3333
3334ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3335ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3336
3337ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3338ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003339ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3340 kPropertyAccessorsOffset)
3341ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3342 kPrototypeTemplateOffset)
3343ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3344ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3345 kNamedPropertyHandlerOffset)
3346ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3347 kIndexedPropertyHandlerOffset)
3348ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3349 kInstanceTemplateOffset)
3350ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3351ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003352ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3353 kInstanceCallHandlerOffset)
3354ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3355 kAccessCheckInfoOffset)
3356ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3357
3358ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003359ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3360 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003361
3362ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3363ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3364
3365ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3366
3367ACCESSORS(Script, source, Object, kSourceOffset)
3368ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003369ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003370ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3371ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003372ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003373ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003374ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003375ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003376ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003377ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003378ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003379ACCESSORS(Script, eval_from_instructions_offset, Smi,
3380 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003381
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003382#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003383ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3384ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3385ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3386ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3387
3388ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3389ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3390ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3391ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003392#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003393
3394ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003395ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3396ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003397ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3398 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003399ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003400ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3401ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003402ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003403ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3404 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003405
3406BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3407 kHiddenPrototypeBit)
3408BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3409BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3410 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003411BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3412 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003413BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3414 kIsExpressionBit)
3415BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3416 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003417BOOL_GETTER(SharedFunctionInfo,
3418 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003419 has_only_simple_this_property_assignments,
3420 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003421BOOL_ACCESSORS(SharedFunctionInfo,
3422 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003423 allows_lazy_compilation,
3424 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003425BOOL_ACCESSORS(SharedFunctionInfo,
3426 compiler_hints,
3427 uses_arguments,
3428 kUsesArguments)
3429BOOL_ACCESSORS(SharedFunctionInfo,
3430 compiler_hints,
3431 has_duplicate_parameters,
3432 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003433
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003434
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003435#if V8_HOST_ARCH_32_BIT
3436SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3437SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003438 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003439SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003440 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003441SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3442SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003443 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003444SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3445SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003446 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003447SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003448 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003449SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003450 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003451SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003452#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003453
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003454#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003455 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003456 int holder::name() { \
3457 int value = READ_INT_FIELD(this, offset); \
3458 ASSERT(kHeapObjectTag == 1); \
3459 ASSERT((value & kHeapObjectTag) == 0); \
3460 return value >> 1; \
3461 } \
3462 void holder::set_##name(int value) { \
3463 ASSERT(kHeapObjectTag == 1); \
3464 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3465 (value & 0xC0000000) == 0x000000000); \
3466 WRITE_INT_FIELD(this, \
3467 offset, \
3468 (value << 1) & ~kHeapObjectTag); \
3469 }
3470
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003471#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3472 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003473 INT_ACCESSORS(holder, name, offset)
3474
3475
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003476PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003477PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3478 formal_parameter_count,
3479 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003480
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003481PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3482 expected_nof_properties,
3483 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003484PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3485
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003486PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3487PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3488 start_position_and_type,
3489 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003490
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003491PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3492 function_token_position,
3493 kFunctionTokenPositionOffset)
3494PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3495 compiler_hints,
3496 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003497
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003498PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3499 this_property_assignments_count,
3500 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003501PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003502#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003503
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003504
3505int SharedFunctionInfo::construction_count() {
3506 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3507}
3508
3509
3510void SharedFunctionInfo::set_construction_count(int value) {
3511 ASSERT(0 <= value && value < 256);
3512 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3513}
3514
3515
whesse@chromium.org7b260152011-06-20 15:33:18 +00003516BOOL_ACCESSORS(SharedFunctionInfo,
3517 compiler_hints,
3518 live_objects_may_exist,
3519 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003520
3521
3522bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003523 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003524}
3525
3526
whesse@chromium.org7b260152011-06-20 15:33:18 +00003527BOOL_GETTER(SharedFunctionInfo,
3528 compiler_hints,
3529 optimization_disabled,
3530 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003531
3532
3533void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3534 set_compiler_hints(BooleanBit::set(compiler_hints(),
3535 kOptimizationDisabled,
3536 disable));
3537 // If disabling optimizations we reflect that in the code object so
3538 // it will not be counted as optimizable code.
3539 if ((code()->kind() == Code::FUNCTION) && disable) {
3540 code()->set_optimizable(false);
3541 }
3542}
3543
3544
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003545LanguageMode SharedFunctionInfo::language_mode() {
3546 int hints = compiler_hints();
3547 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3548 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3549 return EXTENDED_MODE;
3550 }
3551 return BooleanBit::get(hints, kStrictModeFunction)
3552 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003553}
3554
3555
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003556void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3557 // We only allow language mode transitions that go set the same language mode
3558 // again or go up in the chain:
3559 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3560 ASSERT(this->language_mode() == CLASSIC_MODE ||
3561 this->language_mode() == language_mode ||
3562 language_mode == EXTENDED_MODE);
3563 int hints = compiler_hints();
3564 hints = BooleanBit::set(
3565 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3566 hints = BooleanBit::set(
3567 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3568 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003569}
3570
3571
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003572bool SharedFunctionInfo::is_classic_mode() {
3573 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3574}
3575
3576BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3577 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003578BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3579BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3580 name_should_print_as_anonymous,
3581 kNameShouldPrintAsAnonymous)
3582BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3583BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003584
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003585ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3586ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3587
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003588ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3589
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003590bool Script::HasValidSource() {
3591 Object* src = this->source();
3592 if (!src->IsString()) return true;
3593 String* src_str = String::cast(src);
3594 if (!StringShape(src_str).IsExternal()) return true;
3595 if (src_str->IsAsciiRepresentation()) {
3596 return ExternalAsciiString::cast(src)->resource() != NULL;
3597 } else if (src_str->IsTwoByteRepresentation()) {
3598 return ExternalTwoByteString::cast(src)->resource() != NULL;
3599 }
3600 return true;
3601}
3602
3603
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003604void SharedFunctionInfo::DontAdaptArguments() {
3605 ASSERT(code()->kind() == Code::BUILTIN);
3606 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3607}
3608
3609
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003610int SharedFunctionInfo::start_position() {
3611 return start_position_and_type() >> kStartPositionShift;
3612}
3613
3614
3615void SharedFunctionInfo::set_start_position(int start_position) {
3616 set_start_position_and_type((start_position << kStartPositionShift)
3617 | (start_position_and_type() & ~kStartPositionMask));
3618}
3619
3620
3621Code* SharedFunctionInfo::code() {
3622 return Code::cast(READ_FIELD(this, kCodeOffset));
3623}
3624
3625
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003626Code* SharedFunctionInfo::unchecked_code() {
3627 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3628}
3629
3630
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003631void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003632 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003633 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003634}
3635
3636
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003637ScopeInfo* SharedFunctionInfo::scope_info() {
3638 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003639}
3640
3641
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003642void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003643 WriteBarrierMode mode) {
3644 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003645 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3646 this,
3647 kScopeInfoOffset,
3648 reinterpret_cast<Object*>(value),
3649 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003650}
3651
3652
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003653Smi* SharedFunctionInfo::deopt_counter() {
3654 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3655}
3656
3657
3658void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3659 WRITE_FIELD(this, kDeoptCounterOffset, value);
3660}
3661
3662
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003663bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003664 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003665 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003666}
3667
3668
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003669bool SharedFunctionInfo::IsApiFunction() {
3670 return function_data()->IsFunctionTemplateInfo();
3671}
3672
3673
3674FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3675 ASSERT(IsApiFunction());
3676 return FunctionTemplateInfo::cast(function_data());
3677}
3678
3679
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003680bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003681 return function_data()->IsSmi();
3682}
3683
3684
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003685BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3686 ASSERT(HasBuiltinFunctionId());
3687 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003688}
3689
3690
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003691int SharedFunctionInfo::code_age() {
3692 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3693}
3694
3695
3696void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003697 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3698 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003699}
3700
3701
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003702bool SharedFunctionInfo::has_deoptimization_support() {
3703 Code* code = this->code();
3704 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3705}
3706
3707
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003708bool JSFunction::IsBuiltin() {
3709 return context()->global()->IsJSBuiltinsObject();
3710}
3711
3712
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003713bool JSFunction::NeedsArgumentsAdaption() {
3714 return shared()->formal_parameter_count() !=
3715 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3716}
3717
3718
3719bool JSFunction::IsOptimized() {
3720 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3721}
3722
3723
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003724bool JSFunction::IsOptimizable() {
3725 return code()->kind() == Code::FUNCTION && code()->optimizable();
3726}
3727
3728
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003729bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003730 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003731}
3732
3733
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003734Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003735 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003736}
3737
3738
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003739Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003740 return reinterpret_cast<Code*>(
3741 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003742}
3743
3744
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003745void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003746 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003747 Address entry = value->entry();
3748 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003749 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3750 this,
3751 HeapObject::RawField(this, kCodeEntryOffset),
3752 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003753}
3754
3755
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003756void JSFunction::ReplaceCode(Code* code) {
3757 bool was_optimized = IsOptimized();
3758 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3759
3760 set_code(code);
3761
3762 // Add/remove the function from the list of optimized functions for this
3763 // context based on the state change.
3764 if (!was_optimized && is_optimized) {
3765 context()->global_context()->AddOptimizedFunction(this);
3766 }
3767 if (was_optimized && !is_optimized) {
3768 context()->global_context()->RemoveOptimizedFunction(this);
3769 }
3770}
3771
3772
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003773Context* JSFunction::context() {
3774 return Context::cast(READ_FIELD(this, kContextOffset));
3775}
3776
3777
3778Object* JSFunction::unchecked_context() {
3779 return READ_FIELD(this, kContextOffset);
3780}
3781
3782
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003783SharedFunctionInfo* JSFunction::unchecked_shared() {
3784 return reinterpret_cast<SharedFunctionInfo*>(
3785 READ_FIELD(this, kSharedFunctionInfoOffset));
3786}
3787
3788
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003789void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003790 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003791 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003792 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003793}
3794
3795ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3796 kPrototypeOrInitialMapOffset)
3797
3798
3799Map* JSFunction::initial_map() {
3800 return Map::cast(prototype_or_initial_map());
3801}
3802
3803
3804void JSFunction::set_initial_map(Map* value) {
3805 set_prototype_or_initial_map(value);
3806}
3807
3808
3809bool JSFunction::has_initial_map() {
3810 return prototype_or_initial_map()->IsMap();
3811}
3812
3813
3814bool JSFunction::has_instance_prototype() {
3815 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3816}
3817
3818
3819bool JSFunction::has_prototype() {
3820 return map()->has_non_instance_prototype() || has_instance_prototype();
3821}
3822
3823
3824Object* JSFunction::instance_prototype() {
3825 ASSERT(has_instance_prototype());
3826 if (has_initial_map()) return initial_map()->prototype();
3827 // When there is no initial map and the prototype is a JSObject, the
3828 // initial map field is used for the prototype field.
3829 return prototype_or_initial_map();
3830}
3831
3832
3833Object* JSFunction::prototype() {
3834 ASSERT(has_prototype());
3835 // If the function's prototype property has been set to a non-JSObject
3836 // value, that value is stored in the constructor field of the map.
3837 if (map()->has_non_instance_prototype()) return map()->constructor();
3838 return instance_prototype();
3839}
3840
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003841bool JSFunction::should_have_prototype() {
3842 return map()->function_with_prototype();
3843}
3844
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003845
3846bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003847 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003848}
3849
3850
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003851FixedArray* JSFunction::literals() {
3852 ASSERT(!shared()->bound());
3853 return literals_or_bindings();
3854}
3855
3856
3857void JSFunction::set_literals(FixedArray* literals) {
3858 ASSERT(!shared()->bound());
3859 set_literals_or_bindings(literals);
3860}
3861
3862
3863FixedArray* JSFunction::function_bindings() {
3864 ASSERT(shared()->bound());
3865 return literals_or_bindings();
3866}
3867
3868
3869void JSFunction::set_function_bindings(FixedArray* bindings) {
3870 ASSERT(shared()->bound());
3871 // Bound function literal may be initialized to the empty fixed array
3872 // before the bindings are set.
3873 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
3874 bindings->map() == GetHeap()->fixed_cow_array_map());
3875 set_literals_or_bindings(bindings);
3876}
3877
3878
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003879int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003880 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003881 return literals()->length();
3882}
3883
3884
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003885Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003886 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003887 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003888}
3889
3890
3891void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3892 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003893 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003894 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003895 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003896}
3897
3898
3899Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003900 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003901 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3902}
3903
3904
3905void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3906 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003907 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003908 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003909 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003910}
3911
3912
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003913ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003914ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003915ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3916ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3917
3918
3919void JSProxy::InitializeBody(int object_size, Object* value) {
3920 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3921 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3922 WRITE_FIELD(this, offset, value);
3923 }
3924}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003925
3926
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003927ACCESSORS(JSSet, table, Object, kTableOffset)
3928ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003929ACCESSORS(JSWeakMap, table, Object, kTableOffset)
3930ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003931
3932
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003933Address Foreign::foreign_address() {
3934 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003935}
3936
3937
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003938void Foreign::set_foreign_address(Address value) {
3939 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003940}
3941
3942
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003943ACCESSORS(JSValue, value, Object, kValueOffset)
3944
3945
3946JSValue* JSValue::cast(Object* obj) {
3947 ASSERT(obj->IsJSValue());
3948 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3949 return reinterpret_cast<JSValue*>(obj);
3950}
3951
3952
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003953ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3954ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3955ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3956ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3957ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3958SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3959SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3960
3961
3962JSMessageObject* JSMessageObject::cast(Object* obj) {
3963 ASSERT(obj->IsJSMessageObject());
3964 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3965 return reinterpret_cast<JSMessageObject*>(obj);
3966}
3967
3968
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003969INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003970ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00003971ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003972ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003973ACCESSORS(Code, next_code_flushing_candidate,
3974 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003975
3976
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003977byte* Code::instruction_start() {
3978 return FIELD_ADDR(this, kHeaderSize);
3979}
3980
3981
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003982byte* Code::instruction_end() {
3983 return instruction_start() + instruction_size();
3984}
3985
3986
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003987int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003988 return RoundUp(instruction_size(), kObjectAlignment);
3989}
3990
3991
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003992FixedArray* Code::unchecked_deoptimization_data() {
3993 return reinterpret_cast<FixedArray*>(
3994 READ_FIELD(this, kDeoptimizationDataOffset));
3995}
3996
3997
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003998ByteArray* Code::unchecked_relocation_info() {
3999 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004000}
4001
4002
4003byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004004 return unchecked_relocation_info()->GetDataStartAddress();
4005}
4006
4007
4008int Code::relocation_size() {
4009 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004010}
4011
4012
4013byte* Code::entry() {
4014 return instruction_start();
4015}
4016
4017
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004018bool Code::contains(byte* inner_pointer) {
4019 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004020}
4021
4022
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004023ACCESSORS(JSArray, length, Object, kLengthOffset)
4024
4025
ager@chromium.org236ad962008-09-25 09:45:57 +00004026ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004027
4028
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004029JSRegExp::Type JSRegExp::TypeTag() {
4030 Object* data = this->data();
4031 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4032 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4033 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004034}
4035
4036
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004037JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4038 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4039 return static_cast<JSRegExp::Type>(smi->value());
4040}
4041
4042
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004043int JSRegExp::CaptureCount() {
4044 switch (TypeTag()) {
4045 case ATOM:
4046 return 0;
4047 case IRREGEXP:
4048 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4049 default:
4050 UNREACHABLE();
4051 return -1;
4052 }
4053}
4054
4055
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004056JSRegExp::Flags JSRegExp::GetFlags() {
4057 ASSERT(this->data()->IsFixedArray());
4058 Object* data = this->data();
4059 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4060 return Flags(smi->value());
4061}
4062
4063
4064String* JSRegExp::Pattern() {
4065 ASSERT(this->data()->IsFixedArray());
4066 Object* data = this->data();
4067 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4068 return pattern;
4069}
4070
4071
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004072Object* JSRegExp::DataAt(int index) {
4073 ASSERT(TypeTag() != NOT_COMPILED);
4074 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004075}
4076
4077
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004078Object* JSRegExp::DataAtUnchecked(int index) {
4079 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4080 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4081 return READ_FIELD(fa, offset);
4082}
4083
4084
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004085void JSRegExp::SetDataAt(int index, Object* value) {
4086 ASSERT(TypeTag() != NOT_COMPILED);
4087 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4088 FixedArray::cast(data())->set(index, value);
4089}
4090
4091
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004092void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4093 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4094 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4095 if (value->IsSmi()) {
4096 fa->set_unchecked(index, Smi::cast(value));
4097 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004098 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004099 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4100 }
4101}
4102
4103
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004104ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004105 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004106#if DEBUG
4107 FixedArrayBase* fixed_array =
4108 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4109 Map* map = fixed_array->map();
4110 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004111 (map == GetHeap()->fixed_array_map() ||
4112 map == GetHeap()->fixed_cow_array_map())) ||
4113 (kind == FAST_DOUBLE_ELEMENTS &&
4114 fixed_array->IsFixedDoubleArray()) ||
4115 (kind == DICTIONARY_ELEMENTS &&
4116 fixed_array->IsFixedArray() &&
4117 fixed_array->IsDictionary()) ||
4118 (kind > DICTIONARY_ELEMENTS));
4119 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4120 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004121#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004122 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004123}
4124
4125
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004126ElementsAccessor* JSObject::GetElementsAccessor() {
4127 return ElementsAccessor::ForKind(GetElementsKind());
4128}
4129
4130
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004131bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004132 return GetElementsKind() == FAST_ELEMENTS;
4133}
4134
4135
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004136bool JSObject::HasFastSmiOnlyElements() {
4137 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4138}
4139
4140
4141bool JSObject::HasFastTypeElements() {
4142 ElementsKind elements_kind = GetElementsKind();
4143 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4144 elements_kind == FAST_ELEMENTS;
4145}
4146
4147
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004148bool JSObject::HasFastDoubleElements() {
4149 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4150}
4151
4152
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004153bool JSObject::HasDictionaryElements() {
4154 return GetElementsKind() == DICTIONARY_ELEMENTS;
4155}
4156
4157
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004158bool JSObject::HasNonStrictArgumentsElements() {
4159 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4160}
4161
4162
ager@chromium.org3811b432009-10-28 14:53:37 +00004163bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004164 HeapObject* array = elements();
4165 ASSERT(array != NULL);
4166 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004167}
4168
4169
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004170#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4171bool JSObject::HasExternal##name##Elements() { \
4172 HeapObject* array = elements(); \
4173 ASSERT(array != NULL); \
4174 if (!array->IsHeapObject()) \
4175 return false; \
4176 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004177}
4178
4179
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004180EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4181EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4182EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4183EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4184 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4185EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4186EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4187 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4188EXTERNAL_ELEMENTS_CHECK(Float,
4189 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004190EXTERNAL_ELEMENTS_CHECK(Double,
4191 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004192EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004193
4194
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004195bool JSObject::HasNamedInterceptor() {
4196 return map()->has_named_interceptor();
4197}
4198
4199
4200bool JSObject::HasIndexedInterceptor() {
4201 return map()->has_indexed_interceptor();
4202}
4203
4204
ager@chromium.org5c838252010-02-19 08:53:10 +00004205bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004206 bool result = elements()->IsFixedArray() ||
4207 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004208 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004209 return result;
4210}
4211
4212
lrn@chromium.org303ada72010-10-27 09:33:13 +00004213MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004214 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004215 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004216 Isolate* isolate = GetIsolate();
4217 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004218 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004219 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4220 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004221 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4222 return maybe_writable_elems;
4223 }
4224 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004225 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004226 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004227 return writable_elems;
4228}
4229
4230
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004231StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004232 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004233 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004234}
4235
4236
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004237NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004238 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004239 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004240}
4241
4242
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004243bool String::IsHashFieldComputed(uint32_t field) {
4244 return (field & kHashNotComputedMask) == 0;
4245}
4246
4247
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004248bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004249 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004250}
4251
4252
4253uint32_t String::Hash() {
4254 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004255 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004256 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004257 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004258 return ComputeAndSetHash();
4259}
4260
4261
ager@chromium.org7c537e22008-10-16 08:43:32 +00004262StringHasher::StringHasher(int length)
4263 : length_(length),
4264 raw_running_hash_(0),
4265 array_index_(0),
4266 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4267 is_first_char_(true),
4268 is_valid_(true) { }
4269
4270
4271bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004272 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004273}
4274
4275
4276void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004277 // Use the Jenkins one-at-a-time hash function to update the hash
4278 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004279 raw_running_hash_ += c;
4280 raw_running_hash_ += (raw_running_hash_ << 10);
4281 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004282 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004283 if (is_array_index_) {
4284 if (c < '0' || c > '9') {
4285 is_array_index_ = false;
4286 } else {
4287 int d = c - '0';
4288 if (is_first_char_) {
4289 is_first_char_ = false;
4290 if (c == '0' && length_ > 1) {
4291 is_array_index_ = false;
4292 return;
4293 }
4294 }
4295 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4296 is_array_index_ = false;
4297 } else {
4298 array_index_ = array_index_ * 10 + d;
4299 }
4300 }
4301 }
4302}
4303
4304
4305void StringHasher::AddCharacterNoIndex(uc32 c) {
4306 ASSERT(!is_array_index());
4307 raw_running_hash_ += c;
4308 raw_running_hash_ += (raw_running_hash_ << 10);
4309 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4310}
4311
4312
4313uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004314 // Get the calculated raw hash value and do some more bit ops to distribute
4315 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004316 uint32_t result = raw_running_hash_;
4317 result += (result << 3);
4318 result ^= (result >> 11);
4319 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004320 if (result == 0) {
4321 result = 27;
4322 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004323 return result;
4324}
4325
4326
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004327template <typename schar>
4328uint32_t HashSequentialString(const schar* chars, int length) {
4329 StringHasher hasher(length);
4330 if (!hasher.has_trivial_hash()) {
4331 int i;
4332 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4333 hasher.AddCharacter(chars[i]);
4334 }
4335 for (; i < length; i++) {
4336 hasher.AddCharacterNoIndex(chars[i]);
4337 }
4338 }
4339 return hasher.GetHashField();
4340}
4341
4342
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004343bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004344 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004345 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4346 return false;
4347 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004348 return SlowAsArrayIndex(index);
4349}
4350
4351
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004352Object* JSReceiver::GetPrototype() {
4353 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004354}
4355
4356
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004357bool JSReceiver::HasProperty(String* name) {
4358 if (IsJSProxy()) {
4359 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4360 }
4361 return GetPropertyAttribute(name) != ABSENT;
4362}
4363
4364
4365bool JSReceiver::HasLocalProperty(String* name) {
4366 if (IsJSProxy()) {
4367 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4368 }
4369 return GetLocalPropertyAttribute(name) != ABSENT;
4370}
4371
4372
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004373PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004374 return GetPropertyAttributeWithReceiver(this, key);
4375}
4376
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004377// TODO(504): this may be useful in other places too where JSGlobalProxy
4378// is used.
4379Object* JSObject::BypassGlobalProxy() {
4380 if (IsJSGlobalProxy()) {
4381 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004382 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004383 ASSERT(proto->IsJSGlobalObject());
4384 return proto;
4385 }
4386 return this;
4387}
4388
4389
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004390MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4391 return IsJSProxy()
4392 ? JSProxy::cast(this)->GetIdentityHash(flag)
4393 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004394}
4395
4396
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004397bool JSReceiver::HasElement(uint32_t index) {
4398 if (IsJSProxy()) {
4399 return JSProxy::cast(this)->HasElementWithHandler(index);
4400 }
4401 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004402}
4403
4404
4405bool AccessorInfo::all_can_read() {
4406 return BooleanBit::get(flag(), kAllCanReadBit);
4407}
4408
4409
4410void AccessorInfo::set_all_can_read(bool value) {
4411 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4412}
4413
4414
4415bool AccessorInfo::all_can_write() {
4416 return BooleanBit::get(flag(), kAllCanWriteBit);
4417}
4418
4419
4420void AccessorInfo::set_all_can_write(bool value) {
4421 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4422}
4423
4424
ager@chromium.org870a0b62008-11-04 11:43:05 +00004425bool AccessorInfo::prohibits_overwriting() {
4426 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4427}
4428
4429
4430void AccessorInfo::set_prohibits_overwriting(bool value) {
4431 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4432}
4433
4434
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004435PropertyAttributes AccessorInfo::property_attributes() {
4436 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4437}
4438
4439
4440void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004441 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004442}
4443
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004444
4445template<typename Shape, typename Key>
4446void Dictionary<Shape, Key>::SetEntry(int entry,
4447 Object* key,
4448 Object* value) {
4449 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4450}
4451
4452
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004453template<typename Shape, typename Key>
4454void Dictionary<Shape, Key>::SetEntry(int entry,
4455 Object* key,
4456 Object* value,
4457 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004458 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004459 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004460 AssertNoAllocation no_gc;
4461 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004462 FixedArray::set(index, key, mode);
4463 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004464 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004465}
4466
4467
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004468bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4469 ASSERT(other->IsNumber());
4470 return key == static_cast<uint32_t>(other->Number());
4471}
4472
4473
4474uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4475 return ComputeIntegerHash(key);
4476}
4477
4478
4479uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4480 ASSERT(other->IsNumber());
4481 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4482}
4483
4484
4485MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4486 return Isolate::Current()->heap()->NumberFromUint32(key);
4487}
4488
4489
4490bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4491 // We know that all entries in a hash table had their hash keys created.
4492 // Use that knowledge to have fast failure.
4493 if (key->Hash() != String::cast(other)->Hash()) return false;
4494 return key->Equals(String::cast(other));
4495}
4496
4497
4498uint32_t StringDictionaryShape::Hash(String* key) {
4499 return key->Hash();
4500}
4501
4502
4503uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4504 return String::cast(other)->Hash();
4505}
4506
4507
4508MaybeObject* StringDictionaryShape::AsObject(String* key) {
4509 return key;
4510}
4511
4512
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004513template <int entrysize>
4514bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4515 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004516}
4517
4518
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004519template <int entrysize>
4520uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004521 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4522 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004523}
4524
4525
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004526template <int entrysize>
4527uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4528 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004529 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4530 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004531}
4532
4533
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004534template <int entrysize>
4535MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004536 return key;
4537}
4538
4539
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004540void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004541 // No write barrier is needed since empty_fixed_array is not in new space.
4542 // Please note this function is used during marking:
4543 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004544 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4545 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004546}
4547
4548
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004549void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004550 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004551 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004552 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4553 if (elts->length() < required_size) {
4554 // Doubling in size would be overkill, but leave some slack to avoid
4555 // constantly growing.
4556 Expand(required_size + (required_size >> 3));
4557 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004558 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004559 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4560 // Expand will allocate a new backing store in new space even if the size
4561 // we asked for isn't larger than what we had before.
4562 Expand(required_size);
4563 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004564}
4565
4566
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004567void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004568 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004569 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4570}
4571
4572
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004573MaybeObject* JSArray::SetContent(FixedArray* storage) {
4574 MaybeObject* maybe_object = EnsureCanContainElements(storage);
4575 if (maybe_object->IsFailure()) return maybe_object;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004576 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004577 set_elements(storage);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004578 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004579}
4580
4581
lrn@chromium.org303ada72010-10-27 09:33:13 +00004582MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004583 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004584 return GetHeap()->CopyFixedArray(this);
4585}
4586
4587
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004588MaybeObject* FixedDoubleArray::Copy() {
4589 if (length() == 0) return this;
4590 return GetHeap()->CopyFixedDoubleArray(this);
4591}
4592
4593
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004594Relocatable::Relocatable(Isolate* isolate) {
4595 ASSERT(isolate == Isolate::Current());
4596 isolate_ = isolate;
4597 prev_ = isolate->relocatable_top();
4598 isolate->set_relocatable_top(this);
4599}
4600
4601
4602Relocatable::~Relocatable() {
4603 ASSERT(isolate_ == Isolate::Current());
4604 ASSERT_EQ(isolate_->relocatable_top(), this);
4605 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004606}
4607
4608
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004609int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4610 return map->instance_size();
4611}
4612
4613
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004614void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004615 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004616 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004617}
4618
4619
4620template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004621void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004622 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004623 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004624}
4625
4626
4627void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4628 typedef v8::String::ExternalAsciiStringResource Resource;
4629 v->VisitExternalAsciiString(
4630 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4631}
4632
4633
4634template<typename StaticVisitor>
4635void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4636 typedef v8::String::ExternalAsciiStringResource Resource;
4637 StaticVisitor::VisitExternalAsciiString(
4638 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4639}
4640
4641
4642void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4643 typedef v8::String::ExternalStringResource Resource;
4644 v->VisitExternalTwoByteString(
4645 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4646}
4647
4648
4649template<typename StaticVisitor>
4650void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4651 typedef v8::String::ExternalStringResource Resource;
4652 StaticVisitor::VisitExternalTwoByteString(
4653 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4654}
4655
4656#define SLOT_ADDR(obj, offset) \
4657 reinterpret_cast<Object**>((obj)->address() + offset)
4658
4659template<int start_offset, int end_offset, int size>
4660void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4661 HeapObject* obj,
4662 ObjectVisitor* v) {
4663 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4664}
4665
4666
4667template<int start_offset>
4668void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4669 int object_size,
4670 ObjectVisitor* v) {
4671 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4672}
4673
4674#undef SLOT_ADDR
4675
4676
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004677#undef CAST_ACCESSOR
4678#undef INT_ACCESSORS
4679#undef SMI_ACCESSORS
4680#undef ACCESSORS
4681#undef FIELD_ADDR
4682#undef READ_FIELD
4683#undef WRITE_FIELD
4684#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004685#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004686#undef READ_MEMADDR_FIELD
4687#undef WRITE_MEMADDR_FIELD
4688#undef READ_DOUBLE_FIELD
4689#undef WRITE_DOUBLE_FIELD
4690#undef READ_INT_FIELD
4691#undef WRITE_INT_FIELD
4692#undef READ_SHORT_FIELD
4693#undef WRITE_SHORT_FIELD
4694#undef READ_BYTE_FIELD
4695#undef WRITE_BYTE_FIELD
4696
4697
4698} } // namespace v8::internal
4699
4700#endif // V8_OBJECTS_INL_H_