blob: 9da480ea743a6df283a4228a51669acccafa37ad [file] [log] [blame]
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001// Copyright 2011 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000038#include "elements.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000039#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040#include "contexts.h"
41#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000042#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000043#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000045#include "spaces.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000046#include "store-buffer.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000047#include "v8memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000049#include "incremental-marking.h"
50
kasperl@chromium.org71affb52009-05-26 05:44:31 +000051namespace v8 {
52namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000053
54PropertyDetails::PropertyDetails(Smi* smi) {
55 value_ = smi->value();
56}
57
58
59Smi* PropertyDetails::AsSmi() {
60 return Smi::FromInt(value_);
61}
62
63
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000064PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000065 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000066 return PropertyDetails(smi);
67}
68
69
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000070#define TYPE_CHECKER(type, instancetype) \
71 bool Object::Is##type() { \
72 return Object::IsHeapObject() && \
73 HeapObject::cast(this)->map()->instance_type() == instancetype; \
74 }
75
76
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077#define CAST_ACCESSOR(type) \
78 type* type::cast(Object* object) { \
79 ASSERT(object->Is##type()); \
80 return reinterpret_cast<type*>(object); \
81 }
82
83
84#define INT_ACCESSORS(holder, name, offset) \
85 int holder::name() { return READ_INT_FIELD(this, offset); } \
86 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
87
88
89#define ACCESSORS(holder, name, type, offset) \
90 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000091 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000093 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094 }
95
96
97#define SMI_ACCESSORS(holder, name, offset) \
98 int holder::name() { \
99 Object* value = READ_FIELD(this, offset); \
100 return Smi::cast(value)->value(); \
101 } \
102 void holder::set_##name(int value) { \
103 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
104 }
105
106
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000107#define BOOL_GETTER(holder, field, name, offset) \
108 bool holder::name() { \
109 return BooleanBit::get(field(), offset); \
110 } \
111
112
113#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000114 bool holder::name() { \
115 return BooleanBit::get(field(), offset); \
116 } \
117 void holder::set_##name(bool value) { \
118 set_##field(BooleanBit::set(field(), offset, value)); \
119 }
120
121
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000122bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
123 ElementsKind to_kind) {
124 if (to_kind == FAST_ELEMENTS) {
125 return from_kind == FAST_SMI_ONLY_ELEMENTS ||
126 from_kind == FAST_DOUBLE_ELEMENTS;
127 } else {
128 return to_kind == FAST_DOUBLE_ELEMENTS &&
129 from_kind == FAST_SMI_ONLY_ELEMENTS;
130 }
131}
132
133
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000134bool Object::IsFixedArrayBase() {
135 return IsFixedArray() || IsFixedDoubleArray();
136}
137
138
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000139bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
140 // There is a constraint on the object; check.
141 if (!this->IsJSObject()) return false;
142 // Fetch the constructor function of the object.
143 Object* cons_obj = JSObject::cast(this)->map()->constructor();
144 if (!cons_obj->IsJSFunction()) return false;
145 JSFunction* fun = JSFunction::cast(cons_obj);
146 // Iterate through the chain of inheriting function templates to
147 // see if the required one occurs.
148 for (Object* type = fun->shared()->function_data();
149 type->IsFunctionTemplateInfo();
150 type = FunctionTemplateInfo::cast(type)->parent_template()) {
151 if (type == expected) return true;
152 }
153 // Didn't find the required type in the inheritance chain.
154 return false;
155}
156
157
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000158bool Object::IsSmi() {
159 return HAS_SMI_TAG(this);
160}
161
162
163bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000164 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000165}
166
167
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000168bool Object::NonFailureIsHeapObject() {
169 ASSERT(!this->IsFailure());
170 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
171}
172
173
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000174TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000175
176
177bool Object::IsString() {
178 return Object::IsHeapObject()
179 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
180}
181
182
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000183bool Object::IsSpecObject() {
184 return Object::IsHeapObject()
185 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
186}
187
188
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000189bool Object::IsSpecFunction() {
190 if (!Object::IsHeapObject()) return false;
191 InstanceType type = HeapObject::cast(this)->map()->instance_type();
192 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
193}
194
195
ager@chromium.org870a0b62008-11-04 11:43:05 +0000196bool Object::IsSymbol() {
197 if (!this->IsHeapObject()) return false;
198 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000199 // Because the symbol tag is non-zero and no non-string types have the
200 // symbol bit set we can test for symbols with a very simple test
201 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000202 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000203 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
204 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000205}
206
207
208bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000209 if (!IsString()) return false;
210 return StringShape(String::cast(this)).IsCons();
211}
212
213
214bool Object::IsSlicedString() {
215 if (!IsString()) return false;
216 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000217}
218
219
ager@chromium.org870a0b62008-11-04 11:43:05 +0000220bool Object::IsSeqString() {
221 if (!IsString()) return false;
222 return StringShape(String::cast(this)).IsSequential();
223}
224
225
226bool Object::IsSeqAsciiString() {
227 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000228 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000229 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000230}
231
232
233bool Object::IsSeqTwoByteString() {
234 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000235 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000236 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000237}
238
239
240bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000241 if (!IsString()) return false;
242 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243}
244
245
246bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000247 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000248 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000249 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000250}
251
252
253bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000254 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000255 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000256 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000257}
258
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000259bool Object::HasValidElements() {
260 // Dictionary is covered under FixedArray.
261 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
262}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000263
ager@chromium.org870a0b62008-11-04 11:43:05 +0000264StringShape::StringShape(String* str)
265 : type_(str->map()->instance_type()) {
266 set_valid();
267 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000268}
269
270
ager@chromium.org870a0b62008-11-04 11:43:05 +0000271StringShape::StringShape(Map* map)
272 : type_(map->instance_type()) {
273 set_valid();
274 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000275}
276
277
ager@chromium.org870a0b62008-11-04 11:43:05 +0000278StringShape::StringShape(InstanceType t)
279 : type_(static_cast<uint32_t>(t)) {
280 set_valid();
281 ASSERT((type_ & kIsNotStringMask) == kStringTag);
282}
283
284
285bool StringShape::IsSymbol() {
286 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000287 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000288 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000289}
290
291
ager@chromium.org5ec48922009-05-05 07:25:34 +0000292bool String::IsAsciiRepresentation() {
293 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000294 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000295}
296
297
ager@chromium.org5ec48922009-05-05 07:25:34 +0000298bool String::IsTwoByteRepresentation() {
299 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000300 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000301}
302
303
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000304bool String::IsAsciiRepresentationUnderneath() {
305 uint32_t type = map()->instance_type();
306 STATIC_ASSERT(kIsIndirectStringTag != 0);
307 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
308 ASSERT(IsFlat());
309 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
310 case kAsciiStringTag:
311 return true;
312 case kTwoByteStringTag:
313 return false;
314 default: // Cons or sliced string. Need to go deeper.
315 return GetUnderlying()->IsAsciiRepresentation();
316 }
317}
318
319
320bool String::IsTwoByteRepresentationUnderneath() {
321 uint32_t type = map()->instance_type();
322 STATIC_ASSERT(kIsIndirectStringTag != 0);
323 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
324 ASSERT(IsFlat());
325 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
326 case kAsciiStringTag:
327 return false;
328 case kTwoByteStringTag:
329 return true;
330 default: // Cons or sliced string. Need to go deeper.
331 return GetUnderlying()->IsTwoByteRepresentation();
332 }
333}
334
335
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000336bool String::HasOnlyAsciiChars() {
337 uint32_t type = map()->instance_type();
338 return (type & kStringEncodingMask) == kAsciiStringTag ||
339 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000340}
341
342
ager@chromium.org870a0b62008-11-04 11:43:05 +0000343bool StringShape::IsCons() {
344 return (type_ & kStringRepresentationMask) == kConsStringTag;
345}
346
347
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000348bool StringShape::IsSliced() {
349 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
350}
351
352
353bool StringShape::IsIndirect() {
354 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
355}
356
357
ager@chromium.org870a0b62008-11-04 11:43:05 +0000358bool StringShape::IsExternal() {
359 return (type_ & kStringRepresentationMask) == kExternalStringTag;
360}
361
362
363bool StringShape::IsSequential() {
364 return (type_ & kStringRepresentationMask) == kSeqStringTag;
365}
366
367
368StringRepresentationTag StringShape::representation_tag() {
369 uint32_t tag = (type_ & kStringRepresentationMask);
370 return static_cast<StringRepresentationTag>(tag);
371}
372
373
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000374uint32_t StringShape::encoding_tag() {
375 return type_ & kStringEncodingMask;
376}
377
378
ager@chromium.org870a0b62008-11-04 11:43:05 +0000379uint32_t StringShape::full_representation_tag() {
380 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
381}
382
383
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000384STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
385 Internals::kFullStringRepresentationMask);
386
387
ager@chromium.org870a0b62008-11-04 11:43:05 +0000388bool StringShape::IsSequentialAscii() {
389 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
390}
391
392
393bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000394 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000395}
396
397
398bool StringShape::IsExternalAscii() {
399 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
400}
401
402
403bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000404 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000405}
406
407
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000408STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
409 Internals::kExternalTwoByteRepresentationTag);
410
411
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000412uc32 FlatStringReader::Get(int index) {
413 ASSERT(0 <= index && index <= length_);
414 if (is_ascii_) {
415 return static_cast<const byte*>(start_)[index];
416 } else {
417 return static_cast<const uc16*>(start_)[index];
418 }
419}
420
421
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000422bool Object::IsNumber() {
423 return IsSmi() || IsHeapNumber();
424}
425
426
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000427TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
428TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000429
430
431bool Object::IsFiller() {
432 if (!Object::IsHeapObject()) return false;
433 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
434 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
435}
436
437
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000438TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000439
440
ager@chromium.org3811b432009-10-28 14:53:37 +0000441bool Object::IsExternalArray() {
442 if (!Object::IsHeapObject())
443 return false;
444 InstanceType instance_type =
445 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000446 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
447 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000448}
449
450
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000451TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
452TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
453TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
454TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
455TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
456TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
457TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
458TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000459
460
lrn@chromium.org303ada72010-10-27 09:33:13 +0000461bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000462 return HAS_FAILURE_TAG(this);
463}
464
465
lrn@chromium.org303ada72010-10-27 09:33:13 +0000466bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000467 return HAS_FAILURE_TAG(this)
468 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
469}
470
471
lrn@chromium.org303ada72010-10-27 09:33:13 +0000472bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000473 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000474 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000475}
476
477
lrn@chromium.org303ada72010-10-27 09:33:13 +0000478bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000479 return this == Failure::Exception();
480}
481
482
lrn@chromium.org303ada72010-10-27 09:33:13 +0000483bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000484 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000485}
486
487
488Failure* Failure::cast(MaybeObject* obj) {
489 ASSERT(HAS_FAILURE_TAG(obj));
490 return reinterpret_cast<Failure*>(obj);
491}
492
493
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000494bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000495 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000496 return IsHeapObject() &&
497 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
498}
499
500
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000501bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000502 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
503 return IsHeapObject() &&
504 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000505}
506
507
508bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000509 if (!Object::IsHeapObject()) return false;
510 InstanceType type = HeapObject::cast(this)->map()->instance_type();
511 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000512}
513
514
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000515TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
516TYPE_CHECKER(JSSet, JS_SET_TYPE)
517TYPE_CHECKER(JSMap, JS_MAP_TYPE)
518TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
519TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
520TYPE_CHECKER(Map, MAP_TYPE)
521TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
522TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000523
524
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000525bool Object::IsDescriptorArray() {
526 return IsFixedArray();
527}
528
529
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000530bool Object::IsDeoptimizationInputData() {
531 // Must be a fixed array.
532 if (!IsFixedArray()) return false;
533
534 // There's no sure way to detect the difference between a fixed array and
535 // a deoptimization data array. Since this is used for asserts we can
536 // check that the length is zero or else the fixed size plus a multiple of
537 // the entry size.
538 int length = FixedArray::cast(this)->length();
539 if (length == 0) return true;
540
541 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
542 return length >= 0 &&
543 length % DeoptimizationInputData::kDeoptEntrySize == 0;
544}
545
546
547bool Object::IsDeoptimizationOutputData() {
548 if (!IsFixedArray()) return false;
549 // There's actually no way to see the difference between a fixed array and
550 // a deoptimization data array. Since this is used for asserts we can check
551 // that the length is plausible though.
552 if (FixedArray::cast(this)->length() % 2 != 0) return false;
553 return true;
554}
555
556
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000557bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000558 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000559 Map* map = HeapObject::cast(this)->map();
560 Heap* heap = map->GetHeap();
561 return (map == heap->function_context_map() ||
562 map == heap->catch_context_map() ||
563 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000564 map == heap->global_context_map() ||
565 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000566 }
567 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000568}
569
570
571bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000572 return Object::IsHeapObject() &&
573 HeapObject::cast(this)->map() ==
574 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000575}
576
577
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000578bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000579 return Object::IsHeapObject() &&
580 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000581 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000582}
583
584
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000585TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000586
587
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000588template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000589 return obj->IsJSFunction();
590}
591
592
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000593TYPE_CHECKER(Code, CODE_TYPE)
594TYPE_CHECKER(Oddball, ODDBALL_TYPE)
595TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
596TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
597TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
598TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000599
600
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000601bool Object::IsStringWrapper() {
602 return IsJSValue() && JSValue::cast(this)->value()->IsString();
603}
604
605
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000606TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000607
608
609bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000610 return IsOddball() &&
611 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000612}
613
614
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000615TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
616TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000617
618
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000619template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620 return obj->IsJSArray();
621}
622
623
624bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000625 return Object::IsHeapObject() &&
626 HeapObject::cast(this)->map() ==
627 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000628}
629
630
631bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000632 return IsHashTable() &&
633 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000634}
635
636
637bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000638 return IsHashTable() && this ==
639 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000640}
641
642
ager@chromium.orgac091b72010-05-05 07:34:42 +0000643bool Object::IsJSFunctionResultCache() {
644 if (!IsFixedArray()) return false;
645 FixedArray* self = FixedArray::cast(this);
646 int length = self->length();
647 if (length < JSFunctionResultCache::kEntriesIndex) return false;
648 if ((length - JSFunctionResultCache::kEntriesIndex)
649 % JSFunctionResultCache::kEntrySize != 0) {
650 return false;
651 }
652#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000653 if (FLAG_verify_heap) {
654 reinterpret_cast<JSFunctionResultCache*>(this)->
655 JSFunctionResultCacheVerify();
656 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000657#endif
658 return true;
659}
660
661
ricow@chromium.org65fae842010-08-25 15:26:24 +0000662bool Object::IsNormalizedMapCache() {
663 if (!IsFixedArray()) return false;
664 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
665 return false;
666 }
667#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000668 if (FLAG_verify_heap) {
669 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
670 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000671#endif
672 return true;
673}
674
675
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000676bool Object::IsCompilationCacheTable() {
677 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000678}
679
680
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000681bool Object::IsCodeCacheHashTable() {
682 return IsHashTable();
683}
684
685
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000686bool Object::IsPolymorphicCodeCacheHashTable() {
687 return IsHashTable();
688}
689
690
ager@chromium.org236ad962008-09-25 09:45:57 +0000691bool Object::IsMapCache() {
692 return IsHashTable();
693}
694
695
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000696bool Object::IsPrimitive() {
697 return IsOddball() || IsNumber() || IsString();
698}
699
700
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000701bool Object::IsJSGlobalProxy() {
702 bool result = IsHeapObject() &&
703 (HeapObject::cast(this)->map()->instance_type() ==
704 JS_GLOBAL_PROXY_TYPE);
705 ASSERT(!result || IsAccessCheckNeeded());
706 return result;
707}
708
709
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000710bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000711 if (!IsHeapObject()) return false;
712
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000713 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000714 return type == JS_GLOBAL_OBJECT_TYPE ||
715 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000716}
717
718
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000719TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
720TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000721
722
723bool Object::IsUndetectableObject() {
724 return IsHeapObject()
725 && HeapObject::cast(this)->map()->is_undetectable();
726}
727
728
729bool Object::IsAccessCheckNeeded() {
730 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000731 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000732}
733
734
735bool Object::IsStruct() {
736 if (!IsHeapObject()) return false;
737 switch (HeapObject::cast(this)->map()->instance_type()) {
738#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
739 STRUCT_LIST(MAKE_STRUCT_CASE)
740#undef MAKE_STRUCT_CASE
741 default: return false;
742 }
743}
744
745
746#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
747 bool Object::Is##Name() { \
748 return Object::IsHeapObject() \
749 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
750 }
751 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
752#undef MAKE_STRUCT_PREDICATE
753
754
755bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000756 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000757}
758
759
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000760bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000761 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
762}
763
764
765bool Object::IsTheHole() {
766 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000767}
768
769
770bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000771 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000772}
773
774
775bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000776 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777}
778
779
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000780bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000781 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000782}
783
784
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000785double Object::Number() {
786 ASSERT(IsNumber());
787 return IsSmi()
788 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
789 : reinterpret_cast<HeapNumber*>(this)->value();
790}
791
792
lrn@chromium.org303ada72010-10-27 09:33:13 +0000793MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000794 if (IsSmi()) return this;
795 if (IsHeapNumber()) {
796 double value = HeapNumber::cast(this)->value();
797 int int_value = FastD2I(value);
798 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
799 return Smi::FromInt(int_value);
800 }
801 }
802 return Failure::Exception();
803}
804
805
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000806bool Object::HasSpecificClassOf(String* name) {
807 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
808}
809
810
lrn@chromium.org303ada72010-10-27 09:33:13 +0000811MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000812 // GetElement can trigger a getter which can cause allocation.
813 // This was not always the case. This ASSERT is here to catch
814 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000815 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000816 return GetElementWithReceiver(this, index);
817}
818
819
lrn@chromium.org303ada72010-10-27 09:33:13 +0000820Object* Object::GetElementNoExceptionThrown(uint32_t index) {
821 MaybeObject* maybe = GetElementWithReceiver(this, index);
822 ASSERT(!maybe->IsFailure());
823 Object* result = NULL; // Initialization to please compiler.
824 maybe->ToObject(&result);
825 return result;
826}
827
828
829MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000830 PropertyAttributes attributes;
831 return GetPropertyWithReceiver(this, key, &attributes);
832}
833
834
lrn@chromium.org303ada72010-10-27 09:33:13 +0000835MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000836 return GetPropertyWithReceiver(this, key, attributes);
837}
838
839
840#define FIELD_ADDR(p, offset) \
841 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
842
843#define READ_FIELD(p, offset) \
844 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
845
846#define WRITE_FIELD(p, offset, value) \
847 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
848
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000849#define WRITE_BARRIER(heap, object, offset, value) \
850 heap->incremental_marking()->RecordWrite( \
851 object, HeapObject::RawField(object, offset), value); \
852 if (heap->InNewSpace(value)) { \
853 heap->RecordWrite(object->address(), offset); \
854 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000855
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000856#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
857 if (mode == UPDATE_WRITE_BARRIER) { \
858 heap->incremental_marking()->RecordWrite( \
859 object, HeapObject::RawField(object, offset), value); \
860 if (heap->InNewSpace(value)) { \
861 heap->RecordWrite(object->address(), offset); \
862 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000863 }
864
lrn@chromium.org7516f052011-03-30 08:52:27 +0000865#ifndef V8_TARGET_ARCH_MIPS
866 #define READ_DOUBLE_FIELD(p, offset) \
867 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
868#else // V8_TARGET_ARCH_MIPS
869 // Prevent gcc from using load-double (mips ldc1) on (possibly)
870 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000871 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000872 union conversion {
873 double d;
874 uint32_t u[2];
875 } c;
876 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
877 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
878 return c.d;
879 }
880 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
881#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000882
lrn@chromium.org7516f052011-03-30 08:52:27 +0000883#ifndef V8_TARGET_ARCH_MIPS
884 #define WRITE_DOUBLE_FIELD(p, offset, value) \
885 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
886#else // V8_TARGET_ARCH_MIPS
887 // Prevent gcc from using store-double (mips sdc1) on (possibly)
888 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000889 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000890 double value) {
891 union conversion {
892 double d;
893 uint32_t u[2];
894 } c;
895 c.d = value;
896 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
897 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
898 }
899 #define WRITE_DOUBLE_FIELD(p, offset, value) \
900 write_double_field(p, offset, value)
901#endif // V8_TARGET_ARCH_MIPS
902
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000903
904#define READ_INT_FIELD(p, offset) \
905 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
906
907#define WRITE_INT_FIELD(p, offset, value) \
908 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
909
ager@chromium.org3e875802009-06-29 08:26:34 +0000910#define READ_INTPTR_FIELD(p, offset) \
911 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
912
913#define WRITE_INTPTR_FIELD(p, offset, value) \
914 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
915
ager@chromium.org7c537e22008-10-16 08:43:32 +0000916#define READ_UINT32_FIELD(p, offset) \
917 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
918
919#define WRITE_UINT32_FIELD(p, offset, value) \
920 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000922#define READ_SHORT_FIELD(p, offset) \
923 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
924
925#define WRITE_SHORT_FIELD(p, offset, value) \
926 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
927
928#define READ_BYTE_FIELD(p, offset) \
929 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
930
931#define WRITE_BYTE_FIELD(p, offset, value) \
932 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
933
934
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000935Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
936 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000937}
938
939
940int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000941 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000942}
943
944
945Smi* Smi::FromInt(int value) {
946 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000947 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000948 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000949 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000950 return reinterpret_cast<Smi*>(tagged_value);
951}
952
953
954Smi* Smi::FromIntptr(intptr_t value) {
955 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000956 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
957 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958}
959
960
961Failure::Type Failure::type() const {
962 return static_cast<Type>(value() & kFailureTypeTagMask);
963}
964
965
966bool Failure::IsInternalError() const {
967 return type() == INTERNAL_ERROR;
968}
969
970
971bool Failure::IsOutOfMemoryException() const {
972 return type() == OUT_OF_MEMORY_EXCEPTION;
973}
974
975
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000976AllocationSpace Failure::allocation_space() const {
977 ASSERT_EQ(RETRY_AFTER_GC, type());
978 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
979 & kSpaceTagMask);
980}
981
982
983Failure* Failure::InternalError() {
984 return Construct(INTERNAL_ERROR);
985}
986
987
988Failure* Failure::Exception() {
989 return Construct(EXCEPTION);
990}
991
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000992
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000993Failure* Failure::OutOfMemoryException() {
994 return Construct(OUT_OF_MEMORY_EXCEPTION);
995}
996
997
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000998intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000999 return static_cast<intptr_t>(
1000 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001001}
1002
1003
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001004Failure* Failure::RetryAfterGC() {
1005 return RetryAfterGC(NEW_SPACE);
1006}
1007
1008
1009Failure* Failure::RetryAfterGC(AllocationSpace space) {
1010 ASSERT((space & ~kSpaceTagMask) == 0);
1011 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001012}
1013
1014
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001015Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001016 uintptr_t info =
1017 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001018 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001019 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020}
1021
1022
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001023bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001024#ifdef DEBUG
1025 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1026#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001027
1028#ifdef V8_TARGET_ARCH_X64
1029 // To be representable as a long smi, the value must be a 32-bit integer.
1030 bool result = (value == static_cast<int32_t>(value));
1031#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001032 // To be representable as an tagged small integer, the two
1033 // most-significant bits of 'value' must be either 00 or 11 due to
1034 // sign-extension. To check this we add 01 to the two
1035 // most-significant bits, and check if the most-significant bit is 0
1036 //
1037 // CAUTION: The original code below:
1038 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1039 // may lead to incorrect results according to the C language spec, and
1040 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1041 // compiler may produce undefined results in case of signed integer
1042 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001043 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001044#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001045 ASSERT(result == in_range);
1046 return result;
1047}
1048
1049
kasper.lund7276f142008-07-30 08:49:36 +00001050MapWord MapWord::FromMap(Map* map) {
1051 return MapWord(reinterpret_cast<uintptr_t>(map));
1052}
1053
1054
1055Map* MapWord::ToMap() {
1056 return reinterpret_cast<Map*>(value_);
1057}
1058
1059
1060bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001061 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001062}
1063
1064
1065MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001066 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1067 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001068}
1069
1070
1071HeapObject* MapWord::ToForwardingAddress() {
1072 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001073 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001074}
1075
1076
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001077#ifdef DEBUG
1078void HeapObject::VerifyObjectField(int offset) {
1079 VerifyPointer(READ_FIELD(this, offset));
1080}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001081
1082void HeapObject::VerifySmiField(int offset) {
1083 ASSERT(READ_FIELD(this, offset)->IsSmi());
1084}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001085#endif
1086
1087
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001088Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001089 Heap* heap =
1090 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1091 ASSERT(heap != NULL);
1092 ASSERT(heap->isolate() == Isolate::Current());
1093 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001094}
1095
1096
1097Isolate* HeapObject::GetIsolate() {
1098 return GetHeap()->isolate();
1099}
1100
1101
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001102Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001103 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001104}
1105
1106
1107void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001108 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001109 if (value != NULL) {
1110 // TODO(1600) We are passing NULL as a slot because maps can never be on
1111 // evacuation candidate.
1112 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1113 }
1114}
1115
1116
1117// Unsafe accessor omitting write barrier.
1118void HeapObject::set_map_unsafe(Map* value) {
1119 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001120}
1121
1122
kasper.lund7276f142008-07-30 08:49:36 +00001123MapWord HeapObject::map_word() {
1124 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1125}
1126
1127
1128void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001129 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001130 // here.
1131 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1132}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001133
1134
1135HeapObject* HeapObject::FromAddress(Address address) {
1136 ASSERT_TAG_ALIGNED(address);
1137 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1138}
1139
1140
1141Address HeapObject::address() {
1142 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1143}
1144
1145
1146int HeapObject::Size() {
1147 return SizeFromMap(map());
1148}
1149
1150
1151void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1152 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1153 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1154}
1155
1156
1157void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1158 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1159}
1160
1161
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001162double HeapNumber::value() {
1163 return READ_DOUBLE_FIELD(this, kValueOffset);
1164}
1165
1166
1167void HeapNumber::set_value(double value) {
1168 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1169}
1170
1171
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001172int HeapNumber::get_exponent() {
1173 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1174 kExponentShift) - kExponentBias;
1175}
1176
1177
1178int HeapNumber::get_sign() {
1179 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1180}
1181
1182
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001183ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001184
1185
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001186FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001187 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001188 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001189}
1190
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001191void JSObject::ValidateSmiOnlyElements() {
1192#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001193 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001194 Heap* heap = GetHeap();
1195 // Don't use elements, since integrity checks will fail if there
1196 // are filler pointers in the array.
1197 FixedArray* fixed_array =
1198 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1199 Map* map = fixed_array->map();
1200 // Arrays that have been shifted in place can't be verified.
1201 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1202 map != heap->raw_unchecked_two_pointer_filler_map() &&
1203 map != heap->free_space_map()) {
1204 for (int i = 0; i < fixed_array->length(); i++) {
1205 Object* current = fixed_array->get(i);
1206 ASSERT(current->IsSmi() || current == heap->the_hole_value());
1207 }
1208 }
1209 }
1210#endif
1211}
1212
1213
1214MaybeObject* JSObject::EnsureCanContainNonSmiElements() {
1215#if DEBUG
1216 ValidateSmiOnlyElements();
1217#endif
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001218 if ((map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001219 Object* obj;
1220 MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS);
1221 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1222 set_map(Map::cast(obj));
1223 }
1224 return this;
1225}
1226
1227
1228MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
1229 uint32_t count) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001230 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001231 for (uint32_t i = 0; i < count; ++i) {
1232 Object* current = *objects++;
1233 if (!current->IsSmi() && current != GetHeap()->the_hole_value()) {
1234 return EnsureCanContainNonSmiElements();
1235 }
1236 }
1237 }
1238 return this;
1239}
1240
1241
1242MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001243 Object** objects = reinterpret_cast<Object**>(
1244 FIELD_ADDR(elements, elements->OffsetOfElementAt(0)));
1245 return EnsureCanContainElements(objects, elements->length());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001246}
1247
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001248
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001249void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001250 ASSERT((map()->has_fast_elements() ||
1251 map()->has_fast_smi_only_elements()) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001252 (value->map() == GetHeap()->fixed_array_map() ||
1253 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001254 ASSERT(map()->has_fast_double_elements() ==
1255 value->IsFixedDoubleArray());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001256 ASSERT(value->HasValidElements());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001257#ifdef DEBUG
1258 ValidateSmiOnlyElements();
1259#endif
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001260 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001261 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001262}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001263
1264
1265void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001266 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1267 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001268}
1269
1270
1271void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001272 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001273 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1274 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001275}
1276
1277
lrn@chromium.org303ada72010-10-27 09:33:13 +00001278MaybeObject* JSObject::ResetElements() {
1279 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001280 ElementsKind elements_kind = FLAG_smi_only_arrays
1281 ? FAST_SMI_ONLY_ELEMENTS
1282 : FAST_ELEMENTS;
1283 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind);
1284 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001285 set_map(Map::cast(obj));
1286 initialize_elements();
1287 return this;
1288}
1289
1290
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001291ACCESSORS(Oddball, to_string, String, kToStringOffset)
1292ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1293
1294
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001295byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001296 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001297}
1298
1299
1300void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001301 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001302}
1303
1304
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001305Object* JSGlobalPropertyCell::value() {
1306 return READ_FIELD(this, kValueOffset);
1307}
1308
1309
1310void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1311 // The write barrier is not used for global property cells.
1312 ASSERT(!val->IsJSGlobalPropertyCell());
1313 WRITE_FIELD(this, kValueOffset, val);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001314 GetHeap()->incremental_marking()->RecordWrite(
1315 this, HeapObject::RawField(this, kValueOffset), val);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001316}
1317
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001318
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001319int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001320 InstanceType type = map()->instance_type();
1321 // Check for the most common kind of JavaScript object before
1322 // falling into the generic switch. This speeds up the internal
1323 // field operations considerably on average.
1324 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1325 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001326 case JS_GLOBAL_PROXY_TYPE:
1327 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001328 case JS_GLOBAL_OBJECT_TYPE:
1329 return JSGlobalObject::kSize;
1330 case JS_BUILTINS_OBJECT_TYPE:
1331 return JSBuiltinsObject::kSize;
1332 case JS_FUNCTION_TYPE:
1333 return JSFunction::kSize;
1334 case JS_VALUE_TYPE:
1335 return JSValue::kSize;
1336 case JS_ARRAY_TYPE:
1337 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001338 case JS_WEAK_MAP_TYPE:
1339 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001340 case JS_REGEXP_TYPE:
1341 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001342 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001343 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001344 case JS_MESSAGE_OBJECT_TYPE:
1345 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001346 default:
1347 UNREACHABLE();
1348 return 0;
1349 }
1350}
1351
1352
1353int JSObject::GetInternalFieldCount() {
1354 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001355 // Make sure to adjust for the number of in-object properties. These
1356 // properties do contribute to the size, but are not internal fields.
1357 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1358 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001359}
1360
1361
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001362int JSObject::GetInternalFieldOffset(int index) {
1363 ASSERT(index < GetInternalFieldCount() && index >= 0);
1364 return GetHeaderSize() + (kPointerSize * index);
1365}
1366
1367
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001368Object* JSObject::GetInternalField(int index) {
1369 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001370 // Internal objects do follow immediately after the header, whereas in-object
1371 // properties are at the end of the object. Therefore there is no need
1372 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001373 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1374}
1375
1376
1377void JSObject::SetInternalField(int index, Object* value) {
1378 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001379 // Internal objects do follow immediately after the header, whereas in-object
1380 // properties are at the end of the object. Therefore there is no need
1381 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001382 int offset = GetHeaderSize() + (kPointerSize * index);
1383 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001384 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001385}
1386
1387
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001388void JSObject::SetInternalField(int index, Smi* value) {
1389 ASSERT(index < GetInternalFieldCount() && index >= 0);
1390 // Internal objects do follow immediately after the header, whereas in-object
1391 // properties are at the end of the object. Therefore there is no need
1392 // to adjust the index here.
1393 int offset = GetHeaderSize() + (kPointerSize * index);
1394 WRITE_FIELD(this, offset, value);
1395}
1396
1397
ager@chromium.org7c537e22008-10-16 08:43:32 +00001398// Access fast-case object properties at index. The use of these routines
1399// is needed to correctly distinguish between properties stored in-object and
1400// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001401Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001402 // Adjust for the number of properties stored in the object.
1403 index -= map()->inobject_properties();
1404 if (index < 0) {
1405 int offset = map()->instance_size() + (index * kPointerSize);
1406 return READ_FIELD(this, offset);
1407 } else {
1408 ASSERT(index < properties()->length());
1409 return properties()->get(index);
1410 }
1411}
1412
1413
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001414Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001415 // Adjust for the number of properties stored in the object.
1416 index -= map()->inobject_properties();
1417 if (index < 0) {
1418 int offset = map()->instance_size() + (index * kPointerSize);
1419 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001420 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001421 } else {
1422 ASSERT(index < properties()->length());
1423 properties()->set(index, value);
1424 }
1425 return value;
1426}
1427
1428
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001429int JSObject::GetInObjectPropertyOffset(int index) {
1430 // Adjust for the number of properties stored in the object.
1431 index -= map()->inobject_properties();
1432 ASSERT(index < 0);
1433 return map()->instance_size() + (index * kPointerSize);
1434}
1435
1436
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001437Object* JSObject::InObjectPropertyAt(int index) {
1438 // Adjust for the number of properties stored in the object.
1439 index -= map()->inobject_properties();
1440 ASSERT(index < 0);
1441 int offset = map()->instance_size() + (index * kPointerSize);
1442 return READ_FIELD(this, offset);
1443}
1444
1445
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001446Object* JSObject::InObjectPropertyAtPut(int index,
1447 Object* value,
1448 WriteBarrierMode mode) {
1449 // Adjust for the number of properties stored in the object.
1450 index -= map()->inobject_properties();
1451 ASSERT(index < 0);
1452 int offset = map()->instance_size() + (index * kPointerSize);
1453 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001454 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001455 return value;
1456}
1457
1458
1459
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001460void JSObject::InitializeBody(Map* map,
1461 Object* pre_allocated_value,
1462 Object* filler_value) {
1463 ASSERT(!filler_value->IsHeapObject() ||
1464 !GetHeap()->InNewSpace(filler_value));
1465 ASSERT(!pre_allocated_value->IsHeapObject() ||
1466 !GetHeap()->InNewSpace(pre_allocated_value));
1467 int size = map->instance_size();
1468 int offset = kHeaderSize;
1469 if (filler_value != pre_allocated_value) {
1470 int pre_allocated = map->pre_allocated_property_fields();
1471 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1472 for (int i = 0; i < pre_allocated; i++) {
1473 WRITE_FIELD(this, offset, pre_allocated_value);
1474 offset += kPointerSize;
1475 }
1476 }
1477 while (offset < size) {
1478 WRITE_FIELD(this, offset, filler_value);
1479 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001480 }
1481}
1482
1483
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001484bool JSObject::HasFastProperties() {
1485 return !properties()->IsDictionary();
1486}
1487
1488
1489int JSObject::MaxFastProperties() {
1490 // Allow extra fast properties if the object has more than
1491 // kMaxFastProperties in-object properties. When this is the case,
1492 // it is very unlikely that the object is being used as a dictionary
1493 // and there is a good chance that allowing more map transitions
1494 // will be worth it.
1495 return Max(map()->inobject_properties(), kMaxFastProperties);
1496}
1497
1498
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001499void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001500 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001501 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001502 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001503 }
1504}
1505
1506
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001507bool Object::ToArrayIndex(uint32_t* index) {
1508 if (IsSmi()) {
1509 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001510 if (value < 0) return false;
1511 *index = value;
1512 return true;
1513 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001514 if (IsHeapNumber()) {
1515 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001516 uint32_t uint_value = static_cast<uint32_t>(value);
1517 if (value == static_cast<double>(uint_value)) {
1518 *index = uint_value;
1519 return true;
1520 }
1521 }
1522 return false;
1523}
1524
1525
1526bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1527 if (!this->IsJSValue()) return false;
1528
1529 JSValue* js_value = JSValue::cast(this);
1530 if (!js_value->value()->IsString()) return false;
1531
1532 String* str = String::cast(js_value->value());
1533 if (index >= (uint32_t)str->length()) return false;
1534
1535 return true;
1536}
1537
1538
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001539FixedArrayBase* FixedArrayBase::cast(Object* object) {
1540 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1541 return reinterpret_cast<FixedArrayBase*>(object);
1542}
1543
1544
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001545Object* FixedArray::get(int index) {
1546 ASSERT(index >= 0 && index < this->length());
1547 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1548}
1549
1550
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001551void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001552 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001553 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001554 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1555 int offset = kHeaderSize + index * kPointerSize;
1556 WRITE_FIELD(this, offset, value);
1557}
1558
1559
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001560void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001561 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001562 ASSERT(index >= 0 && index < this->length());
1563 int offset = kHeaderSize + index * kPointerSize;
1564 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001565 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001566}
1567
1568
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001569inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1570 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1571}
1572
1573
1574inline double FixedDoubleArray::hole_nan_as_double() {
1575 return BitCast<double, uint64_t>(kHoleNanInt64);
1576}
1577
1578
1579inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1580 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1581 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1582 return OS::nan_value();
1583}
1584
1585
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001586double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001587 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1588 map() != HEAP->fixed_array_map());
1589 ASSERT(index >= 0 && index < this->length());
1590 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1591 ASSERT(!is_the_hole_nan(result));
1592 return result;
1593}
1594
1595
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001596MaybeObject* FixedDoubleArray::get(int index) {
1597 if (is_the_hole(index)) {
1598 return GetHeap()->the_hole_value();
1599 } else {
1600 return GetHeap()->NumberFromDouble(get_scalar(index));
1601 }
1602}
1603
1604
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001605void FixedDoubleArray::set(int index, double value) {
1606 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1607 map() != HEAP->fixed_array_map());
1608 int offset = kHeaderSize + index * kDoubleSize;
1609 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1610 WRITE_DOUBLE_FIELD(this, offset, value);
1611}
1612
1613
1614void FixedDoubleArray::set_the_hole(int index) {
1615 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1616 map() != HEAP->fixed_array_map());
1617 int offset = kHeaderSize + index * kDoubleSize;
1618 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1619}
1620
1621
1622bool FixedDoubleArray::is_the_hole(int index) {
1623 int offset = kHeaderSize + index * kDoubleSize;
1624 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1625}
1626
1627
1628void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1629 int old_length = from->length();
1630 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001631 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1632 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1633 FIELD_ADDR(from, kHeaderSize),
1634 old_length * kDoubleSize);
1635 } else {
1636 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001637 if (from->is_the_hole(i)) {
1638 set_the_hole(i);
1639 } else {
1640 set(i, from->get_scalar(i));
1641 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001642 }
1643 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001644 int offset = kHeaderSize + old_length * kDoubleSize;
1645 for (int current = from->length(); current < length(); ++current) {
1646 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1647 offset += kDoubleSize;
1648 }
1649}
1650
1651
1652void FixedDoubleArray::Initialize(FixedArray* from) {
1653 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001654 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001655 for (int i = 0; i < old_length; i++) {
1656 Object* hole_or_object = from->get(i);
1657 if (hole_or_object->IsTheHole()) {
1658 set_the_hole(i);
1659 } else {
1660 set(i, hole_or_object->Number());
1661 }
1662 }
1663 int offset = kHeaderSize + old_length * kDoubleSize;
1664 for (int current = from->length(); current < length(); ++current) {
1665 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1666 offset += kDoubleSize;
1667 }
1668}
1669
1670
1671void FixedDoubleArray::Initialize(NumberDictionary* from) {
1672 int offset = kHeaderSize;
1673 for (int current = 0; current < length(); ++current) {
1674 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1675 offset += kDoubleSize;
1676 }
1677 for (int i = 0; i < from->Capacity(); i++) {
1678 Object* key = from->KeyAt(i);
1679 if (key->IsNumber()) {
1680 uint32_t entry = static_cast<uint32_t>(key->Number());
1681 set(entry, from->ValueAt(i)->Number());
1682 }
1683 }
1684}
1685
1686
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001687WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001688 Heap* heap = GetHeap();
1689 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1690 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001691 return UPDATE_WRITE_BARRIER;
1692}
1693
1694
1695void FixedArray::set(int index,
1696 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001697 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001698 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001699 ASSERT(index >= 0 && index < this->length());
1700 int offset = kHeaderSize + index * kPointerSize;
1701 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001702 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001703}
1704
1705
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001706void FixedArray::NoWriteBarrierSet(FixedArray* array,
1707 int index,
1708 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001709 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001710 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001711 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001712 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1713}
1714
1715
1716void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001717 ASSERT(map() != HEAP->fixed_cow_array_map());
1718 set_undefined(GetHeap(), index);
1719}
1720
1721
1722void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001723 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001724 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001725 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001726 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001727}
1728
1729
ager@chromium.org236ad962008-09-25 09:45:57 +00001730void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001731 set_null(GetHeap(), index);
1732}
1733
1734
1735void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001736 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001737 ASSERT(!heap->InNewSpace(heap->null_value()));
1738 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001739}
1740
1741
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001742void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001743 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001744 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001745 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1746 WRITE_FIELD(this,
1747 kHeaderSize + index * kPointerSize,
1748 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001749}
1750
1751
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001752void FixedArray::set_unchecked(int index, Smi* value) {
1753 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1754 int offset = kHeaderSize + index * kPointerSize;
1755 WRITE_FIELD(this, offset, value);
1756}
1757
1758
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001759void FixedArray::set_unchecked(Heap* heap,
1760 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001761 Object* value,
1762 WriteBarrierMode mode) {
1763 int offset = kHeaderSize + index * kPointerSize;
1764 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001765 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001766}
1767
1768
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001769void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001770 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001771 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1772 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001773}
1774
1775
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001776Object** FixedArray::data_start() {
1777 return HeapObject::RawField(this, kHeaderSize);
1778}
1779
1780
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001781bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001782 ASSERT(this->IsSmi() ||
1783 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001784 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001785 return this->IsSmi() || length() <= kFirstIndex;
1786}
1787
1788
1789int DescriptorArray::bit_field3_storage() {
1790 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1791 return Smi::cast(storage)->value();
1792}
1793
1794void DescriptorArray::set_bit_field3_storage(int value) {
1795 ASSERT(!IsEmpty());
1796 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001797}
1798
1799
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001800void DescriptorArray::NoWriteBarrierSwap(FixedArray* array,
1801 int first,
1802 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001803 Object* tmp = array->get(first);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001804 NoWriteBarrierSet(array, first, array->get(second));
1805 NoWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001806}
1807
1808
1809int DescriptorArray::Search(String* name) {
1810 SLOW_ASSERT(IsSortedNoDuplicates());
1811
1812 // Check for empty descriptor array.
1813 int nof = number_of_descriptors();
1814 if (nof == 0) return kNotFound;
1815
1816 // Fast case: do linear search for small arrays.
1817 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001818 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001819 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820 }
1821
1822 // Slow case: perform binary search.
1823 return BinarySearch(name, 0, nof - 1);
1824}
1825
1826
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001827int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001828 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001829 if (number == DescriptorLookupCache::kAbsent) {
1830 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001831 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001832 }
1833 return number;
1834}
1835
1836
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001837String* DescriptorArray::GetKey(int descriptor_number) {
1838 ASSERT(descriptor_number < number_of_descriptors());
1839 return String::cast(get(ToKeyIndex(descriptor_number)));
1840}
1841
1842
1843Object* DescriptorArray::GetValue(int descriptor_number) {
1844 ASSERT(descriptor_number < number_of_descriptors());
1845 return GetContentArray()->get(ToValueIndex(descriptor_number));
1846}
1847
1848
1849Smi* DescriptorArray::GetDetails(int descriptor_number) {
1850 ASSERT(descriptor_number < number_of_descriptors());
1851 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1852}
1853
1854
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001855PropertyType DescriptorArray::GetType(int descriptor_number) {
1856 ASSERT(descriptor_number < number_of_descriptors());
1857 return PropertyDetails(GetDetails(descriptor_number)).type();
1858}
1859
1860
1861int DescriptorArray::GetFieldIndex(int descriptor_number) {
1862 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1863}
1864
1865
1866JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1867 return JSFunction::cast(GetValue(descriptor_number));
1868}
1869
1870
1871Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1872 ASSERT(GetType(descriptor_number) == CALLBACKS);
1873 return GetValue(descriptor_number);
1874}
1875
1876
1877AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1878 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001879 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001880 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001881}
1882
1883
1884bool DescriptorArray::IsProperty(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001885 return IsRealProperty(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001886}
1887
1888
1889bool DescriptorArray::IsTransition(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001890 return IsTransitionType(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001891}
1892
1893
1894bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1895 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1896}
1897
1898
1899bool DescriptorArray::IsDontEnum(int descriptor_number) {
1900 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1901}
1902
1903
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001904void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1905 desc->Init(GetKey(descriptor_number),
1906 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001907 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001908}
1909
1910
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001911void DescriptorArray::Set(int descriptor_number,
1912 Descriptor* desc,
1913 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001914 // Range check.
1915 ASSERT(descriptor_number < number_of_descriptors());
1916
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001917 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001918 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1919 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001920
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001921 NoWriteBarrierSet(this,
1922 ToKeyIndex(descriptor_number),
1923 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001924 FixedArray* content_array = GetContentArray();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001925 NoWriteBarrierSet(content_array,
1926 ToValueIndex(descriptor_number),
1927 desc->GetValue());
1928 NoWriteBarrierSet(content_array,
1929 ToDetailsIndex(descriptor_number),
1930 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001931}
1932
1933
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001934void DescriptorArray::CopyFrom(int index,
1935 DescriptorArray* src,
1936 int src_index,
1937 const WhitenessWitness& witness) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001938 Descriptor desc;
1939 src->Get(src_index, &desc);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001940 Set(index, &desc, witness);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001941}
1942
1943
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001944void DescriptorArray::NoWriteBarrierSwapDescriptors(int first, int second) {
1945 NoWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001946 FixedArray* content_array = GetContentArray();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001947 NoWriteBarrierSwap(content_array,
1948 ToValueIndex(first),
1949 ToValueIndex(second));
1950 NoWriteBarrierSwap(content_array,
1951 ToDetailsIndex(first),
1952 ToDetailsIndex(second));
1953}
1954
1955
1956DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
1957 : marking_(array->GetHeap()->incremental_marking()) {
1958 marking_->EnterNoMarkingScope();
1959 if (array->number_of_descriptors() > 0) {
1960 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
1961 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
1962 }
1963}
1964
1965
1966DescriptorArray::WhitenessWitness::~WhitenessWitness() {
1967 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001968}
1969
1970
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001971template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001972int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
1973 const int kMinCapacity = 32;
1974 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
1975 if (capacity < kMinCapacity) {
1976 capacity = kMinCapacity; // Guarantee min capacity.
1977 }
1978 return capacity;
1979}
1980
1981
1982template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001983int HashTable<Shape, Key>::FindEntry(Key key) {
1984 return FindEntry(GetIsolate(), key);
1985}
1986
1987
1988// Find entry for key otherwise return kNotFound.
1989template<typename Shape, typename Key>
1990int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1991 uint32_t capacity = Capacity();
1992 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1993 uint32_t count = 1;
1994 // EnsureCapacity will guarantee the hash table is never full.
1995 while (true) {
1996 Object* element = KeyAt(entry);
1997 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001998 if (element != isolate->heap()->the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001999 Shape::IsMatch(key, element)) return entry;
2000 entry = NextProbe(entry, count++, capacity);
2001 }
2002 return kNotFound;
2003}
2004
2005
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002006bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002007 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002008 if (!max_index_object->IsSmi()) return false;
2009 return 0 !=
2010 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2011}
2012
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002013uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002014 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002015 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002016 if (!max_index_object->IsSmi()) return 0;
2017 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2018 return value >> kRequiresSlowElementsTagSize;
2019}
2020
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002021void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002022 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002023}
2024
2025
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002026// ------------------------------------
2027// Cast operations
2028
2029
2030CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002031CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002032CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002033CAST_ACCESSOR(DeoptimizationInputData)
2034CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002035CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002036CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002037CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002038CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002039CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002040CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002041CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002042CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002043CAST_ACCESSOR(String)
2044CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002045CAST_ACCESSOR(SeqAsciiString)
2046CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002047CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002048CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049CAST_ACCESSOR(ExternalString)
2050CAST_ACCESSOR(ExternalAsciiString)
2051CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002052CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002053CAST_ACCESSOR(JSObject)
2054CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055CAST_ACCESSOR(HeapObject)
2056CAST_ACCESSOR(HeapNumber)
2057CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002058CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002059CAST_ACCESSOR(SharedFunctionInfo)
2060CAST_ACCESSOR(Map)
2061CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002062CAST_ACCESSOR(GlobalObject)
2063CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002064CAST_ACCESSOR(JSGlobalObject)
2065CAST_ACCESSOR(JSBuiltinsObject)
2066CAST_ACCESSOR(Code)
2067CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002068CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002069CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002070CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002071CAST_ACCESSOR(JSSet)
2072CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002073CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002074CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002075CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002076CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002077CAST_ACCESSOR(ExternalArray)
2078CAST_ACCESSOR(ExternalByteArray)
2079CAST_ACCESSOR(ExternalUnsignedByteArray)
2080CAST_ACCESSOR(ExternalShortArray)
2081CAST_ACCESSOR(ExternalUnsignedShortArray)
2082CAST_ACCESSOR(ExternalIntArray)
2083CAST_ACCESSOR(ExternalUnsignedIntArray)
2084CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002085CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002086CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002087CAST_ACCESSOR(Struct)
2088
2089
2090#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2091 STRUCT_LIST(MAKE_STRUCT_CAST)
2092#undef MAKE_STRUCT_CAST
2093
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002094
2095template <typename Shape, typename Key>
2096HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002097 ASSERT(obj->IsHashTable());
2098 return reinterpret_cast<HashTable*>(obj);
2099}
2100
2101
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002102SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002103SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002104
ager@chromium.orgac091b72010-05-05 07:34:42 +00002105SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002106
2107
2108uint32_t String::hash_field() {
2109 return READ_UINT32_FIELD(this, kHashFieldOffset);
2110}
2111
2112
2113void String::set_hash_field(uint32_t value) {
2114 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002115#if V8_HOST_ARCH_64_BIT
2116 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2117#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002118}
2119
2120
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002121bool String::Equals(String* other) {
2122 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002123 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2124 return false;
2125 }
2126 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002127}
2128
2129
lrn@chromium.org303ada72010-10-27 09:33:13 +00002130MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002131 if (!StringShape(this).IsCons()) return this;
2132 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002133 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002134 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002135}
2136
2137
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002138String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002139 MaybeObject* flat = TryFlatten(pretenure);
2140 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002141 if (!flat->ToObject(&successfully_flattened)) return this;
2142 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002143}
2144
2145
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002146uint16_t String::Get(int index) {
2147 ASSERT(index >= 0 && index < length());
2148 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002149 case kSeqStringTag | kAsciiStringTag:
2150 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2151 case kSeqStringTag | kTwoByteStringTag:
2152 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2153 case kConsStringTag | kAsciiStringTag:
2154 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002155 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002156 case kExternalStringTag | kAsciiStringTag:
2157 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2158 case kExternalStringTag | kTwoByteStringTag:
2159 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002160 case kSlicedStringTag | kAsciiStringTag:
2161 case kSlicedStringTag | kTwoByteStringTag:
2162 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002163 default:
2164 break;
2165 }
2166
2167 UNREACHABLE();
2168 return 0;
2169}
2170
2171
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002172void String::Set(int index, uint16_t value) {
2173 ASSERT(index >= 0 && index < length());
2174 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002175
ager@chromium.org5ec48922009-05-05 07:25:34 +00002176 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002177 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2178 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002179}
2180
2181
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002182bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002183 if (!StringShape(this).IsCons()) return true;
2184 return ConsString::cast(this)->second()->length() == 0;
2185}
2186
2187
2188String* String::GetUnderlying() {
2189 // Giving direct access to underlying string only makes sense if the
2190 // wrapping string is already flattened.
2191 ASSERT(this->IsFlat());
2192 ASSERT(StringShape(this).IsIndirect());
2193 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2194 const int kUnderlyingOffset = SlicedString::kParentOffset;
2195 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002196}
2197
2198
ager@chromium.org7c537e22008-10-16 08:43:32 +00002199uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002200 ASSERT(index >= 0 && index < length());
2201 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2202}
2203
2204
ager@chromium.org7c537e22008-10-16 08:43:32 +00002205void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002206 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2207 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2208 static_cast<byte>(value));
2209}
2210
2211
ager@chromium.org7c537e22008-10-16 08:43:32 +00002212Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002213 return FIELD_ADDR(this, kHeaderSize);
2214}
2215
2216
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002217char* SeqAsciiString::GetChars() {
2218 return reinterpret_cast<char*>(GetCharsAddress());
2219}
2220
2221
ager@chromium.org7c537e22008-10-16 08:43:32 +00002222Address SeqTwoByteString::GetCharsAddress() {
2223 return FIELD_ADDR(this, kHeaderSize);
2224}
2225
2226
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002227uc16* SeqTwoByteString::GetChars() {
2228 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2229}
2230
2231
ager@chromium.org7c537e22008-10-16 08:43:32 +00002232uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002233 ASSERT(index >= 0 && index < length());
2234 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2235}
2236
2237
ager@chromium.org7c537e22008-10-16 08:43:32 +00002238void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002239 ASSERT(index >= 0 && index < length());
2240 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2241}
2242
2243
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002244int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002245 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002246}
2247
2248
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002249int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002250 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002251}
2252
2253
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002254String* SlicedString::parent() {
2255 return String::cast(READ_FIELD(this, kParentOffset));
2256}
2257
2258
2259void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002260 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002261 WRITE_FIELD(this, kParentOffset, parent);
2262}
2263
2264
2265SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2266
2267
ager@chromium.org870a0b62008-11-04 11:43:05 +00002268String* ConsString::first() {
2269 return String::cast(READ_FIELD(this, kFirstOffset));
2270}
2271
2272
2273Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002274 return READ_FIELD(this, kFirstOffset);
2275}
2276
2277
ager@chromium.org870a0b62008-11-04 11:43:05 +00002278void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002279 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002280 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002281}
2282
2283
ager@chromium.org870a0b62008-11-04 11:43:05 +00002284String* ConsString::second() {
2285 return String::cast(READ_FIELD(this, kSecondOffset));
2286}
2287
2288
2289Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002290 return READ_FIELD(this, kSecondOffset);
2291}
2292
2293
ager@chromium.org870a0b62008-11-04 11:43:05 +00002294void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002295 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002296 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002297}
2298
2299
erikcorry0ad885c2011-11-21 13:51:57 +00002300void ExternalString::clear_data_cache() {
2301 WRITE_INTPTR_FIELD(this, kResourceDataOffset, 0);
2302}
2303
2304
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002305const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002306 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2307}
2308
2309
2310void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002311 const ExternalAsciiString::Resource* resource) {
2312 *reinterpret_cast<const Resource**>(
2313 FIELD_ADDR(this, kResourceOffset)) = resource;
erikcorry0ad885c2011-11-21 13:51:57 +00002314 clear_data_cache();
2315}
2316
2317
2318const char* ExternalAsciiString::GetChars() {
2319 const char** data_field =
2320 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2321 if (*data_field == NULL) *data_field = resource()->data();
2322 return *data_field;
2323}
2324
2325
2326uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2327 ASSERT(index >= 0 && index < length());
2328 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002329}
2330
2331
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002332const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002333 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2334}
2335
2336
2337void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002338 const ExternalTwoByteString::Resource* resource) {
2339 *reinterpret_cast<const Resource**>(
2340 FIELD_ADDR(this, kResourceOffset)) = resource;
erikcorry0ad885c2011-11-21 13:51:57 +00002341 clear_data_cache();
2342}
2343
2344
2345const uint16_t* ExternalTwoByteString::GetChars() {
2346 const uint16_t** data_field =
2347 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2348 if (*data_field == NULL) *data_field = resource()->data();
2349 return *data_field;
2350}
2351
2352
2353uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2354 ASSERT(index >= 0 && index < length());
2355 return GetChars()[index];
2356}
2357
2358
2359const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2360 unsigned start) {
2361 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002362}
2363
2364
ager@chromium.orgac091b72010-05-05 07:34:42 +00002365void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002366 set_finger_index(kEntriesIndex);
2367 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002368}
2369
2370
2371void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002372 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002373 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002374 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002375 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002376 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002377 MakeZeroSize();
2378}
2379
2380
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002381int JSFunctionResultCache::size() {
2382 return Smi::cast(get(kCacheSizeIndex))->value();
2383}
2384
2385
2386void JSFunctionResultCache::set_size(int size) {
2387 set(kCacheSizeIndex, Smi::FromInt(size));
2388}
2389
2390
2391int JSFunctionResultCache::finger_index() {
2392 return Smi::cast(get(kFingerIndex))->value();
2393}
2394
2395
2396void JSFunctionResultCache::set_finger_index(int finger_index) {
2397 set(kFingerIndex, Smi::FromInt(finger_index));
2398}
2399
2400
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002401byte ByteArray::get(int index) {
2402 ASSERT(index >= 0 && index < this->length());
2403 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2404}
2405
2406
2407void ByteArray::set(int index, byte value) {
2408 ASSERT(index >= 0 && index < this->length());
2409 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2410}
2411
2412
2413int ByteArray::get_int(int index) {
2414 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2415 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2416}
2417
2418
2419ByteArray* ByteArray::FromDataStartAddress(Address address) {
2420 ASSERT_TAG_ALIGNED(address);
2421 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2422}
2423
2424
2425Address ByteArray::GetDataStartAddress() {
2426 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2427}
2428
2429
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002430uint8_t* ExternalPixelArray::external_pixel_pointer() {
2431 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002432}
2433
2434
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002435uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002436 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002437 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002438 return ptr[index];
2439}
2440
2441
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002442MaybeObject* ExternalPixelArray::get(int index) {
2443 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2444}
2445
2446
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002447void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002448 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002449 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002450 ptr[index] = value;
2451}
2452
2453
ager@chromium.org3811b432009-10-28 14:53:37 +00002454void* ExternalArray::external_pointer() {
2455 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2456 return reinterpret_cast<void*>(ptr);
2457}
2458
2459
2460void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2461 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2462 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2463}
2464
2465
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002466int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002467 ASSERT((index >= 0) && (index < this->length()));
2468 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2469 return ptr[index];
2470}
2471
2472
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002473MaybeObject* ExternalByteArray::get(int index) {
2474 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2475}
2476
2477
ager@chromium.org3811b432009-10-28 14:53:37 +00002478void ExternalByteArray::set(int index, int8_t value) {
2479 ASSERT((index >= 0) && (index < this->length()));
2480 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2481 ptr[index] = value;
2482}
2483
2484
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002485uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002486 ASSERT((index >= 0) && (index < this->length()));
2487 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2488 return ptr[index];
2489}
2490
2491
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002492MaybeObject* ExternalUnsignedByteArray::get(int index) {
2493 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2494}
2495
2496
ager@chromium.org3811b432009-10-28 14:53:37 +00002497void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2498 ASSERT((index >= 0) && (index < this->length()));
2499 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2500 ptr[index] = value;
2501}
2502
2503
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002504int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002505 ASSERT((index >= 0) && (index < this->length()));
2506 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2507 return ptr[index];
2508}
2509
2510
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002511MaybeObject* ExternalShortArray::get(int index) {
2512 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2513}
2514
2515
ager@chromium.org3811b432009-10-28 14:53:37 +00002516void ExternalShortArray::set(int index, int16_t value) {
2517 ASSERT((index >= 0) && (index < this->length()));
2518 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2519 ptr[index] = value;
2520}
2521
2522
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002523uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002524 ASSERT((index >= 0) && (index < this->length()));
2525 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2526 return ptr[index];
2527}
2528
2529
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002530MaybeObject* ExternalUnsignedShortArray::get(int index) {
2531 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2532}
2533
2534
ager@chromium.org3811b432009-10-28 14:53:37 +00002535void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2536 ASSERT((index >= 0) && (index < this->length()));
2537 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2538 ptr[index] = value;
2539}
2540
2541
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002542int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002543 ASSERT((index >= 0) && (index < this->length()));
2544 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2545 return ptr[index];
2546}
2547
2548
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002549MaybeObject* ExternalIntArray::get(int index) {
2550 return GetHeap()->NumberFromInt32(get_scalar(index));
2551}
2552
2553
ager@chromium.org3811b432009-10-28 14:53:37 +00002554void ExternalIntArray::set(int index, int32_t value) {
2555 ASSERT((index >= 0) && (index < this->length()));
2556 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2557 ptr[index] = value;
2558}
2559
2560
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002561uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002562 ASSERT((index >= 0) && (index < this->length()));
2563 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2564 return ptr[index];
2565}
2566
2567
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002568MaybeObject* ExternalUnsignedIntArray::get(int index) {
2569 return GetHeap()->NumberFromUint32(get_scalar(index));
2570}
2571
2572
ager@chromium.org3811b432009-10-28 14:53:37 +00002573void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2574 ASSERT((index >= 0) && (index < this->length()));
2575 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2576 ptr[index] = value;
2577}
2578
2579
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002580float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002581 ASSERT((index >= 0) && (index < this->length()));
2582 float* ptr = static_cast<float*>(external_pointer());
2583 return ptr[index];
2584}
2585
2586
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002587MaybeObject* ExternalFloatArray::get(int index) {
2588 return GetHeap()->NumberFromDouble(get_scalar(index));
2589}
2590
2591
ager@chromium.org3811b432009-10-28 14:53:37 +00002592void ExternalFloatArray::set(int index, float value) {
2593 ASSERT((index >= 0) && (index < this->length()));
2594 float* ptr = static_cast<float*>(external_pointer());
2595 ptr[index] = value;
2596}
2597
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002598
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002599double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002600 ASSERT((index >= 0) && (index < this->length()));
2601 double* ptr = static_cast<double*>(external_pointer());
2602 return ptr[index];
2603}
2604
2605
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002606MaybeObject* ExternalDoubleArray::get(int index) {
2607 return GetHeap()->NumberFromDouble(get_scalar(index));
2608}
2609
2610
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002611void ExternalDoubleArray::set(int index, double value) {
2612 ASSERT((index >= 0) && (index < this->length()));
2613 double* ptr = static_cast<double*>(external_pointer());
2614 ptr[index] = value;
2615}
2616
2617
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002618int Map::visitor_id() {
2619 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2620}
2621
2622
2623void Map::set_visitor_id(int id) {
2624 ASSERT(0 <= id && id < 256);
2625 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2626}
2627
ager@chromium.org3811b432009-10-28 14:53:37 +00002628
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002629int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002630 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2631}
2632
2633
2634int Map::inobject_properties() {
2635 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002636}
2637
2638
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002639int Map::pre_allocated_property_fields() {
2640 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2641}
2642
2643
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002644int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002645 int instance_size = map->instance_size();
2646 if (instance_size != kVariableSizeSentinel) return instance_size;
2647 // We can ignore the "symbol" bit becase it is only set for symbols
2648 // and implies a string type.
2649 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002650 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002651 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002652 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002653 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002654 if (instance_type == ASCII_STRING_TYPE) {
2655 return SeqAsciiString::SizeFor(
2656 reinterpret_cast<SeqAsciiString*>(this)->length());
2657 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002658 if (instance_type == BYTE_ARRAY_TYPE) {
2659 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2660 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002661 if (instance_type == FREE_SPACE_TYPE) {
2662 return reinterpret_cast<FreeSpace*>(this)->size();
2663 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002664 if (instance_type == STRING_TYPE) {
2665 return SeqTwoByteString::SizeFor(
2666 reinterpret_cast<SeqTwoByteString*>(this)->length());
2667 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002668 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2669 return FixedDoubleArray::SizeFor(
2670 reinterpret_cast<FixedDoubleArray*>(this)->length());
2671 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002672 ASSERT(instance_type == CODE_TYPE);
2673 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002674}
2675
2676
2677void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002678 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002679 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002680 ASSERT(0 <= value && value < 256);
2681 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2682}
2683
2684
ager@chromium.org7c537e22008-10-16 08:43:32 +00002685void Map::set_inobject_properties(int value) {
2686 ASSERT(0 <= value && value < 256);
2687 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2688}
2689
2690
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002691void Map::set_pre_allocated_property_fields(int value) {
2692 ASSERT(0 <= value && value < 256);
2693 WRITE_BYTE_FIELD(this,
2694 kPreAllocatedPropertyFieldsOffset,
2695 static_cast<byte>(value));
2696}
2697
2698
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002699InstanceType Map::instance_type() {
2700 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2701}
2702
2703
2704void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002705 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2706}
2707
2708
2709int Map::unused_property_fields() {
2710 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2711}
2712
2713
2714void Map::set_unused_property_fields(int value) {
2715 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2716}
2717
2718
2719byte Map::bit_field() {
2720 return READ_BYTE_FIELD(this, kBitFieldOffset);
2721}
2722
2723
2724void Map::set_bit_field(byte value) {
2725 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2726}
2727
2728
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002729byte Map::bit_field2() {
2730 return READ_BYTE_FIELD(this, kBitField2Offset);
2731}
2732
2733
2734void Map::set_bit_field2(byte value) {
2735 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2736}
2737
2738
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002739void Map::set_non_instance_prototype(bool value) {
2740 if (value) {
2741 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2742 } else {
2743 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2744 }
2745}
2746
2747
2748bool Map::has_non_instance_prototype() {
2749 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2750}
2751
2752
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002753void Map::set_function_with_prototype(bool value) {
2754 if (value) {
2755 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2756 } else {
2757 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2758 }
2759}
2760
2761
2762bool Map::function_with_prototype() {
2763 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2764}
2765
2766
ager@chromium.org870a0b62008-11-04 11:43:05 +00002767void Map::set_is_access_check_needed(bool access_check_needed) {
2768 if (access_check_needed) {
2769 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2770 } else {
2771 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2772 }
2773}
2774
2775
2776bool Map::is_access_check_needed() {
2777 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2778}
2779
2780
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002781void Map::set_is_extensible(bool value) {
2782 if (value) {
2783 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2784 } else {
2785 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2786 }
2787}
2788
2789bool Map::is_extensible() {
2790 return ((1 << kIsExtensible) & bit_field2()) != 0;
2791}
2792
2793
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002794void Map::set_attached_to_shared_function_info(bool value) {
2795 if (value) {
2796 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2797 } else {
2798 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2799 }
2800}
2801
2802bool Map::attached_to_shared_function_info() {
2803 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2804}
2805
2806
2807void Map::set_is_shared(bool value) {
2808 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002809 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002810 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002811 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002812 }
2813}
2814
2815bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002816 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002817}
2818
2819
2820JSFunction* Map::unchecked_constructor() {
2821 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2822}
2823
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002824
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002825Code::Flags Code::flags() {
2826 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2827}
2828
2829
2830void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002831 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002832 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002833 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2834 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002835 ExtractArgumentsCountFromFlags(flags) >= 0);
2836 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2837}
2838
2839
2840Code::Kind Code::kind() {
2841 return ExtractKindFromFlags(flags());
2842}
2843
2844
kasper.lund7276f142008-07-30 08:49:36 +00002845InlineCacheState Code::ic_state() {
2846 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002847 // Only allow uninitialized or debugger states for non-IC code
2848 // objects. This is used in the debugger to determine whether or not
2849 // a call to code object has been replaced with a debug break call.
2850 ASSERT(is_inline_cache_stub() ||
2851 result == UNINITIALIZED ||
2852 result == DEBUG_BREAK ||
2853 result == DEBUG_PREPARE_STEP_IN);
2854 return result;
2855}
2856
2857
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002858Code::ExtraICState Code::extra_ic_state() {
2859 ASSERT(is_inline_cache_stub());
2860 return ExtractExtraICStateFromFlags(flags());
2861}
2862
2863
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002864PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002865 return ExtractTypeFromFlags(flags());
2866}
2867
2868
2869int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002870 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002871 return ExtractArgumentsCountFromFlags(flags());
2872}
2873
2874
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002875int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002876 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002877 kind() == UNARY_OP_IC ||
2878 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002879 kind() == COMPARE_IC ||
2880 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002881 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002882}
2883
2884
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002885void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002886 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002887 kind() == UNARY_OP_IC ||
2888 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002889 kind() == COMPARE_IC ||
2890 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002891 ASSERT(0 <= major && major < 256);
2892 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002893}
2894
2895
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002896bool Code::is_pregenerated() {
2897 return kind() == STUB && IsPregeneratedField::decode(flags());
2898}
2899
2900
2901void Code::set_is_pregenerated(bool value) {
2902 ASSERT(kind() == STUB);
2903 Flags f = flags();
2904 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2905 set_flags(f);
2906}
2907
2908
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002909bool Code::optimizable() {
2910 ASSERT(kind() == FUNCTION);
2911 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2912}
2913
2914
2915void Code::set_optimizable(bool value) {
2916 ASSERT(kind() == FUNCTION);
2917 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2918}
2919
2920
2921bool Code::has_deoptimization_support() {
2922 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002923 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2924 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002925}
2926
2927
2928void Code::set_has_deoptimization_support(bool value) {
2929 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002930 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2931 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
2932 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2933}
2934
2935
2936bool Code::has_debug_break_slots() {
2937 ASSERT(kind() == FUNCTION);
2938 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2939 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
2940}
2941
2942
2943void Code::set_has_debug_break_slots(bool value) {
2944 ASSERT(kind() == FUNCTION);
2945 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2946 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
2947 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002948}
2949
2950
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002951bool Code::is_compiled_optimizable() {
2952 ASSERT(kind() == FUNCTION);
2953 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2954 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
2955}
2956
2957
2958void Code::set_compiled_optimizable(bool value) {
2959 ASSERT(kind() == FUNCTION);
2960 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2961 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
2962 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2963}
2964
2965
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002966int Code::allow_osr_at_loop_nesting_level() {
2967 ASSERT(kind() == FUNCTION);
2968 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2969}
2970
2971
2972void Code::set_allow_osr_at_loop_nesting_level(int level) {
2973 ASSERT(kind() == FUNCTION);
2974 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2975 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2976}
2977
2978
2979unsigned Code::stack_slots() {
2980 ASSERT(kind() == OPTIMIZED_FUNCTION);
2981 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2982}
2983
2984
2985void Code::set_stack_slots(unsigned slots) {
2986 ASSERT(kind() == OPTIMIZED_FUNCTION);
2987 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2988}
2989
2990
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002991unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002992 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002993 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002994}
2995
2996
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002997void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002998 ASSERT(kind() == OPTIMIZED_FUNCTION);
2999 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003000 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003001}
3002
3003
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003004unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003005 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003006 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003007}
3008
3009
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003010void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003011 ASSERT(kind() == FUNCTION);
3012 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003013 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003014}
3015
3016
3017CheckType Code::check_type() {
3018 ASSERT(is_call_stub() || is_keyed_call_stub());
3019 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3020 return static_cast<CheckType>(type);
3021}
3022
3023
3024void Code::set_check_type(CheckType value) {
3025 ASSERT(is_call_stub() || is_keyed_call_stub());
3026 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3027}
3028
3029
danno@chromium.org40cb8782011-05-25 07:58:50 +00003030byte Code::unary_op_type() {
3031 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003032 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3033}
3034
3035
danno@chromium.org40cb8782011-05-25 07:58:50 +00003036void Code::set_unary_op_type(byte value) {
3037 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003038 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3039}
3040
3041
danno@chromium.org40cb8782011-05-25 07:58:50 +00003042byte Code::binary_op_type() {
3043 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003044 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3045}
3046
3047
danno@chromium.org40cb8782011-05-25 07:58:50 +00003048void Code::set_binary_op_type(byte value) {
3049 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003050 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3051}
3052
3053
danno@chromium.org40cb8782011-05-25 07:58:50 +00003054byte Code::binary_op_result_type() {
3055 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003056 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3057}
3058
3059
danno@chromium.org40cb8782011-05-25 07:58:50 +00003060void Code::set_binary_op_result_type(byte value) {
3061 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003062 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3063}
3064
3065
3066byte Code::compare_state() {
3067 ASSERT(is_compare_ic_stub());
3068 return READ_BYTE_FIELD(this, kCompareStateOffset);
3069}
3070
3071
3072void Code::set_compare_state(byte value) {
3073 ASSERT(is_compare_ic_stub());
3074 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3075}
3076
3077
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003078byte Code::to_boolean_state() {
3079 ASSERT(is_to_boolean_ic_stub());
3080 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3081}
3082
3083
3084void Code::set_to_boolean_state(byte value) {
3085 ASSERT(is_to_boolean_ic_stub());
3086 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3087}
3088
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003089
3090bool Code::has_function_cache() {
3091 ASSERT(kind() == STUB);
3092 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3093}
3094
3095
3096void Code::set_has_function_cache(bool flag) {
3097 ASSERT(kind() == STUB);
3098 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3099}
3100
3101
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003102bool Code::is_inline_cache_stub() {
3103 Kind kind = this->kind();
3104 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3105}
3106
3107
3108Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003109 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003110 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003111 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003112 int argc,
3113 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003114 // Extra IC state is only allowed for call IC stubs or for store IC
3115 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003116 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003117 kind == CALL_IC ||
3118 kind == STORE_IC ||
3119 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003120 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003121 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003122 | ICStateField::encode(ic_state)
3123 | TypeField::encode(type)
3124 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003125 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003126 | CacheHolderField::encode(holder);
3127 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003128}
3129
3130
3131Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3132 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003133 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003134 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003135 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003136 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003137}
3138
3139
3140Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003141 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003142}
3143
3144
kasper.lund7276f142008-07-30 08:49:36 +00003145InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003146 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003147}
3148
3149
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003150Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003151 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003152}
3153
3154
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003155PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003156 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003157}
3158
3159
3160int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003161 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003162}
3163
3164
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003165InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003166 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003167}
3168
3169
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003170Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003171 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003172 return static_cast<Flags>(bits);
3173}
3174
3175
ager@chromium.org8bb60582008-12-11 12:02:20 +00003176Code* Code::GetCodeFromTargetAddress(Address address) {
3177 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3178 // GetCodeFromTargetAddress might be called when marking objects during mark
3179 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3180 // Code::cast. Code::cast does not work when the object's map is
3181 // marked.
3182 Code* result = reinterpret_cast<Code*>(code);
3183 return result;
3184}
3185
3186
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003187Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3188 return HeapObject::
3189 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3190}
3191
3192
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003193Object* Map::prototype() {
3194 return READ_FIELD(this, kPrototypeOffset);
3195}
3196
3197
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003198void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003199 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003200 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003201 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003202}
3203
3204
danno@chromium.org40cb8782011-05-25 07:58:50 +00003205DescriptorArray* Map::instance_descriptors() {
3206 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3207 if (object->IsSmi()) {
3208 return HEAP->empty_descriptor_array();
3209 } else {
3210 return DescriptorArray::cast(object);
3211 }
3212}
3213
3214
3215void Map::init_instance_descriptors() {
3216 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3217}
3218
3219
3220void Map::clear_instance_descriptors() {
3221 Object* object = READ_FIELD(this,
3222 kInstanceDescriptorsOrBitField3Offset);
3223 if (!object->IsSmi()) {
3224 WRITE_FIELD(
3225 this,
3226 kInstanceDescriptorsOrBitField3Offset,
3227 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3228 }
3229}
3230
3231
3232void Map::set_instance_descriptors(DescriptorArray* value,
3233 WriteBarrierMode mode) {
3234 Object* object = READ_FIELD(this,
3235 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003236 Heap* heap = GetHeap();
3237 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003238 clear_instance_descriptors();
3239 return;
3240 } else {
3241 if (object->IsSmi()) {
3242 value->set_bit_field3_storage(Smi::cast(object)->value());
3243 } else {
3244 value->set_bit_field3_storage(
3245 DescriptorArray::cast(object)->bit_field3_storage());
3246 }
3247 }
3248 ASSERT(!is_shared());
3249 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003250 CONDITIONAL_WRITE_BARRIER(
3251 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003252}
3253
3254
3255int Map::bit_field3() {
3256 Object* object = READ_FIELD(this,
3257 kInstanceDescriptorsOrBitField3Offset);
3258 if (object->IsSmi()) {
3259 return Smi::cast(object)->value();
3260 } else {
3261 return DescriptorArray::cast(object)->bit_field3_storage();
3262 }
3263}
3264
3265
3266void Map::set_bit_field3(int value) {
3267 ASSERT(Smi::IsValid(value));
3268 Object* object = READ_FIELD(this,
3269 kInstanceDescriptorsOrBitField3Offset);
3270 if (object->IsSmi()) {
3271 WRITE_FIELD(this,
3272 kInstanceDescriptorsOrBitField3Offset,
3273 Smi::FromInt(value));
3274 } else {
3275 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3276 }
3277}
3278
3279
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003280FixedArray* Map::unchecked_prototype_transitions() {
3281 return reinterpret_cast<FixedArray*>(
3282 READ_FIELD(this, kPrototypeTransitionsOffset));
3283}
3284
3285
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003286ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003287ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003288ACCESSORS(Map, constructor, Object, kConstructorOffset)
3289
3290ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003291ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003292ACCESSORS(JSFunction,
3293 next_function_link,
3294 Object,
3295 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003296
3297ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3298ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003299ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003300
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003301ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003302
3303ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3304ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3305ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3306ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3307ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3308
3309ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3310ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3311ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3312
3313ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3314ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3315ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3316ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3317ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3318ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3319
3320ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3321ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3322
3323ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3324ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3325
3326ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3327ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003328ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3329 kPropertyAccessorsOffset)
3330ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3331 kPrototypeTemplateOffset)
3332ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3333ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3334 kNamedPropertyHandlerOffset)
3335ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3336 kIndexedPropertyHandlerOffset)
3337ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3338 kInstanceTemplateOffset)
3339ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3340ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003341ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3342 kInstanceCallHandlerOffset)
3343ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3344 kAccessCheckInfoOffset)
3345ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3346
3347ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003348ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3349 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003350
3351ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3352ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3353
3354ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3355
3356ACCESSORS(Script, source, Object, kSourceOffset)
3357ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003358ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003359ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3360ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003361ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003362ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003363ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003364ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003365ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003366ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003367ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003368ACCESSORS(Script, eval_from_instructions_offset, Smi,
3369 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003370
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003371#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003372ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3373ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3374ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3375ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3376
3377ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3378ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3379ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3380ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003381#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003382
3383ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003384ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3385ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003386ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3387 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003388ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003389ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3390ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003391ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003392ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3393 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003394
3395BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3396 kHiddenPrototypeBit)
3397BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3398BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3399 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003400BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3401 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003402BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3403 kIsExpressionBit)
3404BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3405 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003406BOOL_GETTER(SharedFunctionInfo,
3407 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003408 has_only_simple_this_property_assignments,
3409 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003410BOOL_ACCESSORS(SharedFunctionInfo,
3411 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003412 allows_lazy_compilation,
3413 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003414BOOL_ACCESSORS(SharedFunctionInfo,
3415 compiler_hints,
3416 uses_arguments,
3417 kUsesArguments)
3418BOOL_ACCESSORS(SharedFunctionInfo,
3419 compiler_hints,
3420 has_duplicate_parameters,
3421 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003422
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003423
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003424#if V8_HOST_ARCH_32_BIT
3425SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3426SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003427 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003428SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003429 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003430SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3431SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003432 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003433SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3434SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003435 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003436SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003437 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003438SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003439 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003440SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003441#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003442
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003443#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003444 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003445 int holder::name() { \
3446 int value = READ_INT_FIELD(this, offset); \
3447 ASSERT(kHeapObjectTag == 1); \
3448 ASSERT((value & kHeapObjectTag) == 0); \
3449 return value >> 1; \
3450 } \
3451 void holder::set_##name(int value) { \
3452 ASSERT(kHeapObjectTag == 1); \
3453 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3454 (value & 0xC0000000) == 0x000000000); \
3455 WRITE_INT_FIELD(this, \
3456 offset, \
3457 (value << 1) & ~kHeapObjectTag); \
3458 }
3459
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003460#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3461 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003462 INT_ACCESSORS(holder, name, offset)
3463
3464
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003465PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003466PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3467 formal_parameter_count,
3468 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003469
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003470PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3471 expected_nof_properties,
3472 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003473PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3474
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003475PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3476PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3477 start_position_and_type,
3478 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003479
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003480PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3481 function_token_position,
3482 kFunctionTokenPositionOffset)
3483PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3484 compiler_hints,
3485 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003486
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003487PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3488 this_property_assignments_count,
3489 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003490PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003491#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003492
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003493
3494int SharedFunctionInfo::construction_count() {
3495 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3496}
3497
3498
3499void SharedFunctionInfo::set_construction_count(int value) {
3500 ASSERT(0 <= value && value < 256);
3501 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3502}
3503
3504
whesse@chromium.org7b260152011-06-20 15:33:18 +00003505BOOL_ACCESSORS(SharedFunctionInfo,
3506 compiler_hints,
3507 live_objects_may_exist,
3508 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003509
3510
3511bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003512 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003513}
3514
3515
whesse@chromium.org7b260152011-06-20 15:33:18 +00003516BOOL_GETTER(SharedFunctionInfo,
3517 compiler_hints,
3518 optimization_disabled,
3519 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003520
3521
3522void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3523 set_compiler_hints(BooleanBit::set(compiler_hints(),
3524 kOptimizationDisabled,
3525 disable));
3526 // If disabling optimizations we reflect that in the code object so
3527 // it will not be counted as optimizable code.
3528 if ((code()->kind() == Code::FUNCTION) && disable) {
3529 code()->set_optimizable(false);
3530 }
3531}
3532
3533
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003534StrictModeFlag SharedFunctionInfo::strict_mode_flag() {
3535 return BooleanBit::get(compiler_hints(), kStrictModeFunction)
3536 ? kStrictMode : kNonStrictMode;
3537}
3538
3539
3540void SharedFunctionInfo::set_strict_mode_flag(StrictModeFlag strict_mode_flag) {
3541 ASSERT(strict_mode_flag == kStrictMode ||
3542 strict_mode_flag == kNonStrictMode);
3543 bool value = strict_mode_flag == kStrictMode;
3544 set_compiler_hints(
3545 BooleanBit::set(compiler_hints(), kStrictModeFunction, value));
3546}
3547
3548
3549BOOL_GETTER(SharedFunctionInfo, compiler_hints, strict_mode,
3550 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003551BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3552BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3553 name_should_print_as_anonymous,
3554 kNameShouldPrintAsAnonymous)
3555BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3556BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003557
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003558ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3559ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3560
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003561ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3562
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003563bool Script::HasValidSource() {
3564 Object* src = this->source();
3565 if (!src->IsString()) return true;
3566 String* src_str = String::cast(src);
3567 if (!StringShape(src_str).IsExternal()) return true;
3568 if (src_str->IsAsciiRepresentation()) {
3569 return ExternalAsciiString::cast(src)->resource() != NULL;
3570 } else if (src_str->IsTwoByteRepresentation()) {
3571 return ExternalTwoByteString::cast(src)->resource() != NULL;
3572 }
3573 return true;
3574}
3575
3576
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003577void SharedFunctionInfo::DontAdaptArguments() {
3578 ASSERT(code()->kind() == Code::BUILTIN);
3579 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3580}
3581
3582
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003583int SharedFunctionInfo::start_position() {
3584 return start_position_and_type() >> kStartPositionShift;
3585}
3586
3587
3588void SharedFunctionInfo::set_start_position(int start_position) {
3589 set_start_position_and_type((start_position << kStartPositionShift)
3590 | (start_position_and_type() & ~kStartPositionMask));
3591}
3592
3593
3594Code* SharedFunctionInfo::code() {
3595 return Code::cast(READ_FIELD(this, kCodeOffset));
3596}
3597
3598
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003599Code* SharedFunctionInfo::unchecked_code() {
3600 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3601}
3602
3603
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003604void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003605 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003606 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003607}
3608
3609
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003610ScopeInfo* SharedFunctionInfo::scope_info() {
3611 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003612}
3613
3614
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003615void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003616 WriteBarrierMode mode) {
3617 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003618 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3619 this,
3620 kScopeInfoOffset,
3621 reinterpret_cast<Object*>(value),
3622 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003623}
3624
3625
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003626Smi* SharedFunctionInfo::deopt_counter() {
3627 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3628}
3629
3630
3631void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3632 WRITE_FIELD(this, kDeoptCounterOffset, value);
3633}
3634
3635
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003636bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003637 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003638 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003639}
3640
3641
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003642bool SharedFunctionInfo::IsApiFunction() {
3643 return function_data()->IsFunctionTemplateInfo();
3644}
3645
3646
3647FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3648 ASSERT(IsApiFunction());
3649 return FunctionTemplateInfo::cast(function_data());
3650}
3651
3652
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003653bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003654 return function_data()->IsSmi();
3655}
3656
3657
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003658BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3659 ASSERT(HasBuiltinFunctionId());
3660 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003661}
3662
3663
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003664int SharedFunctionInfo::code_age() {
3665 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3666}
3667
3668
3669void SharedFunctionInfo::set_code_age(int code_age) {
3670 set_compiler_hints(compiler_hints() |
3671 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3672}
3673
3674
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003675bool SharedFunctionInfo::has_deoptimization_support() {
3676 Code* code = this->code();
3677 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3678}
3679
3680
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003681bool JSFunction::IsBuiltin() {
3682 return context()->global()->IsJSBuiltinsObject();
3683}
3684
3685
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003686bool JSFunction::NeedsArgumentsAdaption() {
3687 return shared()->formal_parameter_count() !=
3688 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3689}
3690
3691
3692bool JSFunction::IsOptimized() {
3693 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3694}
3695
3696
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003697bool JSFunction::IsOptimizable() {
3698 return code()->kind() == Code::FUNCTION && code()->optimizable();
3699}
3700
3701
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003702bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003703 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003704}
3705
3706
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003707Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003708 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003709}
3710
3711
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003712Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003713 return reinterpret_cast<Code*>(
3714 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003715}
3716
3717
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003718void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003719 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003720 Address entry = value->entry();
3721 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003722 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3723 this,
3724 HeapObject::RawField(this, kCodeEntryOffset),
3725 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003726}
3727
3728
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003729void JSFunction::ReplaceCode(Code* code) {
3730 bool was_optimized = IsOptimized();
3731 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3732
3733 set_code(code);
3734
3735 // Add/remove the function from the list of optimized functions for this
3736 // context based on the state change.
3737 if (!was_optimized && is_optimized) {
3738 context()->global_context()->AddOptimizedFunction(this);
3739 }
3740 if (was_optimized && !is_optimized) {
3741 context()->global_context()->RemoveOptimizedFunction(this);
3742 }
3743}
3744
3745
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003746Context* JSFunction::context() {
3747 return Context::cast(READ_FIELD(this, kContextOffset));
3748}
3749
3750
3751Object* JSFunction::unchecked_context() {
3752 return READ_FIELD(this, kContextOffset);
3753}
3754
3755
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003756SharedFunctionInfo* JSFunction::unchecked_shared() {
3757 return reinterpret_cast<SharedFunctionInfo*>(
3758 READ_FIELD(this, kSharedFunctionInfoOffset));
3759}
3760
3761
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003762void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003763 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003764 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003765 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003766}
3767
3768ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3769 kPrototypeOrInitialMapOffset)
3770
3771
3772Map* JSFunction::initial_map() {
3773 return Map::cast(prototype_or_initial_map());
3774}
3775
3776
3777void JSFunction::set_initial_map(Map* value) {
3778 set_prototype_or_initial_map(value);
3779}
3780
3781
3782bool JSFunction::has_initial_map() {
3783 return prototype_or_initial_map()->IsMap();
3784}
3785
3786
3787bool JSFunction::has_instance_prototype() {
3788 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3789}
3790
3791
3792bool JSFunction::has_prototype() {
3793 return map()->has_non_instance_prototype() || has_instance_prototype();
3794}
3795
3796
3797Object* JSFunction::instance_prototype() {
3798 ASSERT(has_instance_prototype());
3799 if (has_initial_map()) return initial_map()->prototype();
3800 // When there is no initial map and the prototype is a JSObject, the
3801 // initial map field is used for the prototype field.
3802 return prototype_or_initial_map();
3803}
3804
3805
3806Object* JSFunction::prototype() {
3807 ASSERT(has_prototype());
3808 // If the function's prototype property has been set to a non-JSObject
3809 // value, that value is stored in the constructor field of the map.
3810 if (map()->has_non_instance_prototype()) return map()->constructor();
3811 return instance_prototype();
3812}
3813
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003814bool JSFunction::should_have_prototype() {
3815 return map()->function_with_prototype();
3816}
3817
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003818
3819bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003820 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003821}
3822
3823
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003824FixedArray* JSFunction::literals() {
3825 ASSERT(!shared()->bound());
3826 return literals_or_bindings();
3827}
3828
3829
3830void JSFunction::set_literals(FixedArray* literals) {
3831 ASSERT(!shared()->bound());
3832 set_literals_or_bindings(literals);
3833}
3834
3835
3836FixedArray* JSFunction::function_bindings() {
3837 ASSERT(shared()->bound());
3838 return literals_or_bindings();
3839}
3840
3841
3842void JSFunction::set_function_bindings(FixedArray* bindings) {
3843 ASSERT(shared()->bound());
3844 // Bound function literal may be initialized to the empty fixed array
3845 // before the bindings are set.
3846 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
3847 bindings->map() == GetHeap()->fixed_cow_array_map());
3848 set_literals_or_bindings(bindings);
3849}
3850
3851
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003852int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003853 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003854 return literals()->length();
3855}
3856
3857
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003858Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003859 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003860 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003861}
3862
3863
3864void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3865 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003866 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003867 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003868 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003869}
3870
3871
3872Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003873 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003874 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3875}
3876
3877
3878void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3879 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003880 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003881 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003882 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003883}
3884
3885
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003886ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003887ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003888ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3889ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3890
3891
3892void JSProxy::InitializeBody(int object_size, Object* value) {
3893 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3894 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3895 WRITE_FIELD(this, offset, value);
3896 }
3897}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003898
3899
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003900ACCESSORS(JSSet, table, Object, kTableOffset)
3901ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003902ACCESSORS(JSWeakMap, table, Object, kTableOffset)
3903ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003904
3905
3906ObjectHashTable* JSWeakMap::unchecked_table() {
3907 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3908}
3909
3910
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003911Address Foreign::foreign_address() {
3912 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003913}
3914
3915
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003916void Foreign::set_foreign_address(Address value) {
3917 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003918}
3919
3920
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003921ACCESSORS(JSValue, value, Object, kValueOffset)
3922
3923
3924JSValue* JSValue::cast(Object* obj) {
3925 ASSERT(obj->IsJSValue());
3926 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3927 return reinterpret_cast<JSValue*>(obj);
3928}
3929
3930
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003931ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3932ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3933ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3934ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3935ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3936SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3937SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3938
3939
3940JSMessageObject* JSMessageObject::cast(Object* obj) {
3941 ASSERT(obj->IsJSMessageObject());
3942 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3943 return reinterpret_cast<JSMessageObject*>(obj);
3944}
3945
3946
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003947INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003948ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00003949ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003950ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003951ACCESSORS(Code, next_code_flushing_candidate,
3952 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003953
3954
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003955byte* Code::instruction_start() {
3956 return FIELD_ADDR(this, kHeaderSize);
3957}
3958
3959
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003960byte* Code::instruction_end() {
3961 return instruction_start() + instruction_size();
3962}
3963
3964
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003965int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003966 return RoundUp(instruction_size(), kObjectAlignment);
3967}
3968
3969
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003970FixedArray* Code::unchecked_deoptimization_data() {
3971 return reinterpret_cast<FixedArray*>(
3972 READ_FIELD(this, kDeoptimizationDataOffset));
3973}
3974
3975
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003976ByteArray* Code::unchecked_relocation_info() {
3977 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003978}
3979
3980
3981byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003982 return unchecked_relocation_info()->GetDataStartAddress();
3983}
3984
3985
3986int Code::relocation_size() {
3987 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003988}
3989
3990
3991byte* Code::entry() {
3992 return instruction_start();
3993}
3994
3995
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003996bool Code::contains(byte* inner_pointer) {
3997 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003998}
3999
4000
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004001ACCESSORS(JSArray, length, Object, kLengthOffset)
4002
4003
ager@chromium.org236ad962008-09-25 09:45:57 +00004004ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004005
4006
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004007JSRegExp::Type JSRegExp::TypeTag() {
4008 Object* data = this->data();
4009 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4010 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4011 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004012}
4013
4014
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004015JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4016 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4017 return static_cast<JSRegExp::Type>(smi->value());
4018}
4019
4020
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004021int JSRegExp::CaptureCount() {
4022 switch (TypeTag()) {
4023 case ATOM:
4024 return 0;
4025 case IRREGEXP:
4026 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4027 default:
4028 UNREACHABLE();
4029 return -1;
4030 }
4031}
4032
4033
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004034JSRegExp::Flags JSRegExp::GetFlags() {
4035 ASSERT(this->data()->IsFixedArray());
4036 Object* data = this->data();
4037 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4038 return Flags(smi->value());
4039}
4040
4041
4042String* JSRegExp::Pattern() {
4043 ASSERT(this->data()->IsFixedArray());
4044 Object* data = this->data();
4045 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4046 return pattern;
4047}
4048
4049
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004050Object* JSRegExp::DataAt(int index) {
4051 ASSERT(TypeTag() != NOT_COMPILED);
4052 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004053}
4054
4055
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004056Object* JSRegExp::DataAtUnchecked(int index) {
4057 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4058 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4059 return READ_FIELD(fa, offset);
4060}
4061
4062
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004063void JSRegExp::SetDataAt(int index, Object* value) {
4064 ASSERT(TypeTag() != NOT_COMPILED);
4065 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4066 FixedArray::cast(data())->set(index, value);
4067}
4068
4069
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004070void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4071 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4072 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4073 if (value->IsSmi()) {
4074 fa->set_unchecked(index, Smi::cast(value));
4075 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004076 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004077 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4078 }
4079}
4080
4081
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004082ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004083 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004084#if DEBUG
4085 FixedArrayBase* fixed_array =
4086 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4087 Map* map = fixed_array->map();
4088 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004089 (map == GetHeap()->fixed_array_map() ||
4090 map == GetHeap()->fixed_cow_array_map())) ||
4091 (kind == FAST_DOUBLE_ELEMENTS &&
4092 fixed_array->IsFixedDoubleArray()) ||
4093 (kind == DICTIONARY_ELEMENTS &&
4094 fixed_array->IsFixedArray() &&
4095 fixed_array->IsDictionary()) ||
4096 (kind > DICTIONARY_ELEMENTS));
4097 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4098 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004099#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004100 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004101}
4102
4103
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004104ElementsAccessor* JSObject::GetElementsAccessor() {
4105 return ElementsAccessor::ForKind(GetElementsKind());
4106}
4107
4108
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004109bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004110 return GetElementsKind() == FAST_ELEMENTS;
4111}
4112
4113
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004114bool JSObject::HasFastSmiOnlyElements() {
4115 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4116}
4117
4118
4119bool JSObject::HasFastTypeElements() {
4120 ElementsKind elements_kind = GetElementsKind();
4121 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4122 elements_kind == FAST_ELEMENTS;
4123}
4124
4125
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004126bool JSObject::HasFastDoubleElements() {
4127 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4128}
4129
4130
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004131bool JSObject::HasDictionaryElements() {
4132 return GetElementsKind() == DICTIONARY_ELEMENTS;
4133}
4134
4135
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004136bool JSObject::HasNonStrictArgumentsElements() {
4137 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4138}
4139
4140
ager@chromium.org3811b432009-10-28 14:53:37 +00004141bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004142 HeapObject* array = elements();
4143 ASSERT(array != NULL);
4144 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004145}
4146
4147
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004148#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4149bool JSObject::HasExternal##name##Elements() { \
4150 HeapObject* array = elements(); \
4151 ASSERT(array != NULL); \
4152 if (!array->IsHeapObject()) \
4153 return false; \
4154 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004155}
4156
4157
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004158EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4159EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4160EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4161EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4162 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4163EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4164EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4165 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4166EXTERNAL_ELEMENTS_CHECK(Float,
4167 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004168EXTERNAL_ELEMENTS_CHECK(Double,
4169 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004170EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004171
4172
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004173bool JSObject::HasNamedInterceptor() {
4174 return map()->has_named_interceptor();
4175}
4176
4177
4178bool JSObject::HasIndexedInterceptor() {
4179 return map()->has_indexed_interceptor();
4180}
4181
4182
ager@chromium.org5c838252010-02-19 08:53:10 +00004183bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004184 bool result = elements()->IsFixedArray() ||
4185 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004186 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004187 return result;
4188}
4189
4190
lrn@chromium.org303ada72010-10-27 09:33:13 +00004191MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004192 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004193 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004194 Isolate* isolate = GetIsolate();
4195 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004196 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004197 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4198 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004199 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4200 return maybe_writable_elems;
4201 }
4202 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004203 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004204 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004205 return writable_elems;
4206}
4207
4208
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004209StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004210 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004211 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004212}
4213
4214
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004215NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004216 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004217 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004218}
4219
4220
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004221bool String::IsHashFieldComputed(uint32_t field) {
4222 return (field & kHashNotComputedMask) == 0;
4223}
4224
4225
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004226bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004227 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004228}
4229
4230
4231uint32_t String::Hash() {
4232 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004233 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004234 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004235 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004236 return ComputeAndSetHash();
4237}
4238
4239
ager@chromium.org7c537e22008-10-16 08:43:32 +00004240StringHasher::StringHasher(int length)
4241 : length_(length),
4242 raw_running_hash_(0),
4243 array_index_(0),
4244 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4245 is_first_char_(true),
4246 is_valid_(true) { }
4247
4248
4249bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004250 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004251}
4252
4253
4254void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004255 // Use the Jenkins one-at-a-time hash function to update the hash
4256 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004257 raw_running_hash_ += c;
4258 raw_running_hash_ += (raw_running_hash_ << 10);
4259 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004260 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004261 if (is_array_index_) {
4262 if (c < '0' || c > '9') {
4263 is_array_index_ = false;
4264 } else {
4265 int d = c - '0';
4266 if (is_first_char_) {
4267 is_first_char_ = false;
4268 if (c == '0' && length_ > 1) {
4269 is_array_index_ = false;
4270 return;
4271 }
4272 }
4273 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4274 is_array_index_ = false;
4275 } else {
4276 array_index_ = array_index_ * 10 + d;
4277 }
4278 }
4279 }
4280}
4281
4282
4283void StringHasher::AddCharacterNoIndex(uc32 c) {
4284 ASSERT(!is_array_index());
4285 raw_running_hash_ += c;
4286 raw_running_hash_ += (raw_running_hash_ << 10);
4287 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4288}
4289
4290
4291uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004292 // Get the calculated raw hash value and do some more bit ops to distribute
4293 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004294 uint32_t result = raw_running_hash_;
4295 result += (result << 3);
4296 result ^= (result >> 11);
4297 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004298 if (result == 0) {
4299 result = 27;
4300 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004301 return result;
4302}
4303
4304
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004305template <typename schar>
4306uint32_t HashSequentialString(const schar* chars, int length) {
4307 StringHasher hasher(length);
4308 if (!hasher.has_trivial_hash()) {
4309 int i;
4310 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4311 hasher.AddCharacter(chars[i]);
4312 }
4313 for (; i < length; i++) {
4314 hasher.AddCharacterNoIndex(chars[i]);
4315 }
4316 }
4317 return hasher.GetHashField();
4318}
4319
4320
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004321bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004322 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004323 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4324 return false;
4325 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004326 return SlowAsArrayIndex(index);
4327}
4328
4329
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004330Object* JSReceiver::GetPrototype() {
4331 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004332}
4333
4334
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004335bool JSReceiver::HasProperty(String* name) {
4336 if (IsJSProxy()) {
4337 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4338 }
4339 return GetPropertyAttribute(name) != ABSENT;
4340}
4341
4342
4343bool JSReceiver::HasLocalProperty(String* name) {
4344 if (IsJSProxy()) {
4345 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4346 }
4347 return GetLocalPropertyAttribute(name) != ABSENT;
4348}
4349
4350
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004351PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004352 return GetPropertyAttributeWithReceiver(this, key);
4353}
4354
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004355// TODO(504): this may be useful in other places too where JSGlobalProxy
4356// is used.
4357Object* JSObject::BypassGlobalProxy() {
4358 if (IsJSGlobalProxy()) {
4359 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004360 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004361 ASSERT(proto->IsJSGlobalObject());
4362 return proto;
4363 }
4364 return this;
4365}
4366
4367
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004368MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4369 return IsJSProxy()
4370 ? JSProxy::cast(this)->GetIdentityHash(flag)
4371 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004372}
4373
4374
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004375bool JSReceiver::HasElement(uint32_t index) {
4376 if (IsJSProxy()) {
4377 return JSProxy::cast(this)->HasElementWithHandler(index);
4378 }
4379 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004380}
4381
4382
4383bool AccessorInfo::all_can_read() {
4384 return BooleanBit::get(flag(), kAllCanReadBit);
4385}
4386
4387
4388void AccessorInfo::set_all_can_read(bool value) {
4389 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4390}
4391
4392
4393bool AccessorInfo::all_can_write() {
4394 return BooleanBit::get(flag(), kAllCanWriteBit);
4395}
4396
4397
4398void AccessorInfo::set_all_can_write(bool value) {
4399 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4400}
4401
4402
ager@chromium.org870a0b62008-11-04 11:43:05 +00004403bool AccessorInfo::prohibits_overwriting() {
4404 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4405}
4406
4407
4408void AccessorInfo::set_prohibits_overwriting(bool value) {
4409 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4410}
4411
4412
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004413PropertyAttributes AccessorInfo::property_attributes() {
4414 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4415}
4416
4417
4418void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004419 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004420}
4421
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004422
4423template<typename Shape, typename Key>
4424void Dictionary<Shape, Key>::SetEntry(int entry,
4425 Object* key,
4426 Object* value) {
4427 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4428}
4429
4430
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004431template<typename Shape, typename Key>
4432void Dictionary<Shape, Key>::SetEntry(int entry,
4433 Object* key,
4434 Object* value,
4435 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004436 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004437 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004438 AssertNoAllocation no_gc;
4439 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004440 FixedArray::set(index, key, mode);
4441 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004442 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004443}
4444
4445
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004446bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4447 ASSERT(other->IsNumber());
4448 return key == static_cast<uint32_t>(other->Number());
4449}
4450
4451
4452uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4453 return ComputeIntegerHash(key);
4454}
4455
4456
4457uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4458 ASSERT(other->IsNumber());
4459 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4460}
4461
4462
4463MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4464 return Isolate::Current()->heap()->NumberFromUint32(key);
4465}
4466
4467
4468bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4469 // We know that all entries in a hash table had their hash keys created.
4470 // Use that knowledge to have fast failure.
4471 if (key->Hash() != String::cast(other)->Hash()) return false;
4472 return key->Equals(String::cast(other));
4473}
4474
4475
4476uint32_t StringDictionaryShape::Hash(String* key) {
4477 return key->Hash();
4478}
4479
4480
4481uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4482 return String::cast(other)->Hash();
4483}
4484
4485
4486MaybeObject* StringDictionaryShape::AsObject(String* key) {
4487 return key;
4488}
4489
4490
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004491template <int entrysize>
4492bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4493 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004494}
4495
4496
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004497template <int entrysize>
4498uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004499 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4500 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004501}
4502
4503
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004504template <int entrysize>
4505uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4506 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004507 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4508 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004509}
4510
4511
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004512template <int entrysize>
4513MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004514 return key;
4515}
4516
4517
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004518void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004519 // No write barrier is needed since empty_fixed_array is not in new space.
4520 // Please note this function is used during marking:
4521 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004522 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4523 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004524}
4525
4526
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004527void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004528 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004529 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004530 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4531 if (elts->length() < required_size) {
4532 // Doubling in size would be overkill, but leave some slack to avoid
4533 // constantly growing.
4534 Expand(required_size + (required_size >> 3));
4535 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004536 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004537 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4538 // Expand will allocate a new backing store in new space even if the size
4539 // we asked for isn't larger than what we had before.
4540 Expand(required_size);
4541 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004542}
4543
4544
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004545void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004546 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004547 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4548}
4549
4550
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004551MaybeObject* JSArray::SetContent(FixedArray* storage) {
4552 MaybeObject* maybe_object = EnsureCanContainElements(storage);
4553 if (maybe_object->IsFailure()) return maybe_object;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004554 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004555 set_elements(storage);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004556 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004557}
4558
4559
lrn@chromium.org303ada72010-10-27 09:33:13 +00004560MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004561 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004562 return GetHeap()->CopyFixedArray(this);
4563}
4564
4565
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004566MaybeObject* FixedDoubleArray::Copy() {
4567 if (length() == 0) return this;
4568 return GetHeap()->CopyFixedDoubleArray(this);
4569}
4570
4571
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004572Relocatable::Relocatable(Isolate* isolate) {
4573 ASSERT(isolate == Isolate::Current());
4574 isolate_ = isolate;
4575 prev_ = isolate->relocatable_top();
4576 isolate->set_relocatable_top(this);
4577}
4578
4579
4580Relocatable::~Relocatable() {
4581 ASSERT(isolate_ == Isolate::Current());
4582 ASSERT_EQ(isolate_->relocatable_top(), this);
4583 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004584}
4585
4586
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004587int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4588 return map->instance_size();
4589}
4590
4591
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004592void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004593 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004594 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004595}
4596
4597
4598template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004599void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004600 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004601 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004602}
4603
4604
4605void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4606 typedef v8::String::ExternalAsciiStringResource Resource;
4607 v->VisitExternalAsciiString(
4608 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4609}
4610
4611
4612template<typename StaticVisitor>
4613void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4614 typedef v8::String::ExternalAsciiStringResource Resource;
4615 StaticVisitor::VisitExternalAsciiString(
4616 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4617}
4618
4619
4620void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4621 typedef v8::String::ExternalStringResource Resource;
4622 v->VisitExternalTwoByteString(
4623 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4624}
4625
4626
4627template<typename StaticVisitor>
4628void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4629 typedef v8::String::ExternalStringResource Resource;
4630 StaticVisitor::VisitExternalTwoByteString(
4631 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4632}
4633
4634#define SLOT_ADDR(obj, offset) \
4635 reinterpret_cast<Object**>((obj)->address() + offset)
4636
4637template<int start_offset, int end_offset, int size>
4638void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4639 HeapObject* obj,
4640 ObjectVisitor* v) {
4641 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4642}
4643
4644
4645template<int start_offset>
4646void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4647 int object_size,
4648 ObjectVisitor* v) {
4649 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4650}
4651
4652#undef SLOT_ADDR
4653
4654
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004655#undef CAST_ACCESSOR
4656#undef INT_ACCESSORS
4657#undef SMI_ACCESSORS
4658#undef ACCESSORS
4659#undef FIELD_ADDR
4660#undef READ_FIELD
4661#undef WRITE_FIELD
4662#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004663#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004664#undef READ_MEMADDR_FIELD
4665#undef WRITE_MEMADDR_FIELD
4666#undef READ_DOUBLE_FIELD
4667#undef WRITE_DOUBLE_FIELD
4668#undef READ_INT_FIELD
4669#undef WRITE_INT_FIELD
4670#undef READ_SHORT_FIELD
4671#undef WRITE_SHORT_FIELD
4672#undef READ_BYTE_FIELD
4673#undef WRITE_BYTE_FIELD
4674
4675
4676} } // namespace v8::internal
4677
4678#endif // V8_OBJECTS_INL_H_