blob: 11819eaa09d13db19bf029f07c9b92a960c72c31 [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
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002300const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002301 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2302}
2303
2304
2305void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002306 const ExternalAsciiString::Resource* resource) {
2307 *reinterpret_cast<const Resource**>(
2308 FIELD_ADDR(this, kResourceOffset)) = resource;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002309}
2310
2311
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002312const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002313 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2314}
2315
2316
2317void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002318 const ExternalTwoByteString::Resource* resource) {
2319 *reinterpret_cast<const Resource**>(
2320 FIELD_ADDR(this, kResourceOffset)) = resource;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002321}
2322
2323
ager@chromium.orgac091b72010-05-05 07:34:42 +00002324void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002325 set_finger_index(kEntriesIndex);
2326 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002327}
2328
2329
2330void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002331 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002332 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002333 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002334 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002335 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002336 MakeZeroSize();
2337}
2338
2339
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002340int JSFunctionResultCache::size() {
2341 return Smi::cast(get(kCacheSizeIndex))->value();
2342}
2343
2344
2345void JSFunctionResultCache::set_size(int size) {
2346 set(kCacheSizeIndex, Smi::FromInt(size));
2347}
2348
2349
2350int JSFunctionResultCache::finger_index() {
2351 return Smi::cast(get(kFingerIndex))->value();
2352}
2353
2354
2355void JSFunctionResultCache::set_finger_index(int finger_index) {
2356 set(kFingerIndex, Smi::FromInt(finger_index));
2357}
2358
2359
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002360byte ByteArray::get(int index) {
2361 ASSERT(index >= 0 && index < this->length());
2362 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2363}
2364
2365
2366void ByteArray::set(int index, byte value) {
2367 ASSERT(index >= 0 && index < this->length());
2368 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2369}
2370
2371
2372int ByteArray::get_int(int index) {
2373 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2374 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2375}
2376
2377
2378ByteArray* ByteArray::FromDataStartAddress(Address address) {
2379 ASSERT_TAG_ALIGNED(address);
2380 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2381}
2382
2383
2384Address ByteArray::GetDataStartAddress() {
2385 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2386}
2387
2388
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002389uint8_t* ExternalPixelArray::external_pixel_pointer() {
2390 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002391}
2392
2393
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002394uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002395 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002396 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002397 return ptr[index];
2398}
2399
2400
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002401MaybeObject* ExternalPixelArray::get(int index) {
2402 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2403}
2404
2405
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002406void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002407 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002408 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002409 ptr[index] = value;
2410}
2411
2412
ager@chromium.org3811b432009-10-28 14:53:37 +00002413void* ExternalArray::external_pointer() {
2414 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2415 return reinterpret_cast<void*>(ptr);
2416}
2417
2418
2419void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2420 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2421 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2422}
2423
2424
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002425int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002426 ASSERT((index >= 0) && (index < this->length()));
2427 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2428 return ptr[index];
2429}
2430
2431
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002432MaybeObject* ExternalByteArray::get(int index) {
2433 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2434}
2435
2436
ager@chromium.org3811b432009-10-28 14:53:37 +00002437void ExternalByteArray::set(int index, int8_t value) {
2438 ASSERT((index >= 0) && (index < this->length()));
2439 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2440 ptr[index] = value;
2441}
2442
2443
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002444uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002445 ASSERT((index >= 0) && (index < this->length()));
2446 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2447 return ptr[index];
2448}
2449
2450
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002451MaybeObject* ExternalUnsignedByteArray::get(int index) {
2452 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2453}
2454
2455
ager@chromium.org3811b432009-10-28 14:53:37 +00002456void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2457 ASSERT((index >= 0) && (index < this->length()));
2458 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2459 ptr[index] = value;
2460}
2461
2462
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002463int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002464 ASSERT((index >= 0) && (index < this->length()));
2465 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2466 return ptr[index];
2467}
2468
2469
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002470MaybeObject* ExternalShortArray::get(int index) {
2471 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2472}
2473
2474
ager@chromium.org3811b432009-10-28 14:53:37 +00002475void ExternalShortArray::set(int index, int16_t value) {
2476 ASSERT((index >= 0) && (index < this->length()));
2477 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2478 ptr[index] = value;
2479}
2480
2481
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002482uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002483 ASSERT((index >= 0) && (index < this->length()));
2484 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2485 return ptr[index];
2486}
2487
2488
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002489MaybeObject* ExternalUnsignedShortArray::get(int index) {
2490 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2491}
2492
2493
ager@chromium.org3811b432009-10-28 14:53:37 +00002494void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2495 ASSERT((index >= 0) && (index < this->length()));
2496 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2497 ptr[index] = value;
2498}
2499
2500
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002501int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002502 ASSERT((index >= 0) && (index < this->length()));
2503 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2504 return ptr[index];
2505}
2506
2507
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002508MaybeObject* ExternalIntArray::get(int index) {
2509 return GetHeap()->NumberFromInt32(get_scalar(index));
2510}
2511
2512
ager@chromium.org3811b432009-10-28 14:53:37 +00002513void ExternalIntArray::set(int index, int32_t value) {
2514 ASSERT((index >= 0) && (index < this->length()));
2515 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2516 ptr[index] = value;
2517}
2518
2519
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002520uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002521 ASSERT((index >= 0) && (index < this->length()));
2522 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2523 return ptr[index];
2524}
2525
2526
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002527MaybeObject* ExternalUnsignedIntArray::get(int index) {
2528 return GetHeap()->NumberFromUint32(get_scalar(index));
2529}
2530
2531
ager@chromium.org3811b432009-10-28 14:53:37 +00002532void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2533 ASSERT((index >= 0) && (index < this->length()));
2534 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2535 ptr[index] = value;
2536}
2537
2538
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002539float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002540 ASSERT((index >= 0) && (index < this->length()));
2541 float* ptr = static_cast<float*>(external_pointer());
2542 return ptr[index];
2543}
2544
2545
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002546MaybeObject* ExternalFloatArray::get(int index) {
2547 return GetHeap()->NumberFromDouble(get_scalar(index));
2548}
2549
2550
ager@chromium.org3811b432009-10-28 14:53:37 +00002551void ExternalFloatArray::set(int index, float value) {
2552 ASSERT((index >= 0) && (index < this->length()));
2553 float* ptr = static_cast<float*>(external_pointer());
2554 ptr[index] = value;
2555}
2556
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002557
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002558double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002559 ASSERT((index >= 0) && (index < this->length()));
2560 double* ptr = static_cast<double*>(external_pointer());
2561 return ptr[index];
2562}
2563
2564
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002565MaybeObject* ExternalDoubleArray::get(int index) {
2566 return GetHeap()->NumberFromDouble(get_scalar(index));
2567}
2568
2569
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002570void ExternalDoubleArray::set(int index, double value) {
2571 ASSERT((index >= 0) && (index < this->length()));
2572 double* ptr = static_cast<double*>(external_pointer());
2573 ptr[index] = value;
2574}
2575
2576
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002577int Map::visitor_id() {
2578 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2579}
2580
2581
2582void Map::set_visitor_id(int id) {
2583 ASSERT(0 <= id && id < 256);
2584 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2585}
2586
ager@chromium.org3811b432009-10-28 14:53:37 +00002587
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002588int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002589 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2590}
2591
2592
2593int Map::inobject_properties() {
2594 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002595}
2596
2597
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002598int Map::pre_allocated_property_fields() {
2599 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2600}
2601
2602
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002603int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002604 int instance_size = map->instance_size();
2605 if (instance_size != kVariableSizeSentinel) return instance_size;
2606 // We can ignore the "symbol" bit becase it is only set for symbols
2607 // and implies a string type.
2608 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002609 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002610 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002611 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002612 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002613 if (instance_type == ASCII_STRING_TYPE) {
2614 return SeqAsciiString::SizeFor(
2615 reinterpret_cast<SeqAsciiString*>(this)->length());
2616 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002617 if (instance_type == BYTE_ARRAY_TYPE) {
2618 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2619 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002620 if (instance_type == FREE_SPACE_TYPE) {
2621 return reinterpret_cast<FreeSpace*>(this)->size();
2622 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002623 if (instance_type == STRING_TYPE) {
2624 return SeqTwoByteString::SizeFor(
2625 reinterpret_cast<SeqTwoByteString*>(this)->length());
2626 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002627 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2628 return FixedDoubleArray::SizeFor(
2629 reinterpret_cast<FixedDoubleArray*>(this)->length());
2630 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002631 ASSERT(instance_type == CODE_TYPE);
2632 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002633}
2634
2635
2636void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002637 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002638 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002639 ASSERT(0 <= value && value < 256);
2640 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2641}
2642
2643
ager@chromium.org7c537e22008-10-16 08:43:32 +00002644void Map::set_inobject_properties(int value) {
2645 ASSERT(0 <= value && value < 256);
2646 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2647}
2648
2649
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002650void Map::set_pre_allocated_property_fields(int value) {
2651 ASSERT(0 <= value && value < 256);
2652 WRITE_BYTE_FIELD(this,
2653 kPreAllocatedPropertyFieldsOffset,
2654 static_cast<byte>(value));
2655}
2656
2657
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002658InstanceType Map::instance_type() {
2659 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2660}
2661
2662
2663void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002664 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2665}
2666
2667
2668int Map::unused_property_fields() {
2669 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2670}
2671
2672
2673void Map::set_unused_property_fields(int value) {
2674 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2675}
2676
2677
2678byte Map::bit_field() {
2679 return READ_BYTE_FIELD(this, kBitFieldOffset);
2680}
2681
2682
2683void Map::set_bit_field(byte value) {
2684 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2685}
2686
2687
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002688byte Map::bit_field2() {
2689 return READ_BYTE_FIELD(this, kBitField2Offset);
2690}
2691
2692
2693void Map::set_bit_field2(byte value) {
2694 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2695}
2696
2697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002698void Map::set_non_instance_prototype(bool value) {
2699 if (value) {
2700 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2701 } else {
2702 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2703 }
2704}
2705
2706
2707bool Map::has_non_instance_prototype() {
2708 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2709}
2710
2711
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002712void Map::set_function_with_prototype(bool value) {
2713 if (value) {
2714 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2715 } else {
2716 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2717 }
2718}
2719
2720
2721bool Map::function_with_prototype() {
2722 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2723}
2724
2725
ager@chromium.org870a0b62008-11-04 11:43:05 +00002726void Map::set_is_access_check_needed(bool access_check_needed) {
2727 if (access_check_needed) {
2728 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2729 } else {
2730 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2731 }
2732}
2733
2734
2735bool Map::is_access_check_needed() {
2736 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2737}
2738
2739
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002740void Map::set_is_extensible(bool value) {
2741 if (value) {
2742 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2743 } else {
2744 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2745 }
2746}
2747
2748bool Map::is_extensible() {
2749 return ((1 << kIsExtensible) & bit_field2()) != 0;
2750}
2751
2752
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002753void Map::set_attached_to_shared_function_info(bool value) {
2754 if (value) {
2755 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2756 } else {
2757 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2758 }
2759}
2760
2761bool Map::attached_to_shared_function_info() {
2762 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2763}
2764
2765
2766void Map::set_is_shared(bool value) {
2767 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002768 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002769 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002770 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002771 }
2772}
2773
2774bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002775 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002776}
2777
2778
2779JSFunction* Map::unchecked_constructor() {
2780 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2781}
2782
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002783
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002784Code::Flags Code::flags() {
2785 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2786}
2787
2788
2789void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002790 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002791 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002792 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2793 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002794 ExtractArgumentsCountFromFlags(flags) >= 0);
2795 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2796}
2797
2798
2799Code::Kind Code::kind() {
2800 return ExtractKindFromFlags(flags());
2801}
2802
2803
kasper.lund7276f142008-07-30 08:49:36 +00002804InlineCacheState Code::ic_state() {
2805 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002806 // Only allow uninitialized or debugger states for non-IC code
2807 // objects. This is used in the debugger to determine whether or not
2808 // a call to code object has been replaced with a debug break call.
2809 ASSERT(is_inline_cache_stub() ||
2810 result == UNINITIALIZED ||
2811 result == DEBUG_BREAK ||
2812 result == DEBUG_PREPARE_STEP_IN);
2813 return result;
2814}
2815
2816
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002817Code::ExtraICState Code::extra_ic_state() {
2818 ASSERT(is_inline_cache_stub());
2819 return ExtractExtraICStateFromFlags(flags());
2820}
2821
2822
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002823PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002824 return ExtractTypeFromFlags(flags());
2825}
2826
2827
2828int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002829 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002830 return ExtractArgumentsCountFromFlags(flags());
2831}
2832
2833
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002834int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002835 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002836 kind() == UNARY_OP_IC ||
2837 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002838 kind() == COMPARE_IC ||
2839 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002840 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002841}
2842
2843
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002844void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002845 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002846 kind() == UNARY_OP_IC ||
2847 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002848 kind() == COMPARE_IC ||
2849 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002850 ASSERT(0 <= major && major < 256);
2851 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002852}
2853
2854
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002855bool Code::is_pregenerated() {
2856 return kind() == STUB && IsPregeneratedField::decode(flags());
2857}
2858
2859
2860void Code::set_is_pregenerated(bool value) {
2861 ASSERT(kind() == STUB);
2862 Flags f = flags();
2863 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2864 set_flags(f);
2865}
2866
2867
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002868bool Code::optimizable() {
2869 ASSERT(kind() == FUNCTION);
2870 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2871}
2872
2873
2874void Code::set_optimizable(bool value) {
2875 ASSERT(kind() == FUNCTION);
2876 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2877}
2878
2879
2880bool Code::has_deoptimization_support() {
2881 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002882 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2883 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002884}
2885
2886
2887void Code::set_has_deoptimization_support(bool value) {
2888 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002889 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2890 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
2891 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2892}
2893
2894
2895bool Code::has_debug_break_slots() {
2896 ASSERT(kind() == FUNCTION);
2897 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2898 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
2899}
2900
2901
2902void Code::set_has_debug_break_slots(bool value) {
2903 ASSERT(kind() == FUNCTION);
2904 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2905 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
2906 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002907}
2908
2909
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002910bool Code::is_compiled_optimizable() {
2911 ASSERT(kind() == FUNCTION);
2912 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2913 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
2914}
2915
2916
2917void Code::set_compiled_optimizable(bool value) {
2918 ASSERT(kind() == FUNCTION);
2919 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2920 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
2921 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2922}
2923
2924
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002925int Code::allow_osr_at_loop_nesting_level() {
2926 ASSERT(kind() == FUNCTION);
2927 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2928}
2929
2930
2931void Code::set_allow_osr_at_loop_nesting_level(int level) {
2932 ASSERT(kind() == FUNCTION);
2933 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2934 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2935}
2936
2937
2938unsigned Code::stack_slots() {
2939 ASSERT(kind() == OPTIMIZED_FUNCTION);
2940 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2941}
2942
2943
2944void Code::set_stack_slots(unsigned slots) {
2945 ASSERT(kind() == OPTIMIZED_FUNCTION);
2946 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2947}
2948
2949
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002950unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002951 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002952 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002953}
2954
2955
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002956void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002957 ASSERT(kind() == OPTIMIZED_FUNCTION);
2958 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002959 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002960}
2961
2962
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002963unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002964 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002965 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002966}
2967
2968
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002969void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002970 ASSERT(kind() == FUNCTION);
2971 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002972 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002973}
2974
2975
2976CheckType Code::check_type() {
2977 ASSERT(is_call_stub() || is_keyed_call_stub());
2978 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2979 return static_cast<CheckType>(type);
2980}
2981
2982
2983void Code::set_check_type(CheckType value) {
2984 ASSERT(is_call_stub() || is_keyed_call_stub());
2985 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2986}
2987
2988
danno@chromium.org40cb8782011-05-25 07:58:50 +00002989byte Code::unary_op_type() {
2990 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002991 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2992}
2993
2994
danno@chromium.org40cb8782011-05-25 07:58:50 +00002995void Code::set_unary_op_type(byte value) {
2996 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002997 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2998}
2999
3000
danno@chromium.org40cb8782011-05-25 07:58:50 +00003001byte Code::binary_op_type() {
3002 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003003 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3004}
3005
3006
danno@chromium.org40cb8782011-05-25 07:58:50 +00003007void Code::set_binary_op_type(byte value) {
3008 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003009 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3010}
3011
3012
danno@chromium.org40cb8782011-05-25 07:58:50 +00003013byte Code::binary_op_result_type() {
3014 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003015 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3016}
3017
3018
danno@chromium.org40cb8782011-05-25 07:58:50 +00003019void Code::set_binary_op_result_type(byte value) {
3020 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003021 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3022}
3023
3024
3025byte Code::compare_state() {
3026 ASSERT(is_compare_ic_stub());
3027 return READ_BYTE_FIELD(this, kCompareStateOffset);
3028}
3029
3030
3031void Code::set_compare_state(byte value) {
3032 ASSERT(is_compare_ic_stub());
3033 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3034}
3035
3036
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003037byte Code::to_boolean_state() {
3038 ASSERT(is_to_boolean_ic_stub());
3039 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3040}
3041
3042
3043void Code::set_to_boolean_state(byte value) {
3044 ASSERT(is_to_boolean_ic_stub());
3045 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3046}
3047
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003048
3049bool Code::has_function_cache() {
3050 ASSERT(kind() == STUB);
3051 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3052}
3053
3054
3055void Code::set_has_function_cache(bool flag) {
3056 ASSERT(kind() == STUB);
3057 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3058}
3059
3060
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003061bool Code::is_inline_cache_stub() {
3062 Kind kind = this->kind();
3063 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3064}
3065
3066
3067Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003068 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003069 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003070 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003071 int argc,
3072 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003073 // Extra IC state is only allowed for call IC stubs or for store IC
3074 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003075 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003076 kind == CALL_IC ||
3077 kind == STORE_IC ||
3078 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003079 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003080 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003081 | ICStateField::encode(ic_state)
3082 | TypeField::encode(type)
3083 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003084 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003085 | CacheHolderField::encode(holder);
3086 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003087}
3088
3089
3090Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3091 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003092 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003093 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003094 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003095 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003096}
3097
3098
3099Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003100 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003101}
3102
3103
kasper.lund7276f142008-07-30 08:49:36 +00003104InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003105 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003106}
3107
3108
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003109Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003110 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003111}
3112
3113
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003114PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003115 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003116}
3117
3118
3119int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003120 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003121}
3122
3123
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003124InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003125 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003126}
3127
3128
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003129Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003130 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003131 return static_cast<Flags>(bits);
3132}
3133
3134
ager@chromium.org8bb60582008-12-11 12:02:20 +00003135Code* Code::GetCodeFromTargetAddress(Address address) {
3136 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3137 // GetCodeFromTargetAddress might be called when marking objects during mark
3138 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3139 // Code::cast. Code::cast does not work when the object's map is
3140 // marked.
3141 Code* result = reinterpret_cast<Code*>(code);
3142 return result;
3143}
3144
3145
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003146Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3147 return HeapObject::
3148 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3149}
3150
3151
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003152Object* Map::prototype() {
3153 return READ_FIELD(this, kPrototypeOffset);
3154}
3155
3156
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003157void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003158 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003159 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003160 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003161}
3162
3163
danno@chromium.org40cb8782011-05-25 07:58:50 +00003164DescriptorArray* Map::instance_descriptors() {
3165 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3166 if (object->IsSmi()) {
3167 return HEAP->empty_descriptor_array();
3168 } else {
3169 return DescriptorArray::cast(object);
3170 }
3171}
3172
3173
3174void Map::init_instance_descriptors() {
3175 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3176}
3177
3178
3179void Map::clear_instance_descriptors() {
3180 Object* object = READ_FIELD(this,
3181 kInstanceDescriptorsOrBitField3Offset);
3182 if (!object->IsSmi()) {
3183 WRITE_FIELD(
3184 this,
3185 kInstanceDescriptorsOrBitField3Offset,
3186 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3187 }
3188}
3189
3190
3191void Map::set_instance_descriptors(DescriptorArray* value,
3192 WriteBarrierMode mode) {
3193 Object* object = READ_FIELD(this,
3194 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003195 Heap* heap = GetHeap();
3196 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003197 clear_instance_descriptors();
3198 return;
3199 } else {
3200 if (object->IsSmi()) {
3201 value->set_bit_field3_storage(Smi::cast(object)->value());
3202 } else {
3203 value->set_bit_field3_storage(
3204 DescriptorArray::cast(object)->bit_field3_storage());
3205 }
3206 }
3207 ASSERT(!is_shared());
3208 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003209 CONDITIONAL_WRITE_BARRIER(
3210 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003211}
3212
3213
3214int Map::bit_field3() {
3215 Object* object = READ_FIELD(this,
3216 kInstanceDescriptorsOrBitField3Offset);
3217 if (object->IsSmi()) {
3218 return Smi::cast(object)->value();
3219 } else {
3220 return DescriptorArray::cast(object)->bit_field3_storage();
3221 }
3222}
3223
3224
3225void Map::set_bit_field3(int value) {
3226 ASSERT(Smi::IsValid(value));
3227 Object* object = READ_FIELD(this,
3228 kInstanceDescriptorsOrBitField3Offset);
3229 if (object->IsSmi()) {
3230 WRITE_FIELD(this,
3231 kInstanceDescriptorsOrBitField3Offset,
3232 Smi::FromInt(value));
3233 } else {
3234 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3235 }
3236}
3237
3238
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003239FixedArray* Map::unchecked_prototype_transitions() {
3240 return reinterpret_cast<FixedArray*>(
3241 READ_FIELD(this, kPrototypeTransitionsOffset));
3242}
3243
3244
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003245ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003246ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003247ACCESSORS(Map, constructor, Object, kConstructorOffset)
3248
3249ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003250ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003251ACCESSORS(JSFunction,
3252 next_function_link,
3253 Object,
3254 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003255
3256ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3257ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003258ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003259
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003260ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003261
3262ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3263ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3264ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3265ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3266ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3267
3268ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3269ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3270ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3271
3272ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3273ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3274ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3275ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3276ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3277ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3278
3279ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3280ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3281
3282ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3283ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3284
3285ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3286ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003287ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3288 kPropertyAccessorsOffset)
3289ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3290 kPrototypeTemplateOffset)
3291ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3292ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3293 kNamedPropertyHandlerOffset)
3294ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3295 kIndexedPropertyHandlerOffset)
3296ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3297 kInstanceTemplateOffset)
3298ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3299ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003300ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3301 kInstanceCallHandlerOffset)
3302ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3303 kAccessCheckInfoOffset)
3304ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3305
3306ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003307ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3308 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003309
3310ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3311ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3312
3313ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3314
3315ACCESSORS(Script, source, Object, kSourceOffset)
3316ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003317ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003318ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3319ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003320ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003321ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003322ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003323ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003324ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003325ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003326ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003327ACCESSORS(Script, eval_from_instructions_offset, Smi,
3328 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003329
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003330#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003331ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3332ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3333ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3334ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3335
3336ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3337ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3338ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3339ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003340#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003341
3342ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003343ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3344ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003345ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3346 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003347ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003348ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3349ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003350ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003351ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3352 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003353
3354BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3355 kHiddenPrototypeBit)
3356BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3357BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3358 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003359BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3360 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003361BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3362 kIsExpressionBit)
3363BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3364 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003365BOOL_GETTER(SharedFunctionInfo,
3366 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003367 has_only_simple_this_property_assignments,
3368 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003369BOOL_ACCESSORS(SharedFunctionInfo,
3370 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003371 allows_lazy_compilation,
3372 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003373BOOL_ACCESSORS(SharedFunctionInfo,
3374 compiler_hints,
3375 uses_arguments,
3376 kUsesArguments)
3377BOOL_ACCESSORS(SharedFunctionInfo,
3378 compiler_hints,
3379 has_duplicate_parameters,
3380 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003381
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003382
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003383#if V8_HOST_ARCH_32_BIT
3384SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3385SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003386 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003387SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003388 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003389SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3390SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003391 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003392SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3393SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003394 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003395SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003396 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003397SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003398 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003399SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003400#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003401
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003402#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003403 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003404 int holder::name() { \
3405 int value = READ_INT_FIELD(this, offset); \
3406 ASSERT(kHeapObjectTag == 1); \
3407 ASSERT((value & kHeapObjectTag) == 0); \
3408 return value >> 1; \
3409 } \
3410 void holder::set_##name(int value) { \
3411 ASSERT(kHeapObjectTag == 1); \
3412 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3413 (value & 0xC0000000) == 0x000000000); \
3414 WRITE_INT_FIELD(this, \
3415 offset, \
3416 (value << 1) & ~kHeapObjectTag); \
3417 }
3418
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003419#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3420 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003421 INT_ACCESSORS(holder, name, offset)
3422
3423
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003424PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003425PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3426 formal_parameter_count,
3427 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003428
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003429PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3430 expected_nof_properties,
3431 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003432PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3433
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003434PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3435PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3436 start_position_and_type,
3437 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003438
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003439PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3440 function_token_position,
3441 kFunctionTokenPositionOffset)
3442PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3443 compiler_hints,
3444 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003445
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003446PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3447 this_property_assignments_count,
3448 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003449PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003450#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003451
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003452
3453int SharedFunctionInfo::construction_count() {
3454 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3455}
3456
3457
3458void SharedFunctionInfo::set_construction_count(int value) {
3459 ASSERT(0 <= value && value < 256);
3460 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3461}
3462
3463
whesse@chromium.org7b260152011-06-20 15:33:18 +00003464BOOL_ACCESSORS(SharedFunctionInfo,
3465 compiler_hints,
3466 live_objects_may_exist,
3467 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003468
3469
3470bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003471 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003472}
3473
3474
whesse@chromium.org7b260152011-06-20 15:33:18 +00003475BOOL_GETTER(SharedFunctionInfo,
3476 compiler_hints,
3477 optimization_disabled,
3478 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003479
3480
3481void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3482 set_compiler_hints(BooleanBit::set(compiler_hints(),
3483 kOptimizationDisabled,
3484 disable));
3485 // If disabling optimizations we reflect that in the code object so
3486 // it will not be counted as optimizable code.
3487 if ((code()->kind() == Code::FUNCTION) && disable) {
3488 code()->set_optimizable(false);
3489 }
3490}
3491
3492
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003493StrictModeFlag SharedFunctionInfo::strict_mode_flag() {
3494 return BooleanBit::get(compiler_hints(), kStrictModeFunction)
3495 ? kStrictMode : kNonStrictMode;
3496}
3497
3498
3499void SharedFunctionInfo::set_strict_mode_flag(StrictModeFlag strict_mode_flag) {
3500 ASSERT(strict_mode_flag == kStrictMode ||
3501 strict_mode_flag == kNonStrictMode);
3502 bool value = strict_mode_flag == kStrictMode;
3503 set_compiler_hints(
3504 BooleanBit::set(compiler_hints(), kStrictModeFunction, value));
3505}
3506
3507
3508BOOL_GETTER(SharedFunctionInfo, compiler_hints, strict_mode,
3509 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003510BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3511BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3512 name_should_print_as_anonymous,
3513 kNameShouldPrintAsAnonymous)
3514BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3515BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003516
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003517ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3518ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3519
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003520ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3521
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003522bool Script::HasValidSource() {
3523 Object* src = this->source();
3524 if (!src->IsString()) return true;
3525 String* src_str = String::cast(src);
3526 if (!StringShape(src_str).IsExternal()) return true;
3527 if (src_str->IsAsciiRepresentation()) {
3528 return ExternalAsciiString::cast(src)->resource() != NULL;
3529 } else if (src_str->IsTwoByteRepresentation()) {
3530 return ExternalTwoByteString::cast(src)->resource() != NULL;
3531 }
3532 return true;
3533}
3534
3535
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003536void SharedFunctionInfo::DontAdaptArguments() {
3537 ASSERT(code()->kind() == Code::BUILTIN);
3538 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3539}
3540
3541
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003542int SharedFunctionInfo::start_position() {
3543 return start_position_and_type() >> kStartPositionShift;
3544}
3545
3546
3547void SharedFunctionInfo::set_start_position(int start_position) {
3548 set_start_position_and_type((start_position << kStartPositionShift)
3549 | (start_position_and_type() & ~kStartPositionMask));
3550}
3551
3552
3553Code* SharedFunctionInfo::code() {
3554 return Code::cast(READ_FIELD(this, kCodeOffset));
3555}
3556
3557
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003558Code* SharedFunctionInfo::unchecked_code() {
3559 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3560}
3561
3562
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003563void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003564 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003565 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003566}
3567
3568
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003569ScopeInfo* SharedFunctionInfo::scope_info() {
3570 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003571}
3572
3573
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003574void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003575 WriteBarrierMode mode) {
3576 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003577 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3578 this,
3579 kScopeInfoOffset,
3580 reinterpret_cast<Object*>(value),
3581 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003582}
3583
3584
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003585Smi* SharedFunctionInfo::deopt_counter() {
3586 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3587}
3588
3589
3590void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3591 WRITE_FIELD(this, kDeoptCounterOffset, value);
3592}
3593
3594
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003595bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003596 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003597 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003598}
3599
3600
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003601bool SharedFunctionInfo::IsApiFunction() {
3602 return function_data()->IsFunctionTemplateInfo();
3603}
3604
3605
3606FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3607 ASSERT(IsApiFunction());
3608 return FunctionTemplateInfo::cast(function_data());
3609}
3610
3611
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003612bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003613 return function_data()->IsSmi();
3614}
3615
3616
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003617BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3618 ASSERT(HasBuiltinFunctionId());
3619 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003620}
3621
3622
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003623int SharedFunctionInfo::code_age() {
3624 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3625}
3626
3627
3628void SharedFunctionInfo::set_code_age(int code_age) {
3629 set_compiler_hints(compiler_hints() |
3630 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3631}
3632
3633
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003634bool SharedFunctionInfo::has_deoptimization_support() {
3635 Code* code = this->code();
3636 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3637}
3638
3639
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003640bool JSFunction::IsBuiltin() {
3641 return context()->global()->IsJSBuiltinsObject();
3642}
3643
3644
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003645bool JSFunction::NeedsArgumentsAdaption() {
3646 return shared()->formal_parameter_count() !=
3647 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3648}
3649
3650
3651bool JSFunction::IsOptimized() {
3652 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3653}
3654
3655
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003656bool JSFunction::IsOptimizable() {
3657 return code()->kind() == Code::FUNCTION && code()->optimizable();
3658}
3659
3660
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003661bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003662 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003663}
3664
3665
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003666Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003667 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003668}
3669
3670
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003671Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003672 return reinterpret_cast<Code*>(
3673 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003674}
3675
3676
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003677void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003678 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003679 Address entry = value->entry();
3680 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003681 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3682 this,
3683 HeapObject::RawField(this, kCodeEntryOffset),
3684 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003685}
3686
3687
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003688void JSFunction::ReplaceCode(Code* code) {
3689 bool was_optimized = IsOptimized();
3690 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3691
3692 set_code(code);
3693
3694 // Add/remove the function from the list of optimized functions for this
3695 // context based on the state change.
3696 if (!was_optimized && is_optimized) {
3697 context()->global_context()->AddOptimizedFunction(this);
3698 }
3699 if (was_optimized && !is_optimized) {
3700 context()->global_context()->RemoveOptimizedFunction(this);
3701 }
3702}
3703
3704
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003705Context* JSFunction::context() {
3706 return Context::cast(READ_FIELD(this, kContextOffset));
3707}
3708
3709
3710Object* JSFunction::unchecked_context() {
3711 return READ_FIELD(this, kContextOffset);
3712}
3713
3714
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003715SharedFunctionInfo* JSFunction::unchecked_shared() {
3716 return reinterpret_cast<SharedFunctionInfo*>(
3717 READ_FIELD(this, kSharedFunctionInfoOffset));
3718}
3719
3720
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003721void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003722 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003723 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003724 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003725}
3726
3727ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3728 kPrototypeOrInitialMapOffset)
3729
3730
3731Map* JSFunction::initial_map() {
3732 return Map::cast(prototype_or_initial_map());
3733}
3734
3735
3736void JSFunction::set_initial_map(Map* value) {
3737 set_prototype_or_initial_map(value);
3738}
3739
3740
3741bool JSFunction::has_initial_map() {
3742 return prototype_or_initial_map()->IsMap();
3743}
3744
3745
3746bool JSFunction::has_instance_prototype() {
3747 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3748}
3749
3750
3751bool JSFunction::has_prototype() {
3752 return map()->has_non_instance_prototype() || has_instance_prototype();
3753}
3754
3755
3756Object* JSFunction::instance_prototype() {
3757 ASSERT(has_instance_prototype());
3758 if (has_initial_map()) return initial_map()->prototype();
3759 // When there is no initial map and the prototype is a JSObject, the
3760 // initial map field is used for the prototype field.
3761 return prototype_or_initial_map();
3762}
3763
3764
3765Object* JSFunction::prototype() {
3766 ASSERT(has_prototype());
3767 // If the function's prototype property has been set to a non-JSObject
3768 // value, that value is stored in the constructor field of the map.
3769 if (map()->has_non_instance_prototype()) return map()->constructor();
3770 return instance_prototype();
3771}
3772
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003773bool JSFunction::should_have_prototype() {
3774 return map()->function_with_prototype();
3775}
3776
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003777
3778bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003779 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003780}
3781
3782
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003783FixedArray* JSFunction::literals() {
3784 ASSERT(!shared()->bound());
3785 return literals_or_bindings();
3786}
3787
3788
3789void JSFunction::set_literals(FixedArray* literals) {
3790 ASSERT(!shared()->bound());
3791 set_literals_or_bindings(literals);
3792}
3793
3794
3795FixedArray* JSFunction::function_bindings() {
3796 ASSERT(shared()->bound());
3797 return literals_or_bindings();
3798}
3799
3800
3801void JSFunction::set_function_bindings(FixedArray* bindings) {
3802 ASSERT(shared()->bound());
3803 // Bound function literal may be initialized to the empty fixed array
3804 // before the bindings are set.
3805 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
3806 bindings->map() == GetHeap()->fixed_cow_array_map());
3807 set_literals_or_bindings(bindings);
3808}
3809
3810
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003811int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003812 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003813 return literals()->length();
3814}
3815
3816
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003817Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003818 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003819 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003820}
3821
3822
3823void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3824 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003825 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003826 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003827 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003828}
3829
3830
3831Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003832 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003833 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3834}
3835
3836
3837void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3838 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003839 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003840 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003841 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003842}
3843
3844
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003845ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003846ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003847ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3848ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3849
3850
3851void JSProxy::InitializeBody(int object_size, Object* value) {
3852 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3853 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3854 WRITE_FIELD(this, offset, value);
3855 }
3856}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003857
3858
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003859ACCESSORS(JSSet, table, Object, kTableOffset)
3860ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003861ACCESSORS(JSWeakMap, table, Object, kTableOffset)
3862ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003863
3864
3865ObjectHashTable* JSWeakMap::unchecked_table() {
3866 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3867}
3868
3869
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003870Address Foreign::foreign_address() {
3871 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003872}
3873
3874
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003875void Foreign::set_foreign_address(Address value) {
3876 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003877}
3878
3879
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003880ACCESSORS(JSValue, value, Object, kValueOffset)
3881
3882
3883JSValue* JSValue::cast(Object* obj) {
3884 ASSERT(obj->IsJSValue());
3885 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3886 return reinterpret_cast<JSValue*>(obj);
3887}
3888
3889
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003890ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3891ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3892ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3893ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3894ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3895SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3896SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3897
3898
3899JSMessageObject* JSMessageObject::cast(Object* obj) {
3900 ASSERT(obj->IsJSMessageObject());
3901 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3902 return reinterpret_cast<JSMessageObject*>(obj);
3903}
3904
3905
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003906INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003907ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00003908ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003909ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003910ACCESSORS(Code, next_code_flushing_candidate,
3911 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003912
3913
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003914byte* Code::instruction_start() {
3915 return FIELD_ADDR(this, kHeaderSize);
3916}
3917
3918
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003919byte* Code::instruction_end() {
3920 return instruction_start() + instruction_size();
3921}
3922
3923
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003924int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003925 return RoundUp(instruction_size(), kObjectAlignment);
3926}
3927
3928
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003929FixedArray* Code::unchecked_deoptimization_data() {
3930 return reinterpret_cast<FixedArray*>(
3931 READ_FIELD(this, kDeoptimizationDataOffset));
3932}
3933
3934
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003935ByteArray* Code::unchecked_relocation_info() {
3936 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003937}
3938
3939
3940byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003941 return unchecked_relocation_info()->GetDataStartAddress();
3942}
3943
3944
3945int Code::relocation_size() {
3946 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003947}
3948
3949
3950byte* Code::entry() {
3951 return instruction_start();
3952}
3953
3954
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003955bool Code::contains(byte* inner_pointer) {
3956 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003957}
3958
3959
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003960ACCESSORS(JSArray, length, Object, kLengthOffset)
3961
3962
ager@chromium.org236ad962008-09-25 09:45:57 +00003963ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003964
3965
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003966JSRegExp::Type JSRegExp::TypeTag() {
3967 Object* data = this->data();
3968 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3969 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3970 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003971}
3972
3973
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003974JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3975 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3976 return static_cast<JSRegExp::Type>(smi->value());
3977}
3978
3979
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003980int JSRegExp::CaptureCount() {
3981 switch (TypeTag()) {
3982 case ATOM:
3983 return 0;
3984 case IRREGEXP:
3985 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3986 default:
3987 UNREACHABLE();
3988 return -1;
3989 }
3990}
3991
3992
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003993JSRegExp::Flags JSRegExp::GetFlags() {
3994 ASSERT(this->data()->IsFixedArray());
3995 Object* data = this->data();
3996 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3997 return Flags(smi->value());
3998}
3999
4000
4001String* JSRegExp::Pattern() {
4002 ASSERT(this->data()->IsFixedArray());
4003 Object* data = this->data();
4004 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4005 return pattern;
4006}
4007
4008
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004009Object* JSRegExp::DataAt(int index) {
4010 ASSERT(TypeTag() != NOT_COMPILED);
4011 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004012}
4013
4014
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004015Object* JSRegExp::DataAtUnchecked(int index) {
4016 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4017 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4018 return READ_FIELD(fa, offset);
4019}
4020
4021
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004022void JSRegExp::SetDataAt(int index, Object* value) {
4023 ASSERT(TypeTag() != NOT_COMPILED);
4024 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4025 FixedArray::cast(data())->set(index, value);
4026}
4027
4028
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004029void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4030 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4031 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4032 if (value->IsSmi()) {
4033 fa->set_unchecked(index, Smi::cast(value));
4034 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004035 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004036 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4037 }
4038}
4039
4040
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004041ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004042 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004043#if DEBUG
4044 FixedArrayBase* fixed_array =
4045 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4046 Map* map = fixed_array->map();
4047 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004048 (map == GetHeap()->fixed_array_map() ||
4049 map == GetHeap()->fixed_cow_array_map())) ||
4050 (kind == FAST_DOUBLE_ELEMENTS &&
4051 fixed_array->IsFixedDoubleArray()) ||
4052 (kind == DICTIONARY_ELEMENTS &&
4053 fixed_array->IsFixedArray() &&
4054 fixed_array->IsDictionary()) ||
4055 (kind > DICTIONARY_ELEMENTS));
4056 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4057 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004058#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004059 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004060}
4061
4062
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004063ElementsAccessor* JSObject::GetElementsAccessor() {
4064 return ElementsAccessor::ForKind(GetElementsKind());
4065}
4066
4067
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004068bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004069 return GetElementsKind() == FAST_ELEMENTS;
4070}
4071
4072
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004073bool JSObject::HasFastSmiOnlyElements() {
4074 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4075}
4076
4077
4078bool JSObject::HasFastTypeElements() {
4079 ElementsKind elements_kind = GetElementsKind();
4080 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4081 elements_kind == FAST_ELEMENTS;
4082}
4083
4084
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004085bool JSObject::HasFastDoubleElements() {
4086 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4087}
4088
4089
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004090bool JSObject::HasDictionaryElements() {
4091 return GetElementsKind() == DICTIONARY_ELEMENTS;
4092}
4093
4094
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004095bool JSObject::HasNonStrictArgumentsElements() {
4096 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4097}
4098
4099
ager@chromium.org3811b432009-10-28 14:53:37 +00004100bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004101 HeapObject* array = elements();
4102 ASSERT(array != NULL);
4103 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004104}
4105
4106
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004107#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4108bool JSObject::HasExternal##name##Elements() { \
4109 HeapObject* array = elements(); \
4110 ASSERT(array != NULL); \
4111 if (!array->IsHeapObject()) \
4112 return false; \
4113 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004114}
4115
4116
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004117EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4118EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4119EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4120EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4121 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4122EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4123EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4124 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4125EXTERNAL_ELEMENTS_CHECK(Float,
4126 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004127EXTERNAL_ELEMENTS_CHECK(Double,
4128 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004129EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004130
4131
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004132bool JSObject::HasNamedInterceptor() {
4133 return map()->has_named_interceptor();
4134}
4135
4136
4137bool JSObject::HasIndexedInterceptor() {
4138 return map()->has_indexed_interceptor();
4139}
4140
4141
ager@chromium.org5c838252010-02-19 08:53:10 +00004142bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004143 bool result = elements()->IsFixedArray() ||
4144 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004145 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004146 return result;
4147}
4148
4149
lrn@chromium.org303ada72010-10-27 09:33:13 +00004150MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004151 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004152 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004153 Isolate* isolate = GetIsolate();
4154 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004155 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004156 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4157 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004158 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4159 return maybe_writable_elems;
4160 }
4161 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004162 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004163 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004164 return writable_elems;
4165}
4166
4167
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004168StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004169 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004170 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004171}
4172
4173
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004174NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004175 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004176 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004177}
4178
4179
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004180bool String::IsHashFieldComputed(uint32_t field) {
4181 return (field & kHashNotComputedMask) == 0;
4182}
4183
4184
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004185bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004186 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004187}
4188
4189
4190uint32_t String::Hash() {
4191 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004192 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004193 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004194 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004195 return ComputeAndSetHash();
4196}
4197
4198
ager@chromium.org7c537e22008-10-16 08:43:32 +00004199StringHasher::StringHasher(int length)
4200 : length_(length),
4201 raw_running_hash_(0),
4202 array_index_(0),
4203 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4204 is_first_char_(true),
4205 is_valid_(true) { }
4206
4207
4208bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004209 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004210}
4211
4212
4213void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004214 // Use the Jenkins one-at-a-time hash function to update the hash
4215 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004216 raw_running_hash_ += c;
4217 raw_running_hash_ += (raw_running_hash_ << 10);
4218 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004219 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004220 if (is_array_index_) {
4221 if (c < '0' || c > '9') {
4222 is_array_index_ = false;
4223 } else {
4224 int d = c - '0';
4225 if (is_first_char_) {
4226 is_first_char_ = false;
4227 if (c == '0' && length_ > 1) {
4228 is_array_index_ = false;
4229 return;
4230 }
4231 }
4232 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4233 is_array_index_ = false;
4234 } else {
4235 array_index_ = array_index_ * 10 + d;
4236 }
4237 }
4238 }
4239}
4240
4241
4242void StringHasher::AddCharacterNoIndex(uc32 c) {
4243 ASSERT(!is_array_index());
4244 raw_running_hash_ += c;
4245 raw_running_hash_ += (raw_running_hash_ << 10);
4246 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4247}
4248
4249
4250uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004251 // Get the calculated raw hash value and do some more bit ops to distribute
4252 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004253 uint32_t result = raw_running_hash_;
4254 result += (result << 3);
4255 result ^= (result >> 11);
4256 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004257 if (result == 0) {
4258 result = 27;
4259 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004260 return result;
4261}
4262
4263
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004264template <typename schar>
4265uint32_t HashSequentialString(const schar* chars, int length) {
4266 StringHasher hasher(length);
4267 if (!hasher.has_trivial_hash()) {
4268 int i;
4269 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4270 hasher.AddCharacter(chars[i]);
4271 }
4272 for (; i < length; i++) {
4273 hasher.AddCharacterNoIndex(chars[i]);
4274 }
4275 }
4276 return hasher.GetHashField();
4277}
4278
4279
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004280bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004281 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004282 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4283 return false;
4284 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004285 return SlowAsArrayIndex(index);
4286}
4287
4288
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004289Object* JSReceiver::GetPrototype() {
4290 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004291}
4292
4293
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004294bool JSReceiver::HasProperty(String* name) {
4295 if (IsJSProxy()) {
4296 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4297 }
4298 return GetPropertyAttribute(name) != ABSENT;
4299}
4300
4301
4302bool JSReceiver::HasLocalProperty(String* name) {
4303 if (IsJSProxy()) {
4304 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4305 }
4306 return GetLocalPropertyAttribute(name) != ABSENT;
4307}
4308
4309
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004310PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004311 return GetPropertyAttributeWithReceiver(this, key);
4312}
4313
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004314// TODO(504): this may be useful in other places too where JSGlobalProxy
4315// is used.
4316Object* JSObject::BypassGlobalProxy() {
4317 if (IsJSGlobalProxy()) {
4318 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004319 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004320 ASSERT(proto->IsJSGlobalObject());
4321 return proto;
4322 }
4323 return this;
4324}
4325
4326
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004327MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4328 return IsJSProxy()
4329 ? JSProxy::cast(this)->GetIdentityHash(flag)
4330 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004331}
4332
4333
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004334bool JSReceiver::HasElement(uint32_t index) {
4335 if (IsJSProxy()) {
4336 return JSProxy::cast(this)->HasElementWithHandler(index);
4337 }
4338 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004339}
4340
4341
4342bool AccessorInfo::all_can_read() {
4343 return BooleanBit::get(flag(), kAllCanReadBit);
4344}
4345
4346
4347void AccessorInfo::set_all_can_read(bool value) {
4348 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4349}
4350
4351
4352bool AccessorInfo::all_can_write() {
4353 return BooleanBit::get(flag(), kAllCanWriteBit);
4354}
4355
4356
4357void AccessorInfo::set_all_can_write(bool value) {
4358 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4359}
4360
4361
ager@chromium.org870a0b62008-11-04 11:43:05 +00004362bool AccessorInfo::prohibits_overwriting() {
4363 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4364}
4365
4366
4367void AccessorInfo::set_prohibits_overwriting(bool value) {
4368 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4369}
4370
4371
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004372PropertyAttributes AccessorInfo::property_attributes() {
4373 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4374}
4375
4376
4377void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004378 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004379}
4380
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004381
4382template<typename Shape, typename Key>
4383void Dictionary<Shape, Key>::SetEntry(int entry,
4384 Object* key,
4385 Object* value) {
4386 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4387}
4388
4389
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004390template<typename Shape, typename Key>
4391void Dictionary<Shape, Key>::SetEntry(int entry,
4392 Object* key,
4393 Object* value,
4394 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004395 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004396 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004397 AssertNoAllocation no_gc;
4398 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004399 FixedArray::set(index, key, mode);
4400 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004401 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004402}
4403
4404
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004405bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4406 ASSERT(other->IsNumber());
4407 return key == static_cast<uint32_t>(other->Number());
4408}
4409
4410
4411uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4412 return ComputeIntegerHash(key);
4413}
4414
4415
4416uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4417 ASSERT(other->IsNumber());
4418 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4419}
4420
4421
4422MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4423 return Isolate::Current()->heap()->NumberFromUint32(key);
4424}
4425
4426
4427bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4428 // We know that all entries in a hash table had their hash keys created.
4429 // Use that knowledge to have fast failure.
4430 if (key->Hash() != String::cast(other)->Hash()) return false;
4431 return key->Equals(String::cast(other));
4432}
4433
4434
4435uint32_t StringDictionaryShape::Hash(String* key) {
4436 return key->Hash();
4437}
4438
4439
4440uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4441 return String::cast(other)->Hash();
4442}
4443
4444
4445MaybeObject* StringDictionaryShape::AsObject(String* key) {
4446 return key;
4447}
4448
4449
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004450template <int entrysize>
4451bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4452 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004453}
4454
4455
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004456template <int entrysize>
4457uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004458 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4459 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004460}
4461
4462
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004463template <int entrysize>
4464uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4465 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004466 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4467 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004468}
4469
4470
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004471template <int entrysize>
4472MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004473 return key;
4474}
4475
4476
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004477void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004478 // No write barrier is needed since empty_fixed_array is not in new space.
4479 // Please note this function is used during marking:
4480 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004481 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4482 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004483}
4484
4485
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004486void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004487 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004488 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004489 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4490 if (elts->length() < required_size) {
4491 // Doubling in size would be overkill, but leave some slack to avoid
4492 // constantly growing.
4493 Expand(required_size + (required_size >> 3));
4494 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004495 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004496 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4497 // Expand will allocate a new backing store in new space even if the size
4498 // we asked for isn't larger than what we had before.
4499 Expand(required_size);
4500 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004501}
4502
4503
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004504void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004505 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004506 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4507}
4508
4509
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004510MaybeObject* JSArray::SetContent(FixedArray* storage) {
4511 MaybeObject* maybe_object = EnsureCanContainElements(storage);
4512 if (maybe_object->IsFailure()) return maybe_object;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004513 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004514 set_elements(storage);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004515 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004516}
4517
4518
lrn@chromium.org303ada72010-10-27 09:33:13 +00004519MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004520 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004521 return GetHeap()->CopyFixedArray(this);
4522}
4523
4524
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004525MaybeObject* FixedDoubleArray::Copy() {
4526 if (length() == 0) return this;
4527 return GetHeap()->CopyFixedDoubleArray(this);
4528}
4529
4530
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004531Relocatable::Relocatable(Isolate* isolate) {
4532 ASSERT(isolate == Isolate::Current());
4533 isolate_ = isolate;
4534 prev_ = isolate->relocatable_top();
4535 isolate->set_relocatable_top(this);
4536}
4537
4538
4539Relocatable::~Relocatable() {
4540 ASSERT(isolate_ == Isolate::Current());
4541 ASSERT_EQ(isolate_->relocatable_top(), this);
4542 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004543}
4544
4545
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004546int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4547 return map->instance_size();
4548}
4549
4550
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004551void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004552 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004553 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004554}
4555
4556
4557template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004558void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004559 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004560 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004561}
4562
4563
4564void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4565 typedef v8::String::ExternalAsciiStringResource Resource;
4566 v->VisitExternalAsciiString(
4567 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4568}
4569
4570
4571template<typename StaticVisitor>
4572void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4573 typedef v8::String::ExternalAsciiStringResource Resource;
4574 StaticVisitor::VisitExternalAsciiString(
4575 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4576}
4577
4578
4579void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4580 typedef v8::String::ExternalStringResource Resource;
4581 v->VisitExternalTwoByteString(
4582 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4583}
4584
4585
4586template<typename StaticVisitor>
4587void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4588 typedef v8::String::ExternalStringResource Resource;
4589 StaticVisitor::VisitExternalTwoByteString(
4590 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4591}
4592
4593#define SLOT_ADDR(obj, offset) \
4594 reinterpret_cast<Object**>((obj)->address() + offset)
4595
4596template<int start_offset, int end_offset, int size>
4597void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4598 HeapObject* obj,
4599 ObjectVisitor* v) {
4600 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4601}
4602
4603
4604template<int start_offset>
4605void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4606 int object_size,
4607 ObjectVisitor* v) {
4608 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4609}
4610
4611#undef SLOT_ADDR
4612
4613
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004614#undef CAST_ACCESSOR
4615#undef INT_ACCESSORS
4616#undef SMI_ACCESSORS
4617#undef ACCESSORS
4618#undef FIELD_ADDR
4619#undef READ_FIELD
4620#undef WRITE_FIELD
4621#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004622#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004623#undef READ_MEMADDR_FIELD
4624#undef WRITE_MEMADDR_FIELD
4625#undef READ_DOUBLE_FIELD
4626#undef WRITE_DOUBLE_FIELD
4627#undef READ_INT_FIELD
4628#undef WRITE_INT_FIELD
4629#undef READ_SHORT_FIELD
4630#undef WRITE_SHORT_FIELD
4631#undef READ_BYTE_FIELD
4632#undef WRITE_BYTE_FIELD
4633
4634
4635} } // namespace v8::internal
4636
4637#endif // V8_OBJECTS_INL_H_