blob: d6d65718e2c6e4351944c4f2576623b4200b614a [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.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001118void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001119 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
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001186Object** FixedArray::GetFirstElementAddress() {
1187 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1188}
1189
1190
1191bool FixedArray::ContainsOnlySmisOrHoles() {
1192 Object* the_hole = GetHeap()->the_hole_value();
1193 Object** current = GetFirstElementAddress();
1194 for (int i = 0; i < length(); ++i) {
1195 Object* candidate = *current++;
1196 if (!candidate->IsSmi() && candidate != the_hole) return false;
1197 }
1198 return true;
1199}
1200
1201
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001202FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001203 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001204 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001205}
1206
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001207void JSObject::ValidateSmiOnlyElements() {
1208#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001209 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001210 Heap* heap = GetHeap();
1211 // Don't use elements, since integrity checks will fail if there
1212 // are filler pointers in the array.
1213 FixedArray* fixed_array =
1214 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1215 Map* map = fixed_array->map();
1216 // Arrays that have been shifted in place can't be verified.
1217 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1218 map != heap->raw_unchecked_two_pointer_filler_map() &&
1219 map != heap->free_space_map()) {
1220 for (int i = 0; i < fixed_array->length(); i++) {
1221 Object* current = fixed_array->get(i);
1222 ASSERT(current->IsSmi() || current == heap->the_hole_value());
1223 }
1224 }
1225 }
1226#endif
1227}
1228
1229
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001230MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001231#if DEBUG
1232 ValidateSmiOnlyElements();
1233#endif
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001234 if ((map()->elements_kind() != FAST_ELEMENTS)) {
1235 return TransitionElementsKind(FAST_ELEMENTS);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001236 }
1237 return this;
1238}
1239
1240
1241MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001242 uint32_t count,
1243 EnsureElementsMode mode) {
1244 ElementsKind current_kind = map()->elements_kind();
1245 ElementsKind target_kind = current_kind;
1246 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1247 if (current_kind == FAST_ELEMENTS) return this;
1248
1249 Heap* heap = GetHeap();
1250 Object* the_hole = heap->the_hole_value();
1251 Object* heap_number_map = heap->heap_number_map();
1252 for (uint32_t i = 0; i < count; ++i) {
1253 Object* current = *objects++;
1254 if (!current->IsSmi() && current != the_hole) {
1255 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
1256 HeapObject::cast(current)->map() == heap_number_map) {
1257 target_kind = FAST_DOUBLE_ELEMENTS;
1258 } else {
1259 target_kind = FAST_ELEMENTS;
1260 break;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001261 }
1262 }
1263 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001264
1265 if (target_kind != current_kind) {
1266 return TransitionElementsKind(target_kind);
1267 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001268 return this;
1269}
1270
1271
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001272MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
1273 EnsureElementsMode mode) {
1274 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1275 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1276 elements->map() == GetHeap()->fixed_cow_array_map());
1277 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1278 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1279 }
1280 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
1281 return EnsureCanContainElements(objects, elements->length(), mode);
1282 }
1283
1284 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1285 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1286 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1287 }
1288
1289 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001290}
1291
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001292
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001293void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001294 ASSERT((map()->has_fast_elements() ||
1295 map()->has_fast_smi_only_elements()) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001296 (value->map() == GetHeap()->fixed_array_map() ||
1297 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001298 ASSERT(map()->has_fast_double_elements() ==
1299 value->IsFixedDoubleArray());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001300 ASSERT(value->HasValidElements());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001301#ifdef DEBUG
1302 ValidateSmiOnlyElements();
1303#endif
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001304 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001305 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001306}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001307
1308
1309void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001310 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1311 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001312}
1313
1314
1315void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001316 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001317 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1318 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001319}
1320
1321
lrn@chromium.org303ada72010-10-27 09:33:13 +00001322MaybeObject* JSObject::ResetElements() {
1323 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001324 ElementsKind elements_kind = FLAG_smi_only_arrays
1325 ? FAST_SMI_ONLY_ELEMENTS
1326 : FAST_ELEMENTS;
1327 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind);
1328 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001329 set_map(Map::cast(obj));
1330 initialize_elements();
1331 return this;
1332}
1333
1334
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001335ACCESSORS(Oddball, to_string, String, kToStringOffset)
1336ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1337
1338
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001339byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001340 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001341}
1342
1343
1344void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001345 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001346}
1347
1348
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001349Object* JSGlobalPropertyCell::value() {
1350 return READ_FIELD(this, kValueOffset);
1351}
1352
1353
1354void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1355 // The write barrier is not used for global property cells.
1356 ASSERT(!val->IsJSGlobalPropertyCell());
1357 WRITE_FIELD(this, kValueOffset, val);
1358}
1359
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001360
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001361int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001362 InstanceType type = map()->instance_type();
1363 // Check for the most common kind of JavaScript object before
1364 // falling into the generic switch. This speeds up the internal
1365 // field operations considerably on average.
1366 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1367 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001368 case JS_GLOBAL_PROXY_TYPE:
1369 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001370 case JS_GLOBAL_OBJECT_TYPE:
1371 return JSGlobalObject::kSize;
1372 case JS_BUILTINS_OBJECT_TYPE:
1373 return JSBuiltinsObject::kSize;
1374 case JS_FUNCTION_TYPE:
1375 return JSFunction::kSize;
1376 case JS_VALUE_TYPE:
1377 return JSValue::kSize;
1378 case JS_ARRAY_TYPE:
1379 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001380 case JS_WEAK_MAP_TYPE:
1381 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001382 case JS_REGEXP_TYPE:
1383 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001384 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001385 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001386 case JS_MESSAGE_OBJECT_TYPE:
1387 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001388 default:
1389 UNREACHABLE();
1390 return 0;
1391 }
1392}
1393
1394
1395int JSObject::GetInternalFieldCount() {
1396 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001397 // Make sure to adjust for the number of in-object properties. These
1398 // properties do contribute to the size, but are not internal fields.
1399 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1400 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001401}
1402
1403
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001404int JSObject::GetInternalFieldOffset(int index) {
1405 ASSERT(index < GetInternalFieldCount() && index >= 0);
1406 return GetHeaderSize() + (kPointerSize * index);
1407}
1408
1409
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001410Object* JSObject::GetInternalField(int index) {
1411 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001412 // Internal objects do follow immediately after the header, whereas in-object
1413 // properties are at the end of the object. Therefore there is no need
1414 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001415 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1416}
1417
1418
1419void JSObject::SetInternalField(int index, Object* value) {
1420 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001421 // Internal objects do follow immediately after the header, whereas in-object
1422 // properties are at the end of the object. Therefore there is no need
1423 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001424 int offset = GetHeaderSize() + (kPointerSize * index);
1425 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001426 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001427}
1428
1429
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001430void JSObject::SetInternalField(int index, Smi* value) {
1431 ASSERT(index < GetInternalFieldCount() && index >= 0);
1432 // Internal objects do follow immediately after the header, whereas in-object
1433 // properties are at the end of the object. Therefore there is no need
1434 // to adjust the index here.
1435 int offset = GetHeaderSize() + (kPointerSize * index);
1436 WRITE_FIELD(this, offset, value);
1437}
1438
1439
ager@chromium.org7c537e22008-10-16 08:43:32 +00001440// Access fast-case object properties at index. The use of these routines
1441// is needed to correctly distinguish between properties stored in-object and
1442// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001443Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001444 // Adjust for the number of properties stored in the object.
1445 index -= map()->inobject_properties();
1446 if (index < 0) {
1447 int offset = map()->instance_size() + (index * kPointerSize);
1448 return READ_FIELD(this, offset);
1449 } else {
1450 ASSERT(index < properties()->length());
1451 return properties()->get(index);
1452 }
1453}
1454
1455
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001456Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001457 // Adjust for the number of properties stored in the object.
1458 index -= map()->inobject_properties();
1459 if (index < 0) {
1460 int offset = map()->instance_size() + (index * kPointerSize);
1461 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001462 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001463 } else {
1464 ASSERT(index < properties()->length());
1465 properties()->set(index, value);
1466 }
1467 return value;
1468}
1469
1470
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001471int JSObject::GetInObjectPropertyOffset(int index) {
1472 // Adjust for the number of properties stored in the object.
1473 index -= map()->inobject_properties();
1474 ASSERT(index < 0);
1475 return map()->instance_size() + (index * kPointerSize);
1476}
1477
1478
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001479Object* JSObject::InObjectPropertyAt(int index) {
1480 // Adjust for the number of properties stored in the object.
1481 index -= map()->inobject_properties();
1482 ASSERT(index < 0);
1483 int offset = map()->instance_size() + (index * kPointerSize);
1484 return READ_FIELD(this, offset);
1485}
1486
1487
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001488Object* JSObject::InObjectPropertyAtPut(int index,
1489 Object* value,
1490 WriteBarrierMode mode) {
1491 // Adjust for the number of properties stored in the object.
1492 index -= map()->inobject_properties();
1493 ASSERT(index < 0);
1494 int offset = map()->instance_size() + (index * kPointerSize);
1495 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001496 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001497 return value;
1498}
1499
1500
1501
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001502void JSObject::InitializeBody(Map* map,
1503 Object* pre_allocated_value,
1504 Object* filler_value) {
1505 ASSERT(!filler_value->IsHeapObject() ||
1506 !GetHeap()->InNewSpace(filler_value));
1507 ASSERT(!pre_allocated_value->IsHeapObject() ||
1508 !GetHeap()->InNewSpace(pre_allocated_value));
1509 int size = map->instance_size();
1510 int offset = kHeaderSize;
1511 if (filler_value != pre_allocated_value) {
1512 int pre_allocated = map->pre_allocated_property_fields();
1513 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1514 for (int i = 0; i < pre_allocated; i++) {
1515 WRITE_FIELD(this, offset, pre_allocated_value);
1516 offset += kPointerSize;
1517 }
1518 }
1519 while (offset < size) {
1520 WRITE_FIELD(this, offset, filler_value);
1521 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001522 }
1523}
1524
1525
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001526bool JSObject::HasFastProperties() {
1527 return !properties()->IsDictionary();
1528}
1529
1530
1531int JSObject::MaxFastProperties() {
1532 // Allow extra fast properties if the object has more than
1533 // kMaxFastProperties in-object properties. When this is the case,
1534 // it is very unlikely that the object is being used as a dictionary
1535 // and there is a good chance that allowing more map transitions
1536 // will be worth it.
1537 return Max(map()->inobject_properties(), kMaxFastProperties);
1538}
1539
1540
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001541void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001542 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001543 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001544 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001545 }
1546}
1547
1548
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001549bool Object::ToArrayIndex(uint32_t* index) {
1550 if (IsSmi()) {
1551 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001552 if (value < 0) return false;
1553 *index = value;
1554 return true;
1555 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001556 if (IsHeapNumber()) {
1557 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001558 uint32_t uint_value = static_cast<uint32_t>(value);
1559 if (value == static_cast<double>(uint_value)) {
1560 *index = uint_value;
1561 return true;
1562 }
1563 }
1564 return false;
1565}
1566
1567
1568bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1569 if (!this->IsJSValue()) return false;
1570
1571 JSValue* js_value = JSValue::cast(this);
1572 if (!js_value->value()->IsString()) return false;
1573
1574 String* str = String::cast(js_value->value());
1575 if (index >= (uint32_t)str->length()) return false;
1576
1577 return true;
1578}
1579
1580
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001581FixedArrayBase* FixedArrayBase::cast(Object* object) {
1582 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1583 return reinterpret_cast<FixedArrayBase*>(object);
1584}
1585
1586
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001587Object* FixedArray::get(int index) {
1588 ASSERT(index >= 0 && index < this->length());
1589 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1590}
1591
1592
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001593void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001594 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001595 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001596 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1597 int offset = kHeaderSize + index * kPointerSize;
1598 WRITE_FIELD(this, offset, value);
1599}
1600
1601
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001602void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001603 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001604 ASSERT(index >= 0 && index < this->length());
1605 int offset = kHeaderSize + index * kPointerSize;
1606 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001607 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001608}
1609
1610
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001611inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1612 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1613}
1614
1615
1616inline double FixedDoubleArray::hole_nan_as_double() {
1617 return BitCast<double, uint64_t>(kHoleNanInt64);
1618}
1619
1620
1621inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1622 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1623 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1624 return OS::nan_value();
1625}
1626
1627
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001628double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001629 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1630 map() != HEAP->fixed_array_map());
1631 ASSERT(index >= 0 && index < this->length());
1632 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1633 ASSERT(!is_the_hole_nan(result));
1634 return result;
1635}
1636
1637
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001638MaybeObject* FixedDoubleArray::get(int index) {
1639 if (is_the_hole(index)) {
1640 return GetHeap()->the_hole_value();
1641 } else {
1642 return GetHeap()->NumberFromDouble(get_scalar(index));
1643 }
1644}
1645
1646
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001647void FixedDoubleArray::set(int index, double value) {
1648 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1649 map() != HEAP->fixed_array_map());
1650 int offset = kHeaderSize + index * kDoubleSize;
1651 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1652 WRITE_DOUBLE_FIELD(this, offset, value);
1653}
1654
1655
1656void FixedDoubleArray::set_the_hole(int index) {
1657 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1658 map() != HEAP->fixed_array_map());
1659 int offset = kHeaderSize + index * kDoubleSize;
1660 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1661}
1662
1663
1664bool FixedDoubleArray::is_the_hole(int index) {
1665 int offset = kHeaderSize + index * kDoubleSize;
1666 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1667}
1668
1669
1670void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1671 int old_length = from->length();
1672 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001673 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1674 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1675 FIELD_ADDR(from, kHeaderSize),
1676 old_length * kDoubleSize);
1677 } else {
1678 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001679 if (from->is_the_hole(i)) {
1680 set_the_hole(i);
1681 } else {
1682 set(i, from->get_scalar(i));
1683 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001684 }
1685 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001686 int offset = kHeaderSize + old_length * kDoubleSize;
1687 for (int current = from->length(); current < length(); ++current) {
1688 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1689 offset += kDoubleSize;
1690 }
1691}
1692
1693
1694void FixedDoubleArray::Initialize(FixedArray* from) {
1695 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001696 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001697 for (int i = 0; i < old_length; i++) {
1698 Object* hole_or_object = from->get(i);
1699 if (hole_or_object->IsTheHole()) {
1700 set_the_hole(i);
1701 } else {
1702 set(i, hole_or_object->Number());
1703 }
1704 }
1705 int offset = kHeaderSize + old_length * kDoubleSize;
1706 for (int current = from->length(); current < length(); ++current) {
1707 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1708 offset += kDoubleSize;
1709 }
1710}
1711
1712
1713void FixedDoubleArray::Initialize(NumberDictionary* from) {
1714 int offset = kHeaderSize;
1715 for (int current = 0; current < length(); ++current) {
1716 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1717 offset += kDoubleSize;
1718 }
1719 for (int i = 0; i < from->Capacity(); i++) {
1720 Object* key = from->KeyAt(i);
1721 if (key->IsNumber()) {
1722 uint32_t entry = static_cast<uint32_t>(key->Number());
1723 set(entry, from->ValueAt(i)->Number());
1724 }
1725 }
1726}
1727
1728
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001729WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001730 Heap* heap = GetHeap();
1731 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1732 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001733 return UPDATE_WRITE_BARRIER;
1734}
1735
1736
1737void FixedArray::set(int index,
1738 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001739 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001740 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001741 ASSERT(index >= 0 && index < this->length());
1742 int offset = kHeaderSize + index * kPointerSize;
1743 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001744 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001745}
1746
1747
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001748void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1749 int index,
1750 Object* value) {
1751 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1752 ASSERT(index >= 0 && index < array->length());
1753 int offset = kHeaderSize + index * kPointerSize;
1754 WRITE_FIELD(array, offset, value);
1755 Heap* heap = array->GetHeap();
1756 if (heap->InNewSpace(value)) {
1757 heap->RecordWrite(array->address(), offset);
1758 }
1759}
1760
1761
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001762void FixedArray::NoWriteBarrierSet(FixedArray* array,
1763 int index,
1764 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001765 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001766 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001767 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001768 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1769}
1770
1771
1772void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001773 ASSERT(map() != HEAP->fixed_cow_array_map());
1774 set_undefined(GetHeap(), index);
1775}
1776
1777
1778void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001779 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001780 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001781 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001782 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001783}
1784
1785
ager@chromium.org236ad962008-09-25 09:45:57 +00001786void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001787 set_null(GetHeap(), index);
1788}
1789
1790
1791void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001792 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001793 ASSERT(!heap->InNewSpace(heap->null_value()));
1794 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001795}
1796
1797
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001799 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001800 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001801 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1802 WRITE_FIELD(this,
1803 kHeaderSize + index * kPointerSize,
1804 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805}
1806
1807
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001808void FixedArray::set_unchecked(int index, Smi* value) {
1809 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1810 int offset = kHeaderSize + index * kPointerSize;
1811 WRITE_FIELD(this, offset, value);
1812}
1813
1814
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001815void FixedArray::set_unchecked(Heap* heap,
1816 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001817 Object* value,
1818 WriteBarrierMode mode) {
1819 int offset = kHeaderSize + index * kPointerSize;
1820 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001821 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001822}
1823
1824
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001825void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001826 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001827 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1828 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001829}
1830
1831
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001832Object** FixedArray::data_start() {
1833 return HeapObject::RawField(this, kHeaderSize);
1834}
1835
1836
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001837bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001838 ASSERT(this->IsSmi() ||
1839 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001840 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001841 return this->IsSmi() || length() <= kFirstIndex;
1842}
1843
1844
1845int DescriptorArray::bit_field3_storage() {
1846 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1847 return Smi::cast(storage)->value();
1848}
1849
1850void DescriptorArray::set_bit_field3_storage(int value) {
1851 ASSERT(!IsEmpty());
1852 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001853}
1854
1855
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001856void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1857 int first,
1858 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001859 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001860 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1861 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001862}
1863
1864
1865int DescriptorArray::Search(String* name) {
1866 SLOW_ASSERT(IsSortedNoDuplicates());
1867
1868 // Check for empty descriptor array.
1869 int nof = number_of_descriptors();
1870 if (nof == 0) return kNotFound;
1871
1872 // Fast case: do linear search for small arrays.
1873 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001874 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001875 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001876 }
1877
1878 // Slow case: perform binary search.
1879 return BinarySearch(name, 0, nof - 1);
1880}
1881
1882
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001883int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001884 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001885 if (number == DescriptorLookupCache::kAbsent) {
1886 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001887 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001888 }
1889 return number;
1890}
1891
1892
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001893String* DescriptorArray::GetKey(int descriptor_number) {
1894 ASSERT(descriptor_number < number_of_descriptors());
1895 return String::cast(get(ToKeyIndex(descriptor_number)));
1896}
1897
1898
1899Object* DescriptorArray::GetValue(int descriptor_number) {
1900 ASSERT(descriptor_number < number_of_descriptors());
1901 return GetContentArray()->get(ToValueIndex(descriptor_number));
1902}
1903
1904
1905Smi* DescriptorArray::GetDetails(int descriptor_number) {
1906 ASSERT(descriptor_number < number_of_descriptors());
1907 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1908}
1909
1910
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001911PropertyType DescriptorArray::GetType(int descriptor_number) {
1912 ASSERT(descriptor_number < number_of_descriptors());
1913 return PropertyDetails(GetDetails(descriptor_number)).type();
1914}
1915
1916
1917int DescriptorArray::GetFieldIndex(int descriptor_number) {
1918 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1919}
1920
1921
1922JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1923 return JSFunction::cast(GetValue(descriptor_number));
1924}
1925
1926
1927Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1928 ASSERT(GetType(descriptor_number) == CALLBACKS);
1929 return GetValue(descriptor_number);
1930}
1931
1932
1933AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1934 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001935 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001936 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001937}
1938
1939
1940bool DescriptorArray::IsProperty(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001941 return IsRealProperty(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001942}
1943
1944
1945bool DescriptorArray::IsTransition(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001946 return IsTransitionType(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001947}
1948
1949
1950bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1951 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1952}
1953
1954
1955bool DescriptorArray::IsDontEnum(int descriptor_number) {
1956 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1957}
1958
1959
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001960void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1961 desc->Init(GetKey(descriptor_number),
1962 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001963 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001964}
1965
1966
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001967void DescriptorArray::Set(int descriptor_number,
1968 Descriptor* desc,
1969 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001970 // Range check.
1971 ASSERT(descriptor_number < number_of_descriptors());
1972
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001973 NoIncrementalWriteBarrierSet(this,
1974 ToKeyIndex(descriptor_number),
1975 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001976 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001977 NoIncrementalWriteBarrierSet(content_array,
1978 ToValueIndex(descriptor_number),
1979 desc->GetValue());
1980 NoIncrementalWriteBarrierSet(content_array,
1981 ToDetailsIndex(descriptor_number),
1982 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001983}
1984
1985
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001986void DescriptorArray::CopyFrom(int index,
1987 DescriptorArray* src,
1988 int src_index,
1989 const WhitenessWitness& witness) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001990 Descriptor desc;
1991 src->Get(src_index, &desc);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001992 Set(index, &desc, witness);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001993}
1994
1995
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001996void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
1997 int first, int second) {
1998 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001999 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002000 NoIncrementalWriteBarrierSwap(content_array,
2001 ToValueIndex(first),
2002 ToValueIndex(second));
2003 NoIncrementalWriteBarrierSwap(content_array,
2004 ToDetailsIndex(first),
2005 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002006}
2007
2008
2009DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2010 : marking_(array->GetHeap()->incremental_marking()) {
2011 marking_->EnterNoMarkingScope();
2012 if (array->number_of_descriptors() > 0) {
2013 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2014 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2015 }
2016}
2017
2018
2019DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2020 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002021}
2022
2023
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002024template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002025int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2026 const int kMinCapacity = 32;
2027 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2028 if (capacity < kMinCapacity) {
2029 capacity = kMinCapacity; // Guarantee min capacity.
2030 }
2031 return capacity;
2032}
2033
2034
2035template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002036int HashTable<Shape, Key>::FindEntry(Key key) {
2037 return FindEntry(GetIsolate(), key);
2038}
2039
2040
2041// Find entry for key otherwise return kNotFound.
2042template<typename Shape, typename Key>
2043int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2044 uint32_t capacity = Capacity();
2045 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
2046 uint32_t count = 1;
2047 // EnsureCapacity will guarantee the hash table is never full.
2048 while (true) {
2049 Object* element = KeyAt(entry);
2050 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002051 if (element != isolate->heap()->the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002052 Shape::IsMatch(key, element)) return entry;
2053 entry = NextProbe(entry, count++, capacity);
2054 }
2055 return kNotFound;
2056}
2057
2058
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002059bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002060 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002061 if (!max_index_object->IsSmi()) return false;
2062 return 0 !=
2063 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2064}
2065
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002066uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002067 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002068 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002069 if (!max_index_object->IsSmi()) return 0;
2070 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2071 return value >> kRequiresSlowElementsTagSize;
2072}
2073
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002074void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002075 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002076}
2077
2078
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002079// ------------------------------------
2080// Cast operations
2081
2082
2083CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002084CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002085CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002086CAST_ACCESSOR(DeoptimizationInputData)
2087CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002088CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002089CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002090CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002091CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002092CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002093CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002094CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002095CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002096CAST_ACCESSOR(String)
2097CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002098CAST_ACCESSOR(SeqAsciiString)
2099CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002100CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002101CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002102CAST_ACCESSOR(ExternalString)
2103CAST_ACCESSOR(ExternalAsciiString)
2104CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002105CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002106CAST_ACCESSOR(JSObject)
2107CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002108CAST_ACCESSOR(HeapObject)
2109CAST_ACCESSOR(HeapNumber)
2110CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002111CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002112CAST_ACCESSOR(SharedFunctionInfo)
2113CAST_ACCESSOR(Map)
2114CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002115CAST_ACCESSOR(GlobalObject)
2116CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117CAST_ACCESSOR(JSGlobalObject)
2118CAST_ACCESSOR(JSBuiltinsObject)
2119CAST_ACCESSOR(Code)
2120CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002121CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002122CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002123CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002124CAST_ACCESSOR(JSSet)
2125CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002126CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002127CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002128CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002129CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002130CAST_ACCESSOR(ExternalArray)
2131CAST_ACCESSOR(ExternalByteArray)
2132CAST_ACCESSOR(ExternalUnsignedByteArray)
2133CAST_ACCESSOR(ExternalShortArray)
2134CAST_ACCESSOR(ExternalUnsignedShortArray)
2135CAST_ACCESSOR(ExternalIntArray)
2136CAST_ACCESSOR(ExternalUnsignedIntArray)
2137CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002138CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002139CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002140CAST_ACCESSOR(Struct)
2141
2142
2143#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2144 STRUCT_LIST(MAKE_STRUCT_CAST)
2145#undef MAKE_STRUCT_CAST
2146
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002147
2148template <typename Shape, typename Key>
2149HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002150 ASSERT(obj->IsHashTable());
2151 return reinterpret_cast<HashTable*>(obj);
2152}
2153
2154
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002155SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002156SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002157
ager@chromium.orgac091b72010-05-05 07:34:42 +00002158SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002159
2160
2161uint32_t String::hash_field() {
2162 return READ_UINT32_FIELD(this, kHashFieldOffset);
2163}
2164
2165
2166void String::set_hash_field(uint32_t value) {
2167 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002168#if V8_HOST_ARCH_64_BIT
2169 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2170#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002171}
2172
2173
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002174bool String::Equals(String* other) {
2175 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002176 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2177 return false;
2178 }
2179 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002180}
2181
2182
lrn@chromium.org303ada72010-10-27 09:33:13 +00002183MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002184 if (!StringShape(this).IsCons()) return this;
2185 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002186 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002187 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002188}
2189
2190
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002191String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002192 MaybeObject* flat = TryFlatten(pretenure);
2193 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002194 if (!flat->ToObject(&successfully_flattened)) return this;
2195 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002196}
2197
2198
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002199uint16_t String::Get(int index) {
2200 ASSERT(index >= 0 && index < length());
2201 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002202 case kSeqStringTag | kAsciiStringTag:
2203 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2204 case kSeqStringTag | kTwoByteStringTag:
2205 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2206 case kConsStringTag | kAsciiStringTag:
2207 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002208 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002209 case kExternalStringTag | kAsciiStringTag:
2210 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2211 case kExternalStringTag | kTwoByteStringTag:
2212 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002213 case kSlicedStringTag | kAsciiStringTag:
2214 case kSlicedStringTag | kTwoByteStringTag:
2215 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216 default:
2217 break;
2218 }
2219
2220 UNREACHABLE();
2221 return 0;
2222}
2223
2224
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002225void String::Set(int index, uint16_t value) {
2226 ASSERT(index >= 0 && index < length());
2227 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002228
ager@chromium.org5ec48922009-05-05 07:25:34 +00002229 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002230 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2231 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002232}
2233
2234
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002235bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002236 if (!StringShape(this).IsCons()) return true;
2237 return ConsString::cast(this)->second()->length() == 0;
2238}
2239
2240
2241String* String::GetUnderlying() {
2242 // Giving direct access to underlying string only makes sense if the
2243 // wrapping string is already flattened.
2244 ASSERT(this->IsFlat());
2245 ASSERT(StringShape(this).IsIndirect());
2246 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2247 const int kUnderlyingOffset = SlicedString::kParentOffset;
2248 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002249}
2250
2251
ager@chromium.org7c537e22008-10-16 08:43:32 +00002252uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002253 ASSERT(index >= 0 && index < length());
2254 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2255}
2256
2257
ager@chromium.org7c537e22008-10-16 08:43:32 +00002258void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002259 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2260 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2261 static_cast<byte>(value));
2262}
2263
2264
ager@chromium.org7c537e22008-10-16 08:43:32 +00002265Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002266 return FIELD_ADDR(this, kHeaderSize);
2267}
2268
2269
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002270char* SeqAsciiString::GetChars() {
2271 return reinterpret_cast<char*>(GetCharsAddress());
2272}
2273
2274
ager@chromium.org7c537e22008-10-16 08:43:32 +00002275Address SeqTwoByteString::GetCharsAddress() {
2276 return FIELD_ADDR(this, kHeaderSize);
2277}
2278
2279
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002280uc16* SeqTwoByteString::GetChars() {
2281 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2282}
2283
2284
ager@chromium.org7c537e22008-10-16 08:43:32 +00002285uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002286 ASSERT(index >= 0 && index < length());
2287 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2288}
2289
2290
ager@chromium.org7c537e22008-10-16 08:43:32 +00002291void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002292 ASSERT(index >= 0 && index < length());
2293 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2294}
2295
2296
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002297int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002298 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002299}
2300
2301
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002302int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002303 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002304}
2305
2306
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002307String* SlicedString::parent() {
2308 return String::cast(READ_FIELD(this, kParentOffset));
2309}
2310
2311
2312void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002313 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002314 WRITE_FIELD(this, kParentOffset, parent);
2315}
2316
2317
2318SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2319
2320
ager@chromium.org870a0b62008-11-04 11:43:05 +00002321String* ConsString::first() {
2322 return String::cast(READ_FIELD(this, kFirstOffset));
2323}
2324
2325
2326Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002327 return READ_FIELD(this, kFirstOffset);
2328}
2329
2330
ager@chromium.org870a0b62008-11-04 11:43:05 +00002331void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002332 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002333 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002334}
2335
2336
ager@chromium.org870a0b62008-11-04 11:43:05 +00002337String* ConsString::second() {
2338 return String::cast(READ_FIELD(this, kSecondOffset));
2339}
2340
2341
2342Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002343 return READ_FIELD(this, kSecondOffset);
2344}
2345
2346
ager@chromium.org870a0b62008-11-04 11:43:05 +00002347void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002348 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002349 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002350}
2351
2352
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002353bool ExternalString::is_short() {
2354 InstanceType type = map()->instance_type();
2355 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002356}
2357
2358
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002359const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002360 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2361}
2362
2363
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002364void ExternalAsciiString::update_data_cache() {
2365 if (is_short()) return;
2366 const char** data_field =
2367 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2368 *data_field = resource()->data();
2369}
2370
2371
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002372void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002373 const ExternalAsciiString::Resource* resource) {
2374 *reinterpret_cast<const Resource**>(
2375 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002376 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002377}
2378
2379
2380const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002381 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002382}
2383
2384
2385uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2386 ASSERT(index >= 0 && index < length());
2387 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002388}
2389
2390
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002391const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002392 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2393}
2394
2395
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002396void ExternalTwoByteString::update_data_cache() {
2397 if (is_short()) return;
2398 const uint16_t** data_field =
2399 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2400 *data_field = resource()->data();
2401}
2402
2403
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002404void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002405 const ExternalTwoByteString::Resource* resource) {
2406 *reinterpret_cast<const Resource**>(
2407 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002408 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002409}
2410
2411
2412const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002413 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002414}
2415
2416
2417uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2418 ASSERT(index >= 0 && index < length());
2419 return GetChars()[index];
2420}
2421
2422
2423const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2424 unsigned start) {
2425 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002426}
2427
2428
ager@chromium.orgac091b72010-05-05 07:34:42 +00002429void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002430 set_finger_index(kEntriesIndex);
2431 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002432}
2433
2434
2435void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002436 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002437 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002438 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002439 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002440 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002441 MakeZeroSize();
2442}
2443
2444
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002445int JSFunctionResultCache::size() {
2446 return Smi::cast(get(kCacheSizeIndex))->value();
2447}
2448
2449
2450void JSFunctionResultCache::set_size(int size) {
2451 set(kCacheSizeIndex, Smi::FromInt(size));
2452}
2453
2454
2455int JSFunctionResultCache::finger_index() {
2456 return Smi::cast(get(kFingerIndex))->value();
2457}
2458
2459
2460void JSFunctionResultCache::set_finger_index(int finger_index) {
2461 set(kFingerIndex, Smi::FromInt(finger_index));
2462}
2463
2464
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002465byte ByteArray::get(int index) {
2466 ASSERT(index >= 0 && index < this->length());
2467 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2468}
2469
2470
2471void ByteArray::set(int index, byte value) {
2472 ASSERT(index >= 0 && index < this->length());
2473 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2474}
2475
2476
2477int ByteArray::get_int(int index) {
2478 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2479 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2480}
2481
2482
2483ByteArray* ByteArray::FromDataStartAddress(Address address) {
2484 ASSERT_TAG_ALIGNED(address);
2485 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2486}
2487
2488
2489Address ByteArray::GetDataStartAddress() {
2490 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2491}
2492
2493
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002494uint8_t* ExternalPixelArray::external_pixel_pointer() {
2495 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002496}
2497
2498
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002499uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002500 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002501 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002502 return ptr[index];
2503}
2504
2505
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002506MaybeObject* ExternalPixelArray::get(int index) {
2507 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2508}
2509
2510
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002511void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002512 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002513 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002514 ptr[index] = value;
2515}
2516
2517
ager@chromium.org3811b432009-10-28 14:53:37 +00002518void* ExternalArray::external_pointer() {
2519 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2520 return reinterpret_cast<void*>(ptr);
2521}
2522
2523
2524void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2525 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2526 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2527}
2528
2529
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002530int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002531 ASSERT((index >= 0) && (index < this->length()));
2532 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2533 return ptr[index];
2534}
2535
2536
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002537MaybeObject* ExternalByteArray::get(int index) {
2538 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2539}
2540
2541
ager@chromium.org3811b432009-10-28 14:53:37 +00002542void ExternalByteArray::set(int index, int8_t value) {
2543 ASSERT((index >= 0) && (index < this->length()));
2544 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2545 ptr[index] = value;
2546}
2547
2548
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002549uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002550 ASSERT((index >= 0) && (index < this->length()));
2551 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2552 return ptr[index];
2553}
2554
2555
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002556MaybeObject* ExternalUnsignedByteArray::get(int index) {
2557 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2558}
2559
2560
ager@chromium.org3811b432009-10-28 14:53:37 +00002561void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2562 ASSERT((index >= 0) && (index < this->length()));
2563 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2564 ptr[index] = value;
2565}
2566
2567
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002568int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002569 ASSERT((index >= 0) && (index < this->length()));
2570 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2571 return ptr[index];
2572}
2573
2574
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002575MaybeObject* ExternalShortArray::get(int index) {
2576 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2577}
2578
2579
ager@chromium.org3811b432009-10-28 14:53:37 +00002580void ExternalShortArray::set(int index, int16_t value) {
2581 ASSERT((index >= 0) && (index < this->length()));
2582 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2583 ptr[index] = value;
2584}
2585
2586
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002587uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002588 ASSERT((index >= 0) && (index < this->length()));
2589 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2590 return ptr[index];
2591}
2592
2593
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002594MaybeObject* ExternalUnsignedShortArray::get(int index) {
2595 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2596}
2597
2598
ager@chromium.org3811b432009-10-28 14:53:37 +00002599void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2600 ASSERT((index >= 0) && (index < this->length()));
2601 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2602 ptr[index] = value;
2603}
2604
2605
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002606int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002607 ASSERT((index >= 0) && (index < this->length()));
2608 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2609 return ptr[index];
2610}
2611
2612
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002613MaybeObject* ExternalIntArray::get(int index) {
2614 return GetHeap()->NumberFromInt32(get_scalar(index));
2615}
2616
2617
ager@chromium.org3811b432009-10-28 14:53:37 +00002618void ExternalIntArray::set(int index, int32_t value) {
2619 ASSERT((index >= 0) && (index < this->length()));
2620 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2621 ptr[index] = value;
2622}
2623
2624
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002625uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002626 ASSERT((index >= 0) && (index < this->length()));
2627 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2628 return ptr[index];
2629}
2630
2631
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002632MaybeObject* ExternalUnsignedIntArray::get(int index) {
2633 return GetHeap()->NumberFromUint32(get_scalar(index));
2634}
2635
2636
ager@chromium.org3811b432009-10-28 14:53:37 +00002637void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2638 ASSERT((index >= 0) && (index < this->length()));
2639 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2640 ptr[index] = value;
2641}
2642
2643
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002644float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002645 ASSERT((index >= 0) && (index < this->length()));
2646 float* ptr = static_cast<float*>(external_pointer());
2647 return ptr[index];
2648}
2649
2650
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002651MaybeObject* ExternalFloatArray::get(int index) {
2652 return GetHeap()->NumberFromDouble(get_scalar(index));
2653}
2654
2655
ager@chromium.org3811b432009-10-28 14:53:37 +00002656void ExternalFloatArray::set(int index, float value) {
2657 ASSERT((index >= 0) && (index < this->length()));
2658 float* ptr = static_cast<float*>(external_pointer());
2659 ptr[index] = value;
2660}
2661
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002662
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002663double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002664 ASSERT((index >= 0) && (index < this->length()));
2665 double* ptr = static_cast<double*>(external_pointer());
2666 return ptr[index];
2667}
2668
2669
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002670MaybeObject* ExternalDoubleArray::get(int index) {
2671 return GetHeap()->NumberFromDouble(get_scalar(index));
2672}
2673
2674
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002675void ExternalDoubleArray::set(int index, double value) {
2676 ASSERT((index >= 0) && (index < this->length()));
2677 double* ptr = static_cast<double*>(external_pointer());
2678 ptr[index] = value;
2679}
2680
2681
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002682int Map::visitor_id() {
2683 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2684}
2685
2686
2687void Map::set_visitor_id(int id) {
2688 ASSERT(0 <= id && id < 256);
2689 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2690}
2691
ager@chromium.org3811b432009-10-28 14:53:37 +00002692
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002693int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002694 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2695}
2696
2697
2698int Map::inobject_properties() {
2699 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002700}
2701
2702
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002703int Map::pre_allocated_property_fields() {
2704 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2705}
2706
2707
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002708int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002709 int instance_size = map->instance_size();
2710 if (instance_size != kVariableSizeSentinel) return instance_size;
2711 // We can ignore the "symbol" bit becase it is only set for symbols
2712 // and implies a string type.
2713 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002714 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002715 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002716 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002717 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002718 if (instance_type == ASCII_STRING_TYPE) {
2719 return SeqAsciiString::SizeFor(
2720 reinterpret_cast<SeqAsciiString*>(this)->length());
2721 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002722 if (instance_type == BYTE_ARRAY_TYPE) {
2723 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2724 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002725 if (instance_type == FREE_SPACE_TYPE) {
2726 return reinterpret_cast<FreeSpace*>(this)->size();
2727 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002728 if (instance_type == STRING_TYPE) {
2729 return SeqTwoByteString::SizeFor(
2730 reinterpret_cast<SeqTwoByteString*>(this)->length());
2731 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002732 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2733 return FixedDoubleArray::SizeFor(
2734 reinterpret_cast<FixedDoubleArray*>(this)->length());
2735 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002736 ASSERT(instance_type == CODE_TYPE);
2737 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002738}
2739
2740
2741void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002742 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002743 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002744 ASSERT(0 <= value && value < 256);
2745 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2746}
2747
2748
ager@chromium.org7c537e22008-10-16 08:43:32 +00002749void Map::set_inobject_properties(int value) {
2750 ASSERT(0 <= value && value < 256);
2751 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2752}
2753
2754
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002755void Map::set_pre_allocated_property_fields(int value) {
2756 ASSERT(0 <= value && value < 256);
2757 WRITE_BYTE_FIELD(this,
2758 kPreAllocatedPropertyFieldsOffset,
2759 static_cast<byte>(value));
2760}
2761
2762
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002763InstanceType Map::instance_type() {
2764 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2765}
2766
2767
2768void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002769 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2770}
2771
2772
2773int Map::unused_property_fields() {
2774 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2775}
2776
2777
2778void Map::set_unused_property_fields(int value) {
2779 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2780}
2781
2782
2783byte Map::bit_field() {
2784 return READ_BYTE_FIELD(this, kBitFieldOffset);
2785}
2786
2787
2788void Map::set_bit_field(byte value) {
2789 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2790}
2791
2792
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002793byte Map::bit_field2() {
2794 return READ_BYTE_FIELD(this, kBitField2Offset);
2795}
2796
2797
2798void Map::set_bit_field2(byte value) {
2799 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2800}
2801
2802
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002803void Map::set_non_instance_prototype(bool value) {
2804 if (value) {
2805 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2806 } else {
2807 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2808 }
2809}
2810
2811
2812bool Map::has_non_instance_prototype() {
2813 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2814}
2815
2816
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002817void Map::set_function_with_prototype(bool value) {
2818 if (value) {
2819 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2820 } else {
2821 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2822 }
2823}
2824
2825
2826bool Map::function_with_prototype() {
2827 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2828}
2829
2830
ager@chromium.org870a0b62008-11-04 11:43:05 +00002831void Map::set_is_access_check_needed(bool access_check_needed) {
2832 if (access_check_needed) {
2833 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2834 } else {
2835 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2836 }
2837}
2838
2839
2840bool Map::is_access_check_needed() {
2841 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2842}
2843
2844
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002845void Map::set_is_extensible(bool value) {
2846 if (value) {
2847 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2848 } else {
2849 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2850 }
2851}
2852
2853bool Map::is_extensible() {
2854 return ((1 << kIsExtensible) & bit_field2()) != 0;
2855}
2856
2857
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002858void Map::set_attached_to_shared_function_info(bool value) {
2859 if (value) {
2860 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2861 } else {
2862 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2863 }
2864}
2865
2866bool Map::attached_to_shared_function_info() {
2867 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2868}
2869
2870
2871void Map::set_is_shared(bool value) {
2872 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002873 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002874 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002875 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002876 }
2877}
2878
2879bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002880 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002881}
2882
2883
2884JSFunction* Map::unchecked_constructor() {
2885 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2886}
2887
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002888
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002889Code::Flags Code::flags() {
2890 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2891}
2892
2893
2894void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002895 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002896 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002897 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2898 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002899 ExtractArgumentsCountFromFlags(flags) >= 0);
2900 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2901}
2902
2903
2904Code::Kind Code::kind() {
2905 return ExtractKindFromFlags(flags());
2906}
2907
2908
kasper.lund7276f142008-07-30 08:49:36 +00002909InlineCacheState Code::ic_state() {
2910 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002911 // Only allow uninitialized or debugger states for non-IC code
2912 // objects. This is used in the debugger to determine whether or not
2913 // a call to code object has been replaced with a debug break call.
2914 ASSERT(is_inline_cache_stub() ||
2915 result == UNINITIALIZED ||
2916 result == DEBUG_BREAK ||
2917 result == DEBUG_PREPARE_STEP_IN);
2918 return result;
2919}
2920
2921
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002922Code::ExtraICState Code::extra_ic_state() {
2923 ASSERT(is_inline_cache_stub());
2924 return ExtractExtraICStateFromFlags(flags());
2925}
2926
2927
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002928PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002929 return ExtractTypeFromFlags(flags());
2930}
2931
2932
2933int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002934 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002935 return ExtractArgumentsCountFromFlags(flags());
2936}
2937
2938
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002939int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002940 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002941 kind() == UNARY_OP_IC ||
2942 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002943 kind() == COMPARE_IC ||
2944 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002945 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002946}
2947
2948
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002949void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002950 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002951 kind() == UNARY_OP_IC ||
2952 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002953 kind() == COMPARE_IC ||
2954 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002955 ASSERT(0 <= major && major < 256);
2956 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002957}
2958
2959
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002960bool Code::is_pregenerated() {
2961 return kind() == STUB && IsPregeneratedField::decode(flags());
2962}
2963
2964
2965void Code::set_is_pregenerated(bool value) {
2966 ASSERT(kind() == STUB);
2967 Flags f = flags();
2968 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2969 set_flags(f);
2970}
2971
2972
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002973bool Code::optimizable() {
2974 ASSERT(kind() == FUNCTION);
2975 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2976}
2977
2978
2979void Code::set_optimizable(bool value) {
2980 ASSERT(kind() == FUNCTION);
2981 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2982}
2983
2984
2985bool Code::has_deoptimization_support() {
2986 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002987 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2988 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002989}
2990
2991
2992void Code::set_has_deoptimization_support(bool value) {
2993 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002994 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2995 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
2996 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2997}
2998
2999
3000bool Code::has_debug_break_slots() {
3001 ASSERT(kind() == FUNCTION);
3002 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3003 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3004}
3005
3006
3007void Code::set_has_debug_break_slots(bool value) {
3008 ASSERT(kind() == FUNCTION);
3009 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3010 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3011 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003012}
3013
3014
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003015bool Code::is_compiled_optimizable() {
3016 ASSERT(kind() == FUNCTION);
3017 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3018 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3019}
3020
3021
3022void Code::set_compiled_optimizable(bool value) {
3023 ASSERT(kind() == FUNCTION);
3024 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3025 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3026 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3027}
3028
3029
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003030int Code::allow_osr_at_loop_nesting_level() {
3031 ASSERT(kind() == FUNCTION);
3032 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3033}
3034
3035
3036void Code::set_allow_osr_at_loop_nesting_level(int level) {
3037 ASSERT(kind() == FUNCTION);
3038 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3039 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3040}
3041
3042
3043unsigned Code::stack_slots() {
3044 ASSERT(kind() == OPTIMIZED_FUNCTION);
3045 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3046}
3047
3048
3049void Code::set_stack_slots(unsigned slots) {
3050 ASSERT(kind() == OPTIMIZED_FUNCTION);
3051 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3052}
3053
3054
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003055unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003056 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003057 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003058}
3059
3060
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003061void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003062 ASSERT(kind() == OPTIMIZED_FUNCTION);
3063 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003064 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003065}
3066
3067
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003068unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003069 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003070 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003071}
3072
3073
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003074void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003075 ASSERT(kind() == FUNCTION);
3076 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003077 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078}
3079
3080
3081CheckType Code::check_type() {
3082 ASSERT(is_call_stub() || is_keyed_call_stub());
3083 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3084 return static_cast<CheckType>(type);
3085}
3086
3087
3088void Code::set_check_type(CheckType value) {
3089 ASSERT(is_call_stub() || is_keyed_call_stub());
3090 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3091}
3092
3093
danno@chromium.org40cb8782011-05-25 07:58:50 +00003094byte Code::unary_op_type() {
3095 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003096 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3097}
3098
3099
danno@chromium.org40cb8782011-05-25 07:58:50 +00003100void Code::set_unary_op_type(byte value) {
3101 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003102 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3103}
3104
3105
danno@chromium.org40cb8782011-05-25 07:58:50 +00003106byte Code::binary_op_type() {
3107 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003108 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3109}
3110
3111
danno@chromium.org40cb8782011-05-25 07:58:50 +00003112void Code::set_binary_op_type(byte value) {
3113 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003114 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3115}
3116
3117
danno@chromium.org40cb8782011-05-25 07:58:50 +00003118byte Code::binary_op_result_type() {
3119 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003120 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3121}
3122
3123
danno@chromium.org40cb8782011-05-25 07:58:50 +00003124void Code::set_binary_op_result_type(byte value) {
3125 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003126 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3127}
3128
3129
3130byte Code::compare_state() {
3131 ASSERT(is_compare_ic_stub());
3132 return READ_BYTE_FIELD(this, kCompareStateOffset);
3133}
3134
3135
3136void Code::set_compare_state(byte value) {
3137 ASSERT(is_compare_ic_stub());
3138 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3139}
3140
3141
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003142byte Code::to_boolean_state() {
3143 ASSERT(is_to_boolean_ic_stub());
3144 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3145}
3146
3147
3148void Code::set_to_boolean_state(byte value) {
3149 ASSERT(is_to_boolean_ic_stub());
3150 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3151}
3152
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003153
3154bool Code::has_function_cache() {
3155 ASSERT(kind() == STUB);
3156 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3157}
3158
3159
3160void Code::set_has_function_cache(bool flag) {
3161 ASSERT(kind() == STUB);
3162 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3163}
3164
3165
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003166bool Code::is_inline_cache_stub() {
3167 Kind kind = this->kind();
3168 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3169}
3170
3171
3172Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003173 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003174 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003175 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003176 int argc,
3177 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003178 // Extra IC state is only allowed for call IC stubs or for store IC
3179 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003180 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003181 kind == CALL_IC ||
3182 kind == STORE_IC ||
3183 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003184 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003185 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003186 | ICStateField::encode(ic_state)
3187 | TypeField::encode(type)
3188 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003189 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003190 | CacheHolderField::encode(holder);
3191 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003192}
3193
3194
3195Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3196 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003197 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003198 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003199 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003200 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003201}
3202
3203
3204Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003205 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003206}
3207
3208
kasper.lund7276f142008-07-30 08:49:36 +00003209InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003210 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003211}
3212
3213
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003214Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003215 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003216}
3217
3218
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003219PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003220 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003221}
3222
3223
3224int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003225 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003226}
3227
3228
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003229InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003230 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003231}
3232
3233
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003234Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003235 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003236 return static_cast<Flags>(bits);
3237}
3238
3239
ager@chromium.org8bb60582008-12-11 12:02:20 +00003240Code* Code::GetCodeFromTargetAddress(Address address) {
3241 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3242 // GetCodeFromTargetAddress might be called when marking objects during mark
3243 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3244 // Code::cast. Code::cast does not work when the object's map is
3245 // marked.
3246 Code* result = reinterpret_cast<Code*>(code);
3247 return result;
3248}
3249
3250
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003251Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3252 return HeapObject::
3253 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3254}
3255
3256
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003257Object* Map::prototype() {
3258 return READ_FIELD(this, kPrototypeOffset);
3259}
3260
3261
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003262void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003263 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003264 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003265 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003266}
3267
3268
danno@chromium.org40cb8782011-05-25 07:58:50 +00003269DescriptorArray* Map::instance_descriptors() {
3270 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3271 if (object->IsSmi()) {
3272 return HEAP->empty_descriptor_array();
3273 } else {
3274 return DescriptorArray::cast(object);
3275 }
3276}
3277
3278
3279void Map::init_instance_descriptors() {
3280 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3281}
3282
3283
3284void Map::clear_instance_descriptors() {
3285 Object* object = READ_FIELD(this,
3286 kInstanceDescriptorsOrBitField3Offset);
3287 if (!object->IsSmi()) {
3288 WRITE_FIELD(
3289 this,
3290 kInstanceDescriptorsOrBitField3Offset,
3291 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3292 }
3293}
3294
3295
3296void Map::set_instance_descriptors(DescriptorArray* value,
3297 WriteBarrierMode mode) {
3298 Object* object = READ_FIELD(this,
3299 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003300 Heap* heap = GetHeap();
3301 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003302 clear_instance_descriptors();
3303 return;
3304 } else {
3305 if (object->IsSmi()) {
3306 value->set_bit_field3_storage(Smi::cast(object)->value());
3307 } else {
3308 value->set_bit_field3_storage(
3309 DescriptorArray::cast(object)->bit_field3_storage());
3310 }
3311 }
3312 ASSERT(!is_shared());
3313 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003314 CONDITIONAL_WRITE_BARRIER(
3315 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003316}
3317
3318
3319int Map::bit_field3() {
3320 Object* object = READ_FIELD(this,
3321 kInstanceDescriptorsOrBitField3Offset);
3322 if (object->IsSmi()) {
3323 return Smi::cast(object)->value();
3324 } else {
3325 return DescriptorArray::cast(object)->bit_field3_storage();
3326 }
3327}
3328
3329
3330void Map::set_bit_field3(int value) {
3331 ASSERT(Smi::IsValid(value));
3332 Object* object = READ_FIELD(this,
3333 kInstanceDescriptorsOrBitField3Offset);
3334 if (object->IsSmi()) {
3335 WRITE_FIELD(this,
3336 kInstanceDescriptorsOrBitField3Offset,
3337 Smi::FromInt(value));
3338 } else {
3339 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3340 }
3341}
3342
3343
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003344FixedArray* Map::unchecked_prototype_transitions() {
3345 return reinterpret_cast<FixedArray*>(
3346 READ_FIELD(this, kPrototypeTransitionsOffset));
3347}
3348
3349
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003350ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003351ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003352ACCESSORS(Map, constructor, Object, kConstructorOffset)
3353
3354ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003355ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003356ACCESSORS(JSFunction,
3357 next_function_link,
3358 Object,
3359 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003360
3361ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3362ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003363ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003364
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003365ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003366
3367ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3368ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3369ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3370ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3371ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3372
3373ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3374ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3375ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3376
3377ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3378ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3379ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3380ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3381ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3382ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3383
3384ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3385ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3386
3387ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3388ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3389
3390ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3391ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003392ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3393 kPropertyAccessorsOffset)
3394ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3395 kPrototypeTemplateOffset)
3396ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3397ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3398 kNamedPropertyHandlerOffset)
3399ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3400 kIndexedPropertyHandlerOffset)
3401ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3402 kInstanceTemplateOffset)
3403ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3404ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003405ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3406 kInstanceCallHandlerOffset)
3407ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3408 kAccessCheckInfoOffset)
3409ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3410
3411ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003412ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3413 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003414
3415ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3416ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3417
3418ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3419
3420ACCESSORS(Script, source, Object, kSourceOffset)
3421ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003422ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003423ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3424ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003425ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003426ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003427ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003428ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003429ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003430ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003431ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003432ACCESSORS(Script, eval_from_instructions_offset, Smi,
3433 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003434
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003435#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003436ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3437ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3438ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3439ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3440
3441ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3442ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3443ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3444ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003445#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003446
3447ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003448ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3449ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003450ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3451 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003452ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003453ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3454ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003455ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003456ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3457 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003458
3459BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3460 kHiddenPrototypeBit)
3461BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3462BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3463 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003464BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3465 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003466BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3467 kIsExpressionBit)
3468BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3469 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003470BOOL_GETTER(SharedFunctionInfo,
3471 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003472 has_only_simple_this_property_assignments,
3473 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003474BOOL_ACCESSORS(SharedFunctionInfo,
3475 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003476 allows_lazy_compilation,
3477 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003478BOOL_ACCESSORS(SharedFunctionInfo,
3479 compiler_hints,
3480 uses_arguments,
3481 kUsesArguments)
3482BOOL_ACCESSORS(SharedFunctionInfo,
3483 compiler_hints,
3484 has_duplicate_parameters,
3485 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003486
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003487
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003488#if V8_HOST_ARCH_32_BIT
3489SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3490SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003491 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003492SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003493 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003494SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3495SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003496 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003497SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3498SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003499 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003500SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003501 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003502SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003503 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003504SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003505#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003506
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003507#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003508 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003509 int holder::name() { \
3510 int value = READ_INT_FIELD(this, offset); \
3511 ASSERT(kHeapObjectTag == 1); \
3512 ASSERT((value & kHeapObjectTag) == 0); \
3513 return value >> 1; \
3514 } \
3515 void holder::set_##name(int value) { \
3516 ASSERT(kHeapObjectTag == 1); \
3517 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3518 (value & 0xC0000000) == 0x000000000); \
3519 WRITE_INT_FIELD(this, \
3520 offset, \
3521 (value << 1) & ~kHeapObjectTag); \
3522 }
3523
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003524#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3525 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003526 INT_ACCESSORS(holder, name, offset)
3527
3528
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003529PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003530PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3531 formal_parameter_count,
3532 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003533
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003534PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3535 expected_nof_properties,
3536 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003537PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3538
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003539PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3540PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3541 start_position_and_type,
3542 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003543
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003544PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3545 function_token_position,
3546 kFunctionTokenPositionOffset)
3547PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3548 compiler_hints,
3549 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003550
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003551PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3552 this_property_assignments_count,
3553 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003554PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003555#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003556
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003557
3558int SharedFunctionInfo::construction_count() {
3559 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3560}
3561
3562
3563void SharedFunctionInfo::set_construction_count(int value) {
3564 ASSERT(0 <= value && value < 256);
3565 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3566}
3567
3568
whesse@chromium.org7b260152011-06-20 15:33:18 +00003569BOOL_ACCESSORS(SharedFunctionInfo,
3570 compiler_hints,
3571 live_objects_may_exist,
3572 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003573
3574
3575bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003576 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003577}
3578
3579
whesse@chromium.org7b260152011-06-20 15:33:18 +00003580BOOL_GETTER(SharedFunctionInfo,
3581 compiler_hints,
3582 optimization_disabled,
3583 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003584
3585
3586void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3587 set_compiler_hints(BooleanBit::set(compiler_hints(),
3588 kOptimizationDisabled,
3589 disable));
3590 // If disabling optimizations we reflect that in the code object so
3591 // it will not be counted as optimizable code.
3592 if ((code()->kind() == Code::FUNCTION) && disable) {
3593 code()->set_optimizable(false);
3594 }
3595}
3596
3597
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003598LanguageMode SharedFunctionInfo::language_mode() {
3599 int hints = compiler_hints();
3600 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3601 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3602 return EXTENDED_MODE;
3603 }
3604 return BooleanBit::get(hints, kStrictModeFunction)
3605 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003606}
3607
3608
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003609void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3610 // We only allow language mode transitions that go set the same language mode
3611 // again or go up in the chain:
3612 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3613 ASSERT(this->language_mode() == CLASSIC_MODE ||
3614 this->language_mode() == language_mode ||
3615 language_mode == EXTENDED_MODE);
3616 int hints = compiler_hints();
3617 hints = BooleanBit::set(
3618 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3619 hints = BooleanBit::set(
3620 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3621 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003622}
3623
3624
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003625bool SharedFunctionInfo::is_classic_mode() {
3626 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3627}
3628
3629BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3630 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003631BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3632BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3633 name_should_print_as_anonymous,
3634 kNameShouldPrintAsAnonymous)
3635BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3636BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003637
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003638ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3639ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3640
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003641ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3642
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003643bool Script::HasValidSource() {
3644 Object* src = this->source();
3645 if (!src->IsString()) return true;
3646 String* src_str = String::cast(src);
3647 if (!StringShape(src_str).IsExternal()) return true;
3648 if (src_str->IsAsciiRepresentation()) {
3649 return ExternalAsciiString::cast(src)->resource() != NULL;
3650 } else if (src_str->IsTwoByteRepresentation()) {
3651 return ExternalTwoByteString::cast(src)->resource() != NULL;
3652 }
3653 return true;
3654}
3655
3656
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003657void SharedFunctionInfo::DontAdaptArguments() {
3658 ASSERT(code()->kind() == Code::BUILTIN);
3659 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3660}
3661
3662
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003663int SharedFunctionInfo::start_position() {
3664 return start_position_and_type() >> kStartPositionShift;
3665}
3666
3667
3668void SharedFunctionInfo::set_start_position(int start_position) {
3669 set_start_position_and_type((start_position << kStartPositionShift)
3670 | (start_position_and_type() & ~kStartPositionMask));
3671}
3672
3673
3674Code* SharedFunctionInfo::code() {
3675 return Code::cast(READ_FIELD(this, kCodeOffset));
3676}
3677
3678
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003679Code* SharedFunctionInfo::unchecked_code() {
3680 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3681}
3682
3683
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003684void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003685 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003686 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003687}
3688
3689
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003690ScopeInfo* SharedFunctionInfo::scope_info() {
3691 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003692}
3693
3694
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003695void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003696 WriteBarrierMode mode) {
3697 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003698 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3699 this,
3700 kScopeInfoOffset,
3701 reinterpret_cast<Object*>(value),
3702 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003703}
3704
3705
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003706Smi* SharedFunctionInfo::deopt_counter() {
3707 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3708}
3709
3710
3711void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3712 WRITE_FIELD(this, kDeoptCounterOffset, value);
3713}
3714
3715
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003716bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003717 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003718 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003719}
3720
3721
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003722bool SharedFunctionInfo::IsApiFunction() {
3723 return function_data()->IsFunctionTemplateInfo();
3724}
3725
3726
3727FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3728 ASSERT(IsApiFunction());
3729 return FunctionTemplateInfo::cast(function_data());
3730}
3731
3732
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003733bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003734 return function_data()->IsSmi();
3735}
3736
3737
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003738BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3739 ASSERT(HasBuiltinFunctionId());
3740 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003741}
3742
3743
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003744int SharedFunctionInfo::code_age() {
3745 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3746}
3747
3748
3749void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003750 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3751 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003752}
3753
3754
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003755bool SharedFunctionInfo::has_deoptimization_support() {
3756 Code* code = this->code();
3757 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3758}
3759
3760
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003761bool JSFunction::IsBuiltin() {
3762 return context()->global()->IsJSBuiltinsObject();
3763}
3764
3765
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003766bool JSFunction::NeedsArgumentsAdaption() {
3767 return shared()->formal_parameter_count() !=
3768 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3769}
3770
3771
3772bool JSFunction::IsOptimized() {
3773 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3774}
3775
3776
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003777bool JSFunction::IsOptimizable() {
3778 return code()->kind() == Code::FUNCTION && code()->optimizable();
3779}
3780
3781
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003782bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003783 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003784}
3785
3786
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003787Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003788 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003789}
3790
3791
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003792Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003793 return reinterpret_cast<Code*>(
3794 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003795}
3796
3797
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003798void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003799 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003800 Address entry = value->entry();
3801 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003802 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3803 this,
3804 HeapObject::RawField(this, kCodeEntryOffset),
3805 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003806}
3807
3808
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003809void JSFunction::ReplaceCode(Code* code) {
3810 bool was_optimized = IsOptimized();
3811 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3812
3813 set_code(code);
3814
3815 // Add/remove the function from the list of optimized functions for this
3816 // context based on the state change.
3817 if (!was_optimized && is_optimized) {
3818 context()->global_context()->AddOptimizedFunction(this);
3819 }
3820 if (was_optimized && !is_optimized) {
3821 context()->global_context()->RemoveOptimizedFunction(this);
3822 }
3823}
3824
3825
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003826Context* JSFunction::context() {
3827 return Context::cast(READ_FIELD(this, kContextOffset));
3828}
3829
3830
3831Object* JSFunction::unchecked_context() {
3832 return READ_FIELD(this, kContextOffset);
3833}
3834
3835
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003836SharedFunctionInfo* JSFunction::unchecked_shared() {
3837 return reinterpret_cast<SharedFunctionInfo*>(
3838 READ_FIELD(this, kSharedFunctionInfoOffset));
3839}
3840
3841
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003842void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003843 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003844 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003845 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003846}
3847
3848ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3849 kPrototypeOrInitialMapOffset)
3850
3851
3852Map* JSFunction::initial_map() {
3853 return Map::cast(prototype_or_initial_map());
3854}
3855
3856
3857void JSFunction::set_initial_map(Map* value) {
3858 set_prototype_or_initial_map(value);
3859}
3860
3861
3862bool JSFunction::has_initial_map() {
3863 return prototype_or_initial_map()->IsMap();
3864}
3865
3866
3867bool JSFunction::has_instance_prototype() {
3868 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3869}
3870
3871
3872bool JSFunction::has_prototype() {
3873 return map()->has_non_instance_prototype() || has_instance_prototype();
3874}
3875
3876
3877Object* JSFunction::instance_prototype() {
3878 ASSERT(has_instance_prototype());
3879 if (has_initial_map()) return initial_map()->prototype();
3880 // When there is no initial map and the prototype is a JSObject, the
3881 // initial map field is used for the prototype field.
3882 return prototype_or_initial_map();
3883}
3884
3885
3886Object* JSFunction::prototype() {
3887 ASSERT(has_prototype());
3888 // If the function's prototype property has been set to a non-JSObject
3889 // value, that value is stored in the constructor field of the map.
3890 if (map()->has_non_instance_prototype()) return map()->constructor();
3891 return instance_prototype();
3892}
3893
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003894bool JSFunction::should_have_prototype() {
3895 return map()->function_with_prototype();
3896}
3897
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003898
3899bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003900 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003901}
3902
3903
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003904FixedArray* JSFunction::literals() {
3905 ASSERT(!shared()->bound());
3906 return literals_or_bindings();
3907}
3908
3909
3910void JSFunction::set_literals(FixedArray* literals) {
3911 ASSERT(!shared()->bound());
3912 set_literals_or_bindings(literals);
3913}
3914
3915
3916FixedArray* JSFunction::function_bindings() {
3917 ASSERT(shared()->bound());
3918 return literals_or_bindings();
3919}
3920
3921
3922void JSFunction::set_function_bindings(FixedArray* bindings) {
3923 ASSERT(shared()->bound());
3924 // Bound function literal may be initialized to the empty fixed array
3925 // before the bindings are set.
3926 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
3927 bindings->map() == GetHeap()->fixed_cow_array_map());
3928 set_literals_or_bindings(bindings);
3929}
3930
3931
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003932int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003933 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003934 return literals()->length();
3935}
3936
3937
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003938Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003939 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003940 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003941}
3942
3943
3944void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3945 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003946 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003947 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003948 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003949}
3950
3951
3952Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003953 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003954 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3955}
3956
3957
3958void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3959 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003960 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003961 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003962 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003963}
3964
3965
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003966ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003967ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003968ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3969ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3970
3971
3972void JSProxy::InitializeBody(int object_size, Object* value) {
3973 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3974 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3975 WRITE_FIELD(this, offset, value);
3976 }
3977}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003978
3979
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003980ACCESSORS(JSSet, table, Object, kTableOffset)
3981ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003982ACCESSORS(JSWeakMap, table, Object, kTableOffset)
3983ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003984
3985
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003986Address Foreign::foreign_address() {
3987 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003988}
3989
3990
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003991void Foreign::set_foreign_address(Address value) {
3992 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003993}
3994
3995
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003996ACCESSORS(JSValue, value, Object, kValueOffset)
3997
3998
3999JSValue* JSValue::cast(Object* obj) {
4000 ASSERT(obj->IsJSValue());
4001 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4002 return reinterpret_cast<JSValue*>(obj);
4003}
4004
4005
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004006ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4007ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4008ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4009ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4010ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4011SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4012SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4013
4014
4015JSMessageObject* JSMessageObject::cast(Object* obj) {
4016 ASSERT(obj->IsJSMessageObject());
4017 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4018 return reinterpret_cast<JSMessageObject*>(obj);
4019}
4020
4021
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004022INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004023ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004024ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004025ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004026ACCESSORS(Code, next_code_flushing_candidate,
4027 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004028
4029
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004030byte* Code::instruction_start() {
4031 return FIELD_ADDR(this, kHeaderSize);
4032}
4033
4034
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004035byte* Code::instruction_end() {
4036 return instruction_start() + instruction_size();
4037}
4038
4039
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004040int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004041 return RoundUp(instruction_size(), kObjectAlignment);
4042}
4043
4044
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004045FixedArray* Code::unchecked_deoptimization_data() {
4046 return reinterpret_cast<FixedArray*>(
4047 READ_FIELD(this, kDeoptimizationDataOffset));
4048}
4049
4050
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004051ByteArray* Code::unchecked_relocation_info() {
4052 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004053}
4054
4055
4056byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004057 return unchecked_relocation_info()->GetDataStartAddress();
4058}
4059
4060
4061int Code::relocation_size() {
4062 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004063}
4064
4065
4066byte* Code::entry() {
4067 return instruction_start();
4068}
4069
4070
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004071bool Code::contains(byte* inner_pointer) {
4072 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004073}
4074
4075
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004076ACCESSORS(JSArray, length, Object, kLengthOffset)
4077
4078
ager@chromium.org236ad962008-09-25 09:45:57 +00004079ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004080
4081
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004082JSRegExp::Type JSRegExp::TypeTag() {
4083 Object* data = this->data();
4084 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4085 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4086 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004087}
4088
4089
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004090JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4091 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4092 return static_cast<JSRegExp::Type>(smi->value());
4093}
4094
4095
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004096int JSRegExp::CaptureCount() {
4097 switch (TypeTag()) {
4098 case ATOM:
4099 return 0;
4100 case IRREGEXP:
4101 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4102 default:
4103 UNREACHABLE();
4104 return -1;
4105 }
4106}
4107
4108
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004109JSRegExp::Flags JSRegExp::GetFlags() {
4110 ASSERT(this->data()->IsFixedArray());
4111 Object* data = this->data();
4112 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4113 return Flags(smi->value());
4114}
4115
4116
4117String* JSRegExp::Pattern() {
4118 ASSERT(this->data()->IsFixedArray());
4119 Object* data = this->data();
4120 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4121 return pattern;
4122}
4123
4124
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004125Object* JSRegExp::DataAt(int index) {
4126 ASSERT(TypeTag() != NOT_COMPILED);
4127 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004128}
4129
4130
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004131Object* JSRegExp::DataAtUnchecked(int index) {
4132 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4133 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4134 return READ_FIELD(fa, offset);
4135}
4136
4137
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004138void JSRegExp::SetDataAt(int index, Object* value) {
4139 ASSERT(TypeTag() != NOT_COMPILED);
4140 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4141 FixedArray::cast(data())->set(index, value);
4142}
4143
4144
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004145void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4146 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4147 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4148 if (value->IsSmi()) {
4149 fa->set_unchecked(index, Smi::cast(value));
4150 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004151 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004152 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4153 }
4154}
4155
4156
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004157ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004158 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004159#if DEBUG
4160 FixedArrayBase* fixed_array =
4161 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4162 Map* map = fixed_array->map();
4163 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004164 (map == GetHeap()->fixed_array_map() ||
4165 map == GetHeap()->fixed_cow_array_map())) ||
4166 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004167 (fixed_array->IsFixedDoubleArray() ||
4168 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004169 (kind == DICTIONARY_ELEMENTS &&
4170 fixed_array->IsFixedArray() &&
4171 fixed_array->IsDictionary()) ||
4172 (kind > DICTIONARY_ELEMENTS));
4173 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4174 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004175#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004176 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004177}
4178
4179
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004180ElementsAccessor* JSObject::GetElementsAccessor() {
4181 return ElementsAccessor::ForKind(GetElementsKind());
4182}
4183
4184
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004185bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004186 return GetElementsKind() == FAST_ELEMENTS;
4187}
4188
4189
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004190bool JSObject::HasFastSmiOnlyElements() {
4191 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4192}
4193
4194
4195bool JSObject::HasFastTypeElements() {
4196 ElementsKind elements_kind = GetElementsKind();
4197 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4198 elements_kind == FAST_ELEMENTS;
4199}
4200
4201
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004202bool JSObject::HasFastDoubleElements() {
4203 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4204}
4205
4206
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004207bool JSObject::HasDictionaryElements() {
4208 return GetElementsKind() == DICTIONARY_ELEMENTS;
4209}
4210
4211
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004212bool JSObject::HasNonStrictArgumentsElements() {
4213 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4214}
4215
4216
ager@chromium.org3811b432009-10-28 14:53:37 +00004217bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004218 HeapObject* array = elements();
4219 ASSERT(array != NULL);
4220 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004221}
4222
4223
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004224#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4225bool JSObject::HasExternal##name##Elements() { \
4226 HeapObject* array = elements(); \
4227 ASSERT(array != NULL); \
4228 if (!array->IsHeapObject()) \
4229 return false; \
4230 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004231}
4232
4233
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004234EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4235EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4236EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4237EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4238 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4239EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4240EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4241 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4242EXTERNAL_ELEMENTS_CHECK(Float,
4243 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004244EXTERNAL_ELEMENTS_CHECK(Double,
4245 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004246EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004247
4248
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004249bool JSObject::HasNamedInterceptor() {
4250 return map()->has_named_interceptor();
4251}
4252
4253
4254bool JSObject::HasIndexedInterceptor() {
4255 return map()->has_indexed_interceptor();
4256}
4257
4258
ager@chromium.org5c838252010-02-19 08:53:10 +00004259bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004260 bool result = elements()->IsFixedArray() ||
4261 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004262 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004263 return result;
4264}
4265
4266
lrn@chromium.org303ada72010-10-27 09:33:13 +00004267MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004268 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004269 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004270 Isolate* isolate = GetIsolate();
4271 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004272 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004273 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4274 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004275 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4276 return maybe_writable_elems;
4277 }
4278 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004279 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004280 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004281 return writable_elems;
4282}
4283
4284
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004285StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004286 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004287 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004288}
4289
4290
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004291NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004292 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004293 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004294}
4295
4296
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004297bool String::IsHashFieldComputed(uint32_t field) {
4298 return (field & kHashNotComputedMask) == 0;
4299}
4300
4301
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004302bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004303 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004304}
4305
4306
4307uint32_t String::Hash() {
4308 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004309 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004310 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004311 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004312 return ComputeAndSetHash();
4313}
4314
4315
ager@chromium.org7c537e22008-10-16 08:43:32 +00004316StringHasher::StringHasher(int length)
4317 : length_(length),
4318 raw_running_hash_(0),
4319 array_index_(0),
4320 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4321 is_first_char_(true),
4322 is_valid_(true) { }
4323
4324
4325bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004326 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004327}
4328
4329
4330void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004331 // Use the Jenkins one-at-a-time hash function to update the hash
4332 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004333 raw_running_hash_ += c;
4334 raw_running_hash_ += (raw_running_hash_ << 10);
4335 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004336 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004337 if (is_array_index_) {
4338 if (c < '0' || c > '9') {
4339 is_array_index_ = false;
4340 } else {
4341 int d = c - '0';
4342 if (is_first_char_) {
4343 is_first_char_ = false;
4344 if (c == '0' && length_ > 1) {
4345 is_array_index_ = false;
4346 return;
4347 }
4348 }
4349 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4350 is_array_index_ = false;
4351 } else {
4352 array_index_ = array_index_ * 10 + d;
4353 }
4354 }
4355 }
4356}
4357
4358
4359void StringHasher::AddCharacterNoIndex(uc32 c) {
4360 ASSERT(!is_array_index());
4361 raw_running_hash_ += c;
4362 raw_running_hash_ += (raw_running_hash_ << 10);
4363 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4364}
4365
4366
4367uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004368 // Get the calculated raw hash value and do some more bit ops to distribute
4369 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004370 uint32_t result = raw_running_hash_;
4371 result += (result << 3);
4372 result ^= (result >> 11);
4373 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004374 if (result == 0) {
4375 result = 27;
4376 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004377 return result;
4378}
4379
4380
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004381template <typename schar>
4382uint32_t HashSequentialString(const schar* chars, int length) {
4383 StringHasher hasher(length);
4384 if (!hasher.has_trivial_hash()) {
4385 int i;
4386 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4387 hasher.AddCharacter(chars[i]);
4388 }
4389 for (; i < length; i++) {
4390 hasher.AddCharacterNoIndex(chars[i]);
4391 }
4392 }
4393 return hasher.GetHashField();
4394}
4395
4396
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004397bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004398 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004399 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4400 return false;
4401 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004402 return SlowAsArrayIndex(index);
4403}
4404
4405
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004406Object* JSReceiver::GetPrototype() {
4407 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004408}
4409
4410
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004411bool JSReceiver::HasProperty(String* name) {
4412 if (IsJSProxy()) {
4413 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4414 }
4415 return GetPropertyAttribute(name) != ABSENT;
4416}
4417
4418
4419bool JSReceiver::HasLocalProperty(String* name) {
4420 if (IsJSProxy()) {
4421 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4422 }
4423 return GetLocalPropertyAttribute(name) != ABSENT;
4424}
4425
4426
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004427PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004428 return GetPropertyAttributeWithReceiver(this, key);
4429}
4430
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004431// TODO(504): this may be useful in other places too where JSGlobalProxy
4432// is used.
4433Object* JSObject::BypassGlobalProxy() {
4434 if (IsJSGlobalProxy()) {
4435 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004436 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004437 ASSERT(proto->IsJSGlobalObject());
4438 return proto;
4439 }
4440 return this;
4441}
4442
4443
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004444MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4445 return IsJSProxy()
4446 ? JSProxy::cast(this)->GetIdentityHash(flag)
4447 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004448}
4449
4450
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004451bool JSReceiver::HasElement(uint32_t index) {
4452 if (IsJSProxy()) {
4453 return JSProxy::cast(this)->HasElementWithHandler(index);
4454 }
4455 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004456}
4457
4458
4459bool AccessorInfo::all_can_read() {
4460 return BooleanBit::get(flag(), kAllCanReadBit);
4461}
4462
4463
4464void AccessorInfo::set_all_can_read(bool value) {
4465 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4466}
4467
4468
4469bool AccessorInfo::all_can_write() {
4470 return BooleanBit::get(flag(), kAllCanWriteBit);
4471}
4472
4473
4474void AccessorInfo::set_all_can_write(bool value) {
4475 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4476}
4477
4478
ager@chromium.org870a0b62008-11-04 11:43:05 +00004479bool AccessorInfo::prohibits_overwriting() {
4480 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4481}
4482
4483
4484void AccessorInfo::set_prohibits_overwriting(bool value) {
4485 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4486}
4487
4488
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004489PropertyAttributes AccessorInfo::property_attributes() {
4490 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4491}
4492
4493
4494void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004495 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004496}
4497
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004498
4499template<typename Shape, typename Key>
4500void Dictionary<Shape, Key>::SetEntry(int entry,
4501 Object* key,
4502 Object* value) {
4503 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4504}
4505
4506
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004507template<typename Shape, typename Key>
4508void Dictionary<Shape, Key>::SetEntry(int entry,
4509 Object* key,
4510 Object* value,
4511 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004512 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004513 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004514 AssertNoAllocation no_gc;
4515 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004516 FixedArray::set(index, key, mode);
4517 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004518 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004519}
4520
4521
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004522bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4523 ASSERT(other->IsNumber());
4524 return key == static_cast<uint32_t>(other->Number());
4525}
4526
4527
4528uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4529 return ComputeIntegerHash(key);
4530}
4531
4532
4533uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4534 ASSERT(other->IsNumber());
4535 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4536}
4537
4538
4539MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4540 return Isolate::Current()->heap()->NumberFromUint32(key);
4541}
4542
4543
4544bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4545 // We know that all entries in a hash table had their hash keys created.
4546 // Use that knowledge to have fast failure.
4547 if (key->Hash() != String::cast(other)->Hash()) return false;
4548 return key->Equals(String::cast(other));
4549}
4550
4551
4552uint32_t StringDictionaryShape::Hash(String* key) {
4553 return key->Hash();
4554}
4555
4556
4557uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4558 return String::cast(other)->Hash();
4559}
4560
4561
4562MaybeObject* StringDictionaryShape::AsObject(String* key) {
4563 return key;
4564}
4565
4566
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004567template <int entrysize>
4568bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4569 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004570}
4571
4572
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004573template <int entrysize>
4574uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004575 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4576 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004577}
4578
4579
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004580template <int entrysize>
4581uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4582 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004583 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4584 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004585}
4586
4587
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004588template <int entrysize>
4589MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004590 return key;
4591}
4592
4593
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004594void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004595 // No write barrier is needed since empty_fixed_array is not in new space.
4596 // Please note this function is used during marking:
4597 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004598 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4599 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004600}
4601
4602
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004603void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004604 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004605 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004606 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4607 if (elts->length() < required_size) {
4608 // Doubling in size would be overkill, but leave some slack to avoid
4609 // constantly growing.
4610 Expand(required_size + (required_size >> 3));
4611 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004612 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004613 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4614 // Expand will allocate a new backing store in new space even if the size
4615 // we asked for isn't larger than what we had before.
4616 Expand(required_size);
4617 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004618}
4619
4620
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004621void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004622 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004623 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4624}
4625
4626
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004627MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4628 MaybeObject* maybe_result = EnsureCanContainElements(
4629 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4630 if (maybe_result->IsFailure()) return maybe_result;
4631 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4632 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4633 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4634 ((GetElementsKind() == FAST_ELEMENTS) ||
4635 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4636 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004637 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004638 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004639 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004640}
4641
4642
lrn@chromium.org303ada72010-10-27 09:33:13 +00004643MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004644 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004645 return GetHeap()->CopyFixedArray(this);
4646}
4647
4648
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004649MaybeObject* FixedDoubleArray::Copy() {
4650 if (length() == 0) return this;
4651 return GetHeap()->CopyFixedDoubleArray(this);
4652}
4653
4654
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004655Relocatable::Relocatable(Isolate* isolate) {
4656 ASSERT(isolate == Isolate::Current());
4657 isolate_ = isolate;
4658 prev_ = isolate->relocatable_top();
4659 isolate->set_relocatable_top(this);
4660}
4661
4662
4663Relocatable::~Relocatable() {
4664 ASSERT(isolate_ == Isolate::Current());
4665 ASSERT_EQ(isolate_->relocatable_top(), this);
4666 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004667}
4668
4669
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004670int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4671 return map->instance_size();
4672}
4673
4674
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004675void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004676 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004677 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004678}
4679
4680
4681template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004682void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004683 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004684 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004685}
4686
4687
4688void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4689 typedef v8::String::ExternalAsciiStringResource Resource;
4690 v->VisitExternalAsciiString(
4691 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4692}
4693
4694
4695template<typename StaticVisitor>
4696void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4697 typedef v8::String::ExternalAsciiStringResource Resource;
4698 StaticVisitor::VisitExternalAsciiString(
4699 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4700}
4701
4702
4703void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4704 typedef v8::String::ExternalStringResource Resource;
4705 v->VisitExternalTwoByteString(
4706 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4707}
4708
4709
4710template<typename StaticVisitor>
4711void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4712 typedef v8::String::ExternalStringResource Resource;
4713 StaticVisitor::VisitExternalTwoByteString(
4714 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4715}
4716
4717#define SLOT_ADDR(obj, offset) \
4718 reinterpret_cast<Object**>((obj)->address() + offset)
4719
4720template<int start_offset, int end_offset, int size>
4721void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4722 HeapObject* obj,
4723 ObjectVisitor* v) {
4724 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4725}
4726
4727
4728template<int start_offset>
4729void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4730 int object_size,
4731 ObjectVisitor* v) {
4732 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4733}
4734
4735#undef SLOT_ADDR
4736
4737
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004738#undef CAST_ACCESSOR
4739#undef INT_ACCESSORS
4740#undef SMI_ACCESSORS
4741#undef ACCESSORS
4742#undef FIELD_ADDR
4743#undef READ_FIELD
4744#undef WRITE_FIELD
4745#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004746#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004747#undef READ_MEMADDR_FIELD
4748#undef WRITE_MEMADDR_FIELD
4749#undef READ_DOUBLE_FIELD
4750#undef WRITE_DOUBLE_FIELD
4751#undef READ_INT_FIELD
4752#undef WRITE_INT_FIELD
4753#undef READ_SHORT_FIELD
4754#undef WRITE_SHORT_FIELD
4755#undef READ_BYTE_FIELD
4756#undef WRITE_BYTE_FIELD
4757
4758
4759} } // namespace v8::internal
4760
4761#endif // V8_OBJECTS_INL_H_