blob: 99a0bb08d29be6f9a4f80cd244e623dea297f3c8 [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);
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001222 ASSERT(current->IsSmi() || current->IsTheHole());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001223 }
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
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001293void JSObject::set_map_and_elements(Map* new_map,
1294 FixedArrayBase* value,
1295 WriteBarrierMode mode) {
1296 ASSERT(value->HasValidElements());
1297#ifdef DEBUG
1298 ValidateSmiOnlyElements();
1299#endif
1300 if (new_map != NULL) {
1301 if (mode == UPDATE_WRITE_BARRIER) {
1302 set_map(new_map);
1303 } else {
1304 ASSERT(mode == SKIP_WRITE_BARRIER);
1305 set_map_no_write_barrier(new_map);
1306 }
1307 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001308 ASSERT((map()->has_fast_elements() ||
1309 map()->has_fast_smi_only_elements()) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001310 (value->map() == GetHeap()->fixed_array_map() ||
1311 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001312 ASSERT(map()->has_fast_double_elements() ==
1313 value->IsFixedDoubleArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001314 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001315 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001316}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001317
1318
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001319void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1320 set_map_and_elements(NULL, value, mode);
1321}
1322
1323
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001324void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001325 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1326 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001327}
1328
1329
1330void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001331 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001332 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1333 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001334}
1335
1336
lrn@chromium.org303ada72010-10-27 09:33:13 +00001337MaybeObject* JSObject::ResetElements() {
1338 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001339 ElementsKind elements_kind = FLAG_smi_only_arrays
1340 ? FAST_SMI_ONLY_ELEMENTS
1341 : FAST_ELEMENTS;
1342 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind);
1343 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001344 set_map(Map::cast(obj));
1345 initialize_elements();
1346 return this;
1347}
1348
1349
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001350ACCESSORS(Oddball, to_string, String, kToStringOffset)
1351ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1352
1353
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001354byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001355 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001356}
1357
1358
1359void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001360 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001361}
1362
1363
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001364Object* JSGlobalPropertyCell::value() {
1365 return READ_FIELD(this, kValueOffset);
1366}
1367
1368
1369void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1370 // The write barrier is not used for global property cells.
1371 ASSERT(!val->IsJSGlobalPropertyCell());
1372 WRITE_FIELD(this, kValueOffset, val);
1373}
1374
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001375
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001376int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001377 InstanceType type = map()->instance_type();
1378 // Check for the most common kind of JavaScript object before
1379 // falling into the generic switch. This speeds up the internal
1380 // field operations considerably on average.
1381 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1382 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001383 case JS_GLOBAL_PROXY_TYPE:
1384 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001385 case JS_GLOBAL_OBJECT_TYPE:
1386 return JSGlobalObject::kSize;
1387 case JS_BUILTINS_OBJECT_TYPE:
1388 return JSBuiltinsObject::kSize;
1389 case JS_FUNCTION_TYPE:
1390 return JSFunction::kSize;
1391 case JS_VALUE_TYPE:
1392 return JSValue::kSize;
1393 case JS_ARRAY_TYPE:
1394 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001395 case JS_WEAK_MAP_TYPE:
1396 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001397 case JS_REGEXP_TYPE:
1398 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001399 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001400 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001401 case JS_MESSAGE_OBJECT_TYPE:
1402 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001403 default:
1404 UNREACHABLE();
1405 return 0;
1406 }
1407}
1408
1409
1410int JSObject::GetInternalFieldCount() {
1411 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001412 // Make sure to adjust for the number of in-object properties. These
1413 // properties do contribute to the size, but are not internal fields.
1414 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1415 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001416}
1417
1418
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001419int JSObject::GetInternalFieldOffset(int index) {
1420 ASSERT(index < GetInternalFieldCount() && index >= 0);
1421 return GetHeaderSize() + (kPointerSize * index);
1422}
1423
1424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001425Object* JSObject::GetInternalField(int index) {
1426 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001427 // Internal objects do follow immediately after the header, whereas in-object
1428 // properties are at the end of the object. Therefore there is no need
1429 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001430 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1431}
1432
1433
1434void JSObject::SetInternalField(int index, Object* value) {
1435 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001436 // Internal objects do follow immediately after the header, whereas in-object
1437 // properties are at the end of the object. Therefore there is no need
1438 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001439 int offset = GetHeaderSize() + (kPointerSize * index);
1440 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001441 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001442}
1443
1444
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001445void JSObject::SetInternalField(int index, Smi* value) {
1446 ASSERT(index < GetInternalFieldCount() && index >= 0);
1447 // Internal objects do follow immediately after the header, whereas in-object
1448 // properties are at the end of the object. Therefore there is no need
1449 // to adjust the index here.
1450 int offset = GetHeaderSize() + (kPointerSize * index);
1451 WRITE_FIELD(this, offset, value);
1452}
1453
1454
ager@chromium.org7c537e22008-10-16 08:43:32 +00001455// Access fast-case object properties at index. The use of these routines
1456// is needed to correctly distinguish between properties stored in-object and
1457// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001458Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001459 // Adjust for the number of properties stored in the object.
1460 index -= map()->inobject_properties();
1461 if (index < 0) {
1462 int offset = map()->instance_size() + (index * kPointerSize);
1463 return READ_FIELD(this, offset);
1464 } else {
1465 ASSERT(index < properties()->length());
1466 return properties()->get(index);
1467 }
1468}
1469
1470
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001471Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001472 // Adjust for the number of properties stored in the object.
1473 index -= map()->inobject_properties();
1474 if (index < 0) {
1475 int offset = map()->instance_size() + (index * kPointerSize);
1476 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001477 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001478 } else {
1479 ASSERT(index < properties()->length());
1480 properties()->set(index, value);
1481 }
1482 return value;
1483}
1484
1485
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001486int JSObject::GetInObjectPropertyOffset(int index) {
1487 // Adjust for the number of properties stored in the object.
1488 index -= map()->inobject_properties();
1489 ASSERT(index < 0);
1490 return map()->instance_size() + (index * kPointerSize);
1491}
1492
1493
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001494Object* JSObject::InObjectPropertyAt(int index) {
1495 // Adjust for the number of properties stored in the object.
1496 index -= map()->inobject_properties();
1497 ASSERT(index < 0);
1498 int offset = map()->instance_size() + (index * kPointerSize);
1499 return READ_FIELD(this, offset);
1500}
1501
1502
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001503Object* JSObject::InObjectPropertyAtPut(int index,
1504 Object* value,
1505 WriteBarrierMode mode) {
1506 // Adjust for the number of properties stored in the object.
1507 index -= map()->inobject_properties();
1508 ASSERT(index < 0);
1509 int offset = map()->instance_size() + (index * kPointerSize);
1510 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001511 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001512 return value;
1513}
1514
1515
1516
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001517void JSObject::InitializeBody(Map* map,
1518 Object* pre_allocated_value,
1519 Object* filler_value) {
1520 ASSERT(!filler_value->IsHeapObject() ||
1521 !GetHeap()->InNewSpace(filler_value));
1522 ASSERT(!pre_allocated_value->IsHeapObject() ||
1523 !GetHeap()->InNewSpace(pre_allocated_value));
1524 int size = map->instance_size();
1525 int offset = kHeaderSize;
1526 if (filler_value != pre_allocated_value) {
1527 int pre_allocated = map->pre_allocated_property_fields();
1528 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1529 for (int i = 0; i < pre_allocated; i++) {
1530 WRITE_FIELD(this, offset, pre_allocated_value);
1531 offset += kPointerSize;
1532 }
1533 }
1534 while (offset < size) {
1535 WRITE_FIELD(this, offset, filler_value);
1536 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001537 }
1538}
1539
1540
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001541bool JSObject::HasFastProperties() {
1542 return !properties()->IsDictionary();
1543}
1544
1545
1546int JSObject::MaxFastProperties() {
1547 // Allow extra fast properties if the object has more than
1548 // kMaxFastProperties in-object properties. When this is the case,
1549 // it is very unlikely that the object is being used as a dictionary
1550 // and there is a good chance that allowing more map transitions
1551 // will be worth it.
1552 return Max(map()->inobject_properties(), kMaxFastProperties);
1553}
1554
1555
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001556void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001557 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001558 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001559 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001560 }
1561}
1562
1563
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001564bool Object::ToArrayIndex(uint32_t* index) {
1565 if (IsSmi()) {
1566 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001567 if (value < 0) return false;
1568 *index = value;
1569 return true;
1570 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001571 if (IsHeapNumber()) {
1572 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001573 uint32_t uint_value = static_cast<uint32_t>(value);
1574 if (value == static_cast<double>(uint_value)) {
1575 *index = uint_value;
1576 return true;
1577 }
1578 }
1579 return false;
1580}
1581
1582
1583bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1584 if (!this->IsJSValue()) return false;
1585
1586 JSValue* js_value = JSValue::cast(this);
1587 if (!js_value->value()->IsString()) return false;
1588
1589 String* str = String::cast(js_value->value());
1590 if (index >= (uint32_t)str->length()) return false;
1591
1592 return true;
1593}
1594
1595
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001596FixedArrayBase* FixedArrayBase::cast(Object* object) {
1597 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1598 return reinterpret_cast<FixedArrayBase*>(object);
1599}
1600
1601
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001602Object* FixedArray::get(int index) {
1603 ASSERT(index >= 0 && index < this->length());
1604 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1605}
1606
1607
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001608void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001609 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001610 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001611 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1612 int offset = kHeaderSize + index * kPointerSize;
1613 WRITE_FIELD(this, offset, value);
1614}
1615
1616
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001617void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001618 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001619 ASSERT(index >= 0 && index < this->length());
1620 int offset = kHeaderSize + index * kPointerSize;
1621 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001622 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001623}
1624
1625
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001626inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1627 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1628}
1629
1630
1631inline double FixedDoubleArray::hole_nan_as_double() {
1632 return BitCast<double, uint64_t>(kHoleNanInt64);
1633}
1634
1635
1636inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1637 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1638 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1639 return OS::nan_value();
1640}
1641
1642
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001643double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001644 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1645 map() != HEAP->fixed_array_map());
1646 ASSERT(index >= 0 && index < this->length());
1647 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1648 ASSERT(!is_the_hole_nan(result));
1649 return result;
1650}
1651
1652
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001653MaybeObject* FixedDoubleArray::get(int index) {
1654 if (is_the_hole(index)) {
1655 return GetHeap()->the_hole_value();
1656 } else {
1657 return GetHeap()->NumberFromDouble(get_scalar(index));
1658 }
1659}
1660
1661
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001662void FixedDoubleArray::set(int index, double value) {
1663 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1664 map() != HEAP->fixed_array_map());
1665 int offset = kHeaderSize + index * kDoubleSize;
1666 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1667 WRITE_DOUBLE_FIELD(this, offset, value);
1668}
1669
1670
1671void FixedDoubleArray::set_the_hole(int index) {
1672 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1673 map() != HEAP->fixed_array_map());
1674 int offset = kHeaderSize + index * kDoubleSize;
1675 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1676}
1677
1678
1679bool FixedDoubleArray::is_the_hole(int index) {
1680 int offset = kHeaderSize + index * kDoubleSize;
1681 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1682}
1683
1684
1685void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1686 int old_length = from->length();
1687 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001688 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1689 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1690 FIELD_ADDR(from, kHeaderSize),
1691 old_length * kDoubleSize);
1692 } else {
1693 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001694 if (from->is_the_hole(i)) {
1695 set_the_hole(i);
1696 } else {
1697 set(i, from->get_scalar(i));
1698 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001699 }
1700 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001701 int offset = kHeaderSize + old_length * kDoubleSize;
1702 for (int current = from->length(); current < length(); ++current) {
1703 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1704 offset += kDoubleSize;
1705 }
1706}
1707
1708
1709void FixedDoubleArray::Initialize(FixedArray* from) {
1710 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001711 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001712 for (int i = 0; i < old_length; i++) {
1713 Object* hole_or_object = from->get(i);
1714 if (hole_or_object->IsTheHole()) {
1715 set_the_hole(i);
1716 } else {
1717 set(i, hole_or_object->Number());
1718 }
1719 }
1720 int offset = kHeaderSize + old_length * kDoubleSize;
1721 for (int current = from->length(); current < length(); ++current) {
1722 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1723 offset += kDoubleSize;
1724 }
1725}
1726
1727
1728void FixedDoubleArray::Initialize(NumberDictionary* from) {
1729 int offset = kHeaderSize;
1730 for (int current = 0; current < length(); ++current) {
1731 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1732 offset += kDoubleSize;
1733 }
1734 for (int i = 0; i < from->Capacity(); i++) {
1735 Object* key = from->KeyAt(i);
1736 if (key->IsNumber()) {
1737 uint32_t entry = static_cast<uint32_t>(key->Number());
1738 set(entry, from->ValueAt(i)->Number());
1739 }
1740 }
1741}
1742
1743
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001744WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001745 Heap* heap = GetHeap();
1746 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1747 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001748 return UPDATE_WRITE_BARRIER;
1749}
1750
1751
1752void FixedArray::set(int index,
1753 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001754 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001755 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001756 ASSERT(index >= 0 && index < this->length());
1757 int offset = kHeaderSize + index * kPointerSize;
1758 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001759 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001760}
1761
1762
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001763void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1764 int index,
1765 Object* value) {
1766 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1767 ASSERT(index >= 0 && index < array->length());
1768 int offset = kHeaderSize + index * kPointerSize;
1769 WRITE_FIELD(array, offset, value);
1770 Heap* heap = array->GetHeap();
1771 if (heap->InNewSpace(value)) {
1772 heap->RecordWrite(array->address(), offset);
1773 }
1774}
1775
1776
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001777void FixedArray::NoWriteBarrierSet(FixedArray* array,
1778 int index,
1779 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001780 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001781 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001782 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001783 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1784}
1785
1786
1787void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001788 ASSERT(map() != HEAP->fixed_cow_array_map());
1789 set_undefined(GetHeap(), index);
1790}
1791
1792
1793void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001794 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001795 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001796 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001797 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798}
1799
1800
ager@chromium.org236ad962008-09-25 09:45:57 +00001801void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001802 set_null(GetHeap(), index);
1803}
1804
1805
1806void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001807 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001808 ASSERT(!heap->InNewSpace(heap->null_value()));
1809 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001810}
1811
1812
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001813void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001814 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001815 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001816 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1817 WRITE_FIELD(this,
1818 kHeaderSize + index * kPointerSize,
1819 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820}
1821
1822
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001823void FixedArray::set_unchecked(int index, Smi* value) {
1824 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1825 int offset = kHeaderSize + index * kPointerSize;
1826 WRITE_FIELD(this, offset, value);
1827}
1828
1829
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001830void FixedArray::set_unchecked(Heap* heap,
1831 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001832 Object* value,
1833 WriteBarrierMode mode) {
1834 int offset = kHeaderSize + index * kPointerSize;
1835 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001836 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001837}
1838
1839
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001840void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001841 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001842 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1843 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001844}
1845
1846
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001847Object** FixedArray::data_start() {
1848 return HeapObject::RawField(this, kHeaderSize);
1849}
1850
1851
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001852bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001853 ASSERT(this->IsSmi() ||
1854 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001855 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001856 return this->IsSmi() || length() <= kFirstIndex;
1857}
1858
1859
1860int DescriptorArray::bit_field3_storage() {
1861 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1862 return Smi::cast(storage)->value();
1863}
1864
1865void DescriptorArray::set_bit_field3_storage(int value) {
1866 ASSERT(!IsEmpty());
1867 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001868}
1869
1870
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001871void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1872 int first,
1873 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001874 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001875 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1876 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877}
1878
1879
1880int DescriptorArray::Search(String* name) {
1881 SLOW_ASSERT(IsSortedNoDuplicates());
1882
1883 // Check for empty descriptor array.
1884 int nof = number_of_descriptors();
1885 if (nof == 0) return kNotFound;
1886
1887 // Fast case: do linear search for small arrays.
1888 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001889 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001890 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001891 }
1892
1893 // Slow case: perform binary search.
1894 return BinarySearch(name, 0, nof - 1);
1895}
1896
1897
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001898int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001899 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001900 if (number == DescriptorLookupCache::kAbsent) {
1901 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001902 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001903 }
1904 return number;
1905}
1906
1907
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001908String* DescriptorArray::GetKey(int descriptor_number) {
1909 ASSERT(descriptor_number < number_of_descriptors());
1910 return String::cast(get(ToKeyIndex(descriptor_number)));
1911}
1912
1913
1914Object* DescriptorArray::GetValue(int descriptor_number) {
1915 ASSERT(descriptor_number < number_of_descriptors());
1916 return GetContentArray()->get(ToValueIndex(descriptor_number));
1917}
1918
1919
1920Smi* DescriptorArray::GetDetails(int descriptor_number) {
1921 ASSERT(descriptor_number < number_of_descriptors());
1922 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1923}
1924
1925
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001926PropertyType DescriptorArray::GetType(int descriptor_number) {
1927 ASSERT(descriptor_number < number_of_descriptors());
1928 return PropertyDetails(GetDetails(descriptor_number)).type();
1929}
1930
1931
1932int DescriptorArray::GetFieldIndex(int descriptor_number) {
1933 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1934}
1935
1936
1937JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1938 return JSFunction::cast(GetValue(descriptor_number));
1939}
1940
1941
1942Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1943 ASSERT(GetType(descriptor_number) == CALLBACKS);
1944 return GetValue(descriptor_number);
1945}
1946
1947
1948AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1949 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001950 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001951 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001952}
1953
1954
1955bool DescriptorArray::IsProperty(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001956 return IsRealProperty(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001957}
1958
1959
1960bool DescriptorArray::IsTransition(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001961 return IsTransitionType(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001962}
1963
1964
1965bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1966 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1967}
1968
1969
1970bool DescriptorArray::IsDontEnum(int descriptor_number) {
1971 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1972}
1973
1974
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001975void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1976 desc->Init(GetKey(descriptor_number),
1977 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001978 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001979}
1980
1981
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001982void DescriptorArray::Set(int descriptor_number,
1983 Descriptor* desc,
1984 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001985 // Range check.
1986 ASSERT(descriptor_number < number_of_descriptors());
1987
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001988 NoIncrementalWriteBarrierSet(this,
1989 ToKeyIndex(descriptor_number),
1990 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001991 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001992 NoIncrementalWriteBarrierSet(content_array,
1993 ToValueIndex(descriptor_number),
1994 desc->GetValue());
1995 NoIncrementalWriteBarrierSet(content_array,
1996 ToDetailsIndex(descriptor_number),
1997 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001998}
1999
2000
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002001void DescriptorArray::CopyFrom(int index,
2002 DescriptorArray* src,
2003 int src_index,
2004 const WhitenessWitness& witness) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002005 Descriptor desc;
2006 src->Get(src_index, &desc);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002007 Set(index, &desc, witness);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002008}
2009
2010
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002011void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2012 int first, int second) {
2013 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002014 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002015 NoIncrementalWriteBarrierSwap(content_array,
2016 ToValueIndex(first),
2017 ToValueIndex(second));
2018 NoIncrementalWriteBarrierSwap(content_array,
2019 ToDetailsIndex(first),
2020 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002021}
2022
2023
2024DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2025 : marking_(array->GetHeap()->incremental_marking()) {
2026 marking_->EnterNoMarkingScope();
2027 if (array->number_of_descriptors() > 0) {
2028 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2029 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2030 }
2031}
2032
2033
2034DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2035 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002036}
2037
2038
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002039template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002040int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2041 const int kMinCapacity = 32;
2042 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2043 if (capacity < kMinCapacity) {
2044 capacity = kMinCapacity; // Guarantee min capacity.
2045 }
2046 return capacity;
2047}
2048
2049
2050template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002051int HashTable<Shape, Key>::FindEntry(Key key) {
2052 return FindEntry(GetIsolate(), key);
2053}
2054
2055
2056// Find entry for key otherwise return kNotFound.
2057template<typename Shape, typename Key>
2058int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2059 uint32_t capacity = Capacity();
2060 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
2061 uint32_t count = 1;
2062 // EnsureCapacity will guarantee the hash table is never full.
2063 while (true) {
2064 Object* element = KeyAt(entry);
2065 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002066 if (element != isolate->heap()->the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002067 Shape::IsMatch(key, element)) return entry;
2068 entry = NextProbe(entry, count++, capacity);
2069 }
2070 return kNotFound;
2071}
2072
2073
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002074bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002075 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002076 if (!max_index_object->IsSmi()) return false;
2077 return 0 !=
2078 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2079}
2080
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002081uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002082 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002083 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002084 if (!max_index_object->IsSmi()) return 0;
2085 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2086 return value >> kRequiresSlowElementsTagSize;
2087}
2088
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002089void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002090 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002091}
2092
2093
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002094// ------------------------------------
2095// Cast operations
2096
2097
2098CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002099CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002100CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002101CAST_ACCESSOR(DeoptimizationInputData)
2102CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002103CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002104CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002105CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002106CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002107CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002108CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002109CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002110CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002111CAST_ACCESSOR(String)
2112CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002113CAST_ACCESSOR(SeqAsciiString)
2114CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002115CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002116CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117CAST_ACCESSOR(ExternalString)
2118CAST_ACCESSOR(ExternalAsciiString)
2119CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002120CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002121CAST_ACCESSOR(JSObject)
2122CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002123CAST_ACCESSOR(HeapObject)
2124CAST_ACCESSOR(HeapNumber)
2125CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002126CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002127CAST_ACCESSOR(SharedFunctionInfo)
2128CAST_ACCESSOR(Map)
2129CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002130CAST_ACCESSOR(GlobalObject)
2131CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002132CAST_ACCESSOR(JSGlobalObject)
2133CAST_ACCESSOR(JSBuiltinsObject)
2134CAST_ACCESSOR(Code)
2135CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002136CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002137CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002138CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002139CAST_ACCESSOR(JSSet)
2140CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002141CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002142CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002143CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002144CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002145CAST_ACCESSOR(ExternalArray)
2146CAST_ACCESSOR(ExternalByteArray)
2147CAST_ACCESSOR(ExternalUnsignedByteArray)
2148CAST_ACCESSOR(ExternalShortArray)
2149CAST_ACCESSOR(ExternalUnsignedShortArray)
2150CAST_ACCESSOR(ExternalIntArray)
2151CAST_ACCESSOR(ExternalUnsignedIntArray)
2152CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002153CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002154CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002155CAST_ACCESSOR(Struct)
2156
2157
2158#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2159 STRUCT_LIST(MAKE_STRUCT_CAST)
2160#undef MAKE_STRUCT_CAST
2161
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002162
2163template <typename Shape, typename Key>
2164HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002165 ASSERT(obj->IsHashTable());
2166 return reinterpret_cast<HashTable*>(obj);
2167}
2168
2169
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002170SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002171SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002172
ager@chromium.orgac091b72010-05-05 07:34:42 +00002173SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002174
2175
2176uint32_t String::hash_field() {
2177 return READ_UINT32_FIELD(this, kHashFieldOffset);
2178}
2179
2180
2181void String::set_hash_field(uint32_t value) {
2182 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002183#if V8_HOST_ARCH_64_BIT
2184 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2185#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002186}
2187
2188
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002189bool String::Equals(String* other) {
2190 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002191 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2192 return false;
2193 }
2194 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002195}
2196
2197
lrn@chromium.org303ada72010-10-27 09:33:13 +00002198MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002199 if (!StringShape(this).IsCons()) return this;
2200 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002201 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002202 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002203}
2204
2205
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002206String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002207 MaybeObject* flat = TryFlatten(pretenure);
2208 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002209 if (!flat->ToObject(&successfully_flattened)) return this;
2210 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002211}
2212
2213
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002214uint16_t String::Get(int index) {
2215 ASSERT(index >= 0 && index < length());
2216 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002217 case kSeqStringTag | kAsciiStringTag:
2218 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2219 case kSeqStringTag | kTwoByteStringTag:
2220 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2221 case kConsStringTag | kAsciiStringTag:
2222 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002223 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002224 case kExternalStringTag | kAsciiStringTag:
2225 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2226 case kExternalStringTag | kTwoByteStringTag:
2227 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002228 case kSlicedStringTag | kAsciiStringTag:
2229 case kSlicedStringTag | kTwoByteStringTag:
2230 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002231 default:
2232 break;
2233 }
2234
2235 UNREACHABLE();
2236 return 0;
2237}
2238
2239
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002240void String::Set(int index, uint16_t value) {
2241 ASSERT(index >= 0 && index < length());
2242 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002243
ager@chromium.org5ec48922009-05-05 07:25:34 +00002244 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002245 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2246 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002247}
2248
2249
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002250bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002251 if (!StringShape(this).IsCons()) return true;
2252 return ConsString::cast(this)->second()->length() == 0;
2253}
2254
2255
2256String* String::GetUnderlying() {
2257 // Giving direct access to underlying string only makes sense if the
2258 // wrapping string is already flattened.
2259 ASSERT(this->IsFlat());
2260 ASSERT(StringShape(this).IsIndirect());
2261 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2262 const int kUnderlyingOffset = SlicedString::kParentOffset;
2263 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002264}
2265
2266
ager@chromium.org7c537e22008-10-16 08:43:32 +00002267uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002268 ASSERT(index >= 0 && index < length());
2269 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2270}
2271
2272
ager@chromium.org7c537e22008-10-16 08:43:32 +00002273void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002274 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2275 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2276 static_cast<byte>(value));
2277}
2278
2279
ager@chromium.org7c537e22008-10-16 08:43:32 +00002280Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002281 return FIELD_ADDR(this, kHeaderSize);
2282}
2283
2284
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002285char* SeqAsciiString::GetChars() {
2286 return reinterpret_cast<char*>(GetCharsAddress());
2287}
2288
2289
ager@chromium.org7c537e22008-10-16 08:43:32 +00002290Address SeqTwoByteString::GetCharsAddress() {
2291 return FIELD_ADDR(this, kHeaderSize);
2292}
2293
2294
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002295uc16* SeqTwoByteString::GetChars() {
2296 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2297}
2298
2299
ager@chromium.org7c537e22008-10-16 08:43:32 +00002300uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002301 ASSERT(index >= 0 && index < length());
2302 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2303}
2304
2305
ager@chromium.org7c537e22008-10-16 08:43:32 +00002306void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002307 ASSERT(index >= 0 && index < length());
2308 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2309}
2310
2311
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002312int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002313 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002314}
2315
2316
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002317int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002318 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002319}
2320
2321
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002322String* SlicedString::parent() {
2323 return String::cast(READ_FIELD(this, kParentOffset));
2324}
2325
2326
2327void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002328 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002329 WRITE_FIELD(this, kParentOffset, parent);
2330}
2331
2332
2333SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2334
2335
ager@chromium.org870a0b62008-11-04 11:43:05 +00002336String* ConsString::first() {
2337 return String::cast(READ_FIELD(this, kFirstOffset));
2338}
2339
2340
2341Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002342 return READ_FIELD(this, kFirstOffset);
2343}
2344
2345
ager@chromium.org870a0b62008-11-04 11:43:05 +00002346void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002347 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002348 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002349}
2350
2351
ager@chromium.org870a0b62008-11-04 11:43:05 +00002352String* ConsString::second() {
2353 return String::cast(READ_FIELD(this, kSecondOffset));
2354}
2355
2356
2357Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002358 return READ_FIELD(this, kSecondOffset);
2359}
2360
2361
ager@chromium.org870a0b62008-11-04 11:43:05 +00002362void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002363 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002364 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002365}
2366
2367
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002368bool ExternalString::is_short() {
2369 InstanceType type = map()->instance_type();
2370 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002371}
2372
2373
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002374const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002375 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2376}
2377
2378
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002379void ExternalAsciiString::update_data_cache() {
2380 if (is_short()) return;
2381 const char** data_field =
2382 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2383 *data_field = resource()->data();
2384}
2385
2386
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002387void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002388 const ExternalAsciiString::Resource* resource) {
2389 *reinterpret_cast<const Resource**>(
2390 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002391 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002392}
2393
2394
2395const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002396 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002397}
2398
2399
2400uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2401 ASSERT(index >= 0 && index < length());
2402 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002403}
2404
2405
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002406const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002407 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2408}
2409
2410
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002411void ExternalTwoByteString::update_data_cache() {
2412 if (is_short()) return;
2413 const uint16_t** data_field =
2414 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2415 *data_field = resource()->data();
2416}
2417
2418
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002419void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002420 const ExternalTwoByteString::Resource* resource) {
2421 *reinterpret_cast<const Resource**>(
2422 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002423 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002424}
2425
2426
2427const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002428 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002429}
2430
2431
2432uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2433 ASSERT(index >= 0 && index < length());
2434 return GetChars()[index];
2435}
2436
2437
2438const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2439 unsigned start) {
2440 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002441}
2442
2443
ager@chromium.orgac091b72010-05-05 07:34:42 +00002444void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002445 set_finger_index(kEntriesIndex);
2446 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002447}
2448
2449
2450void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002451 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002452 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002453 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002454 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002455 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002456 MakeZeroSize();
2457}
2458
2459
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002460int JSFunctionResultCache::size() {
2461 return Smi::cast(get(kCacheSizeIndex))->value();
2462}
2463
2464
2465void JSFunctionResultCache::set_size(int size) {
2466 set(kCacheSizeIndex, Smi::FromInt(size));
2467}
2468
2469
2470int JSFunctionResultCache::finger_index() {
2471 return Smi::cast(get(kFingerIndex))->value();
2472}
2473
2474
2475void JSFunctionResultCache::set_finger_index(int finger_index) {
2476 set(kFingerIndex, Smi::FromInt(finger_index));
2477}
2478
2479
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002480byte ByteArray::get(int index) {
2481 ASSERT(index >= 0 && index < this->length());
2482 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2483}
2484
2485
2486void ByteArray::set(int index, byte value) {
2487 ASSERT(index >= 0 && index < this->length());
2488 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2489}
2490
2491
2492int ByteArray::get_int(int index) {
2493 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2494 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2495}
2496
2497
2498ByteArray* ByteArray::FromDataStartAddress(Address address) {
2499 ASSERT_TAG_ALIGNED(address);
2500 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2501}
2502
2503
2504Address ByteArray::GetDataStartAddress() {
2505 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2506}
2507
2508
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002509uint8_t* ExternalPixelArray::external_pixel_pointer() {
2510 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002511}
2512
2513
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002514uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002515 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002516 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002517 return ptr[index];
2518}
2519
2520
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002521MaybeObject* ExternalPixelArray::get(int index) {
2522 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2523}
2524
2525
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002526void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002527 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002528 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002529 ptr[index] = value;
2530}
2531
2532
ager@chromium.org3811b432009-10-28 14:53:37 +00002533void* ExternalArray::external_pointer() {
2534 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2535 return reinterpret_cast<void*>(ptr);
2536}
2537
2538
2539void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2540 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2541 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2542}
2543
2544
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002545int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002546 ASSERT((index >= 0) && (index < this->length()));
2547 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2548 return ptr[index];
2549}
2550
2551
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002552MaybeObject* ExternalByteArray::get(int index) {
2553 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2554}
2555
2556
ager@chromium.org3811b432009-10-28 14:53:37 +00002557void ExternalByteArray::set(int index, int8_t value) {
2558 ASSERT((index >= 0) && (index < this->length()));
2559 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2560 ptr[index] = value;
2561}
2562
2563
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002564uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002565 ASSERT((index >= 0) && (index < this->length()));
2566 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2567 return ptr[index];
2568}
2569
2570
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002571MaybeObject* ExternalUnsignedByteArray::get(int index) {
2572 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2573}
2574
2575
ager@chromium.org3811b432009-10-28 14:53:37 +00002576void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2577 ASSERT((index >= 0) && (index < this->length()));
2578 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2579 ptr[index] = value;
2580}
2581
2582
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002583int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002584 ASSERT((index >= 0) && (index < this->length()));
2585 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2586 return ptr[index];
2587}
2588
2589
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002590MaybeObject* ExternalShortArray::get(int index) {
2591 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2592}
2593
2594
ager@chromium.org3811b432009-10-28 14:53:37 +00002595void ExternalShortArray::set(int index, int16_t value) {
2596 ASSERT((index >= 0) && (index < this->length()));
2597 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2598 ptr[index] = value;
2599}
2600
2601
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002602uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002603 ASSERT((index >= 0) && (index < this->length()));
2604 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2605 return ptr[index];
2606}
2607
2608
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002609MaybeObject* ExternalUnsignedShortArray::get(int index) {
2610 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2611}
2612
2613
ager@chromium.org3811b432009-10-28 14:53:37 +00002614void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2615 ASSERT((index >= 0) && (index < this->length()));
2616 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2617 ptr[index] = value;
2618}
2619
2620
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002621int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002622 ASSERT((index >= 0) && (index < this->length()));
2623 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2624 return ptr[index];
2625}
2626
2627
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002628MaybeObject* ExternalIntArray::get(int index) {
2629 return GetHeap()->NumberFromInt32(get_scalar(index));
2630}
2631
2632
ager@chromium.org3811b432009-10-28 14:53:37 +00002633void ExternalIntArray::set(int index, int32_t value) {
2634 ASSERT((index >= 0) && (index < this->length()));
2635 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2636 ptr[index] = value;
2637}
2638
2639
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002640uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002641 ASSERT((index >= 0) && (index < this->length()));
2642 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2643 return ptr[index];
2644}
2645
2646
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002647MaybeObject* ExternalUnsignedIntArray::get(int index) {
2648 return GetHeap()->NumberFromUint32(get_scalar(index));
2649}
2650
2651
ager@chromium.org3811b432009-10-28 14:53:37 +00002652void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2653 ASSERT((index >= 0) && (index < this->length()));
2654 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2655 ptr[index] = value;
2656}
2657
2658
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002659float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002660 ASSERT((index >= 0) && (index < this->length()));
2661 float* ptr = static_cast<float*>(external_pointer());
2662 return ptr[index];
2663}
2664
2665
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002666MaybeObject* ExternalFloatArray::get(int index) {
2667 return GetHeap()->NumberFromDouble(get_scalar(index));
2668}
2669
2670
ager@chromium.org3811b432009-10-28 14:53:37 +00002671void ExternalFloatArray::set(int index, float value) {
2672 ASSERT((index >= 0) && (index < this->length()));
2673 float* ptr = static_cast<float*>(external_pointer());
2674 ptr[index] = value;
2675}
2676
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002677
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002678double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002679 ASSERT((index >= 0) && (index < this->length()));
2680 double* ptr = static_cast<double*>(external_pointer());
2681 return ptr[index];
2682}
2683
2684
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002685MaybeObject* ExternalDoubleArray::get(int index) {
2686 return GetHeap()->NumberFromDouble(get_scalar(index));
2687}
2688
2689
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002690void ExternalDoubleArray::set(int index, double value) {
2691 ASSERT((index >= 0) && (index < this->length()));
2692 double* ptr = static_cast<double*>(external_pointer());
2693 ptr[index] = value;
2694}
2695
2696
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002697int Map::visitor_id() {
2698 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2699}
2700
2701
2702void Map::set_visitor_id(int id) {
2703 ASSERT(0 <= id && id < 256);
2704 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2705}
2706
ager@chromium.org3811b432009-10-28 14:53:37 +00002707
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002708int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002709 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2710}
2711
2712
2713int Map::inobject_properties() {
2714 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002715}
2716
2717
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002718int Map::pre_allocated_property_fields() {
2719 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2720}
2721
2722
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002723int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002724 int instance_size = map->instance_size();
2725 if (instance_size != kVariableSizeSentinel) return instance_size;
2726 // We can ignore the "symbol" bit becase it is only set for symbols
2727 // and implies a string type.
2728 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002729 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002730 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002731 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002732 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002733 if (instance_type == ASCII_STRING_TYPE) {
2734 return SeqAsciiString::SizeFor(
2735 reinterpret_cast<SeqAsciiString*>(this)->length());
2736 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002737 if (instance_type == BYTE_ARRAY_TYPE) {
2738 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2739 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002740 if (instance_type == FREE_SPACE_TYPE) {
2741 return reinterpret_cast<FreeSpace*>(this)->size();
2742 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002743 if (instance_type == STRING_TYPE) {
2744 return SeqTwoByteString::SizeFor(
2745 reinterpret_cast<SeqTwoByteString*>(this)->length());
2746 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002747 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2748 return FixedDoubleArray::SizeFor(
2749 reinterpret_cast<FixedDoubleArray*>(this)->length());
2750 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002751 ASSERT(instance_type == CODE_TYPE);
2752 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002753}
2754
2755
2756void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002757 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002758 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002759 ASSERT(0 <= value && value < 256);
2760 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2761}
2762
2763
ager@chromium.org7c537e22008-10-16 08:43:32 +00002764void Map::set_inobject_properties(int value) {
2765 ASSERT(0 <= value && value < 256);
2766 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2767}
2768
2769
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002770void Map::set_pre_allocated_property_fields(int value) {
2771 ASSERT(0 <= value && value < 256);
2772 WRITE_BYTE_FIELD(this,
2773 kPreAllocatedPropertyFieldsOffset,
2774 static_cast<byte>(value));
2775}
2776
2777
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002778InstanceType Map::instance_type() {
2779 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2780}
2781
2782
2783void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002784 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2785}
2786
2787
2788int Map::unused_property_fields() {
2789 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2790}
2791
2792
2793void Map::set_unused_property_fields(int value) {
2794 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2795}
2796
2797
2798byte Map::bit_field() {
2799 return READ_BYTE_FIELD(this, kBitFieldOffset);
2800}
2801
2802
2803void Map::set_bit_field(byte value) {
2804 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2805}
2806
2807
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002808byte Map::bit_field2() {
2809 return READ_BYTE_FIELD(this, kBitField2Offset);
2810}
2811
2812
2813void Map::set_bit_field2(byte value) {
2814 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2815}
2816
2817
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002818void Map::set_non_instance_prototype(bool value) {
2819 if (value) {
2820 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2821 } else {
2822 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2823 }
2824}
2825
2826
2827bool Map::has_non_instance_prototype() {
2828 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2829}
2830
2831
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002832void Map::set_function_with_prototype(bool value) {
2833 if (value) {
2834 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2835 } else {
2836 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2837 }
2838}
2839
2840
2841bool Map::function_with_prototype() {
2842 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2843}
2844
2845
ager@chromium.org870a0b62008-11-04 11:43:05 +00002846void Map::set_is_access_check_needed(bool access_check_needed) {
2847 if (access_check_needed) {
2848 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2849 } else {
2850 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2851 }
2852}
2853
2854
2855bool Map::is_access_check_needed() {
2856 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2857}
2858
2859
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002860void Map::set_is_extensible(bool value) {
2861 if (value) {
2862 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2863 } else {
2864 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2865 }
2866}
2867
2868bool Map::is_extensible() {
2869 return ((1 << kIsExtensible) & bit_field2()) != 0;
2870}
2871
2872
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002873void Map::set_attached_to_shared_function_info(bool value) {
2874 if (value) {
2875 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2876 } else {
2877 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2878 }
2879}
2880
2881bool Map::attached_to_shared_function_info() {
2882 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2883}
2884
2885
2886void Map::set_is_shared(bool value) {
2887 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002888 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002889 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002890 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002891 }
2892}
2893
2894bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002895 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002896}
2897
2898
2899JSFunction* Map::unchecked_constructor() {
2900 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2901}
2902
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002903
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002904Code::Flags Code::flags() {
2905 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2906}
2907
2908
2909void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002910 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002911 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002912 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2913 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002914 ExtractArgumentsCountFromFlags(flags) >= 0);
2915 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2916}
2917
2918
2919Code::Kind Code::kind() {
2920 return ExtractKindFromFlags(flags());
2921}
2922
2923
kasper.lund7276f142008-07-30 08:49:36 +00002924InlineCacheState Code::ic_state() {
2925 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002926 // Only allow uninitialized or debugger states for non-IC code
2927 // objects. This is used in the debugger to determine whether or not
2928 // a call to code object has been replaced with a debug break call.
2929 ASSERT(is_inline_cache_stub() ||
2930 result == UNINITIALIZED ||
2931 result == DEBUG_BREAK ||
2932 result == DEBUG_PREPARE_STEP_IN);
2933 return result;
2934}
2935
2936
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002937Code::ExtraICState Code::extra_ic_state() {
2938 ASSERT(is_inline_cache_stub());
2939 return ExtractExtraICStateFromFlags(flags());
2940}
2941
2942
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002943PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002944 return ExtractTypeFromFlags(flags());
2945}
2946
2947
2948int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002949 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002950 return ExtractArgumentsCountFromFlags(flags());
2951}
2952
2953
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002954int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002955 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002956 kind() == UNARY_OP_IC ||
2957 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002958 kind() == COMPARE_IC ||
2959 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002960 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002961}
2962
2963
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002964void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002965 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002966 kind() == UNARY_OP_IC ||
2967 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002968 kind() == COMPARE_IC ||
2969 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002970 ASSERT(0 <= major && major < 256);
2971 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002972}
2973
2974
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002975bool Code::is_pregenerated() {
2976 return kind() == STUB && IsPregeneratedField::decode(flags());
2977}
2978
2979
2980void Code::set_is_pregenerated(bool value) {
2981 ASSERT(kind() == STUB);
2982 Flags f = flags();
2983 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2984 set_flags(f);
2985}
2986
2987
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002988bool Code::optimizable() {
2989 ASSERT(kind() == FUNCTION);
2990 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2991}
2992
2993
2994void Code::set_optimizable(bool value) {
2995 ASSERT(kind() == FUNCTION);
2996 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2997}
2998
2999
3000bool Code::has_deoptimization_support() {
3001 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003002 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3003 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003004}
3005
3006
3007void Code::set_has_deoptimization_support(bool value) {
3008 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003009 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3010 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3011 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3012}
3013
3014
3015bool Code::has_debug_break_slots() {
3016 ASSERT(kind() == FUNCTION);
3017 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3018 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3019}
3020
3021
3022void Code::set_has_debug_break_slots(bool value) {
3023 ASSERT(kind() == FUNCTION);
3024 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3025 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3026 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003027}
3028
3029
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003030bool Code::is_compiled_optimizable() {
3031 ASSERT(kind() == FUNCTION);
3032 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3033 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3034}
3035
3036
3037void Code::set_compiled_optimizable(bool value) {
3038 ASSERT(kind() == FUNCTION);
3039 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3040 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3041 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3042}
3043
3044
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003045int Code::allow_osr_at_loop_nesting_level() {
3046 ASSERT(kind() == FUNCTION);
3047 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3048}
3049
3050
3051void Code::set_allow_osr_at_loop_nesting_level(int level) {
3052 ASSERT(kind() == FUNCTION);
3053 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3054 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3055}
3056
3057
3058unsigned Code::stack_slots() {
3059 ASSERT(kind() == OPTIMIZED_FUNCTION);
3060 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3061}
3062
3063
3064void Code::set_stack_slots(unsigned slots) {
3065 ASSERT(kind() == OPTIMIZED_FUNCTION);
3066 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3067}
3068
3069
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003070unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003071 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003072 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003073}
3074
3075
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003076void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003077 ASSERT(kind() == OPTIMIZED_FUNCTION);
3078 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003079 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003080}
3081
3082
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003083unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003084 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003085 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003086}
3087
3088
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003089void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003090 ASSERT(kind() == FUNCTION);
3091 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003092 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003093}
3094
3095
3096CheckType Code::check_type() {
3097 ASSERT(is_call_stub() || is_keyed_call_stub());
3098 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3099 return static_cast<CheckType>(type);
3100}
3101
3102
3103void Code::set_check_type(CheckType value) {
3104 ASSERT(is_call_stub() || is_keyed_call_stub());
3105 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3106}
3107
3108
danno@chromium.org40cb8782011-05-25 07:58:50 +00003109byte Code::unary_op_type() {
3110 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003111 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3112}
3113
3114
danno@chromium.org40cb8782011-05-25 07:58:50 +00003115void Code::set_unary_op_type(byte value) {
3116 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003117 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3118}
3119
3120
danno@chromium.org40cb8782011-05-25 07:58:50 +00003121byte Code::binary_op_type() {
3122 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003123 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3124}
3125
3126
danno@chromium.org40cb8782011-05-25 07:58:50 +00003127void Code::set_binary_op_type(byte value) {
3128 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003129 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3130}
3131
3132
danno@chromium.org40cb8782011-05-25 07:58:50 +00003133byte Code::binary_op_result_type() {
3134 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003135 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3136}
3137
3138
danno@chromium.org40cb8782011-05-25 07:58:50 +00003139void Code::set_binary_op_result_type(byte value) {
3140 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003141 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3142}
3143
3144
3145byte Code::compare_state() {
3146 ASSERT(is_compare_ic_stub());
3147 return READ_BYTE_FIELD(this, kCompareStateOffset);
3148}
3149
3150
3151void Code::set_compare_state(byte value) {
3152 ASSERT(is_compare_ic_stub());
3153 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3154}
3155
3156
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003157byte Code::to_boolean_state() {
3158 ASSERT(is_to_boolean_ic_stub());
3159 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3160}
3161
3162
3163void Code::set_to_boolean_state(byte value) {
3164 ASSERT(is_to_boolean_ic_stub());
3165 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3166}
3167
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003168
3169bool Code::has_function_cache() {
3170 ASSERT(kind() == STUB);
3171 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3172}
3173
3174
3175void Code::set_has_function_cache(bool flag) {
3176 ASSERT(kind() == STUB);
3177 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3178}
3179
3180
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003181bool Code::is_inline_cache_stub() {
3182 Kind kind = this->kind();
3183 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3184}
3185
3186
3187Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003188 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003189 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003190 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003191 int argc,
3192 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003193 // Extra IC state is only allowed for call IC stubs or for store IC
3194 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003195 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003196 kind == CALL_IC ||
3197 kind == STORE_IC ||
3198 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003199 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003200 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003201 | ICStateField::encode(ic_state)
3202 | TypeField::encode(type)
3203 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003204 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003205 | CacheHolderField::encode(holder);
3206 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003207}
3208
3209
3210Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3211 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003212 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003213 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003214 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003215 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003216}
3217
3218
3219Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003220 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003221}
3222
3223
kasper.lund7276f142008-07-30 08:49:36 +00003224InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003225 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003226}
3227
3228
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003229Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003230 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003231}
3232
3233
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003234PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003235 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003236}
3237
3238
3239int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003240 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003241}
3242
3243
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003244InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003245 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003246}
3247
3248
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003249Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003250 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003251 return static_cast<Flags>(bits);
3252}
3253
3254
ager@chromium.org8bb60582008-12-11 12:02:20 +00003255Code* Code::GetCodeFromTargetAddress(Address address) {
3256 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3257 // GetCodeFromTargetAddress might be called when marking objects during mark
3258 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3259 // Code::cast. Code::cast does not work when the object's map is
3260 // marked.
3261 Code* result = reinterpret_cast<Code*>(code);
3262 return result;
3263}
3264
3265
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003266Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3267 return HeapObject::
3268 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3269}
3270
3271
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003272Object* Map::prototype() {
3273 return READ_FIELD(this, kPrototypeOffset);
3274}
3275
3276
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003277void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003278 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003279 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003280 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003281}
3282
3283
danno@chromium.org40cb8782011-05-25 07:58:50 +00003284DescriptorArray* Map::instance_descriptors() {
3285 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3286 if (object->IsSmi()) {
3287 return HEAP->empty_descriptor_array();
3288 } else {
3289 return DescriptorArray::cast(object);
3290 }
3291}
3292
3293
3294void Map::init_instance_descriptors() {
3295 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3296}
3297
3298
3299void Map::clear_instance_descriptors() {
3300 Object* object = READ_FIELD(this,
3301 kInstanceDescriptorsOrBitField3Offset);
3302 if (!object->IsSmi()) {
3303 WRITE_FIELD(
3304 this,
3305 kInstanceDescriptorsOrBitField3Offset,
3306 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3307 }
3308}
3309
3310
3311void Map::set_instance_descriptors(DescriptorArray* value,
3312 WriteBarrierMode mode) {
3313 Object* object = READ_FIELD(this,
3314 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003315 Heap* heap = GetHeap();
3316 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003317 clear_instance_descriptors();
3318 return;
3319 } else {
3320 if (object->IsSmi()) {
3321 value->set_bit_field3_storage(Smi::cast(object)->value());
3322 } else {
3323 value->set_bit_field3_storage(
3324 DescriptorArray::cast(object)->bit_field3_storage());
3325 }
3326 }
3327 ASSERT(!is_shared());
3328 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003329 CONDITIONAL_WRITE_BARRIER(
3330 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003331}
3332
3333
3334int Map::bit_field3() {
3335 Object* object = READ_FIELD(this,
3336 kInstanceDescriptorsOrBitField3Offset);
3337 if (object->IsSmi()) {
3338 return Smi::cast(object)->value();
3339 } else {
3340 return DescriptorArray::cast(object)->bit_field3_storage();
3341 }
3342}
3343
3344
3345void Map::set_bit_field3(int value) {
3346 ASSERT(Smi::IsValid(value));
3347 Object* object = READ_FIELD(this,
3348 kInstanceDescriptorsOrBitField3Offset);
3349 if (object->IsSmi()) {
3350 WRITE_FIELD(this,
3351 kInstanceDescriptorsOrBitField3Offset,
3352 Smi::FromInt(value));
3353 } else {
3354 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3355 }
3356}
3357
3358
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003359FixedArray* Map::unchecked_prototype_transitions() {
3360 return reinterpret_cast<FixedArray*>(
3361 READ_FIELD(this, kPrototypeTransitionsOffset));
3362}
3363
3364
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003365ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003366ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003367ACCESSORS(Map, constructor, Object, kConstructorOffset)
3368
3369ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003370ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003371ACCESSORS(JSFunction,
3372 next_function_link,
3373 Object,
3374 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003375
3376ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3377ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003378ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003379
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003380ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003381
3382ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3383ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3384ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3385ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3386ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3387
3388ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3389ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3390ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3391
3392ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3393ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3394ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3395ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3396ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3397ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3398
3399ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3400ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3401
3402ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3403ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3404
3405ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3406ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003407ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3408 kPropertyAccessorsOffset)
3409ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3410 kPrototypeTemplateOffset)
3411ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3412ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3413 kNamedPropertyHandlerOffset)
3414ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3415 kIndexedPropertyHandlerOffset)
3416ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3417 kInstanceTemplateOffset)
3418ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3419ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003420ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3421 kInstanceCallHandlerOffset)
3422ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3423 kAccessCheckInfoOffset)
3424ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3425
3426ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003427ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3428 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003429
3430ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3431ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3432
3433ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3434
3435ACCESSORS(Script, source, Object, kSourceOffset)
3436ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003437ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003438ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3439ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003440ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003441ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003442ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003443ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003444ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003445ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003446ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003447ACCESSORS(Script, eval_from_instructions_offset, Smi,
3448 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003449
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003450#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003451ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3452ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3453ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3454ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3455
3456ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3457ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3458ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3459ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003460#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003461
3462ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003463ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3464ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003465ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3466 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003467ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003468ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3469ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003470ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003471ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3472 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003473
3474BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3475 kHiddenPrototypeBit)
3476BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3477BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3478 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003479BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3480 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003481BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3482 kIsExpressionBit)
3483BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3484 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003485BOOL_GETTER(SharedFunctionInfo,
3486 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003487 has_only_simple_this_property_assignments,
3488 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003489BOOL_ACCESSORS(SharedFunctionInfo,
3490 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003491 allows_lazy_compilation,
3492 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003493BOOL_ACCESSORS(SharedFunctionInfo,
3494 compiler_hints,
3495 uses_arguments,
3496 kUsesArguments)
3497BOOL_ACCESSORS(SharedFunctionInfo,
3498 compiler_hints,
3499 has_duplicate_parameters,
3500 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003501
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003502
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003503#if V8_HOST_ARCH_32_BIT
3504SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3505SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003506 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003507SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003508 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003509SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3510SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003511 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003512SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3513SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003514 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003515SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003516 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003517SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003518 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003519SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003520#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003521
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003522#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003523 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003524 int holder::name() { \
3525 int value = READ_INT_FIELD(this, offset); \
3526 ASSERT(kHeapObjectTag == 1); \
3527 ASSERT((value & kHeapObjectTag) == 0); \
3528 return value >> 1; \
3529 } \
3530 void holder::set_##name(int value) { \
3531 ASSERT(kHeapObjectTag == 1); \
3532 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3533 (value & 0xC0000000) == 0x000000000); \
3534 WRITE_INT_FIELD(this, \
3535 offset, \
3536 (value << 1) & ~kHeapObjectTag); \
3537 }
3538
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003539#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3540 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003541 INT_ACCESSORS(holder, name, offset)
3542
3543
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003544PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003545PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3546 formal_parameter_count,
3547 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003548
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003549PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3550 expected_nof_properties,
3551 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003552PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3553
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003554PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3555PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3556 start_position_and_type,
3557 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003558
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003559PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3560 function_token_position,
3561 kFunctionTokenPositionOffset)
3562PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3563 compiler_hints,
3564 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003565
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003566PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3567 this_property_assignments_count,
3568 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003569PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003570#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003571
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003572
3573int SharedFunctionInfo::construction_count() {
3574 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3575}
3576
3577
3578void SharedFunctionInfo::set_construction_count(int value) {
3579 ASSERT(0 <= value && value < 256);
3580 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3581}
3582
3583
whesse@chromium.org7b260152011-06-20 15:33:18 +00003584BOOL_ACCESSORS(SharedFunctionInfo,
3585 compiler_hints,
3586 live_objects_may_exist,
3587 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003588
3589
3590bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003591 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003592}
3593
3594
whesse@chromium.org7b260152011-06-20 15:33:18 +00003595BOOL_GETTER(SharedFunctionInfo,
3596 compiler_hints,
3597 optimization_disabled,
3598 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003599
3600
3601void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3602 set_compiler_hints(BooleanBit::set(compiler_hints(),
3603 kOptimizationDisabled,
3604 disable));
3605 // If disabling optimizations we reflect that in the code object so
3606 // it will not be counted as optimizable code.
3607 if ((code()->kind() == Code::FUNCTION) && disable) {
3608 code()->set_optimizable(false);
3609 }
3610}
3611
3612
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003613LanguageMode SharedFunctionInfo::language_mode() {
3614 int hints = compiler_hints();
3615 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3616 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3617 return EXTENDED_MODE;
3618 }
3619 return BooleanBit::get(hints, kStrictModeFunction)
3620 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003621}
3622
3623
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003624void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3625 // We only allow language mode transitions that go set the same language mode
3626 // again or go up in the chain:
3627 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3628 ASSERT(this->language_mode() == CLASSIC_MODE ||
3629 this->language_mode() == language_mode ||
3630 language_mode == EXTENDED_MODE);
3631 int hints = compiler_hints();
3632 hints = BooleanBit::set(
3633 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3634 hints = BooleanBit::set(
3635 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3636 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003637}
3638
3639
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003640bool SharedFunctionInfo::is_classic_mode() {
3641 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3642}
3643
3644BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3645 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003646BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3647BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3648 name_should_print_as_anonymous,
3649 kNameShouldPrintAsAnonymous)
3650BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3651BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003652
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003653ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3654ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3655
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003656ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3657
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003658bool Script::HasValidSource() {
3659 Object* src = this->source();
3660 if (!src->IsString()) return true;
3661 String* src_str = String::cast(src);
3662 if (!StringShape(src_str).IsExternal()) return true;
3663 if (src_str->IsAsciiRepresentation()) {
3664 return ExternalAsciiString::cast(src)->resource() != NULL;
3665 } else if (src_str->IsTwoByteRepresentation()) {
3666 return ExternalTwoByteString::cast(src)->resource() != NULL;
3667 }
3668 return true;
3669}
3670
3671
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003672void SharedFunctionInfo::DontAdaptArguments() {
3673 ASSERT(code()->kind() == Code::BUILTIN);
3674 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3675}
3676
3677
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003678int SharedFunctionInfo::start_position() {
3679 return start_position_and_type() >> kStartPositionShift;
3680}
3681
3682
3683void SharedFunctionInfo::set_start_position(int start_position) {
3684 set_start_position_and_type((start_position << kStartPositionShift)
3685 | (start_position_and_type() & ~kStartPositionMask));
3686}
3687
3688
3689Code* SharedFunctionInfo::code() {
3690 return Code::cast(READ_FIELD(this, kCodeOffset));
3691}
3692
3693
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003694Code* SharedFunctionInfo::unchecked_code() {
3695 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3696}
3697
3698
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003699void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003700 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003701 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003702}
3703
3704
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003705ScopeInfo* SharedFunctionInfo::scope_info() {
3706 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003707}
3708
3709
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003710void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003711 WriteBarrierMode mode) {
3712 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003713 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3714 this,
3715 kScopeInfoOffset,
3716 reinterpret_cast<Object*>(value),
3717 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003718}
3719
3720
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003721Smi* SharedFunctionInfo::deopt_counter() {
3722 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3723}
3724
3725
3726void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3727 WRITE_FIELD(this, kDeoptCounterOffset, value);
3728}
3729
3730
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003731bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003732 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003733 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003734}
3735
3736
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003737bool SharedFunctionInfo::IsApiFunction() {
3738 return function_data()->IsFunctionTemplateInfo();
3739}
3740
3741
3742FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3743 ASSERT(IsApiFunction());
3744 return FunctionTemplateInfo::cast(function_data());
3745}
3746
3747
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003748bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003749 return function_data()->IsSmi();
3750}
3751
3752
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003753BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3754 ASSERT(HasBuiltinFunctionId());
3755 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003756}
3757
3758
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003759int SharedFunctionInfo::code_age() {
3760 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3761}
3762
3763
3764void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003765 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3766 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003767}
3768
3769
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003770bool SharedFunctionInfo::has_deoptimization_support() {
3771 Code* code = this->code();
3772 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3773}
3774
3775
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003776bool JSFunction::IsBuiltin() {
3777 return context()->global()->IsJSBuiltinsObject();
3778}
3779
3780
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003781bool JSFunction::NeedsArgumentsAdaption() {
3782 return shared()->formal_parameter_count() !=
3783 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3784}
3785
3786
3787bool JSFunction::IsOptimized() {
3788 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3789}
3790
3791
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003792bool JSFunction::IsOptimizable() {
3793 return code()->kind() == Code::FUNCTION && code()->optimizable();
3794}
3795
3796
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003797bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003798 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003799}
3800
3801
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003802Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003803 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003804}
3805
3806
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003807Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003808 return reinterpret_cast<Code*>(
3809 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003810}
3811
3812
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003813void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003814 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003815 Address entry = value->entry();
3816 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003817 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3818 this,
3819 HeapObject::RawField(this, kCodeEntryOffset),
3820 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003821}
3822
3823
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003824void JSFunction::ReplaceCode(Code* code) {
3825 bool was_optimized = IsOptimized();
3826 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3827
3828 set_code(code);
3829
3830 // Add/remove the function from the list of optimized functions for this
3831 // context based on the state change.
3832 if (!was_optimized && is_optimized) {
3833 context()->global_context()->AddOptimizedFunction(this);
3834 }
3835 if (was_optimized && !is_optimized) {
3836 context()->global_context()->RemoveOptimizedFunction(this);
3837 }
3838}
3839
3840
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003841Context* JSFunction::context() {
3842 return Context::cast(READ_FIELD(this, kContextOffset));
3843}
3844
3845
3846Object* JSFunction::unchecked_context() {
3847 return READ_FIELD(this, kContextOffset);
3848}
3849
3850
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003851SharedFunctionInfo* JSFunction::unchecked_shared() {
3852 return reinterpret_cast<SharedFunctionInfo*>(
3853 READ_FIELD(this, kSharedFunctionInfoOffset));
3854}
3855
3856
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003857void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003858 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003859 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003860 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003861}
3862
3863ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3864 kPrototypeOrInitialMapOffset)
3865
3866
3867Map* JSFunction::initial_map() {
3868 return Map::cast(prototype_or_initial_map());
3869}
3870
3871
3872void JSFunction::set_initial_map(Map* value) {
3873 set_prototype_or_initial_map(value);
3874}
3875
3876
3877bool JSFunction::has_initial_map() {
3878 return prototype_or_initial_map()->IsMap();
3879}
3880
3881
3882bool JSFunction::has_instance_prototype() {
3883 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3884}
3885
3886
3887bool JSFunction::has_prototype() {
3888 return map()->has_non_instance_prototype() || has_instance_prototype();
3889}
3890
3891
3892Object* JSFunction::instance_prototype() {
3893 ASSERT(has_instance_prototype());
3894 if (has_initial_map()) return initial_map()->prototype();
3895 // When there is no initial map and the prototype is a JSObject, the
3896 // initial map field is used for the prototype field.
3897 return prototype_or_initial_map();
3898}
3899
3900
3901Object* JSFunction::prototype() {
3902 ASSERT(has_prototype());
3903 // If the function's prototype property has been set to a non-JSObject
3904 // value, that value is stored in the constructor field of the map.
3905 if (map()->has_non_instance_prototype()) return map()->constructor();
3906 return instance_prototype();
3907}
3908
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003909bool JSFunction::should_have_prototype() {
3910 return map()->function_with_prototype();
3911}
3912
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003913
3914bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003915 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003916}
3917
3918
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003919FixedArray* JSFunction::literals() {
3920 ASSERT(!shared()->bound());
3921 return literals_or_bindings();
3922}
3923
3924
3925void JSFunction::set_literals(FixedArray* literals) {
3926 ASSERT(!shared()->bound());
3927 set_literals_or_bindings(literals);
3928}
3929
3930
3931FixedArray* JSFunction::function_bindings() {
3932 ASSERT(shared()->bound());
3933 return literals_or_bindings();
3934}
3935
3936
3937void JSFunction::set_function_bindings(FixedArray* bindings) {
3938 ASSERT(shared()->bound());
3939 // Bound function literal may be initialized to the empty fixed array
3940 // before the bindings are set.
3941 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
3942 bindings->map() == GetHeap()->fixed_cow_array_map());
3943 set_literals_or_bindings(bindings);
3944}
3945
3946
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003947int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003948 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003949 return literals()->length();
3950}
3951
3952
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003953Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003954 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003955 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003956}
3957
3958
3959void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3960 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003961 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003962 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003963 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003964}
3965
3966
3967Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003968 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003969 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3970}
3971
3972
3973void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3974 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003975 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003976 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003977 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003978}
3979
3980
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003981ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003982ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003983ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3984ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3985
3986
3987void JSProxy::InitializeBody(int object_size, Object* value) {
3988 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3989 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3990 WRITE_FIELD(this, offset, value);
3991 }
3992}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003993
3994
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003995ACCESSORS(JSSet, table, Object, kTableOffset)
3996ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003997ACCESSORS(JSWeakMap, table, Object, kTableOffset)
3998ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003999
4000
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004001Address Foreign::foreign_address() {
4002 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004003}
4004
4005
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004006void Foreign::set_foreign_address(Address value) {
4007 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004008}
4009
4010
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004011ACCESSORS(JSValue, value, Object, kValueOffset)
4012
4013
4014JSValue* JSValue::cast(Object* obj) {
4015 ASSERT(obj->IsJSValue());
4016 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4017 return reinterpret_cast<JSValue*>(obj);
4018}
4019
4020
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004021ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4022ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4023ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4024ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4025ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4026SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4027SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4028
4029
4030JSMessageObject* JSMessageObject::cast(Object* obj) {
4031 ASSERT(obj->IsJSMessageObject());
4032 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4033 return reinterpret_cast<JSMessageObject*>(obj);
4034}
4035
4036
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004037INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004038ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004039ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004040ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004041ACCESSORS(Code, next_code_flushing_candidate,
4042 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004043
4044
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004045byte* Code::instruction_start() {
4046 return FIELD_ADDR(this, kHeaderSize);
4047}
4048
4049
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004050byte* Code::instruction_end() {
4051 return instruction_start() + instruction_size();
4052}
4053
4054
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004055int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004056 return RoundUp(instruction_size(), kObjectAlignment);
4057}
4058
4059
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004060FixedArray* Code::unchecked_deoptimization_data() {
4061 return reinterpret_cast<FixedArray*>(
4062 READ_FIELD(this, kDeoptimizationDataOffset));
4063}
4064
4065
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004066ByteArray* Code::unchecked_relocation_info() {
4067 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004068}
4069
4070
4071byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004072 return unchecked_relocation_info()->GetDataStartAddress();
4073}
4074
4075
4076int Code::relocation_size() {
4077 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004078}
4079
4080
4081byte* Code::entry() {
4082 return instruction_start();
4083}
4084
4085
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004086bool Code::contains(byte* inner_pointer) {
4087 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004088}
4089
4090
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004091ACCESSORS(JSArray, length, Object, kLengthOffset)
4092
4093
ager@chromium.org236ad962008-09-25 09:45:57 +00004094ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004095
4096
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004097JSRegExp::Type JSRegExp::TypeTag() {
4098 Object* data = this->data();
4099 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4100 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4101 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004102}
4103
4104
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004105JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4106 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4107 return static_cast<JSRegExp::Type>(smi->value());
4108}
4109
4110
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004111int JSRegExp::CaptureCount() {
4112 switch (TypeTag()) {
4113 case ATOM:
4114 return 0;
4115 case IRREGEXP:
4116 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4117 default:
4118 UNREACHABLE();
4119 return -1;
4120 }
4121}
4122
4123
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004124JSRegExp::Flags JSRegExp::GetFlags() {
4125 ASSERT(this->data()->IsFixedArray());
4126 Object* data = this->data();
4127 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4128 return Flags(smi->value());
4129}
4130
4131
4132String* JSRegExp::Pattern() {
4133 ASSERT(this->data()->IsFixedArray());
4134 Object* data = this->data();
4135 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4136 return pattern;
4137}
4138
4139
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004140Object* JSRegExp::DataAt(int index) {
4141 ASSERT(TypeTag() != NOT_COMPILED);
4142 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004143}
4144
4145
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004146Object* JSRegExp::DataAtUnchecked(int index) {
4147 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4148 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4149 return READ_FIELD(fa, offset);
4150}
4151
4152
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004153void JSRegExp::SetDataAt(int index, Object* value) {
4154 ASSERT(TypeTag() != NOT_COMPILED);
4155 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4156 FixedArray::cast(data())->set(index, value);
4157}
4158
4159
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004160void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4161 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4162 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4163 if (value->IsSmi()) {
4164 fa->set_unchecked(index, Smi::cast(value));
4165 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004166 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004167 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4168 }
4169}
4170
4171
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004172ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004173 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004174#if DEBUG
4175 FixedArrayBase* fixed_array =
4176 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4177 Map* map = fixed_array->map();
4178 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004179 (map == GetHeap()->fixed_array_map() ||
4180 map == GetHeap()->fixed_cow_array_map())) ||
4181 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004182 (fixed_array->IsFixedDoubleArray() ||
4183 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004184 (kind == DICTIONARY_ELEMENTS &&
4185 fixed_array->IsFixedArray() &&
4186 fixed_array->IsDictionary()) ||
4187 (kind > DICTIONARY_ELEMENTS));
4188 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4189 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004190#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004191 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004192}
4193
4194
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004195ElementsAccessor* JSObject::GetElementsAccessor() {
4196 return ElementsAccessor::ForKind(GetElementsKind());
4197}
4198
4199
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004200bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004201 return GetElementsKind() == FAST_ELEMENTS;
4202}
4203
4204
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004205bool JSObject::HasFastSmiOnlyElements() {
4206 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4207}
4208
4209
4210bool JSObject::HasFastTypeElements() {
4211 ElementsKind elements_kind = GetElementsKind();
4212 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4213 elements_kind == FAST_ELEMENTS;
4214}
4215
4216
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004217bool JSObject::HasFastDoubleElements() {
4218 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4219}
4220
4221
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004222bool JSObject::HasDictionaryElements() {
4223 return GetElementsKind() == DICTIONARY_ELEMENTS;
4224}
4225
4226
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004227bool JSObject::HasNonStrictArgumentsElements() {
4228 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4229}
4230
4231
ager@chromium.org3811b432009-10-28 14:53:37 +00004232bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004233 HeapObject* array = elements();
4234 ASSERT(array != NULL);
4235 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004236}
4237
4238
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004239#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4240bool JSObject::HasExternal##name##Elements() { \
4241 HeapObject* array = elements(); \
4242 ASSERT(array != NULL); \
4243 if (!array->IsHeapObject()) \
4244 return false; \
4245 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004246}
4247
4248
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004249EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4250EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4251EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4252EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4253 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4254EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4255EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4256 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4257EXTERNAL_ELEMENTS_CHECK(Float,
4258 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004259EXTERNAL_ELEMENTS_CHECK(Double,
4260 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004261EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004262
4263
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004264bool JSObject::HasNamedInterceptor() {
4265 return map()->has_named_interceptor();
4266}
4267
4268
4269bool JSObject::HasIndexedInterceptor() {
4270 return map()->has_indexed_interceptor();
4271}
4272
4273
lrn@chromium.org303ada72010-10-27 09:33:13 +00004274MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004275 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004276 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004277 Isolate* isolate = GetIsolate();
4278 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004279 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004280 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4281 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004282 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4283 return maybe_writable_elems;
4284 }
4285 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004286 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004287 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004288 return writable_elems;
4289}
4290
4291
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004292StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004293 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004294 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004295}
4296
4297
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004298NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004299 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004300 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004301}
4302
4303
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004304bool String::IsHashFieldComputed(uint32_t field) {
4305 return (field & kHashNotComputedMask) == 0;
4306}
4307
4308
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004309bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004310 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004311}
4312
4313
4314uint32_t String::Hash() {
4315 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004316 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004317 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004318 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004319 return ComputeAndSetHash();
4320}
4321
4322
ager@chromium.org7c537e22008-10-16 08:43:32 +00004323StringHasher::StringHasher(int length)
4324 : length_(length),
4325 raw_running_hash_(0),
4326 array_index_(0),
4327 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4328 is_first_char_(true),
4329 is_valid_(true) { }
4330
4331
4332bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004333 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004334}
4335
4336
4337void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004338 // Use the Jenkins one-at-a-time hash function to update the hash
4339 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004340 raw_running_hash_ += c;
4341 raw_running_hash_ += (raw_running_hash_ << 10);
4342 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004343 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004344 if (is_array_index_) {
4345 if (c < '0' || c > '9') {
4346 is_array_index_ = false;
4347 } else {
4348 int d = c - '0';
4349 if (is_first_char_) {
4350 is_first_char_ = false;
4351 if (c == '0' && length_ > 1) {
4352 is_array_index_ = false;
4353 return;
4354 }
4355 }
4356 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4357 is_array_index_ = false;
4358 } else {
4359 array_index_ = array_index_ * 10 + d;
4360 }
4361 }
4362 }
4363}
4364
4365
4366void StringHasher::AddCharacterNoIndex(uc32 c) {
4367 ASSERT(!is_array_index());
4368 raw_running_hash_ += c;
4369 raw_running_hash_ += (raw_running_hash_ << 10);
4370 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4371}
4372
4373
4374uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004375 // Get the calculated raw hash value and do some more bit ops to distribute
4376 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004377 uint32_t result = raw_running_hash_;
4378 result += (result << 3);
4379 result ^= (result >> 11);
4380 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004381 if (result == 0) {
4382 result = 27;
4383 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004384 return result;
4385}
4386
4387
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004388template <typename schar>
4389uint32_t HashSequentialString(const schar* chars, int length) {
4390 StringHasher hasher(length);
4391 if (!hasher.has_trivial_hash()) {
4392 int i;
4393 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4394 hasher.AddCharacter(chars[i]);
4395 }
4396 for (; i < length; i++) {
4397 hasher.AddCharacterNoIndex(chars[i]);
4398 }
4399 }
4400 return hasher.GetHashField();
4401}
4402
4403
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004404bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004405 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004406 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4407 return false;
4408 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004409 return SlowAsArrayIndex(index);
4410}
4411
4412
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004413Object* JSReceiver::GetPrototype() {
4414 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004415}
4416
4417
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004418bool JSReceiver::HasProperty(String* name) {
4419 if (IsJSProxy()) {
4420 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4421 }
4422 return GetPropertyAttribute(name) != ABSENT;
4423}
4424
4425
4426bool JSReceiver::HasLocalProperty(String* name) {
4427 if (IsJSProxy()) {
4428 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4429 }
4430 return GetLocalPropertyAttribute(name) != ABSENT;
4431}
4432
4433
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004434PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004435 return GetPropertyAttributeWithReceiver(this, key);
4436}
4437
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004438// TODO(504): this may be useful in other places too where JSGlobalProxy
4439// is used.
4440Object* JSObject::BypassGlobalProxy() {
4441 if (IsJSGlobalProxy()) {
4442 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004443 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004444 ASSERT(proto->IsJSGlobalObject());
4445 return proto;
4446 }
4447 return this;
4448}
4449
4450
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004451MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4452 return IsJSProxy()
4453 ? JSProxy::cast(this)->GetIdentityHash(flag)
4454 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004455}
4456
4457
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004458bool JSReceiver::HasElement(uint32_t index) {
4459 if (IsJSProxy()) {
4460 return JSProxy::cast(this)->HasElementWithHandler(index);
4461 }
4462 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004463}
4464
4465
4466bool AccessorInfo::all_can_read() {
4467 return BooleanBit::get(flag(), kAllCanReadBit);
4468}
4469
4470
4471void AccessorInfo::set_all_can_read(bool value) {
4472 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4473}
4474
4475
4476bool AccessorInfo::all_can_write() {
4477 return BooleanBit::get(flag(), kAllCanWriteBit);
4478}
4479
4480
4481void AccessorInfo::set_all_can_write(bool value) {
4482 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4483}
4484
4485
ager@chromium.org870a0b62008-11-04 11:43:05 +00004486bool AccessorInfo::prohibits_overwriting() {
4487 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4488}
4489
4490
4491void AccessorInfo::set_prohibits_overwriting(bool value) {
4492 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4493}
4494
4495
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004496PropertyAttributes AccessorInfo::property_attributes() {
4497 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4498}
4499
4500
4501void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004502 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004503}
4504
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004505
4506template<typename Shape, typename Key>
4507void Dictionary<Shape, Key>::SetEntry(int entry,
4508 Object* key,
4509 Object* value) {
4510 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4511}
4512
4513
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004514template<typename Shape, typename Key>
4515void Dictionary<Shape, Key>::SetEntry(int entry,
4516 Object* key,
4517 Object* value,
4518 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004519 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004520 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004521 AssertNoAllocation no_gc;
4522 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004523 FixedArray::set(index, key, mode);
4524 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004525 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004526}
4527
4528
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004529bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4530 ASSERT(other->IsNumber());
4531 return key == static_cast<uint32_t>(other->Number());
4532}
4533
4534
4535uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4536 return ComputeIntegerHash(key);
4537}
4538
4539
4540uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4541 ASSERT(other->IsNumber());
4542 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4543}
4544
4545
4546MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4547 return Isolate::Current()->heap()->NumberFromUint32(key);
4548}
4549
4550
4551bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4552 // We know that all entries in a hash table had their hash keys created.
4553 // Use that knowledge to have fast failure.
4554 if (key->Hash() != String::cast(other)->Hash()) return false;
4555 return key->Equals(String::cast(other));
4556}
4557
4558
4559uint32_t StringDictionaryShape::Hash(String* key) {
4560 return key->Hash();
4561}
4562
4563
4564uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4565 return String::cast(other)->Hash();
4566}
4567
4568
4569MaybeObject* StringDictionaryShape::AsObject(String* key) {
4570 return key;
4571}
4572
4573
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004574template <int entrysize>
4575bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4576 return key->SameValue(other);
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>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004582 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4583 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004584}
4585
4586
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004587template <int entrysize>
4588uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4589 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004590 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4591 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004592}
4593
4594
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004595template <int entrysize>
4596MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004597 return key;
4598}
4599
4600
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004601void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004602 // No write barrier is needed since empty_fixed_array is not in new space.
4603 // Please note this function is used during marking:
4604 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004605 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4606 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004607}
4608
4609
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004610void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004611 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004612 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004613 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4614 if (elts->length() < required_size) {
4615 // Doubling in size would be overkill, but leave some slack to avoid
4616 // constantly growing.
4617 Expand(required_size + (required_size >> 3));
4618 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004619 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004620 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4621 // Expand will allocate a new backing store in new space even if the size
4622 // we asked for isn't larger than what we had before.
4623 Expand(required_size);
4624 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004625}
4626
4627
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004628void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004629 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004630 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4631}
4632
4633
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004634bool JSArray::AllowsSetElementsLength() {
4635 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4636 ASSERT(result == !HasExternalArrayElements());
4637 return result;
4638}
4639
4640
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004641MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4642 MaybeObject* maybe_result = EnsureCanContainElements(
4643 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4644 if (maybe_result->IsFailure()) return maybe_result;
4645 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4646 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4647 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4648 ((GetElementsKind() == FAST_ELEMENTS) ||
4649 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4650 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004651 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004652 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004653 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004654}
4655
4656
lrn@chromium.org303ada72010-10-27 09:33:13 +00004657MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004658 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004659 return GetHeap()->CopyFixedArray(this);
4660}
4661
4662
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004663MaybeObject* FixedDoubleArray::Copy() {
4664 if (length() == 0) return this;
4665 return GetHeap()->CopyFixedDoubleArray(this);
4666}
4667
4668
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004669Relocatable::Relocatable(Isolate* isolate) {
4670 ASSERT(isolate == Isolate::Current());
4671 isolate_ = isolate;
4672 prev_ = isolate->relocatable_top();
4673 isolate->set_relocatable_top(this);
4674}
4675
4676
4677Relocatable::~Relocatable() {
4678 ASSERT(isolate_ == Isolate::Current());
4679 ASSERT_EQ(isolate_->relocatable_top(), this);
4680 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004681}
4682
4683
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004684int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4685 return map->instance_size();
4686}
4687
4688
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004689void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004690 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004691 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004692}
4693
4694
4695template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004696void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004697 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004698 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004699}
4700
4701
4702void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4703 typedef v8::String::ExternalAsciiStringResource Resource;
4704 v->VisitExternalAsciiString(
4705 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4706}
4707
4708
4709template<typename StaticVisitor>
4710void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4711 typedef v8::String::ExternalAsciiStringResource Resource;
4712 StaticVisitor::VisitExternalAsciiString(
4713 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4714}
4715
4716
4717void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4718 typedef v8::String::ExternalStringResource Resource;
4719 v->VisitExternalTwoByteString(
4720 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4721}
4722
4723
4724template<typename StaticVisitor>
4725void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4726 typedef v8::String::ExternalStringResource Resource;
4727 StaticVisitor::VisitExternalTwoByteString(
4728 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4729}
4730
4731#define SLOT_ADDR(obj, offset) \
4732 reinterpret_cast<Object**>((obj)->address() + offset)
4733
4734template<int start_offset, int end_offset, int size>
4735void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4736 HeapObject* obj,
4737 ObjectVisitor* v) {
4738 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4739}
4740
4741
4742template<int start_offset>
4743void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4744 int object_size,
4745 ObjectVisitor* v) {
4746 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4747}
4748
4749#undef SLOT_ADDR
4750
4751
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004752#undef CAST_ACCESSOR
4753#undef INT_ACCESSORS
4754#undef SMI_ACCESSORS
4755#undef ACCESSORS
4756#undef FIELD_ADDR
4757#undef READ_FIELD
4758#undef WRITE_FIELD
4759#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004760#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004761#undef READ_MEMADDR_FIELD
4762#undef WRITE_MEMADDR_FIELD
4763#undef READ_DOUBLE_FIELD
4764#undef WRITE_DOUBLE_FIELD
4765#undef READ_INT_FIELD
4766#undef WRITE_INT_FIELD
4767#undef READ_SHORT_FIELD
4768#undef WRITE_SHORT_FIELD
4769#undef READ_BYTE_FIELD
4770#undef WRITE_BYTE_FIELD
4771
4772
4773} } // namespace v8::internal
4774
4775#endif // V8_OBJECTS_INL_H_