blob: 24501c85bb3f429e9d7d6570445d38a54360d7e0 [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
ager@chromium.org7c537e22008-10-16 08:43:32 +00001388// Access fast-case object properties at index. The use of these routines
1389// is needed to correctly distinguish between properties stored in-object and
1390// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001391Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001392 // Adjust for the number of properties stored in the object.
1393 index -= map()->inobject_properties();
1394 if (index < 0) {
1395 int offset = map()->instance_size() + (index * kPointerSize);
1396 return READ_FIELD(this, offset);
1397 } else {
1398 ASSERT(index < properties()->length());
1399 return properties()->get(index);
1400 }
1401}
1402
1403
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001404Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001405 // Adjust for the number of properties stored in the object.
1406 index -= map()->inobject_properties();
1407 if (index < 0) {
1408 int offset = map()->instance_size() + (index * kPointerSize);
1409 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001410 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001411 } else {
1412 ASSERT(index < properties()->length());
1413 properties()->set(index, value);
1414 }
1415 return value;
1416}
1417
1418
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001419int JSObject::GetInObjectPropertyOffset(int index) {
1420 // Adjust for the number of properties stored in the object.
1421 index -= map()->inobject_properties();
1422 ASSERT(index < 0);
1423 return map()->instance_size() + (index * kPointerSize);
1424}
1425
1426
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001427Object* JSObject::InObjectPropertyAt(int index) {
1428 // Adjust for the number of properties stored in the object.
1429 index -= map()->inobject_properties();
1430 ASSERT(index < 0);
1431 int offset = map()->instance_size() + (index * kPointerSize);
1432 return READ_FIELD(this, offset);
1433}
1434
1435
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001436Object* JSObject::InObjectPropertyAtPut(int index,
1437 Object* value,
1438 WriteBarrierMode mode) {
1439 // Adjust for the number of properties stored in the object.
1440 index -= map()->inobject_properties();
1441 ASSERT(index < 0);
1442 int offset = map()->instance_size() + (index * kPointerSize);
1443 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001444 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001445 return value;
1446}
1447
1448
1449
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001450void JSObject::InitializeBody(Map* map,
1451 Object* pre_allocated_value,
1452 Object* filler_value) {
1453 ASSERT(!filler_value->IsHeapObject() ||
1454 !GetHeap()->InNewSpace(filler_value));
1455 ASSERT(!pre_allocated_value->IsHeapObject() ||
1456 !GetHeap()->InNewSpace(pre_allocated_value));
1457 int size = map->instance_size();
1458 int offset = kHeaderSize;
1459 if (filler_value != pre_allocated_value) {
1460 int pre_allocated = map->pre_allocated_property_fields();
1461 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1462 for (int i = 0; i < pre_allocated; i++) {
1463 WRITE_FIELD(this, offset, pre_allocated_value);
1464 offset += kPointerSize;
1465 }
1466 }
1467 while (offset < size) {
1468 WRITE_FIELD(this, offset, filler_value);
1469 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001470 }
1471}
1472
1473
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001474bool JSObject::HasFastProperties() {
1475 return !properties()->IsDictionary();
1476}
1477
1478
1479int JSObject::MaxFastProperties() {
1480 // Allow extra fast properties if the object has more than
1481 // kMaxFastProperties in-object properties. When this is the case,
1482 // it is very unlikely that the object is being used as a dictionary
1483 // and there is a good chance that allowing more map transitions
1484 // will be worth it.
1485 return Max(map()->inobject_properties(), kMaxFastProperties);
1486}
1487
1488
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001489void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001490 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001491 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001492 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001493 }
1494}
1495
1496
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001497bool Object::ToArrayIndex(uint32_t* index) {
1498 if (IsSmi()) {
1499 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001500 if (value < 0) return false;
1501 *index = value;
1502 return true;
1503 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001504 if (IsHeapNumber()) {
1505 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001506 uint32_t uint_value = static_cast<uint32_t>(value);
1507 if (value == static_cast<double>(uint_value)) {
1508 *index = uint_value;
1509 return true;
1510 }
1511 }
1512 return false;
1513}
1514
1515
1516bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1517 if (!this->IsJSValue()) return false;
1518
1519 JSValue* js_value = JSValue::cast(this);
1520 if (!js_value->value()->IsString()) return false;
1521
1522 String* str = String::cast(js_value->value());
1523 if (index >= (uint32_t)str->length()) return false;
1524
1525 return true;
1526}
1527
1528
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001529FixedArrayBase* FixedArrayBase::cast(Object* object) {
1530 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1531 return reinterpret_cast<FixedArrayBase*>(object);
1532}
1533
1534
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001535Object* FixedArray::get(int index) {
1536 ASSERT(index >= 0 && index < this->length());
1537 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1538}
1539
1540
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001541void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001542 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001543 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001544 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1545 int offset = kHeaderSize + index * kPointerSize;
1546 WRITE_FIELD(this, offset, value);
1547}
1548
1549
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001550void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001551 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001552 ASSERT(index >= 0 && index < this->length());
1553 int offset = kHeaderSize + index * kPointerSize;
1554 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001555 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001556}
1557
1558
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001559inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1560 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1561}
1562
1563
1564inline double FixedDoubleArray::hole_nan_as_double() {
1565 return BitCast<double, uint64_t>(kHoleNanInt64);
1566}
1567
1568
1569inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1570 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1571 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1572 return OS::nan_value();
1573}
1574
1575
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001576double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001577 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1578 map() != HEAP->fixed_array_map());
1579 ASSERT(index >= 0 && index < this->length());
1580 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1581 ASSERT(!is_the_hole_nan(result));
1582 return result;
1583}
1584
1585
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001586MaybeObject* FixedDoubleArray::get(int index) {
1587 if (is_the_hole(index)) {
1588 return GetHeap()->the_hole_value();
1589 } else {
1590 return GetHeap()->NumberFromDouble(get_scalar(index));
1591 }
1592}
1593
1594
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001595void FixedDoubleArray::set(int index, double value) {
1596 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1597 map() != HEAP->fixed_array_map());
1598 int offset = kHeaderSize + index * kDoubleSize;
1599 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1600 WRITE_DOUBLE_FIELD(this, offset, value);
1601}
1602
1603
1604void FixedDoubleArray::set_the_hole(int index) {
1605 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1606 map() != HEAP->fixed_array_map());
1607 int offset = kHeaderSize + index * kDoubleSize;
1608 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1609}
1610
1611
1612bool FixedDoubleArray::is_the_hole(int index) {
1613 int offset = kHeaderSize + index * kDoubleSize;
1614 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1615}
1616
1617
1618void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1619 int old_length = from->length();
1620 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001621 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1622 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1623 FIELD_ADDR(from, kHeaderSize),
1624 old_length * kDoubleSize);
1625 } else {
1626 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001627 if (from->is_the_hole(i)) {
1628 set_the_hole(i);
1629 } else {
1630 set(i, from->get_scalar(i));
1631 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001632 }
1633 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001634 int offset = kHeaderSize + old_length * kDoubleSize;
1635 for (int current = from->length(); current < length(); ++current) {
1636 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1637 offset += kDoubleSize;
1638 }
1639}
1640
1641
1642void FixedDoubleArray::Initialize(FixedArray* from) {
1643 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001644 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001645 for (int i = 0; i < old_length; i++) {
1646 Object* hole_or_object = from->get(i);
1647 if (hole_or_object->IsTheHole()) {
1648 set_the_hole(i);
1649 } else {
1650 set(i, hole_or_object->Number());
1651 }
1652 }
1653 int offset = kHeaderSize + old_length * kDoubleSize;
1654 for (int current = from->length(); current < length(); ++current) {
1655 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1656 offset += kDoubleSize;
1657 }
1658}
1659
1660
1661void FixedDoubleArray::Initialize(NumberDictionary* from) {
1662 int offset = kHeaderSize;
1663 for (int current = 0; current < length(); ++current) {
1664 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1665 offset += kDoubleSize;
1666 }
1667 for (int i = 0; i < from->Capacity(); i++) {
1668 Object* key = from->KeyAt(i);
1669 if (key->IsNumber()) {
1670 uint32_t entry = static_cast<uint32_t>(key->Number());
1671 set(entry, from->ValueAt(i)->Number());
1672 }
1673 }
1674}
1675
1676
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001677WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001678 Heap* heap = GetHeap();
1679 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1680 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001681 return UPDATE_WRITE_BARRIER;
1682}
1683
1684
1685void FixedArray::set(int index,
1686 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001687 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001688 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001689 ASSERT(index >= 0 && index < this->length());
1690 int offset = kHeaderSize + index * kPointerSize;
1691 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001692 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001693}
1694
1695
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001696void FixedArray::NoWriteBarrierSet(FixedArray* array,
1697 int index,
1698 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001699 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001700 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001701 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001702 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1703}
1704
1705
1706void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001707 ASSERT(map() != HEAP->fixed_cow_array_map());
1708 set_undefined(GetHeap(), index);
1709}
1710
1711
1712void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001713 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001714 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001715 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001716 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001717}
1718
1719
ager@chromium.org236ad962008-09-25 09:45:57 +00001720void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001721 set_null(GetHeap(), index);
1722}
1723
1724
1725void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001726 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001727 ASSERT(!heap->InNewSpace(heap->null_value()));
1728 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001729}
1730
1731
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001732void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001733 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001734 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001735 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1736 WRITE_FIELD(this,
1737 kHeaderSize + index * kPointerSize,
1738 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001739}
1740
1741
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001742void FixedArray::set_unchecked(int index, Smi* value) {
1743 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1744 int offset = kHeaderSize + index * kPointerSize;
1745 WRITE_FIELD(this, offset, value);
1746}
1747
1748
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001749void FixedArray::set_unchecked(Heap* heap,
1750 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001751 Object* value,
1752 WriteBarrierMode mode) {
1753 int offset = kHeaderSize + index * kPointerSize;
1754 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001755 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001756}
1757
1758
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001759void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001760 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001761 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1762 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001763}
1764
1765
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001766Object** FixedArray::data_start() {
1767 return HeapObject::RawField(this, kHeaderSize);
1768}
1769
1770
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001771bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001772 ASSERT(this->IsSmi() ||
1773 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001774 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001775 return this->IsSmi() || length() <= kFirstIndex;
1776}
1777
1778
1779int DescriptorArray::bit_field3_storage() {
1780 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1781 return Smi::cast(storage)->value();
1782}
1783
1784void DescriptorArray::set_bit_field3_storage(int value) {
1785 ASSERT(!IsEmpty());
1786 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001787}
1788
1789
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001790void DescriptorArray::NoWriteBarrierSwap(FixedArray* array,
1791 int first,
1792 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001793 Object* tmp = array->get(first);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001794 NoWriteBarrierSet(array, first, array->get(second));
1795 NoWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001796}
1797
1798
1799int DescriptorArray::Search(String* name) {
1800 SLOW_ASSERT(IsSortedNoDuplicates());
1801
1802 // Check for empty descriptor array.
1803 int nof = number_of_descriptors();
1804 if (nof == 0) return kNotFound;
1805
1806 // Fast case: do linear search for small arrays.
1807 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001808 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001809 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001810 }
1811
1812 // Slow case: perform binary search.
1813 return BinarySearch(name, 0, nof - 1);
1814}
1815
1816
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001817int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001818 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001819 if (number == DescriptorLookupCache::kAbsent) {
1820 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001821 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001822 }
1823 return number;
1824}
1825
1826
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001827String* DescriptorArray::GetKey(int descriptor_number) {
1828 ASSERT(descriptor_number < number_of_descriptors());
1829 return String::cast(get(ToKeyIndex(descriptor_number)));
1830}
1831
1832
1833Object* DescriptorArray::GetValue(int descriptor_number) {
1834 ASSERT(descriptor_number < number_of_descriptors());
1835 return GetContentArray()->get(ToValueIndex(descriptor_number));
1836}
1837
1838
1839Smi* DescriptorArray::GetDetails(int descriptor_number) {
1840 ASSERT(descriptor_number < number_of_descriptors());
1841 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1842}
1843
1844
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001845PropertyType DescriptorArray::GetType(int descriptor_number) {
1846 ASSERT(descriptor_number < number_of_descriptors());
1847 return PropertyDetails(GetDetails(descriptor_number)).type();
1848}
1849
1850
1851int DescriptorArray::GetFieldIndex(int descriptor_number) {
1852 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1853}
1854
1855
1856JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1857 return JSFunction::cast(GetValue(descriptor_number));
1858}
1859
1860
1861Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1862 ASSERT(GetType(descriptor_number) == CALLBACKS);
1863 return GetValue(descriptor_number);
1864}
1865
1866
1867AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1868 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001869 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001870 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001871}
1872
1873
1874bool DescriptorArray::IsProperty(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001875 return IsRealProperty(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001876}
1877
1878
1879bool DescriptorArray::IsTransition(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001880 return IsTransitionType(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001881}
1882
1883
1884bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1885 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1886}
1887
1888
1889bool DescriptorArray::IsDontEnum(int descriptor_number) {
1890 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1891}
1892
1893
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001894void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1895 desc->Init(GetKey(descriptor_number),
1896 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001897 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001898}
1899
1900
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001901void DescriptorArray::Set(int descriptor_number,
1902 Descriptor* desc,
1903 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001904 // Range check.
1905 ASSERT(descriptor_number < number_of_descriptors());
1906
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001907 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001908 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1909 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001910
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001911 NoWriteBarrierSet(this,
1912 ToKeyIndex(descriptor_number),
1913 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001914 FixedArray* content_array = GetContentArray();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001915 NoWriteBarrierSet(content_array,
1916 ToValueIndex(descriptor_number),
1917 desc->GetValue());
1918 NoWriteBarrierSet(content_array,
1919 ToDetailsIndex(descriptor_number),
1920 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001921}
1922
1923
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001924void DescriptorArray::CopyFrom(int index,
1925 DescriptorArray* src,
1926 int src_index,
1927 const WhitenessWitness& witness) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001928 Descriptor desc;
1929 src->Get(src_index, &desc);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001930 Set(index, &desc, witness);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001931}
1932
1933
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001934void DescriptorArray::NoWriteBarrierSwapDescriptors(int first, int second) {
1935 NoWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001936 FixedArray* content_array = GetContentArray();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001937 NoWriteBarrierSwap(content_array,
1938 ToValueIndex(first),
1939 ToValueIndex(second));
1940 NoWriteBarrierSwap(content_array,
1941 ToDetailsIndex(first),
1942 ToDetailsIndex(second));
1943}
1944
1945
1946DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
1947 : marking_(array->GetHeap()->incremental_marking()) {
1948 marking_->EnterNoMarkingScope();
1949 if (array->number_of_descriptors() > 0) {
1950 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
1951 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
1952 }
1953}
1954
1955
1956DescriptorArray::WhitenessWitness::~WhitenessWitness() {
1957 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001958}
1959
1960
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001961template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001962int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
1963 const int kMinCapacity = 32;
1964 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
1965 if (capacity < kMinCapacity) {
1966 capacity = kMinCapacity; // Guarantee min capacity.
1967 }
1968 return capacity;
1969}
1970
1971
1972template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001973int HashTable<Shape, Key>::FindEntry(Key key) {
1974 return FindEntry(GetIsolate(), key);
1975}
1976
1977
1978// Find entry for key otherwise return kNotFound.
1979template<typename Shape, typename Key>
1980int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1981 uint32_t capacity = Capacity();
1982 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1983 uint32_t count = 1;
1984 // EnsureCapacity will guarantee the hash table is never full.
1985 while (true) {
1986 Object* element = KeyAt(entry);
1987 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001988 if (element != isolate->heap()->the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001989 Shape::IsMatch(key, element)) return entry;
1990 entry = NextProbe(entry, count++, capacity);
1991 }
1992 return kNotFound;
1993}
1994
1995
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001996bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001997 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001998 if (!max_index_object->IsSmi()) return false;
1999 return 0 !=
2000 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2001}
2002
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002003uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002004 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002005 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002006 if (!max_index_object->IsSmi()) return 0;
2007 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2008 return value >> kRequiresSlowElementsTagSize;
2009}
2010
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002011void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002012 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002013}
2014
2015
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002016// ------------------------------------
2017// Cast operations
2018
2019
2020CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002021CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002022CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002023CAST_ACCESSOR(DeoptimizationInputData)
2024CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002025CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002026CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002027CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002028CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002029CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002030CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002031CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002032CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002033CAST_ACCESSOR(String)
2034CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002035CAST_ACCESSOR(SeqAsciiString)
2036CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002037CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002038CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002039CAST_ACCESSOR(ExternalString)
2040CAST_ACCESSOR(ExternalAsciiString)
2041CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002042CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002043CAST_ACCESSOR(JSObject)
2044CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002045CAST_ACCESSOR(HeapObject)
2046CAST_ACCESSOR(HeapNumber)
2047CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002048CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049CAST_ACCESSOR(SharedFunctionInfo)
2050CAST_ACCESSOR(Map)
2051CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002052CAST_ACCESSOR(GlobalObject)
2053CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002054CAST_ACCESSOR(JSGlobalObject)
2055CAST_ACCESSOR(JSBuiltinsObject)
2056CAST_ACCESSOR(Code)
2057CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002058CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002059CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002060CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002061CAST_ACCESSOR(JSSet)
2062CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002063CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002064CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002065CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002066CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002067CAST_ACCESSOR(ExternalArray)
2068CAST_ACCESSOR(ExternalByteArray)
2069CAST_ACCESSOR(ExternalUnsignedByteArray)
2070CAST_ACCESSOR(ExternalShortArray)
2071CAST_ACCESSOR(ExternalUnsignedShortArray)
2072CAST_ACCESSOR(ExternalIntArray)
2073CAST_ACCESSOR(ExternalUnsignedIntArray)
2074CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002075CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002076CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002077CAST_ACCESSOR(Struct)
2078
2079
2080#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2081 STRUCT_LIST(MAKE_STRUCT_CAST)
2082#undef MAKE_STRUCT_CAST
2083
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002084
2085template <typename Shape, typename Key>
2086HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002087 ASSERT(obj->IsHashTable());
2088 return reinterpret_cast<HashTable*>(obj);
2089}
2090
2091
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002092SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002093SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002094
ager@chromium.orgac091b72010-05-05 07:34:42 +00002095SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002096
2097
2098uint32_t String::hash_field() {
2099 return READ_UINT32_FIELD(this, kHashFieldOffset);
2100}
2101
2102
2103void String::set_hash_field(uint32_t value) {
2104 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002105#if V8_HOST_ARCH_64_BIT
2106 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2107#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002108}
2109
2110
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002111bool String::Equals(String* other) {
2112 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002113 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2114 return false;
2115 }
2116 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117}
2118
2119
lrn@chromium.org303ada72010-10-27 09:33:13 +00002120MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002121 if (!StringShape(this).IsCons()) return this;
2122 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002123 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002124 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002125}
2126
2127
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002128String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002129 MaybeObject* flat = TryFlatten(pretenure);
2130 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002131 if (!flat->ToObject(&successfully_flattened)) return this;
2132 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002133}
2134
2135
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002136uint16_t String::Get(int index) {
2137 ASSERT(index >= 0 && index < length());
2138 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002139 case kSeqStringTag | kAsciiStringTag:
2140 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2141 case kSeqStringTag | kTwoByteStringTag:
2142 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2143 case kConsStringTag | kAsciiStringTag:
2144 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002145 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002146 case kExternalStringTag | kAsciiStringTag:
2147 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2148 case kExternalStringTag | kTwoByteStringTag:
2149 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002150 case kSlicedStringTag | kAsciiStringTag:
2151 case kSlicedStringTag | kTwoByteStringTag:
2152 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002153 default:
2154 break;
2155 }
2156
2157 UNREACHABLE();
2158 return 0;
2159}
2160
2161
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002162void String::Set(int index, uint16_t value) {
2163 ASSERT(index >= 0 && index < length());
2164 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002165
ager@chromium.org5ec48922009-05-05 07:25:34 +00002166 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002167 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2168 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002169}
2170
2171
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002172bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002173 if (!StringShape(this).IsCons()) return true;
2174 return ConsString::cast(this)->second()->length() == 0;
2175}
2176
2177
2178String* String::GetUnderlying() {
2179 // Giving direct access to underlying string only makes sense if the
2180 // wrapping string is already flattened.
2181 ASSERT(this->IsFlat());
2182 ASSERT(StringShape(this).IsIndirect());
2183 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2184 const int kUnderlyingOffset = SlicedString::kParentOffset;
2185 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002186}
2187
2188
ager@chromium.org7c537e22008-10-16 08:43:32 +00002189uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002190 ASSERT(index >= 0 && index < length());
2191 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2192}
2193
2194
ager@chromium.org7c537e22008-10-16 08:43:32 +00002195void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002196 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2197 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2198 static_cast<byte>(value));
2199}
2200
2201
ager@chromium.org7c537e22008-10-16 08:43:32 +00002202Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002203 return FIELD_ADDR(this, kHeaderSize);
2204}
2205
2206
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002207char* SeqAsciiString::GetChars() {
2208 return reinterpret_cast<char*>(GetCharsAddress());
2209}
2210
2211
ager@chromium.org7c537e22008-10-16 08:43:32 +00002212Address SeqTwoByteString::GetCharsAddress() {
2213 return FIELD_ADDR(this, kHeaderSize);
2214}
2215
2216
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002217uc16* SeqTwoByteString::GetChars() {
2218 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2219}
2220
2221
ager@chromium.org7c537e22008-10-16 08:43:32 +00002222uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002223 ASSERT(index >= 0 && index < length());
2224 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2225}
2226
2227
ager@chromium.org7c537e22008-10-16 08:43:32 +00002228void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002229 ASSERT(index >= 0 && index < length());
2230 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2231}
2232
2233
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002234int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002235 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002236}
2237
2238
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002239int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002240 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002241}
2242
2243
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002244String* SlicedString::parent() {
2245 return String::cast(READ_FIELD(this, kParentOffset));
2246}
2247
2248
2249void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002250 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002251 WRITE_FIELD(this, kParentOffset, parent);
2252}
2253
2254
2255SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2256
2257
ager@chromium.org870a0b62008-11-04 11:43:05 +00002258String* ConsString::first() {
2259 return String::cast(READ_FIELD(this, kFirstOffset));
2260}
2261
2262
2263Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002264 return READ_FIELD(this, kFirstOffset);
2265}
2266
2267
ager@chromium.org870a0b62008-11-04 11:43:05 +00002268void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002269 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002270 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002271}
2272
2273
ager@chromium.org870a0b62008-11-04 11:43:05 +00002274String* ConsString::second() {
2275 return String::cast(READ_FIELD(this, kSecondOffset));
2276}
2277
2278
2279Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002280 return READ_FIELD(this, kSecondOffset);
2281}
2282
2283
ager@chromium.org870a0b62008-11-04 11:43:05 +00002284void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002285 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002286 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002287}
2288
2289
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002290const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002291 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2292}
2293
2294
2295void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002296 const ExternalAsciiString::Resource* resource) {
2297 *reinterpret_cast<const Resource**>(
2298 FIELD_ADDR(this, kResourceOffset)) = resource;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002299}
2300
2301
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002302const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002303 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2304}
2305
2306
2307void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002308 const ExternalTwoByteString::Resource* resource) {
2309 *reinterpret_cast<const Resource**>(
2310 FIELD_ADDR(this, kResourceOffset)) = resource;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002311}
2312
2313
ager@chromium.orgac091b72010-05-05 07:34:42 +00002314void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002315 set_finger_index(kEntriesIndex);
2316 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002317}
2318
2319
2320void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002321 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002322 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002323 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002324 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002325 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002326 MakeZeroSize();
2327}
2328
2329
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002330int JSFunctionResultCache::size() {
2331 return Smi::cast(get(kCacheSizeIndex))->value();
2332}
2333
2334
2335void JSFunctionResultCache::set_size(int size) {
2336 set(kCacheSizeIndex, Smi::FromInt(size));
2337}
2338
2339
2340int JSFunctionResultCache::finger_index() {
2341 return Smi::cast(get(kFingerIndex))->value();
2342}
2343
2344
2345void JSFunctionResultCache::set_finger_index(int finger_index) {
2346 set(kFingerIndex, Smi::FromInt(finger_index));
2347}
2348
2349
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002350byte ByteArray::get(int index) {
2351 ASSERT(index >= 0 && index < this->length());
2352 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2353}
2354
2355
2356void ByteArray::set(int index, byte value) {
2357 ASSERT(index >= 0 && index < this->length());
2358 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2359}
2360
2361
2362int ByteArray::get_int(int index) {
2363 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2364 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2365}
2366
2367
2368ByteArray* ByteArray::FromDataStartAddress(Address address) {
2369 ASSERT_TAG_ALIGNED(address);
2370 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2371}
2372
2373
2374Address ByteArray::GetDataStartAddress() {
2375 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2376}
2377
2378
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002379uint8_t* ExternalPixelArray::external_pixel_pointer() {
2380 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002381}
2382
2383
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002384uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002385 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002386 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002387 return ptr[index];
2388}
2389
2390
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002391MaybeObject* ExternalPixelArray::get(int index) {
2392 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2393}
2394
2395
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002396void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002397 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002398 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002399 ptr[index] = value;
2400}
2401
2402
ager@chromium.org3811b432009-10-28 14:53:37 +00002403void* ExternalArray::external_pointer() {
2404 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2405 return reinterpret_cast<void*>(ptr);
2406}
2407
2408
2409void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2410 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2411 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2412}
2413
2414
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002415int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002416 ASSERT((index >= 0) && (index < this->length()));
2417 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2418 return ptr[index];
2419}
2420
2421
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002422MaybeObject* ExternalByteArray::get(int index) {
2423 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2424}
2425
2426
ager@chromium.org3811b432009-10-28 14:53:37 +00002427void ExternalByteArray::set(int index, int8_t value) {
2428 ASSERT((index >= 0) && (index < this->length()));
2429 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2430 ptr[index] = value;
2431}
2432
2433
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002434uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002435 ASSERT((index >= 0) && (index < this->length()));
2436 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2437 return ptr[index];
2438}
2439
2440
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002441MaybeObject* ExternalUnsignedByteArray::get(int index) {
2442 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2443}
2444
2445
ager@chromium.org3811b432009-10-28 14:53:37 +00002446void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2447 ASSERT((index >= 0) && (index < this->length()));
2448 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2449 ptr[index] = value;
2450}
2451
2452
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002453int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002454 ASSERT((index >= 0) && (index < this->length()));
2455 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2456 return ptr[index];
2457}
2458
2459
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002460MaybeObject* ExternalShortArray::get(int index) {
2461 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2462}
2463
2464
ager@chromium.org3811b432009-10-28 14:53:37 +00002465void ExternalShortArray::set(int index, int16_t value) {
2466 ASSERT((index >= 0) && (index < this->length()));
2467 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2468 ptr[index] = value;
2469}
2470
2471
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002472uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002473 ASSERT((index >= 0) && (index < this->length()));
2474 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2475 return ptr[index];
2476}
2477
2478
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002479MaybeObject* ExternalUnsignedShortArray::get(int index) {
2480 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2481}
2482
2483
ager@chromium.org3811b432009-10-28 14:53:37 +00002484void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2485 ASSERT((index >= 0) && (index < this->length()));
2486 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2487 ptr[index] = value;
2488}
2489
2490
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002491int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002492 ASSERT((index >= 0) && (index < this->length()));
2493 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2494 return ptr[index];
2495}
2496
2497
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002498MaybeObject* ExternalIntArray::get(int index) {
2499 return GetHeap()->NumberFromInt32(get_scalar(index));
2500}
2501
2502
ager@chromium.org3811b432009-10-28 14:53:37 +00002503void ExternalIntArray::set(int index, int32_t value) {
2504 ASSERT((index >= 0) && (index < this->length()));
2505 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2506 ptr[index] = value;
2507}
2508
2509
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002510uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002511 ASSERT((index >= 0) && (index < this->length()));
2512 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2513 return ptr[index];
2514}
2515
2516
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002517MaybeObject* ExternalUnsignedIntArray::get(int index) {
2518 return GetHeap()->NumberFromUint32(get_scalar(index));
2519}
2520
2521
ager@chromium.org3811b432009-10-28 14:53:37 +00002522void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2523 ASSERT((index >= 0) && (index < this->length()));
2524 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2525 ptr[index] = value;
2526}
2527
2528
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002529float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002530 ASSERT((index >= 0) && (index < this->length()));
2531 float* ptr = static_cast<float*>(external_pointer());
2532 return ptr[index];
2533}
2534
2535
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002536MaybeObject* ExternalFloatArray::get(int index) {
2537 return GetHeap()->NumberFromDouble(get_scalar(index));
2538}
2539
2540
ager@chromium.org3811b432009-10-28 14:53:37 +00002541void ExternalFloatArray::set(int index, float value) {
2542 ASSERT((index >= 0) && (index < this->length()));
2543 float* ptr = static_cast<float*>(external_pointer());
2544 ptr[index] = value;
2545}
2546
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002547
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002548double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002549 ASSERT((index >= 0) && (index < this->length()));
2550 double* ptr = static_cast<double*>(external_pointer());
2551 return ptr[index];
2552}
2553
2554
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002555MaybeObject* ExternalDoubleArray::get(int index) {
2556 return GetHeap()->NumberFromDouble(get_scalar(index));
2557}
2558
2559
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002560void ExternalDoubleArray::set(int index, double value) {
2561 ASSERT((index >= 0) && (index < this->length()));
2562 double* ptr = static_cast<double*>(external_pointer());
2563 ptr[index] = value;
2564}
2565
2566
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002567int Map::visitor_id() {
2568 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2569}
2570
2571
2572void Map::set_visitor_id(int id) {
2573 ASSERT(0 <= id && id < 256);
2574 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2575}
2576
ager@chromium.org3811b432009-10-28 14:53:37 +00002577
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002578int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002579 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2580}
2581
2582
2583int Map::inobject_properties() {
2584 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002585}
2586
2587
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002588int Map::pre_allocated_property_fields() {
2589 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2590}
2591
2592
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002593int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002594 int instance_size = map->instance_size();
2595 if (instance_size != kVariableSizeSentinel) return instance_size;
2596 // We can ignore the "symbol" bit becase it is only set for symbols
2597 // and implies a string type.
2598 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002599 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002600 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002601 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002602 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002603 if (instance_type == ASCII_STRING_TYPE) {
2604 return SeqAsciiString::SizeFor(
2605 reinterpret_cast<SeqAsciiString*>(this)->length());
2606 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002607 if (instance_type == BYTE_ARRAY_TYPE) {
2608 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2609 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002610 if (instance_type == FREE_SPACE_TYPE) {
2611 return reinterpret_cast<FreeSpace*>(this)->size();
2612 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002613 if (instance_type == STRING_TYPE) {
2614 return SeqTwoByteString::SizeFor(
2615 reinterpret_cast<SeqTwoByteString*>(this)->length());
2616 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002617 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2618 return FixedDoubleArray::SizeFor(
2619 reinterpret_cast<FixedDoubleArray*>(this)->length());
2620 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002621 ASSERT(instance_type == CODE_TYPE);
2622 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002623}
2624
2625
2626void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002627 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002628 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002629 ASSERT(0 <= value && value < 256);
2630 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2631}
2632
2633
ager@chromium.org7c537e22008-10-16 08:43:32 +00002634void Map::set_inobject_properties(int value) {
2635 ASSERT(0 <= value && value < 256);
2636 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2637}
2638
2639
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002640void Map::set_pre_allocated_property_fields(int value) {
2641 ASSERT(0 <= value && value < 256);
2642 WRITE_BYTE_FIELD(this,
2643 kPreAllocatedPropertyFieldsOffset,
2644 static_cast<byte>(value));
2645}
2646
2647
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002648InstanceType Map::instance_type() {
2649 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2650}
2651
2652
2653void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002654 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2655}
2656
2657
2658int Map::unused_property_fields() {
2659 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2660}
2661
2662
2663void Map::set_unused_property_fields(int value) {
2664 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2665}
2666
2667
2668byte Map::bit_field() {
2669 return READ_BYTE_FIELD(this, kBitFieldOffset);
2670}
2671
2672
2673void Map::set_bit_field(byte value) {
2674 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2675}
2676
2677
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002678byte Map::bit_field2() {
2679 return READ_BYTE_FIELD(this, kBitField2Offset);
2680}
2681
2682
2683void Map::set_bit_field2(byte value) {
2684 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2685}
2686
2687
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002688void Map::set_non_instance_prototype(bool value) {
2689 if (value) {
2690 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2691 } else {
2692 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2693 }
2694}
2695
2696
2697bool Map::has_non_instance_prototype() {
2698 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2699}
2700
2701
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002702void Map::set_function_with_prototype(bool value) {
2703 if (value) {
2704 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2705 } else {
2706 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2707 }
2708}
2709
2710
2711bool Map::function_with_prototype() {
2712 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2713}
2714
2715
ager@chromium.org870a0b62008-11-04 11:43:05 +00002716void Map::set_is_access_check_needed(bool access_check_needed) {
2717 if (access_check_needed) {
2718 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2719 } else {
2720 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2721 }
2722}
2723
2724
2725bool Map::is_access_check_needed() {
2726 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2727}
2728
2729
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002730void Map::set_is_extensible(bool value) {
2731 if (value) {
2732 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2733 } else {
2734 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2735 }
2736}
2737
2738bool Map::is_extensible() {
2739 return ((1 << kIsExtensible) & bit_field2()) != 0;
2740}
2741
2742
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002743void Map::set_attached_to_shared_function_info(bool value) {
2744 if (value) {
2745 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2746 } else {
2747 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2748 }
2749}
2750
2751bool Map::attached_to_shared_function_info() {
2752 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2753}
2754
2755
2756void Map::set_is_shared(bool value) {
2757 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002758 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002759 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002760 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002761 }
2762}
2763
2764bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002765 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002766}
2767
2768
2769JSFunction* Map::unchecked_constructor() {
2770 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2771}
2772
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002773
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002774Code::Flags Code::flags() {
2775 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2776}
2777
2778
2779void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002780 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002781 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002782 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2783 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002784 ExtractArgumentsCountFromFlags(flags) >= 0);
2785 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2786}
2787
2788
2789Code::Kind Code::kind() {
2790 return ExtractKindFromFlags(flags());
2791}
2792
2793
kasper.lund7276f142008-07-30 08:49:36 +00002794InlineCacheState Code::ic_state() {
2795 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002796 // Only allow uninitialized or debugger states for non-IC code
2797 // objects. This is used in the debugger to determine whether or not
2798 // a call to code object has been replaced with a debug break call.
2799 ASSERT(is_inline_cache_stub() ||
2800 result == UNINITIALIZED ||
2801 result == DEBUG_BREAK ||
2802 result == DEBUG_PREPARE_STEP_IN);
2803 return result;
2804}
2805
2806
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002807Code::ExtraICState Code::extra_ic_state() {
2808 ASSERT(is_inline_cache_stub());
2809 return ExtractExtraICStateFromFlags(flags());
2810}
2811
2812
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002813PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002814 return ExtractTypeFromFlags(flags());
2815}
2816
2817
2818int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002819 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002820 return ExtractArgumentsCountFromFlags(flags());
2821}
2822
2823
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002824int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002825 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002826 kind() == UNARY_OP_IC ||
2827 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002828 kind() == COMPARE_IC ||
2829 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002830 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002831}
2832
2833
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002834void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002835 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002836 kind() == UNARY_OP_IC ||
2837 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002838 kind() == COMPARE_IC ||
2839 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002840 ASSERT(0 <= major && major < 256);
2841 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002842}
2843
2844
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002845bool Code::is_pregenerated() {
2846 return kind() == STUB && IsPregeneratedField::decode(flags());
2847}
2848
2849
2850void Code::set_is_pregenerated(bool value) {
2851 ASSERT(kind() == STUB);
2852 Flags f = flags();
2853 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2854 set_flags(f);
2855}
2856
2857
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002858bool Code::optimizable() {
2859 ASSERT(kind() == FUNCTION);
2860 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2861}
2862
2863
2864void Code::set_optimizable(bool value) {
2865 ASSERT(kind() == FUNCTION);
2866 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2867}
2868
2869
2870bool Code::has_deoptimization_support() {
2871 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002872 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2873 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002874}
2875
2876
2877void Code::set_has_deoptimization_support(bool value) {
2878 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002879 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2880 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
2881 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2882}
2883
2884
2885bool Code::has_debug_break_slots() {
2886 ASSERT(kind() == FUNCTION);
2887 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2888 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
2889}
2890
2891
2892void Code::set_has_debug_break_slots(bool value) {
2893 ASSERT(kind() == FUNCTION);
2894 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2895 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
2896 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002897}
2898
2899
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002900bool Code::is_compiled_optimizable() {
2901 ASSERT(kind() == FUNCTION);
2902 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2903 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
2904}
2905
2906
2907void Code::set_compiled_optimizable(bool value) {
2908 ASSERT(kind() == FUNCTION);
2909 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2910 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
2911 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2912}
2913
2914
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002915int Code::allow_osr_at_loop_nesting_level() {
2916 ASSERT(kind() == FUNCTION);
2917 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2918}
2919
2920
2921void Code::set_allow_osr_at_loop_nesting_level(int level) {
2922 ASSERT(kind() == FUNCTION);
2923 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2924 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2925}
2926
2927
2928unsigned Code::stack_slots() {
2929 ASSERT(kind() == OPTIMIZED_FUNCTION);
2930 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2931}
2932
2933
2934void Code::set_stack_slots(unsigned slots) {
2935 ASSERT(kind() == OPTIMIZED_FUNCTION);
2936 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2937}
2938
2939
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002940unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002941 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002942 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002943}
2944
2945
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002946void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002947 ASSERT(kind() == OPTIMIZED_FUNCTION);
2948 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002949 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002950}
2951
2952
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002953unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002954 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002955 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002956}
2957
2958
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002959void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002960 ASSERT(kind() == FUNCTION);
2961 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002962 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002963}
2964
2965
2966CheckType Code::check_type() {
2967 ASSERT(is_call_stub() || is_keyed_call_stub());
2968 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2969 return static_cast<CheckType>(type);
2970}
2971
2972
2973void Code::set_check_type(CheckType value) {
2974 ASSERT(is_call_stub() || is_keyed_call_stub());
2975 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2976}
2977
2978
danno@chromium.org40cb8782011-05-25 07:58:50 +00002979byte Code::unary_op_type() {
2980 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002981 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2982}
2983
2984
danno@chromium.org40cb8782011-05-25 07:58:50 +00002985void Code::set_unary_op_type(byte value) {
2986 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002987 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2988}
2989
2990
danno@chromium.org40cb8782011-05-25 07:58:50 +00002991byte Code::binary_op_type() {
2992 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002993 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2994}
2995
2996
danno@chromium.org40cb8782011-05-25 07:58:50 +00002997void Code::set_binary_op_type(byte value) {
2998 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002999 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3000}
3001
3002
danno@chromium.org40cb8782011-05-25 07:58:50 +00003003byte Code::binary_op_result_type() {
3004 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003005 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3006}
3007
3008
danno@chromium.org40cb8782011-05-25 07:58:50 +00003009void Code::set_binary_op_result_type(byte value) {
3010 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003011 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3012}
3013
3014
3015byte Code::compare_state() {
3016 ASSERT(is_compare_ic_stub());
3017 return READ_BYTE_FIELD(this, kCompareStateOffset);
3018}
3019
3020
3021void Code::set_compare_state(byte value) {
3022 ASSERT(is_compare_ic_stub());
3023 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3024}
3025
3026
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003027byte Code::to_boolean_state() {
3028 ASSERT(is_to_boolean_ic_stub());
3029 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3030}
3031
3032
3033void Code::set_to_boolean_state(byte value) {
3034 ASSERT(is_to_boolean_ic_stub());
3035 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3036}
3037
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003038
3039bool Code::has_function_cache() {
3040 ASSERT(kind() == STUB);
3041 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3042}
3043
3044
3045void Code::set_has_function_cache(bool flag) {
3046 ASSERT(kind() == STUB);
3047 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3048}
3049
3050
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003051bool Code::is_inline_cache_stub() {
3052 Kind kind = this->kind();
3053 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3054}
3055
3056
3057Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003058 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003059 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003060 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003061 int argc,
3062 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003063 // Extra IC state is only allowed for call IC stubs or for store IC
3064 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003065 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003066 kind == CALL_IC ||
3067 kind == STORE_IC ||
3068 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003069 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003070 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003071 | ICStateField::encode(ic_state)
3072 | TypeField::encode(type)
3073 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003074 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003075 | CacheHolderField::encode(holder);
3076 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003077}
3078
3079
3080Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3081 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003082 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003083 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003084 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003085 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003086}
3087
3088
3089Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003090 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003091}
3092
3093
kasper.lund7276f142008-07-30 08:49:36 +00003094InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003095 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003096}
3097
3098
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003099Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003100 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003101}
3102
3103
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003104PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003105 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003106}
3107
3108
3109int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003110 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003111}
3112
3113
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003114InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003115 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003116}
3117
3118
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003119Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003120 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003121 return static_cast<Flags>(bits);
3122}
3123
3124
ager@chromium.org8bb60582008-12-11 12:02:20 +00003125Code* Code::GetCodeFromTargetAddress(Address address) {
3126 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3127 // GetCodeFromTargetAddress might be called when marking objects during mark
3128 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3129 // Code::cast. Code::cast does not work when the object's map is
3130 // marked.
3131 Code* result = reinterpret_cast<Code*>(code);
3132 return result;
3133}
3134
3135
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003136Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3137 return HeapObject::
3138 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3139}
3140
3141
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003142Object* Map::prototype() {
3143 return READ_FIELD(this, kPrototypeOffset);
3144}
3145
3146
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003147void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003148 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003149 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003150 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003151}
3152
3153
danno@chromium.org40cb8782011-05-25 07:58:50 +00003154DescriptorArray* Map::instance_descriptors() {
3155 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3156 if (object->IsSmi()) {
3157 return HEAP->empty_descriptor_array();
3158 } else {
3159 return DescriptorArray::cast(object);
3160 }
3161}
3162
3163
3164void Map::init_instance_descriptors() {
3165 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3166}
3167
3168
3169void Map::clear_instance_descriptors() {
3170 Object* object = READ_FIELD(this,
3171 kInstanceDescriptorsOrBitField3Offset);
3172 if (!object->IsSmi()) {
3173 WRITE_FIELD(
3174 this,
3175 kInstanceDescriptorsOrBitField3Offset,
3176 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3177 }
3178}
3179
3180
3181void Map::set_instance_descriptors(DescriptorArray* value,
3182 WriteBarrierMode mode) {
3183 Object* object = READ_FIELD(this,
3184 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003185 Heap* heap = GetHeap();
3186 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003187 clear_instance_descriptors();
3188 return;
3189 } else {
3190 if (object->IsSmi()) {
3191 value->set_bit_field3_storage(Smi::cast(object)->value());
3192 } else {
3193 value->set_bit_field3_storage(
3194 DescriptorArray::cast(object)->bit_field3_storage());
3195 }
3196 }
3197 ASSERT(!is_shared());
3198 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003199 CONDITIONAL_WRITE_BARRIER(
3200 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003201}
3202
3203
3204int Map::bit_field3() {
3205 Object* object = READ_FIELD(this,
3206 kInstanceDescriptorsOrBitField3Offset);
3207 if (object->IsSmi()) {
3208 return Smi::cast(object)->value();
3209 } else {
3210 return DescriptorArray::cast(object)->bit_field3_storage();
3211 }
3212}
3213
3214
3215void Map::set_bit_field3(int value) {
3216 ASSERT(Smi::IsValid(value));
3217 Object* object = READ_FIELD(this,
3218 kInstanceDescriptorsOrBitField3Offset);
3219 if (object->IsSmi()) {
3220 WRITE_FIELD(this,
3221 kInstanceDescriptorsOrBitField3Offset,
3222 Smi::FromInt(value));
3223 } else {
3224 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3225 }
3226}
3227
3228
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003229FixedArray* Map::unchecked_prototype_transitions() {
3230 return reinterpret_cast<FixedArray*>(
3231 READ_FIELD(this, kPrototypeTransitionsOffset));
3232}
3233
3234
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003235ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003236ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003237ACCESSORS(Map, constructor, Object, kConstructorOffset)
3238
3239ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003240ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003241ACCESSORS(JSFunction,
3242 next_function_link,
3243 Object,
3244 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003245
3246ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3247ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003248ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003249
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003250ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003251
3252ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3253ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3254ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3255ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3256ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3257
3258ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3259ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3260ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3261
3262ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3263ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3264ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3265ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3266ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3267ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3268
3269ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3270ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3271
3272ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3273ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3274
3275ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3276ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003277ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3278 kPropertyAccessorsOffset)
3279ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3280 kPrototypeTemplateOffset)
3281ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3282ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3283 kNamedPropertyHandlerOffset)
3284ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3285 kIndexedPropertyHandlerOffset)
3286ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3287 kInstanceTemplateOffset)
3288ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3289ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003290ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3291 kInstanceCallHandlerOffset)
3292ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3293 kAccessCheckInfoOffset)
3294ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3295
3296ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003297ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3298 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003299
3300ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3301ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3302
3303ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3304
3305ACCESSORS(Script, source, Object, kSourceOffset)
3306ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003307ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003308ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3309ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003310ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003311ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003312ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003313ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003314ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003315ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003316ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003317ACCESSORS(Script, eval_from_instructions_offset, Smi,
3318 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003319
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003320#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003321ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3322ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3323ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3324ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3325
3326ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3327ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3328ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3329ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003330#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003331
3332ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003333ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3334ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003335ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3336 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003337ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003338ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3339ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003340ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003341ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3342 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003343
3344BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3345 kHiddenPrototypeBit)
3346BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3347BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3348 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003349BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3350 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003351BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3352 kIsExpressionBit)
3353BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3354 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003355BOOL_GETTER(SharedFunctionInfo,
3356 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003357 has_only_simple_this_property_assignments,
3358 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003359BOOL_ACCESSORS(SharedFunctionInfo,
3360 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003361 allows_lazy_compilation,
3362 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003363BOOL_ACCESSORS(SharedFunctionInfo,
3364 compiler_hints,
3365 uses_arguments,
3366 kUsesArguments)
3367BOOL_ACCESSORS(SharedFunctionInfo,
3368 compiler_hints,
3369 has_duplicate_parameters,
3370 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003371
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003372
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003373#if V8_HOST_ARCH_32_BIT
3374SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3375SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003376 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003377SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003378 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003379SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3380SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003381 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003382SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3383SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003384 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003385SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003386 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003387SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003388 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003389SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003390#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003391
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003392#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003393 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003394 int holder::name() { \
3395 int value = READ_INT_FIELD(this, offset); \
3396 ASSERT(kHeapObjectTag == 1); \
3397 ASSERT((value & kHeapObjectTag) == 0); \
3398 return value >> 1; \
3399 } \
3400 void holder::set_##name(int value) { \
3401 ASSERT(kHeapObjectTag == 1); \
3402 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3403 (value & 0xC0000000) == 0x000000000); \
3404 WRITE_INT_FIELD(this, \
3405 offset, \
3406 (value << 1) & ~kHeapObjectTag); \
3407 }
3408
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003409#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3410 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003411 INT_ACCESSORS(holder, name, offset)
3412
3413
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003414PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003415PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3416 formal_parameter_count,
3417 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003418
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003419PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3420 expected_nof_properties,
3421 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003422PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3423
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003424PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3425PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3426 start_position_and_type,
3427 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003428
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003429PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3430 function_token_position,
3431 kFunctionTokenPositionOffset)
3432PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3433 compiler_hints,
3434 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003435
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003436PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3437 this_property_assignments_count,
3438 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003439PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003440#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003441
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003442
3443int SharedFunctionInfo::construction_count() {
3444 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3445}
3446
3447
3448void SharedFunctionInfo::set_construction_count(int value) {
3449 ASSERT(0 <= value && value < 256);
3450 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3451}
3452
3453
whesse@chromium.org7b260152011-06-20 15:33:18 +00003454BOOL_ACCESSORS(SharedFunctionInfo,
3455 compiler_hints,
3456 live_objects_may_exist,
3457 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003458
3459
3460bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003461 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003462}
3463
3464
whesse@chromium.org7b260152011-06-20 15:33:18 +00003465BOOL_GETTER(SharedFunctionInfo,
3466 compiler_hints,
3467 optimization_disabled,
3468 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003469
3470
3471void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3472 set_compiler_hints(BooleanBit::set(compiler_hints(),
3473 kOptimizationDisabled,
3474 disable));
3475 // If disabling optimizations we reflect that in the code object so
3476 // it will not be counted as optimizable code.
3477 if ((code()->kind() == Code::FUNCTION) && disable) {
3478 code()->set_optimizable(false);
3479 }
3480}
3481
3482
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003483StrictModeFlag SharedFunctionInfo::strict_mode_flag() {
3484 return BooleanBit::get(compiler_hints(), kStrictModeFunction)
3485 ? kStrictMode : kNonStrictMode;
3486}
3487
3488
3489void SharedFunctionInfo::set_strict_mode_flag(StrictModeFlag strict_mode_flag) {
3490 ASSERT(strict_mode_flag == kStrictMode ||
3491 strict_mode_flag == kNonStrictMode);
3492 bool value = strict_mode_flag == kStrictMode;
3493 set_compiler_hints(
3494 BooleanBit::set(compiler_hints(), kStrictModeFunction, value));
3495}
3496
3497
3498BOOL_GETTER(SharedFunctionInfo, compiler_hints, strict_mode,
3499 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003500BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3501BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3502 name_should_print_as_anonymous,
3503 kNameShouldPrintAsAnonymous)
3504BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3505BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003506
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003507ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3508ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3509
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003510ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3511
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003512bool Script::HasValidSource() {
3513 Object* src = this->source();
3514 if (!src->IsString()) return true;
3515 String* src_str = String::cast(src);
3516 if (!StringShape(src_str).IsExternal()) return true;
3517 if (src_str->IsAsciiRepresentation()) {
3518 return ExternalAsciiString::cast(src)->resource() != NULL;
3519 } else if (src_str->IsTwoByteRepresentation()) {
3520 return ExternalTwoByteString::cast(src)->resource() != NULL;
3521 }
3522 return true;
3523}
3524
3525
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003526void SharedFunctionInfo::DontAdaptArguments() {
3527 ASSERT(code()->kind() == Code::BUILTIN);
3528 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3529}
3530
3531
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003532int SharedFunctionInfo::start_position() {
3533 return start_position_and_type() >> kStartPositionShift;
3534}
3535
3536
3537void SharedFunctionInfo::set_start_position(int start_position) {
3538 set_start_position_and_type((start_position << kStartPositionShift)
3539 | (start_position_and_type() & ~kStartPositionMask));
3540}
3541
3542
3543Code* SharedFunctionInfo::code() {
3544 return Code::cast(READ_FIELD(this, kCodeOffset));
3545}
3546
3547
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003548Code* SharedFunctionInfo::unchecked_code() {
3549 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3550}
3551
3552
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003553void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003554 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003555 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003556}
3557
3558
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003559ScopeInfo* SharedFunctionInfo::scope_info() {
3560 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003561}
3562
3563
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003564void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003565 WriteBarrierMode mode) {
3566 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003567 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3568 this,
3569 kScopeInfoOffset,
3570 reinterpret_cast<Object*>(value),
3571 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003572}
3573
3574
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003575Smi* SharedFunctionInfo::deopt_counter() {
3576 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3577}
3578
3579
3580void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3581 WRITE_FIELD(this, kDeoptCounterOffset, value);
3582}
3583
3584
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003585bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003586 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003587 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003588}
3589
3590
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003591bool SharedFunctionInfo::IsApiFunction() {
3592 return function_data()->IsFunctionTemplateInfo();
3593}
3594
3595
3596FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3597 ASSERT(IsApiFunction());
3598 return FunctionTemplateInfo::cast(function_data());
3599}
3600
3601
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003602bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003603 return function_data()->IsSmi();
3604}
3605
3606
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003607BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3608 ASSERT(HasBuiltinFunctionId());
3609 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003610}
3611
3612
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003613int SharedFunctionInfo::code_age() {
3614 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3615}
3616
3617
3618void SharedFunctionInfo::set_code_age(int code_age) {
3619 set_compiler_hints(compiler_hints() |
3620 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3621}
3622
3623
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003624bool SharedFunctionInfo::has_deoptimization_support() {
3625 Code* code = this->code();
3626 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3627}
3628
3629
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003630bool JSFunction::IsBuiltin() {
3631 return context()->global()->IsJSBuiltinsObject();
3632}
3633
3634
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003635bool JSFunction::NeedsArgumentsAdaption() {
3636 return shared()->formal_parameter_count() !=
3637 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3638}
3639
3640
3641bool JSFunction::IsOptimized() {
3642 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3643}
3644
3645
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003646bool JSFunction::IsOptimizable() {
3647 return code()->kind() == Code::FUNCTION && code()->optimizable();
3648}
3649
3650
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003651bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003652 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003653}
3654
3655
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003656Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003657 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003658}
3659
3660
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003661Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003662 return reinterpret_cast<Code*>(
3663 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003664}
3665
3666
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003667void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003668 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003669 Address entry = value->entry();
3670 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003671 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3672 this,
3673 HeapObject::RawField(this, kCodeEntryOffset),
3674 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003675}
3676
3677
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003678void JSFunction::ReplaceCode(Code* code) {
3679 bool was_optimized = IsOptimized();
3680 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3681
3682 set_code(code);
3683
3684 // Add/remove the function from the list of optimized functions for this
3685 // context based on the state change.
3686 if (!was_optimized && is_optimized) {
3687 context()->global_context()->AddOptimizedFunction(this);
3688 }
3689 if (was_optimized && !is_optimized) {
3690 context()->global_context()->RemoveOptimizedFunction(this);
3691 }
3692}
3693
3694
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003695Context* JSFunction::context() {
3696 return Context::cast(READ_FIELD(this, kContextOffset));
3697}
3698
3699
3700Object* JSFunction::unchecked_context() {
3701 return READ_FIELD(this, kContextOffset);
3702}
3703
3704
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003705SharedFunctionInfo* JSFunction::unchecked_shared() {
3706 return reinterpret_cast<SharedFunctionInfo*>(
3707 READ_FIELD(this, kSharedFunctionInfoOffset));
3708}
3709
3710
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003711void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003712 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003713 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003714 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003715}
3716
3717ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3718 kPrototypeOrInitialMapOffset)
3719
3720
3721Map* JSFunction::initial_map() {
3722 return Map::cast(prototype_or_initial_map());
3723}
3724
3725
3726void JSFunction::set_initial_map(Map* value) {
3727 set_prototype_or_initial_map(value);
3728}
3729
3730
3731bool JSFunction::has_initial_map() {
3732 return prototype_or_initial_map()->IsMap();
3733}
3734
3735
3736bool JSFunction::has_instance_prototype() {
3737 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3738}
3739
3740
3741bool JSFunction::has_prototype() {
3742 return map()->has_non_instance_prototype() || has_instance_prototype();
3743}
3744
3745
3746Object* JSFunction::instance_prototype() {
3747 ASSERT(has_instance_prototype());
3748 if (has_initial_map()) return initial_map()->prototype();
3749 // When there is no initial map and the prototype is a JSObject, the
3750 // initial map field is used for the prototype field.
3751 return prototype_or_initial_map();
3752}
3753
3754
3755Object* JSFunction::prototype() {
3756 ASSERT(has_prototype());
3757 // If the function's prototype property has been set to a non-JSObject
3758 // value, that value is stored in the constructor field of the map.
3759 if (map()->has_non_instance_prototype()) return map()->constructor();
3760 return instance_prototype();
3761}
3762
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003763bool JSFunction::should_have_prototype() {
3764 return map()->function_with_prototype();
3765}
3766
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003767
3768bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003769 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003770}
3771
3772
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003773FixedArray* JSFunction::literals() {
3774 ASSERT(!shared()->bound());
3775 return literals_or_bindings();
3776}
3777
3778
3779void JSFunction::set_literals(FixedArray* literals) {
3780 ASSERT(!shared()->bound());
3781 set_literals_or_bindings(literals);
3782}
3783
3784
3785FixedArray* JSFunction::function_bindings() {
3786 ASSERT(shared()->bound());
3787 return literals_or_bindings();
3788}
3789
3790
3791void JSFunction::set_function_bindings(FixedArray* bindings) {
3792 ASSERT(shared()->bound());
3793 // Bound function literal may be initialized to the empty fixed array
3794 // before the bindings are set.
3795 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
3796 bindings->map() == GetHeap()->fixed_cow_array_map());
3797 set_literals_or_bindings(bindings);
3798}
3799
3800
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003801int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003802 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003803 return literals()->length();
3804}
3805
3806
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003807Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003808 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003809 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003810}
3811
3812
3813void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3814 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003815 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003816 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003817 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003818}
3819
3820
3821Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003822 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003823 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3824}
3825
3826
3827void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3828 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003829 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003830 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003831 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003832}
3833
3834
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003835ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003836ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003837ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3838ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3839
3840
3841void JSProxy::InitializeBody(int object_size, Object* value) {
3842 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3843 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3844 WRITE_FIELD(this, offset, value);
3845 }
3846}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003847
3848
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003849ACCESSORS(JSSet, table, Object, kTableOffset)
3850ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003851ACCESSORS(JSWeakMap, table, Object, kTableOffset)
3852ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003853
3854
3855ObjectHashTable* JSWeakMap::unchecked_table() {
3856 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3857}
3858
3859
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003860Address Foreign::foreign_address() {
3861 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003862}
3863
3864
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003865void Foreign::set_foreign_address(Address value) {
3866 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003867}
3868
3869
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003870ACCESSORS(JSValue, value, Object, kValueOffset)
3871
3872
3873JSValue* JSValue::cast(Object* obj) {
3874 ASSERT(obj->IsJSValue());
3875 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3876 return reinterpret_cast<JSValue*>(obj);
3877}
3878
3879
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003880ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3881ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3882ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3883ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3884ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3885SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3886SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3887
3888
3889JSMessageObject* JSMessageObject::cast(Object* obj) {
3890 ASSERT(obj->IsJSMessageObject());
3891 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3892 return reinterpret_cast<JSMessageObject*>(obj);
3893}
3894
3895
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003896INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003897ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00003898ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003899ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003900ACCESSORS(Code, next_code_flushing_candidate,
3901 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003902
3903
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003904byte* Code::instruction_start() {
3905 return FIELD_ADDR(this, kHeaderSize);
3906}
3907
3908
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003909byte* Code::instruction_end() {
3910 return instruction_start() + instruction_size();
3911}
3912
3913
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003914int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003915 return RoundUp(instruction_size(), kObjectAlignment);
3916}
3917
3918
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003919FixedArray* Code::unchecked_deoptimization_data() {
3920 return reinterpret_cast<FixedArray*>(
3921 READ_FIELD(this, kDeoptimizationDataOffset));
3922}
3923
3924
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003925ByteArray* Code::unchecked_relocation_info() {
3926 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003927}
3928
3929
3930byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003931 return unchecked_relocation_info()->GetDataStartAddress();
3932}
3933
3934
3935int Code::relocation_size() {
3936 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003937}
3938
3939
3940byte* Code::entry() {
3941 return instruction_start();
3942}
3943
3944
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003945bool Code::contains(byte* inner_pointer) {
3946 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003947}
3948
3949
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003950ACCESSORS(JSArray, length, Object, kLengthOffset)
3951
3952
ager@chromium.org236ad962008-09-25 09:45:57 +00003953ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003954
3955
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003956JSRegExp::Type JSRegExp::TypeTag() {
3957 Object* data = this->data();
3958 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3959 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3960 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003961}
3962
3963
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003964JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3965 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3966 return static_cast<JSRegExp::Type>(smi->value());
3967}
3968
3969
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003970int JSRegExp::CaptureCount() {
3971 switch (TypeTag()) {
3972 case ATOM:
3973 return 0;
3974 case IRREGEXP:
3975 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3976 default:
3977 UNREACHABLE();
3978 return -1;
3979 }
3980}
3981
3982
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003983JSRegExp::Flags JSRegExp::GetFlags() {
3984 ASSERT(this->data()->IsFixedArray());
3985 Object* data = this->data();
3986 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3987 return Flags(smi->value());
3988}
3989
3990
3991String* JSRegExp::Pattern() {
3992 ASSERT(this->data()->IsFixedArray());
3993 Object* data = this->data();
3994 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3995 return pattern;
3996}
3997
3998
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003999Object* JSRegExp::DataAt(int index) {
4000 ASSERT(TypeTag() != NOT_COMPILED);
4001 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004002}
4003
4004
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004005Object* JSRegExp::DataAtUnchecked(int index) {
4006 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4007 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4008 return READ_FIELD(fa, offset);
4009}
4010
4011
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004012void JSRegExp::SetDataAt(int index, Object* value) {
4013 ASSERT(TypeTag() != NOT_COMPILED);
4014 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4015 FixedArray::cast(data())->set(index, value);
4016}
4017
4018
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004019void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4020 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4021 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4022 if (value->IsSmi()) {
4023 fa->set_unchecked(index, Smi::cast(value));
4024 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004025 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004026 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4027 }
4028}
4029
4030
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004031ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004032 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004033#if DEBUG
4034 FixedArrayBase* fixed_array =
4035 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4036 Map* map = fixed_array->map();
4037 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004038 (map == GetHeap()->fixed_array_map() ||
4039 map == GetHeap()->fixed_cow_array_map())) ||
4040 (kind == FAST_DOUBLE_ELEMENTS &&
4041 fixed_array->IsFixedDoubleArray()) ||
4042 (kind == DICTIONARY_ELEMENTS &&
4043 fixed_array->IsFixedArray() &&
4044 fixed_array->IsDictionary()) ||
4045 (kind > DICTIONARY_ELEMENTS));
4046 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4047 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004048#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004049 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004050}
4051
4052
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004053ElementsAccessor* JSObject::GetElementsAccessor() {
4054 return ElementsAccessor::ForKind(GetElementsKind());
4055}
4056
4057
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004058bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004059 return GetElementsKind() == FAST_ELEMENTS;
4060}
4061
4062
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004063bool JSObject::HasFastSmiOnlyElements() {
4064 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4065}
4066
4067
4068bool JSObject::HasFastTypeElements() {
4069 ElementsKind elements_kind = GetElementsKind();
4070 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4071 elements_kind == FAST_ELEMENTS;
4072}
4073
4074
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004075bool JSObject::HasFastDoubleElements() {
4076 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4077}
4078
4079
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004080bool JSObject::HasDictionaryElements() {
4081 return GetElementsKind() == DICTIONARY_ELEMENTS;
4082}
4083
4084
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004085bool JSObject::HasNonStrictArgumentsElements() {
4086 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4087}
4088
4089
ager@chromium.org3811b432009-10-28 14:53:37 +00004090bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004091 HeapObject* array = elements();
4092 ASSERT(array != NULL);
4093 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004094}
4095
4096
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004097#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4098bool JSObject::HasExternal##name##Elements() { \
4099 HeapObject* array = elements(); \
4100 ASSERT(array != NULL); \
4101 if (!array->IsHeapObject()) \
4102 return false; \
4103 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004104}
4105
4106
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004107EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4108EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4109EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4110EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4111 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4112EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4113EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4114 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4115EXTERNAL_ELEMENTS_CHECK(Float,
4116 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004117EXTERNAL_ELEMENTS_CHECK(Double,
4118 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004119EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004120
4121
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004122bool JSObject::HasNamedInterceptor() {
4123 return map()->has_named_interceptor();
4124}
4125
4126
4127bool JSObject::HasIndexedInterceptor() {
4128 return map()->has_indexed_interceptor();
4129}
4130
4131
ager@chromium.org5c838252010-02-19 08:53:10 +00004132bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004133 bool result = elements()->IsFixedArray() ||
4134 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004135 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004136 return result;
4137}
4138
4139
lrn@chromium.org303ada72010-10-27 09:33:13 +00004140MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004141 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004142 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004143 Isolate* isolate = GetIsolate();
4144 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004145 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004146 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4147 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004148 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4149 return maybe_writable_elems;
4150 }
4151 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004152 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004153 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004154 return writable_elems;
4155}
4156
4157
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004158StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004159 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004160 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004161}
4162
4163
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004164NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004165 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004166 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004167}
4168
4169
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004170bool String::IsHashFieldComputed(uint32_t field) {
4171 return (field & kHashNotComputedMask) == 0;
4172}
4173
4174
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004175bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004176 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004177}
4178
4179
4180uint32_t String::Hash() {
4181 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004182 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004183 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004184 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004185 return ComputeAndSetHash();
4186}
4187
4188
ager@chromium.org7c537e22008-10-16 08:43:32 +00004189StringHasher::StringHasher(int length)
4190 : length_(length),
4191 raw_running_hash_(0),
4192 array_index_(0),
4193 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4194 is_first_char_(true),
4195 is_valid_(true) { }
4196
4197
4198bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004199 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004200}
4201
4202
4203void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004204 // Use the Jenkins one-at-a-time hash function to update the hash
4205 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004206 raw_running_hash_ += c;
4207 raw_running_hash_ += (raw_running_hash_ << 10);
4208 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004209 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004210 if (is_array_index_) {
4211 if (c < '0' || c > '9') {
4212 is_array_index_ = false;
4213 } else {
4214 int d = c - '0';
4215 if (is_first_char_) {
4216 is_first_char_ = false;
4217 if (c == '0' && length_ > 1) {
4218 is_array_index_ = false;
4219 return;
4220 }
4221 }
4222 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4223 is_array_index_ = false;
4224 } else {
4225 array_index_ = array_index_ * 10 + d;
4226 }
4227 }
4228 }
4229}
4230
4231
4232void StringHasher::AddCharacterNoIndex(uc32 c) {
4233 ASSERT(!is_array_index());
4234 raw_running_hash_ += c;
4235 raw_running_hash_ += (raw_running_hash_ << 10);
4236 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4237}
4238
4239
4240uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004241 // Get the calculated raw hash value and do some more bit ops to distribute
4242 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004243 uint32_t result = raw_running_hash_;
4244 result += (result << 3);
4245 result ^= (result >> 11);
4246 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004247 if (result == 0) {
4248 result = 27;
4249 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004250 return result;
4251}
4252
4253
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004254template <typename schar>
4255uint32_t HashSequentialString(const schar* chars, int length) {
4256 StringHasher hasher(length);
4257 if (!hasher.has_trivial_hash()) {
4258 int i;
4259 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4260 hasher.AddCharacter(chars[i]);
4261 }
4262 for (; i < length; i++) {
4263 hasher.AddCharacterNoIndex(chars[i]);
4264 }
4265 }
4266 return hasher.GetHashField();
4267}
4268
4269
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004270bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004271 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004272 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4273 return false;
4274 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004275 return SlowAsArrayIndex(index);
4276}
4277
4278
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004279Object* JSReceiver::GetPrototype() {
4280 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004281}
4282
4283
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004284bool JSReceiver::HasProperty(String* name) {
4285 if (IsJSProxy()) {
4286 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4287 }
4288 return GetPropertyAttribute(name) != ABSENT;
4289}
4290
4291
4292bool JSReceiver::HasLocalProperty(String* name) {
4293 if (IsJSProxy()) {
4294 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4295 }
4296 return GetLocalPropertyAttribute(name) != ABSENT;
4297}
4298
4299
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004300PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004301 return GetPropertyAttributeWithReceiver(this, key);
4302}
4303
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004304// TODO(504): this may be useful in other places too where JSGlobalProxy
4305// is used.
4306Object* JSObject::BypassGlobalProxy() {
4307 if (IsJSGlobalProxy()) {
4308 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004309 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004310 ASSERT(proto->IsJSGlobalObject());
4311 return proto;
4312 }
4313 return this;
4314}
4315
4316
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004317MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4318 return IsJSProxy()
4319 ? JSProxy::cast(this)->GetIdentityHash(flag)
4320 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004321}
4322
4323
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004324bool JSReceiver::HasElement(uint32_t index) {
4325 if (IsJSProxy()) {
4326 return JSProxy::cast(this)->HasElementWithHandler(index);
4327 }
4328 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004329}
4330
4331
4332bool AccessorInfo::all_can_read() {
4333 return BooleanBit::get(flag(), kAllCanReadBit);
4334}
4335
4336
4337void AccessorInfo::set_all_can_read(bool value) {
4338 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4339}
4340
4341
4342bool AccessorInfo::all_can_write() {
4343 return BooleanBit::get(flag(), kAllCanWriteBit);
4344}
4345
4346
4347void AccessorInfo::set_all_can_write(bool value) {
4348 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4349}
4350
4351
ager@chromium.org870a0b62008-11-04 11:43:05 +00004352bool AccessorInfo::prohibits_overwriting() {
4353 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4354}
4355
4356
4357void AccessorInfo::set_prohibits_overwriting(bool value) {
4358 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4359}
4360
4361
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004362PropertyAttributes AccessorInfo::property_attributes() {
4363 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4364}
4365
4366
4367void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004368 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004369}
4370
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004371
4372template<typename Shape, typename Key>
4373void Dictionary<Shape, Key>::SetEntry(int entry,
4374 Object* key,
4375 Object* value) {
4376 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4377}
4378
4379
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004380template<typename Shape, typename Key>
4381void Dictionary<Shape, Key>::SetEntry(int entry,
4382 Object* key,
4383 Object* value,
4384 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004385 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004386 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004387 AssertNoAllocation no_gc;
4388 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004389 FixedArray::set(index, key, mode);
4390 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004391 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004392}
4393
4394
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004395bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4396 ASSERT(other->IsNumber());
4397 return key == static_cast<uint32_t>(other->Number());
4398}
4399
4400
4401uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4402 return ComputeIntegerHash(key);
4403}
4404
4405
4406uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4407 ASSERT(other->IsNumber());
4408 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4409}
4410
4411
4412MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4413 return Isolate::Current()->heap()->NumberFromUint32(key);
4414}
4415
4416
4417bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4418 // We know that all entries in a hash table had their hash keys created.
4419 // Use that knowledge to have fast failure.
4420 if (key->Hash() != String::cast(other)->Hash()) return false;
4421 return key->Equals(String::cast(other));
4422}
4423
4424
4425uint32_t StringDictionaryShape::Hash(String* key) {
4426 return key->Hash();
4427}
4428
4429
4430uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4431 return String::cast(other)->Hash();
4432}
4433
4434
4435MaybeObject* StringDictionaryShape::AsObject(String* key) {
4436 return key;
4437}
4438
4439
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004440template <int entrysize>
4441bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4442 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004443}
4444
4445
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004446template <int entrysize>
4447uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004448 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4449 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004450}
4451
4452
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004453template <int entrysize>
4454uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4455 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004456 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4457 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004458}
4459
4460
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004461template <int entrysize>
4462MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004463 return key;
4464}
4465
4466
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004467void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004468 // No write barrier is needed since empty_fixed_array is not in new space.
4469 // Please note this function is used during marking:
4470 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004471 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4472 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004473}
4474
4475
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004476void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004477 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004478 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004479 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4480 if (elts->length() < required_size) {
4481 // Doubling in size would be overkill, but leave some slack to avoid
4482 // constantly growing.
4483 Expand(required_size + (required_size >> 3));
4484 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004485 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004486 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4487 // Expand will allocate a new backing store in new space even if the size
4488 // we asked for isn't larger than what we had before.
4489 Expand(required_size);
4490 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004491}
4492
4493
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004494void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004495 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004496 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4497}
4498
4499
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004500MaybeObject* JSArray::SetContent(FixedArray* storage) {
4501 MaybeObject* maybe_object = EnsureCanContainElements(storage);
4502 if (maybe_object->IsFailure()) return maybe_object;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004503 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004504 set_elements(storage);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004505 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004506}
4507
4508
lrn@chromium.org303ada72010-10-27 09:33:13 +00004509MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004510 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004511 return GetHeap()->CopyFixedArray(this);
4512}
4513
4514
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004515MaybeObject* FixedDoubleArray::Copy() {
4516 if (length() == 0) return this;
4517 return GetHeap()->CopyFixedDoubleArray(this);
4518}
4519
4520
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004521Relocatable::Relocatable(Isolate* isolate) {
4522 ASSERT(isolate == Isolate::Current());
4523 isolate_ = isolate;
4524 prev_ = isolate->relocatable_top();
4525 isolate->set_relocatable_top(this);
4526}
4527
4528
4529Relocatable::~Relocatable() {
4530 ASSERT(isolate_ == Isolate::Current());
4531 ASSERT_EQ(isolate_->relocatable_top(), this);
4532 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004533}
4534
4535
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004536int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4537 return map->instance_size();
4538}
4539
4540
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004541void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004542 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004543 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004544}
4545
4546
4547template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004548void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004549 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004550 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004551}
4552
4553
4554void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4555 typedef v8::String::ExternalAsciiStringResource Resource;
4556 v->VisitExternalAsciiString(
4557 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4558}
4559
4560
4561template<typename StaticVisitor>
4562void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4563 typedef v8::String::ExternalAsciiStringResource Resource;
4564 StaticVisitor::VisitExternalAsciiString(
4565 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4566}
4567
4568
4569void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4570 typedef v8::String::ExternalStringResource Resource;
4571 v->VisitExternalTwoByteString(
4572 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4573}
4574
4575
4576template<typename StaticVisitor>
4577void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4578 typedef v8::String::ExternalStringResource Resource;
4579 StaticVisitor::VisitExternalTwoByteString(
4580 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4581}
4582
4583#define SLOT_ADDR(obj, offset) \
4584 reinterpret_cast<Object**>((obj)->address() + offset)
4585
4586template<int start_offset, int end_offset, int size>
4587void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4588 HeapObject* obj,
4589 ObjectVisitor* v) {
4590 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4591}
4592
4593
4594template<int start_offset>
4595void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4596 int object_size,
4597 ObjectVisitor* v) {
4598 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4599}
4600
4601#undef SLOT_ADDR
4602
4603
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004604#undef CAST_ACCESSOR
4605#undef INT_ACCESSORS
4606#undef SMI_ACCESSORS
4607#undef ACCESSORS
4608#undef FIELD_ADDR
4609#undef READ_FIELD
4610#undef WRITE_FIELD
4611#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004612#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004613#undef READ_MEMADDR_FIELD
4614#undef WRITE_MEMADDR_FIELD
4615#undef READ_DOUBLE_FIELD
4616#undef WRITE_DOUBLE_FIELD
4617#undef READ_INT_FIELD
4618#undef WRITE_INT_FIELD
4619#undef READ_SHORT_FIELD
4620#undef WRITE_SHORT_FIELD
4621#undef READ_BYTE_FIELD
4622#undef WRITE_BYTE_FIELD
4623
4624
4625} } // namespace v8::internal
4626
4627#endif // V8_OBJECTS_INL_H_